#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define _overload3(_1,_2,_3,name,...) name #define _rep(i,n) repi(i,0,n) #define repi(i,a,b) for(int i=a;i=b;--i) #define rrep(...) _overload3(__VA_ARGS__,rrepi,_rrep,)(__VA_ARGS__) #define all(x) (x).begin(),(x).end() #define PRINT(V) cout << V << "\n" #define SORT(V) sort((V).begin(),(V).end()) #define RSORT(V) sort((V).rbegin(), (V).rend()) using namespace std; using namespace atcoder; using ll = long long; templatebool chmax(T &a, const T &b) { if (abool chmin(T &a, const T &b) { if (b void cins(itr first,itr last){ for (auto i = first;i != last;i++){ cin >> (*i); } } template void array_output(itr start,itr goal){ string ans = "",k = " "; for (auto i = start;i != goal;i++) ans += to_string(*i)+k; if (!ans.empty()) ans.pop_back(); PRINT(ans); } ll gcd(ll a, ll b) { return a ? gcd(b%a,a) : b; } const ll INF = 1e18; const ll MOD = 1000000007; const ll MOD2 = 998244353; const ll MOD3 = 1e6; const ll EPS = 1e-10; int sgn(const double a){ return (a < -EPS ? -1 : (a > EPS ? +1 : 0)); } typedef pair pi; typedef pair P; typedef tuple tri; typedef pair point; typedef complex Point; const ll MAX = 105; constexpr ll nx[4] = {-1,0,1,0}; constexpr ll ny[4] = {0,1,0,-1}; template struct FormalPowerSeries : vector { using vector::vector; using vector::operator=; using F = FormalPowerSeries; F operator-() const { F res(*this); for (auto &e : res) e = -e; return res; } F &operator*=(const T &g) { for (auto &e : *this) e *= g; return *this; } F &operator/=(const T &g) { assert(g != T(0)); *this *= g.inv(); return *this; } F &operator+=(const F &g) { int n = (*this).size(), m = g.size(); rep(i, min(n, m)) (*this)[i] += g[i]; return *this; } F &operator-=(const F &g) { int n = (*this).size(), m = g.size(); rep(i, min(n, m)) (*this)[i] -= g[i]; return *this; } F &operator<<=(const int d) { int n = (*this).size(); (*this).insert((*this).begin(), d, 0); (*this).resize(n); return *this; } F &operator>>=(const int d) { int n = (*this).size(); (*this).erase((*this).begin(), (*this).begin() + min(n, d)); (*this).resize(n); return *this; } F inv(int d = -1) const { int n = (*this).size(); assert(n != 0 && (*this)[0] != 0); if (d == -1) d = n; assert(d > 0); F res{(*this)[0].inv()}; while (res.size() < d) { int m = size(res); F f(begin(*this), begin(*this) + min(n, 2*m)); F r(res); f.resize(2*m), internal::butterfly(f); r.resize(2*m), internal::butterfly(r); rep(i, 2*m) f[i] *= r[i]; internal::butterfly_inv(f); f.erase(f.begin(), f.begin() + m); f.resize(2*m), internal::butterfly(f); rep(i, 2*m) f[i] *= r[i]; internal::butterfly_inv(f); T iz = T(2*m).inv(); iz *= -iz; rep(i, m) f[i] *= iz; res.insert(res.end(), f.begin(), f.begin() + m); } return {res.begin(), res.begin() + d}; } //fast: FMT-friendly modulus only /* F &operator*=(const F &g) { int n = (*this).size(); *this = convolution(*this, g); (*this).resize(n); return *this; } F &operator/=(const F &g) { int n = (*this).size(); *this = convolution(*this, g.inv(n)); (*this).resize(n); return *this; }*/ //naive F &operator*=(const F &g) { int n = (*this).size(), m = g.size(); rrep(i, n) { (*this)[i] *= g[0]; rep(j, 1, min(i+1, m)) (*this)[i] += (*this)[i-j] * g[j]; } return *this; } F &operator/=(const F &g) { assert(g[0] != T(0)); T ig0 = g[0].inv(); int n = (*this).size(), m = g.size(); rep(i, n) { rep(j, 1, min(i+1, m)) (*this)[i] -= (*this)[i-j] * g[j]; (*this)[i] *= ig0; } return *this; } //sparse F &operator*=(vector> g) { int n = (*this).size(); auto [d, c] = g.front(); if (d == 0) g.erase(g.begin()); else c = 0; rrep(i, n) { (*this)[i] *= c; for (auto &[j, b] : g) { if (j > i) break; (*this)[i] += (*this)[i-j] * b; } } return *this; } F &operator/=(vector> g) { int n = (*this).size(); auto [d, c] = g.front(); assert(d == 0 && c != T(0)); T ic = c.inv(); g.erase(g.begin()); rep(i, n) { for (auto &[j, b] : g) { if (j > i) break; (*this)[i] -= (*this)[i-j] * b; } (*this)[i] *= ic; } return *this; } //multiply and divide (1 + cz^d) void multiply(const int d, const T c) { int n = (*this).size(); if (c == T(1)) rrep(i, n-d) (*this)[i+d] += (*this)[i]; else if (c == T(-1)) rrep(i, n-d) (*this)[i+d] -= (*this)[i]; else rrep(i, n-d) (*this)[i+d] += (*this)[i] * c; } void divide(const int d, const T c) { int n = (*this).size(); if (c == T(1)) rep(i, n-d) (*this)[i+d] -= (*this)[i]; else if (c == T(-1)) rep(i, n-d) (*this)[i+d] += (*this)[i]; else rep(i, n-d) (*this)[i+d] -= (*this)[i] * c; } T eval(const T &a) const { T x(1), res(0); for (auto e : *this) res += e * x, x *= a; return res; } F operator*(const T &g) const { return F(*this) *= g; } F operator/(const T &g) const { return F(*this) /= g; } F operator+(const F &g) const { return F(*this) += g; } F operator-(const F &g) const { return F(*this) -= g; } F operator<<(const int d) const { return F(*this) <<= d; } F operator>>(const int d) const { return F(*this) >>= d; } F operator*(const F &g) const { return F(*this) *= g; } F operator/(const F &g) const { return F(*this) /= g; } F operator*(vector> g) const { return F(*this) *= g; } F operator/(vector> g) const { return F(*this) /= g; } }; using mint = modint1000000007; using fps = FormalPowerSeries; using sfps = vector>; // p/qの有理式で表される母関数のn番目(0-indexed) ll recur(ll n,fps p,fps q){ if (n == 0) return p[0].val(); ll s = q.size(); p.resize(2*s); q.resize(2*s); fps mq = q; rep(i,s){ if (i%2 == 1){ mq[i] = -mq[i]; } } ll res; fps qmq = q*mq,pmq = p*mq,v(s); rep(i,s){ v[i] = qmq[2*i]; } if (n%2 == 0){ fps e(s,0); rep(i,s){ e[i] = pmq[2*i]; } res = recur(n/2,e,v); } else{ fps o(s,0); rep(i,s){ o[i] = pmq[2*i+1]; } res = recur((n-1)/2,o,v); } return res; } inline ll Mod(ll a,ll m){ return (a%m + m)%m; } ll extGCD(ll a,ll b,ll &p,ll &q){ if (b == 0){ p = 1;q = 0;return a; } ll d = extGCD(b,a%b,q,p); q -= a/b*p; return d; } ll mod_inv(ll a,ll m){ ll x,y; extGCD(a,m,x,y); return Mod(x,m); } template F Berlekamp_Massey(F s){ using T = typename F::value_type; ll n = s.size(); F c{-1},c2{0}; T r2 = 1; ll i2 = -1; rep(i,n){ ll d = c.size(); T r = 0; rep(j,d){ r += c[j]*s[i-j]; } if (r == 0){ continue; } T coef = -r/r2; ll d2 = c2.size(); if (d-i >= d2-i2){ rep(j,d2){ c[j+i-i2] += c2[j]*coef; } } else{ auto tmp = c; c.resize(d2+i-i2); rep(j,d2){ c[j+i-i2] += c2[j]*coef; } c2 = move(tmp); i2 = i,r2 = r; } } return c; } template ll get(ll k,F s){ auto a = Berlekamp_Massey(s); fps q(a.begin()+1,a.end()),t(s.begin(),s.end()); q.insert(q.begin(),-1); ll n = t.size(); fps p = t*q; return recur(k,p,q); } int main(){ vector s{0,1,12,65,172,297,456,649,876,1137,1432,1761,2124,2521,2952,3417}; ll n; cin >> n; PRINT(get(n+1,s)); }