#include using namespace std; #define rep(i,a,b) for(ll i=a;i=b;i--) #define ll long long #define ull unsigned ll #define ld long double #define bl __int128_t #define fi first #define se second #define vel vector #define vvel vector #define pll pair #define vepll vector #define vvepll vector #define ves vector #define mint Mint<998244353> #define vem vector #define vvem vector #define pmm pair #define cleout(i) cout<using PQ=priority_queue,greater>; // 上 右 下 左 vector di={-1, 0, 1, 0}; vector dj={ 0, 1, 0,-1}; vector dx={ 0, 1, 0,-1}; vector dy={ 1, 0,-1, 0}; vector ddx={ 1, 1, 1, 0, -1, -1, -1, 0 }; vector ddy={ 1, 0, -1, -1, -1, 0, 1, 1 }; ll inf=1000000000000000000;//1e18 // LLONG_MAX mt19937_64 rng((ull)chrono::steady_clock::now().time_since_epoch().count()); template struct Mint{ ll num; static constexpr ll MOD=P; Mint(ll x=0){ if(x<0){ x*=-1; x%=P; x=P-x; } x%=P; num=x; } Mint operator+(const Mint &other)const{ return Mint(num+other.num); } Mint operator-(const Mint &other)const{ return Mint(num-other.num); } Mint operator*(const Mint &other)const{ return Mint(num*other.num); } Mint &operator+=(const Mint &other){ num+=other.num; if(num>=P) num-=P; return *this; } Mint &operator-=(const Mint &other){ num-=other.num; if(num<0) num+=P; return *this; } Mint &operator*=(const Mint &other){ num=(num*other.num)%P; return *this; } Mint beki(const ll &x)const{ Mint res=1; Mint now=num; rep(i,0,60){ if(x&(1ll<>(istream& is, Mint& m) { ll x; is>>x; m=Mint(x); return is; } }; struct fps:std::vem{ using vem::vector; static fps DFT(fps &f,mint iv){ ll cnt=1; ll size=f.size()/2; fps INV(f.size(),1); INV[1]=iv; rep(i,2,f.size()){ INV[i]=INV[i-1]*iv; } ll SIZE=1; while(size!=0){ rep(i,0,SIZE){ mint IV=1; ll I=i*(mint)2*size; rep(j,0,size){ f[I+j]=f[I+j]+f[I+size+j]; f[I+size+j]=(f[I+j]-(mint)2*f[I+size+j])*INV[cnt*j]; } } cnt<<=1; size>>=1; SIZE<<=1; } int n=f.size(); int j=0; for(int i=1;i>1; while(j>=bit){ j-=bit; bit>>=1; } j+=bit; if(isize()){ (*this)[i]*=c; } return *this; } fps operator*(const mint &c)const{ return (fps(*this)*=c); } fps &operator/=(const mint &c){ mint c_inv=(mint)1/c; rep(i,0,this->size()){ (*this)[i]*=c_inv; } return *this; } fps operator/(const mint &c)const{ return (fps(*this)/=c); } fps pre(ll d){ fps res(this->begin(),this->begin()+min((ll)this->size(),d)); if(this->size()size()&&this->back()==0)this->pop_back(); } fps &operator+=(const fps &other){ if(other.size()>this->size()){ this->resize(other.size(),0); } rep(i,0,other.size()){ (*this)[i]+=other[i]; } return *this; } fps operator+(const fps &other)const{ return (fps(*this)+=other); } fps &operator-=(const fps &other){ if(other.size()>this->size()){ this->resize(other.size(),0); } rep(i,0,other.size()){ (*this)[i]-=other[i]; } return *this; } fps operator-(const fps &other)const{ return (fps(*this)-=other); } fps operator*(const fps &other)const{ if(this->empty()||other.empty())return{}; int rsz=this->size()+other.size()-1; int sz=bit_ceil((ull)this->size()+other.size()-1); mint w=mint(3).beki(998244352/sz); fps Fthis(this->begin(),this->end()); Fthis.resize(sz); Fthis=DFT(Fthis,w); fps Fother=other; Fother.resize(sz); Fother=DFT(Fother,w); rep(i,0,Fthis.size())Fthis[i]*=Fother[i]; fps res=DFT(Fthis,(mint)1/w); res.resize(rsz); return res/(mint)sz; } fps &operator*=(const fps &other){ *this=(*this)*other; return *this; } fps &operator<<=(int d){ this->insert(this->begin(),d,(mint)0); return *this; } fps operator<<(int d)const{ return(fps(*this)<<=d); } fps &operator>>=(int d){ if((ll)this->size()<=d){ this->clear(); }else{ this->erase(this->begin(),this->begin()+d); } return *this; } fps operator>>(int d)const{ return(fps(*this)>>=d); } void show(){ for(auto it=this->begin();it!=this->end();it++){ cout<<*it<<" "; } cout<<"\n"; } }; mint bostan_mori(fps f,fps g,ll K){//[x^k]f/g fps og; while(K){ og=g; for(ll i=1;i Berlekamp_Massey(fps &S){ ll N=S.size(); fps Q={1}; ll L=0; fps B={1}; ll n0=-1; mint b=1; rep(n,0,N){ mint d=0; rep(j,0,min((ll)Q.size(),n+1))d+=Q[j]*S[n-j]; if(d==0)continue; fps Q_new=Q-(B<<(n-n0))*(d/b); ll L_new; if(2*L<=n){ L_new=n+1-L; B=Q; n0=n; b=d; }else L_new=L; Q=Q_new; L=L_new; } return {L,Q}; } mint BMBM(fps &f,ll K,bool debug=false){ auto[L,Q]=Berlekamp_Massey(f); if(debug)cout<=2*L); fps P=(f*Q).pre(Q.size()-1); P.shrink(); return bostan_mori(P,Q,K); } fps Str(ll K){//klogk fps f(K+1,0); fps g(K+1,0); mint dv=1; rep(i,1,K+1)dv*=(mint)i; dv=(mint)1/dv; rrep(i,K+1,1){ f[i]=dv; if(i%2)f[i]*=(mint)(-1); mint I=i; g[i]=I.beki(K)*dv; dv*=(mint)i; } f[0]=1; return f*g.pre(K+1); } struct CB{ vem n,r; CB(ll N){//N以下のものをmod INFで返す n.assign(N+1,1); r.assign(N+1,1); rep(i,2,N+1){ n.at(i)=n.at(i-1)*mint(i); } r.back()=n.back().inv(); rrep(i,N,0) r.at(i)=r.at(i+1)*(mint)(i+1); } mint comb(ll N,ll R){//NCR if(Ntarget)mul.resize(target); mul[0]-=(mint)2; mul*=(mint)(-1); res=res*mul; if(res.size()>target)res.resize(target); } if(res.size()>N)res.resize(N); return res; } fps log(fps &f,ll N=0){ if(N==0)N=f.size(); fps inv=inverse(f,N); // 微分 fps df(N-1); rep(i,0,N-1)df[i]=get_val(f,i+1)*(mint)(i+1); fps res=df*inv; // 積分 fps ret(N); ret[0]=0; rep(i,1,N)ret[i]=get_val(res,i-1)*cb.n[i-1]*cb.r[i]; return ret; } fps exp(fps &f,ll N=0){ if(N==0)N=f.size(); fps res={1}; while(res.size()len)res.resize(len); } return res.pre(N); } fps pow(fps &f,ll Pow,ll N=0){ if(N==0)N=f.size(); ll pos=0; while(pos=N){ fps ret(N,0); return ret; } fps g=f>>pos; mint c=g[0]; g/=c; fps ret=log(g,N)*(mint)Pow; ret=exp(ret,N)<<(Pow*pos); ret=ret.pre(N); ret*=c.beki(Pow); return ret; } void _solve(){ ll N; cin>>N; fps h(N+1); rep(i,1,N+1){ h[i]=cb.r[i]; } fps e(N+1); rep(i,0,N+1){ e[i]=cb.r[i]; } { mint now=N; rep(i,1,N+1){ e[i]*=now; now*=(mint)N; } } e.back()-=(mint)1; fps ret=h*e; fps S=Str(N); mint ans=0; mint mul=N; mint now=mul.beki(N-1); mint div=(mint)1/mul; rep(k,1,N+1){ ans+=cb.comb(N,k)*(S[k]*cb.n[k])*now*(ret[k]*cb.n[k]); now*=div; } cout<>_; else _=1; rep(__,0,_){ _solve(); } }