#include "num.h"
#include <stdint.h>

int calc_val(int val, int mod, int64_t a) {
if (mod != 0) {
if (a > 0)
val = a % mod;
else
val = (mod + (a % mod)) % mod;
} else {
val = a;
}
return val;
}

Num::Num(int value, int modulo) : value(value), modulo(modulo) {
if (modulo != 0) this->value = value % modulo;
}

Num &Num::operator=(const Num &other) {
this->value = other.value;
this->modulo = other.modulo;
return *this;
}

Num Num::operator+(const Num &other) {
Num N(this->value, this->modulo);
int64_t a = (int64_t) this->value + other.value;
N.value = calc_val(N.value, modulo, a);
return N;
}

Num &Num::operator+=(const Num &other) { return *this = *this + other; }

Num Num::operator-(const Num &other) {
Num N(this->value, this->modulo);
int64_t a = (int64_t) this->value - other.value;
N.value = calc_val(N.value, modulo, a);
return N;
}

Num &Num::operator-=(const Num &other) { return *this = *this - other; }

Num Num::operator*(const Num &other) {
Num N(this->value, this->modulo);
int64_t a = (int64_t) this->value * other.value;
N.value = calc_val(N.value, modulo, a);
return N;
}

Num &Num::operator*=(const Num &other) { return *this = *this * other; }

Num Num::operator+(int num) {
Num N(this->value, this->modulo);
int64_t a = (int64_t) this->value + num;
N.value = calc_val(N.value, modulo, a);
return N;
}

Num &Num::operator+=(int num) { return *this = *this + num; }

Num Num::operator-(int num) {
Num N(this->value, this->modulo);
int64_t a = (int64_t) this->value - num;
N.value = calc_val(N.value, modulo, a);
return N;
}

Num &Num::operator-=(int num) { return *this = *this - num; }

Num Num::operator*(int num) {
Num N(this->value, this->modulo);
int64_t a = (int64_t) this->value * num;
N.value = calc_val(N.value, modulo, a);
return N;
}

Num &Num::operator*=(int num) { return *this = *this * num; }
#include <vector>

template <typename T, typename M>
auto initialize_vector(T value, M size) {
std::vector<T> vec(size, value);
return vec;
}

template <typename T, typename M, typename... Args>
auto initialize_vector(T value, M arg, Args... others) {
std::vector<decltype(initialize_vector(value, others...))> vec(
arg, initialize_vector(value, others...));
return vec;
}