struct bignum {
vector<int> v;
bignum() { }
bignum(long long num) {
while (num) {
v.push_back(num % 10);
num /= 10;
}
}
bignum(char str[], int begin, int len) {
for (int i = begin + len - 1; i >= begin; --i)
v.push_back(str[i] - '0');
}
void tostr(char res[]) {
int j = 0;
for (int i = v.size() - 1; i >= 0; --i)
res[j++] = v[i] + '0';
res[j] = '\0';
if (res[0] == '\0') {
res[0] = '0';
res[1] = '\0';
}
}
};
bignum operator +(const bignum& a, const bignum& b) {
bignum res;
res.v.resize(max(a.v.size(), b.v.size()) + 1);
for (int i = 0; i < res.v.size(); ++i) {
if (i < a.v.size() && i < b.v.size())
res.v[i] = a.v[i] + b.v[i];
else if (i < a.v.size())
res.v[i] = a.v[i];
else if (i < b.v.size())
res.v[i] = b.v[i];
}
for (int i = 0; i < res.v.size() - 1; ++i) {
if (res.v[i] >= 10) {
res.v[i] -= 10;
++res.v[i + 1];
}
}
if (res.v[res.v.size() - 1] == 0) res.v.pop_back();
return res;
}
bignum operator *(const bignum& a, const bignum& b) {
bignum res;
vector<bignum> mid;
mid.resize(b.v.size());
for (int i = 0; i < b.v.size(); ++i) {
mid[i].v.resize(i + a.v.size() + 1);
for (int j = 0; j < a.v.size(); ++j)
mid[i].v[i + j] = a.v[j] * b.v[i];
for (int j = i; j < mid[i].v.size() - 1; ++j) {
mid[i].v[j + 1] += mid[i].v[j] / 10;
mid[i].v[j] %= 10;
}
}
for (int i = 0; i < b.v.size(); ++i)
res = res + mid[i];
if (res.v[res.v.size() - 1] == 0) res.v.pop_back();
return res;
}