namespace BIGINT { using ull = unsignedlonglong; using bigint = __int128; using bigbig = __int128; structbign { staticconstint block = 16; staticconst ull base = 10000000000000000; std::vector<ull> a; bign() : a(std::vector<ull>()) {} bign(ull x) { for (; x; x /= base) a.push_back(x % base); } bign(std::string s) { std::reverse(s.begin(), s.end()); for (int i = 0; i < (int)s.length(); i += block) { int r = std::min((int)s.length(), i + block); ull x = 0; for (int j = r - 1; j >= i; j--) x = x * 10 + s[j] - 48; a.push_back(x); } } bign operator=(ull x) { return *this = bign(x); } bign operator=(std::string s) { return *this = bign(s); } voidresize(int len){ a.assign(len, 0); } ull operator[](constint &x) const { return a[x]; } ull &operator[](constint &x) { return a[x]; } friend std::istream &operator>>(std::istream &in, bign &x) { std::string s; in >> s, x = s; return in; } friend std::ostream &operator<<(std::ostream &out, const bign &x) { if (x.a.empty()) out << "0"; else { ull ed = x.a.back(); printf("%llu", ed); for (int i = x.a.size() - 2; ~i; i--) printf("%0*llu", block, x[i]); } return out; } booloperator<(const bign &x) const { if (a.size() != x.a.size()) return a.size() < x.a.size(); for (int i = a.size() - 1; ~i; i--) if (a[i] ^ x[i]) return a[i] < x[i]; return0; } booloperator==(const bign &x) const { if (a.size() != x.a.size()) return0; for (int i = 0; i < (int)a.size(); i++) if (a[i] ^ x[i]) return0; return1; } booloperator!=(const bign &x) const { return !(*this == x); } booloperator>(const bign &x) const { return x < *this; } booloperator<=(const bign &x) const { if (a.size() != x.a.size()) return a.size() < x.a.size(); for (int i = a.size() - 1; ~i; i--) if (a[i] ^ x[i]) return a[i] < x[i]; return1; } booloperator>=(const bign &x) const { return x <= *this; } bign operator+=(const bign &x) { ull r = 0; for (int i = 0; i < (int)x.a.size() || r; i++) { if (i < (int)x.a.size()) r += x[i]; if (i >= (int)a.size()) a.push_back(0); if ((a[i] += r) >= base) r = 1, a[i] -= base; else r = 0; } return *this; } bign operator+(const bign &x) const { bign t = *this; return t += x; } bign operator-=(const bign &x) { ull r = 0; for (int i = 0; i < (int)x.a.size() || r; i++) { if (i < (int)x.a.size()) r += x[i]; if (a[i] >= r) a[i] -= r, r = 0; else a[i] += base - r, r = 1; } for (; !a.empty() && !a.back();) a.pop_back(); return *this; } bign operator-(const bign &x) const { bign t = *this; return t -= x; } bign operator-=(const ull &_x) { ull r = 0; ull x = _x; for (int i = 0; x || r; i++) { r += x % base, x /= base; if (a[i] >= r) a[i] -= r, r = 0; else a[i] += base - r, r = 1; } for (; !a.empty() && !a.back();) a.pop_back(); return *this; } bign operator-(const ull &x) const { bign t = *this; return t -= x; } friendvoidreduce(bign &a){ for (; !a.a.empty() && !a.a.back(); a.a.pop_back()); } friendvoidsplit(const bign &a, bign &x, bign &y, int mid){ int len = std::min(mid, (int)a.a.size()); y.resize(len); for (int i = 0; i < len; i++) y[i] = a[i]; len = std::max<int>(0, (int)a.a.size() - mid); x.resize(len); for (int i = 0; i < len; i++) x[i] = a[mid + i]; reduce(x), reduce(y); } friend bign mul(const bign &a, int x){ if (a.a.empty()) returnbign(); bign b; b.resize(a.a.size() + x); for (int i = a.a.size() - 1; ~i; i--) b[i + x] = a[i]; return b; } bign operator*(const bign &x) const { if (a.size() <= 20 && x.a.size() <= 20) { int len = a.size() + x.a.size() + 1; std::vector<bigbig> t(a.size() + x.a.size() + 1); for (int i = 0; i < (int)a.size(); i++) for (int j = 0; j < (int)x.a.size(); j++) { int k = i + j; t[k] += (bigbig)a[i] * x[j], t[k + 1] += t[k] / base, t[k] %= base; } bign ans; ans.resize(len); for (int i = 0; i < (int)t.size(); i++) { if (i + 1 < (int)t.size()) t[i + 1] += t[i] / base; ans[i] = t[i] % base; } reduce(ans); return ans; } int mid = (std::max(a.size(), x.a.size()) + 1) / 2; bign A, B, C, D; split(*this, A, B, mid); split(x, C, D, mid); bign ac = A * C, bd = B * D, t = (A + B) * (C + D) - ac - bd; returnmul(ac, mid * 2) + mul(t, mid) + bd; } bign operator*=(const bign &x) { return *this = *this * x; } bign operator*=(constint &x) { bigint r = 0; for (int i = 0; i < (int)a.size() || r; i++) { if (i >= (int)a.size()) a.push_back(0); r += x * (bigint)a[i], a[i] = r % base, r /= base; } return *this; } bign operator*(constint &x) const { bign t = *this; return t *= x; } bign operator*=(const ull &x) { bigint r = 0; for (int i = 0; i < (int)a.size() || r; i++) { if (i >= (int)a.size()) a.push_back(0); r += x * (bigint)a[i], a[i] = r % base, r /= base; } return *this; } bign operator*(const ull &x) const { bign t = *this; return t *= x; } bign operator/=(const ull &x) { bigint r = 0; for (int i = a.size() - 1; ~i; i--) { r = r * base + a[i]; a[i] = r / x, r %= x; } for (; !a.empty() && !a.back();) a.pop_back(); return *this; } bign operator/(const ull &x) const { bign t = *this; return t /= x; } friend bign qpow(const bign &_x, const ull &_y){ bign x(_x), ans(1); for (ull y = _y; y; y >>= 1, x *= x) if (y & 1) ans *= x; return ans; } ull trans()const{ ull x = 0; for (int i = a.size() - 1; ~i; i--) x = x * base + a[i]; return x; } ull operator%(const ull &x) const { ull res = 0; for (int i = a.size() - 1; ~i; i--) { res = ((bigbig)res * base + a[i]) % x; } return res; } }; } // namespace BIGINT
using BIGINT::bign;
using i128 = __int128_t;
constint kMaxN = 270, kMod = 1e9 + 7;
bign f[kMaxN], g[kMaxN][kMaxN], h[kMaxN];
constexprintqpow(int bs, int64_t idx = kMod - 2){ int ret = 1; for (; idx; idx >>= 1, bs = (int64_t)bs * bs % kMod) if (idx & 1) ret = (int64_t)ret * bs % kMod; return ret; }
inlineintadd(int x, int y){ return (x + y >= kMod ? x + y - kMod : x + y); } inlineintsub(int x, int y){ return (x >= y ? x - y : x - y + kMod); } inlinevoidinc(int &x, int y){ (x += y) >= kMod ? x -= kMod : x; } inlinevoiddec(int &x, int y){ (x -= y) < 0 ? x += kMod : x; }
bign C(bign n, int m){ staticbool vis[kMaxN]; if (n < m) return0; bign ret = 1; memset(vis, 0, sizeof(vis)); for (bign i = n; i > n - m; i = i - 1) { ret *= i; for (int j = 1; j <= m; ++j) if (!vis[j] && ret % j == 0) ret /= j, vis[j] = 1; } return ret; }
voidprework(){ g[0][0] = 1; for (int i = 1; i <= 266; ++i) { h[i] = g[i - 1][i - 1]; if (i & 1) f[i] = g[(i - 1) / 2][i - 1]; else f[i] = g[i / 2 - 1][i - 1] + C(h[i / 2], 2); for (int j = 0; j <= 266; ++j) { for (int k = 0; k <= j / i; ++k) g[i][j] += C(h[i], k) * g[i - 1][j - i * k]; } } }
intsolve(bign n){ if (n == 1) return0; elseif (n <= 5) return-1; elseif (n == 6) return9; int _n = n % kMod, ans = (1ll * _n * (_n - 1) / 2 % kMod - _n + kMod) % kMod; for (int i = 1; i <= 266; ++i) { if (n > (bign)i * f[i]) { n -= (bign)i * f[i], inc(ans, f[i] % kMod); } else { inc(ans, (n / i) % kMod); break; } } return ans; }