using int64 = long long;
struct hpint {
std::vector<int> val;
bool isPositive = true;
hpint() {}
template <class T>
hpint(const T x) {
auto result = str_to_vec(x);
isPositive = result.first;
val = result.second;
}
hpint(const std::string& s) {
auto result = str_to_vec(s);
isPositive = result.first;
val = result.second;
}
hpint(const std::vector<int>& v) : val(v) {}
hpint(const std::pair<bool, std::vector<int>>& A) {
isPositive = A.first;
val = A.second;
}
static std::pair<bool, std::vector<int>> str_to_vec(const std::string& s) {
std::vector<int> res;
bool positive = true;
std::string str = s;
if (str[0] == '-') {
positive = false;
str = str.substr(1);
}
for (auto x : str) {
res.push_back(x - '0');
}
return std::make_pair(positive, res);
}
static int hpint_to_int(const hpint &A) {
int res = 0, power = -1 + 2 * (A.isPositive);
for (int i = A.val.size() - 1; i >= 0; i--) {
res += A.val[i] * power;
power *= 10;
}
return res;
}
static hpint abs(const hpint& A) {
return hpint(std::make_pair(true, A.val));
}
static std::vector<int> add(const std::vector<int>& A, const std::vector<int>& B) {
std::vector<int> res;
int carry = 0, backA = A.size() - 1, backB = B.size() - 1;
while (backA >= 0 || backB >= 0 || carry) {
if (backA >= 0) {
carry += A[backA];
backA--;
}
if (backB >= 0) {
carry += B[backB];
backB--;
}
res.insert(res.begin(), carry % 10);
carry /= 10;
}
return res;
}
static std::vector<int> sub(const std::vector<int>& A, const std::vector<int>& B) {
std::vector<int> res;
int borrow = 0;
for (int i = 0; i < A.size(); i++) {
int digitA = A[A.size() - 1 - i];
int digitB = (i < B.size()) ? B[B.size() - 1 - i] : 0;
int diff = digitA - digitB - borrow;
if (diff < 0) {
diff += 10;
borrow = 1;
} else {
borrow = 0;
}
res.insert(res.begin(), diff);
}
while (res.size() > 1 && res[0] == 0) {
res.erase(res.begin());
}
return res;
}
template <class T>
static std::pair<bool, std::vector<int>> str_to_vec(const T x) {
return str_to_vec(std::to_string(x));
}
bool operator<(const hpint& other) const {
if (isPositive == false && other.isPositive == true) {
return true;
}
if (isPositive == true && other.isPositive == false) {
return false;
}
if (isPositive == false && other.isPositive == false) {
if (val.size() != other.val.size()) {
return val.size() > other.val.size();
}
for (int i = 0; i < val.size(); i++) {
if (val[i] != other.val[i]) {
return val[i] > other.val[i];
}
}
return false;
}
if (isPositive == true && other.isPositive == true) {
if (val.size() != other.val.size()) {
return val.size() < other.val.size();
}
for (int i = 0; i < val.size(); i++) {
if (val[i] != other.val[i]) {
return val[i] < other.val[i];
}
}
return false;
}
return false;
}
bool operator<(const int other) const {
return *this < hpint(other);
}
bool operator>(const hpint& other) const {
return other < *this;
}
bool operator>(const int other) const {
return hpint(other) < *this;
}
hpint operator+(const hpint& other) const {
if (isPositive == other.isPositive) {
return hpint(std::make_pair(isPositive, add(val, other.val)));
} else {
std::vector<int> value;
if (hpint::abs(*this) > hpint::abs(other)) {
value = sub(val, other.val);
return hpint(std::make_pair(isPositive, value));
} else {
value = sub(other.val, val);
return hpint(std::make_pair(other.isPositive, value));
}
}
}
const hpint operator-(const hpint& other) const {
return *this + hpint(std::make_pair(!other.isPositive, other.val));
}
const hpint operator*(int &b) const {
hpint res;
res.isPositive = (isPositive == (b > 0));
int absb = std::abs(b);
int carry = 0;
for (int i = val.size() - 1; i >= 0; i--) {
int product = val[i] * absb + carry;
res.val.insert(res.val.begin(), product % 10);
carry = product / 10;
}
if (carry > 0) {
res.val.insert(res.val.begin(), carry);
}
while (res.val.size() > 1 && res.val[0] == 0) {
res.val.erase(res.val.begin());
}
return res;
}
const hpint operator/(int b) const {
hpint res;
res.isPositive = (isPositive == (b > 0));
int absb = std::abs(b);
int remainder = 0;
for (int i = 0; i < val.size(); i++) {
int dividend = remainder * 10 + val[i];
res.val.push_back(dividend / absb);
remainder = dividend % absb;
}
while (res.val.size() > 1 && res.val[0] == 0) {
res.val.erase(res.val.begin());
}
return hpint(res);
}
const int operator%(int b) const {
hpint remainder = *this - (*this / b * b);
return hpint_to_int(remainder);
}
friend std::istream &operator>>(std::istream &is, hpint &a) {
std::string s;
is >> s;
a = hpint(s);
return is;
}
friend std::ostream &operator<<(std::ostream& os, const hpint &a) {
if (a.isPositive == 0 && (a.val[0] != 0)) {
os << '-';
}
for (int x : a.val) {
os << x;
}
return os;
}
};