struct BI {
string s; int op = 0;
BI(string s = "") : s(s) {}
BI operator+(const BI &x) {
BI res;
int a[N] = {}, b[N] = {}, c[N] = {}, op = 0, len = max(s.size(), x.s.size());
for (int i = 0; i < s.size(); i ++) a[i + 1] = s[s.size() - i - 1] - '0';
for (int i = 0; i < x.s.size(); i ++) b[i + 1] = x.s[x.s.size() - i - 1] - '0';
for (int i = 1; i <= len; i ++) c[i] = a[i] + b[i] + op, op = c[i] / 10, c[i] %= 10;
if (op) c[++ len] = 1;
for (int i = 0; i < len; i ++) res.s += c[len - i] + '0';
return res;
}
bool operator>(const BI &x) {
return s.size() != x.s.size() ? s.size() > x.s.size() : s > x.s;
}
bool operator<(const BI &x) {
return s.size() != x.s.size() ? s.size() < x.s.size() : s < x.s;
}
BI operator-(const BI &x) {
BI A(s), B = x, res("");
if (A.s == B.s) return BI("0"); if (A < B) swap(A, B), res.op = 1;
int a[N] = {}, b[N] = {}, c[N] = {}, op = 0, len = A.s.size();
for (int i = 0; i < A.s.size(); i ++) a[i + 1] = A.s[A.s.size() - i - 1] - '0';
for (int i = 0; i < B.s.size(); i ++) b[i + 1] = B.s[B.s.size() - i - 1] - '0';
for (int i = 1; i <= len; i ++)
c[i] = a[i] - op - b[i], op = (c[i] < 0), (c[i] += 10) %= 10;
while (c[len] == 0) len --; if (res.op) res.s += '-';
for (int i = 0; i < len; i ++) res.s += c[len - i] + '0';
return res;
}
BI operator*(const BI &x) {
BI res("");
if (s == "0" || x.s == "0") return BI("0");
int a[N] = {}, b[N] = {}, c[N] = {}, op = 0, l1 = s.size(), l2 = x.s.size();
for (int i = 0; i < s.size(); i ++) a[i + 1] = s[s.size() - i - 1] - '0';
for (int i = 0; i < x.s.size(); i ++) b[i + 1] = x.s[x.s.size() - i - 1] - '0';
for (int i = 1; i <= l1; i ++) for (int j = 1; j <= l2; j ++) c[i + j - 1] += a[i] * b[j];
for (int i = 1; i <= l1 + l2 - 1; i ++) c[i] += op, op = c[i] / 10, c[i] %= 10;
for (int i = 0; i < l1 + l2 - 1; i ++) res.s += c[l1 + l2 - 1 - i] + '0';
while (op) res.s += (op % 10) + '0', op /= 10;
return res;
}
};