#include #define rep(i,n) for(int i=0;i<(int)(n);i++) #define rep1(i,n) for(int i=1;i<=(int)(n);i++) #define all(c) c.begin(),c.end() #define pb push_back #define fs first #define sc second #define show(x) cout << #x << " = " << x << endl #define chmin(x,y) x=min(x,y) #define chmax(x,y) x=max(x,y) using namespace std; template ostream& operator<<(ostream& o,const pair &p){return o<<"("< ostream& operator<<(ostream& o,const vector &vc){o<<"sz = "<; void fft(bool type, vector &c){ //multiply : false -> mult -> true static vector buf[30]; int N = c.size(); int s = bsr(N); assert(1<(N); rep(i,N) buf[s][i] = polar(1,i*2*pi/N); } vector a(N),b(N); copy(begin(c),end(c),begin(a)); rep1(i,s){ int W = 1<<(s-i); for(int y=0;y>1] = l-r; } } swap(a,b); } copy(begin(a),end(a),begin(c)); } template vector multiply_fft(const vector& x,const vector& y){ const int B = 15; int S = x.size()+y.size()-1; int N = 2< a[2],b[2]; rep(t,2){ a[t] = vector(N); b[t] = vector(N); rep(i,x.size()) a[t][i] = Pc( (x[i].v >> (t*B)) & ((1<> (t*B)) & ((1< z(S); vector c(N); Mint base = 1; rep(t,3){ fill_n(begin(c),N,Pc(0,0)); for(int xt = max(t-1,0); xt<=min(1,t); xt++){ int yt = t-xt; rep(i,N) c[i] += a[xt][i]*b[yt][i]; } fft(true,c); rep(i,S){ c[i] *= 1.0/N; z[i] += Mint(ll(round(c[i].real()))) * base; } base *= 1< struct Poly{ vector v; int size() const{ return v.size();} //deg+1 Poly(int N=0) : v(vector(N)){} Poly(vector v) : v(v){shrink();} Poly& shrink(){ while(!v.empty()&&v.back()==D(0)) v.pop_back(); //double? iszeroをglobalに用意したほうがいいかな return *this; } D at(int i) const{ return (i=size() && !x) return; while(i>=size()) v.push_back(D(0)); v[i]=x; shrink(); return; } Poly operator+(const Poly &r) const{ int N=max(size(),r.size()); vector ret(N); rep(i,N) ret[i]=at(i)+r.at(i); return Poly(ret); } Poly operator-(const Poly &r) const{ int N=max(size(),r.size()); vector ret(N); rep(i,N) ret[i]=at(i)-r.at(i); return Poly(ret); } Poly operator-() const{ int N=size(); vector ret(N); rep(i,N) ret[i] = -at(i); return Poly(ret); } Poly operator*(const Poly &r) const{ if(size()==0||r.size()==0) return Poly(); return mul_fft(r); } Poly operator*(const D &r) const{ int N=size(); vector ret(N); rep(i,N) ret[i]=v[i]*r; return Poly(ret); } Poly operator/(const Poly &y) const{ return div_fast(y); } Poly operator%(const Poly &y) const{ return rem_fast(y); // return rem_naive(y); } Poly operator<<(const int &n) const{ // *=x^n assert(n>=0); int N=size(); vector ret(N+n); rep(i,N) ret[i+n]=v[i]; return Poly(ret); } Poly operator>>(const int &n) const{ // /=x^n assert(n>=0); int N=size(); if(N<=n) return Poly(); vector ret(N-n); rep(i,N-n) ret[i]=v[i+n]; return Poly(ret); } bool operator==(const Poly &y) const{ return v==y.v; } bool operator!=(const Poly &y) const{ return v!=y.v; } Poly& operator+=(const Poly &r) {return *this = *this+r;} Poly& operator-=(const Poly &r) {return *this = *this-r;} Poly& operator*=(const Poly &r) {return *this = *this*r;} Poly& operator*=(const D &r) {return *this = *this*r;} Poly& operator%=(const Poly &y) {return *this = *this%y;} Poly& operator<<=(const int &n) {return *this = *this<>=(const int &n) {return *this = *this>>n;} Poly mul_naive(const Poly &r) const{ int N=size(),M=r.size(); vector ret(N+M-1); rep(i,N) rep(j,M) ret[i+j]+=at(i)*r.at(j); return Poly(ret); } Poly mul_ntt(const Poly &r) const{ return Poly(multiply_ntt(this->v,r.v)); } Poly mul_fft(const Poly &r) const{ vector ret = multiply_fft(v,r.v); return Poly(ret); } Poly div_fast_with_inv(const Poly &inv, int B) const { return (*this * inv)>>(B-1); } Poly div_fast(const Poly &y) const{ if(size() res = v; res.resize(min(n,size())); return Poly(res); } Poly rev(int n = -1) const { //ignore x^n ~ -> return x^(n-1) * f(1/x) vector res = v; if(n!=-1) res.resize(n); reverse(all(res)); return Poly(res); } Poly inv(int n) const{ // f * f.inv() = x^B + r(x) (B>=n) int N = size(); assert(N>=1); //f : non0 assert(n>=N-1); //f = .. + c_{N-1}x^{N-1} D coef = D(1)/at(N-1); Poly a = rev(); Poly g(vector(1,coef)); for(int i=1; i+N-2{2})-a*g).strip(2*i); } return g.rev(n+1-N); } friend ostream& operator<<(ostream &o,const Poly& x){ if(x.size()==0) return o<<0; rep(i,x.size()) if(x.v[i]!=D(0)){ o< Poly berlekamp_massey(const vector &u){ int N = u.size(); vector b = {D(-1)}, c = {D(-1)}; D y = D(1); rep1(n,N){ int L = c.size(), M = b.size(); D x = 0; rep(i,L) x += c[i]*u[n-L+i]; b.pb(0); M++; if(!x) continue; D coef = x/y; if(L(c); } template struct ModInt{ using uint = unsigned int; using ll = long long; using ull = unsigned long long; constexpr static uint mod = mod_; uint v; ModInt():v(0){} ModInt(ll v):v(normS(v%mod+mod)){} explicit operator bool() const {return v!=0;} static uint normS(const uint &x){return (x [0 , mod-1] static ModInt make(const uint &x){ModInt m; m.v=x; return m;} ModInt operator+(const ModInt& b) const { return make(normS(v+b.v));} ModInt operator-(const ModInt& b) const { return make(normS(v+mod-b.v));} ModInt operator-() const { return make(normS(mod-v)); } ModInt operator*(const ModInt& b) const { return make((ull)v*b.v%mod);} ModInt operator/(const ModInt& b) const { return *this*b.inv();} ModInt& operator+=(const ModInt& b){ return *this=*this+b;} ModInt& operator-=(const ModInt& b){ return *this=*this-b;} ModInt& operator*=(const ModInt& b){ return *this=*this*b;} ModInt& operator/=(const ModInt& b){ return *this=*this/b;} ll extgcd(ll a,ll b,ll &x,ll &y) const{ ll u[]={a,1,0},v[]={b,0,1}; while(*v){ ll t=*u/ *v; rep(i,3) swap(u[i]-=t*v[i],v[i]); } if(u[0]<0) rep(i,3) u[i]=-u[i]; x=u[1],y=u[2]; return u[0]; } ModInt inv() const{ ll x,y; extgcd(v,mod,x,y); return make(normS(x+mod)); } bool operator==(const ModInt& b) const { return v==b.v;} bool operator!=(const ModInt& b) const { return v!=b.v;} friend istream& operator>>(istream &o,ModInt& x){ ll tmp; o>>tmp; x=ModInt(tmp); return o; } friend ostream& operator<<(ostream &o,const ModInt& x){ return o<; int dx[4]={1,0,-1,0}; int dy[4]={0,1,0,-1}; bool vis[4][20]; int res; int H,W; void dfs(int x,int y){ if(x==H-1 && y==W-1){ res++; return; } vis[x][y] = 1; rep(d,4){ int nx = x+dx[d]; int ny = y+dy[d]; if(0<=nx&&nx vals; // rep1(W,12){ // vals.pb(brute(4,W)); // } vector vc = {1LL,8LL,38LL,184LL,976LL,5382LL,29739LL,163496LL,896476LL,4913258LL,26932712LL,147657866LL,809563548LL,4438573234LL,24335048679LL,133419610132LL,731487691902LL,4010463268476LL,21987818897998LL,120550710615560LL,660932932108467LL,3623639655071710LL,19867014742102743LL,108923158053332350LL}; vector vals; for(long long v:vc) vals.pb(v); auto mod = berlekamp_massey(vals); // show(mod); Poly a = vector{1}; Poly x = vector{0,1}; long long N; cin>>N; while(N){ if(N%2) (a*=x)%=mod; x*=x; x%=mod; N/=2; } mint ans=0; int K = mod.size(); rep(i,K) ans+=a.at(i)*vals[i]; cout<