#include // clang-format off using namespace std;constexpr int INF=1001001001;constexpr long long INFll=1001001001001001001;namespace viewer{using s=string;templates f(T i){s S=i==INF||i==INFll?"inf":to_string(i);return s(max(0,3-int(S.size())),' ')+S;} templateauto v(T&x,s&&e)->decltype(cerr<void v(const pair&p,s&&e="\n"){cerr<<"(";v(p.first,", ");v(p.second,")"+e);}templatevoid v(const tuple&t,s&&e="\n"){cerr<<"(";v(get<0>(t),", ");v(get<1>(t),")"+e);}templatevoid v(const tuple&t,s&&e="\n"){cerr<<"(";v(get<0>(t),", ");v(get<1>(t),", ");v(get<2>(t),")"+e);}templatevoid v(const tuple&t,s&&e="\n"){cerr<<"(";v(get<0>(t),", ");v(get<1>(t),", ");v(get<2>(t),", ");v(get<3>(t),")"+e);} templatevoid v(const vector&vx,s);templateauto ve(int,const vector&vx)->decltype(cerr<auto ve(bool,const vector&vx){cerr<<"{\n";for(const T&x:vx)cerr<<" ",v(x,",");cerr<<"}\n";}templatevoid v(const vector&vx,s){ve(0,vx);} templatevoid v(const deque&q,s&&e){v(vector(q.begin(),q.end()),e);}templatevoid v(const set&S,s&&e){v(vector(S.begin(),S.end()),e);}templatevoid v(const multiset&S,s&&e){v(vector(S.begin(),S.end()),e);}templatevoid v(const unordered_set&S,s&&e){v(vector(S.begin(),S.end()),e);} templatevoid v(const priority_queue&p,s&&e){priority_queueq=p;vectorz;while(!q.empty()){z.push_back(q.top());q.pop();}v(z,e);}templatevoid v(const map&m,s&&e){cerr<<"{"<<(m.empty()?"":"\n");for(const auto&kv:m){cerr<<" [";v(kv.first,"");cerr<<"] : ";v(kv.second,"");cerr<<"\n";}cerr<<"}"+e;} templatevoid _view(int n,s&S,T&var){cerr<<"\033[1;32m"<void grid([[maybe_unused]]T _){}void grid(const vector>&vvb){cerr<<"\n";for(const vector&vb:vvb){for(const bool&b:vb)cerr<<(b?".":"#");cerr<<"\n";}} void _debug(int,s){}templatevoid _debug(int n,s S,const H&h,const T&... t){int i=0,cnt=0;for(;iap;mint re=a;for(long long r=1;rroots,iroots,rate3,irate3; static int max_base; NumberTheoreticTransformFriendlyModInt()=default; static void init(){ if(roots.empty()){const unsigned mod=mint::mod();assert(mod>=3&&mod%2==1);auto tmp=mod-1;max_base=0;while(tmp%2==0)tmp>>=1,max_base++;mint root=2;while(root.pow((mod-1)>>1)==1)root+=1;assert(root.pow(mod-1)==1);roots.resize(max_base+1);iroots.resize(max_base+1);rate3.resize(max_base+1);irate3.resize(max_base+1);roots[max_base]=root.pow((mod-1)>>max_base);iroots[max_base]=mint(1)/roots[max_base]; for(int i=max_base-1;i>=0;i--){roots[i]=roots[i+1]*roots[i+1];iroots[i]=iroots[i+1]*iroots[i+1];}{mint prod=1,iprod=1;for(int i=0;i<=max_base-3;i++){rate3[i]=roots[i+3]*prod;irate3[i]=iroots[i+3]*iprod;prod*=iroots[i+3];iprod*=roots[i+3];}}}} static void ntt(vector&a){init();const int n=(int)a.size();assert((n&(n-1))==0);int h=__builtin_ctz(n);assert(h<=max_base);int len=0;mint imag=roots[2];if(h&1){int p=1<<(h-1);for(int i=0;i&a,bool f=true){ init();const int n=(int)a.size();assert((n&(n-1))==0);int h=__builtin_ctz(n);assert(h<=max_base);int len=h;mint iimag=iroots[2];for(;len>1;len-=2){int p=1<<(h-len);{for(int i=0;i=1){int p=1<<(h-1);for(int i=0;imultiply(vectora,vectorb){int need=a.size()+b.size()-1;int nbase=1;while((1<NumberTheoreticTransformFriendlyModInt::roots=vector();vectorNumberTheoreticTransformFriendlyModInt::iroots=vector();vectorNumberTheoreticTransformFriendlyModInt::rate3=vector();vectorNumberTheoreticTransformFriendlyModInt::irate3=vector();int NumberTheoreticTransformFriendlyModInt::max_base=0; templatestruct FormalPowerSeriesFriendlyNTT:vector{ using vector::vector;using P=FormalPowerSeriesFriendlyNTT;using NTT=NumberTheoreticTransformFriendlyModInt; P pre(int deg)const{return P(begin(*this),begin(*this)+min((int)this->size(),deg));} P rev(int deg=-1)const{P ret(*this);if(deg!=-1)ret.resize(deg,T(0));reverse(begin(ret),end(ret));return ret;} void shrink(){while(this->size()&&this->back()==T(0))this->pop_back();} P operator+(const P&r)const{return P(*this)+=r;} P operator+(const T&v)const{return P(*this)+=v;} P operator-(const P&r)const{return P(*this)-=r;} P operator-(const T&v)const{return P(*this)-=v;} P operator*(const P&r)const{return P(*this)*=r;} P operator*(const T&v)const{return P(*this)*=v;} P operator/(const P&r)const{return P(*this)/=r;} P operator/(const T&v)const{return P(*this)/=v;} P operator%(const P&r)const{return P(*this)%=r;} P operator>>(int r)const{return P(*this)>>=r;} P operator<<(int r)const{return P(*this)<<=r;} // https://judge.yosupo.jp/problem/convolution_mod P operator-()const{P ret(this->size());for(int i=0;i<(int)this->size();i++)ret[i]=-(*this)[i];return ret;} P&operator+=(const P&r){if(r.size()>this->size())this->resize(r.size());for(int i=0;i<(int)r.size();i++)(*this)[i]+=r[i];return*this;} P&operator-=(const P&r){if(r.size()>this->size())this->resize(r.size());for(int i=0;i<(int)r.size();i++)(*this)[i]-=r[i];return*this;} P&operator*=(const P&r){if(this->empty()||r.empty()){this->clear();return*this;}auto ret=NTT::multiply(*this,r);return*this={begin(ret),end(ret)};} P&operator/=(const P&r){if(this->size()clear();return*this;}int n=this->size()-r.size()+1;return*this=(rev().pre(n)*r.rev().inv(n)).pre(n).rev(n);} P&operator%=(const P&r){*this-=*this/r*r;shrink();return*this;} P&operator+=(const T&r){if(this->empty())this->resize(1);(*this)[0]+=r;return*this;} P&operator-=(const T&r){if(this->empty())this->resize(1);(*this)[0]-=r;return*this;} P&operator*=(const T&v){for(int i=0;i<(int)this->size();i++)(*this)[i]*=v;return*this;} P&operator/=(const T&v){for(int i=0;i<(int)this->size();i++)(*this)[i]/=v;return*this;} P&operator>>=(int sz){this->erase(this->begin(),this->begin()+min(sz,(int)this->size()));return*this;} P&operator<<=(int sz){this->insert(this->begin(),sz,T(0));return*this;} // https://judge.yosupo.jp/problem/division_of_polynomials pairdiv_mod(const P&r){P q=*this/r;P x=*this-q*r;x.shrink();return make_pair(q,x);} P dot(P r)const{P ret(min(this->size(),r.size()));for(int i=0;i<(int)ret.size();i++)ret[i]=(*this)[i]*r[i];return ret;} // operator(x): f(x)の値を評価して返す O(n) T operator()(T x)const{T r=0,w=1;for(auto&v:*this){r+=w*v;w*=x;}return r;} // diff(): f'(x)を返す O(n) P diff()const{const int n=(int)this->size();P ret(max(0,n-1));for(int i=1;isize();P ret(n+1);ret[0]=T(0);for(int i=0;isize();if(deg==-1)deg=n;P res(deg);res[0]={T(1)/(*this)[0]};for(int d=1;dsize();if(deg==-1)deg=n;return(this->diff()*this->inv(deg)).pre(deg-1).integral();} // sqrt(): √f(x)(i.e. g(x) s.t. g(x)*g(x)==f(x))を返す // 存在しない場合は空配列を返す deg==-1の時、同じ次数で打ち切る // https://judge.yosupo.jp/problem/sqrt_of_formal_power_series P sqrt(int deg=-1,const function&get_sqrt=[](T y){return modsqrt(y);})const{const int n=(int)this->size();if(deg==-1)deg=n;if((*this)[0]==T(0)){for(int i=1;i>i).sqrt(deg-i/2,get_sqrt);if(ret.empty())return{};ret=ret<<(i/2);if((int)ret.size()&get_sqrt,int deg=-1)const{return sqrt(deg,get_sqrt);} // exp(): exp(f(x))を返す f(0)=0を要求する deg==-1の時、同じ次数で打ち切る // https://judge.yosupo.jp/problem/exp_of_formal_power_series P exp(int deg=-1)const{if(deg==-1)deg=this->size();assert((*this)[0]==T(0));P inv;inv.reserve(deg+1);inv.push_back(T(0));inv.push_back(T(1));auto inplace_integral=[&](P&F)->void{const int n=(int)F.size();auto mod=T::getmod();while((int)inv.size()<=n){int i=inv.size();inv.push_back((-inv[mod%i])*(mod/i));}F.insert(begin(F),T(0));for(int i=1;i<=n;i++)F[i]*=inv[i];}; auto inplace_diff=[](P&F)->void{if(F.empty())return;F.erase(begin(F));T coeff=1,one=1;for(int i=0;i<(int)F.size();i++){F[i]*=coeff;coeff+=one;}};P b{1,1<(int)this->size()?(*this)[1]:0},c{1},z1,z2{1,1}; for(int m=2;m(this->size(),m));inplace_diff(x);x.push_back(T(0));NTT::ntt(x); for(int i=0;i(this->size(),2*m);++i)x[i]+=(*this)[i];fill(begin(x),begin(x)+m,T(0));NTT::ntt(x);for(int i=0;i<2*m;++i)x[i]*=y[i];NTT::intt(x);b.insert(end(b),begin(x)+m,end(x));}return P{begin(b),begin(b)+deg};} // pow(k): f^k(x)を返す deg==-1の時、同じ次数で打ち切る // https://judge.yosupo.jp/problem/pow_of_formal_power_series P pow(int64_t k,int deg=-1)const{const int n=(int)this->size();if(deg==-1)deg=n;for(int i=0;i>i).log()*k).exp()*((*this)[i].pow(k));if(i*k>deg)return P(deg,T(0));ret=(ret<<(i*k)).pre(deg);if((int)ret.size()0){if(k&1){ret*=x;ret-=get_div(ret)*g;ret.shrink();}x*=x;x-=get_div(x)*g;x.shrink();k>>=1;}return ret;} // taylor_shift(c): g(x)=f(x+c)を満たすg(x)を返す // https://judge.yosupo.jp/problem/polynomial_taylor_shift P taylor_shift(T c)const{int n=(int)this->size();vectorfact(n),rfact(n);fact[0]=rfact[0]=T(1);for(int i=1;i1;i--)rfact[i-1]=rfact[i]*T(i);P p(*this);for(int i=0;i; // https://qiita.com/ryuhe1/items/da5acbcce4ac1911f47a // [x^N] P(x) / Q(x) require: deg(Q(x)) == d && deg(P(x)) <= d - 1 && Q[0] != 0 // summary: [x^N] P(x)/Q(x) = [x^N] P(x)Q(-x)/Q(x)Q(-x) = [x^N] (U_e(x^2)+xU_o(x^2))/V(x^2) -> x^N/2 or x^(N-1)/2 mint BostanMori(long long N,FPS P,FPS Q){int d=Q.size();assert(int(P.size())<=d-1&&Q[0]!=0);if(Q[0]!=1){for(int i=int(P.size())-1;i>=0;i--)P[i]/=Q[0];for(int i=int(Q.size())-1;i>=0;i--)Q[i]/=Q[0];}if(N==0)return P[0]/Q[0];while(N){FPS Qminus=Q;Qminus.shrink();for(int i=1;i>=1;}return P[0];} // clang-format on // usage: FPS FPS_As(As.begin(), As.end()); // logは恐らく壊れているが、それ以外は基本OK void test(int N) { vector>> fs(N + 1); vector Ps(N); iota(Ps.begin(), Ps.end(), 0); do { int f = 0; for (int i = 0; i < N; i++) { if (*max_element(Ps.begin(), Ps.begin() + i + 1) == Ps[i]) { f++; } } fs[f].push_back(Ps); } while (next_permutation(Ps.begin(), Ps.end())); for (int f = 0; f <= N; f++) { debug(f); debug(fs[f].size()); // debug(fs[f]); } } int main() { cin.tie(0); ios::sync_with_stdio(false); // test(1); // debug("---"); // test(2); // debug("---"); // test(3); // debug("---"); // test(4); // debug("---"); // test(5); // debug("---"); // test(6); // debug("---"); // test(7); int N; cin >> N; // queue q; // for (int i = 0; i < N; i++) { // q.push({i, 1}); // } // while (q.size() >= 2) { // auto f1 = q.front(); // q.pop(); // auto f2 = q.front(); // q.pop(); // q.push(f1 * f2); // } // FPS f = q.front(); // debug(f); // mint ans = 0; // for (int i = 0; i <= N; i++) { // ans += mint(i).pow(3) * f[i]; // } // cout << ans << endl; mint rev1 = 0; mint rev2 = 0; mint rev3 = 0; mint prod = 1; for (int i = 1; i <= N; i++) { mint rev = mint(1) / i; rev1 += rev; rev2 += rev * rev; rev3 += rev * rev * rev; prod *= i; } mint f1 = prod * (rev1); mint f2 = prod * (rev1 * rev1 - rev2); mint f3 = prod * (rev1 * rev1 * rev1 - rev3 - (rev1 * rev2 - rev3) * 3); debug(f1, f2, f3); mint i1 = f1; mint i2 = f2 + i1; mint i3 = f3 + 3 * i2 - 2 * i1; cout << i3 << endl; return 0; }