template <classT> using must_int = enable_if_t<is_integral<T>::value, int>; template <unsigned umod> structmodint { staticconstexprint mod = umod; unsigned v; modint() : v(0) {} template <classT, must_int<T> = 0> modint(T _v) {int x = _v % (int)umod; v = x < 0 ? x + umod : x;} modint operator+() const { return *this; } modint operator-() const { returnmodint() - *this; } friendintraw(const modint &self){ return self.v; } friend ostream &operator<<(ostream &os, const modint &self) { return os << raw(self);} modint &operator+=(const modint &rhs) {v += rhs.v;if (v >= umod) v -= umod;return *this;} modint &operator-=(const modint &rhs) {v -= rhs.v;if (v >= umod) v += umod;return *this;} modint &operator*=(const modint &rhs) {v = 1ull * v * rhs.v % umod; return *this;} modint &operator/=(const modint &rhs) { return *this *= rhs.inv(); } modint inv()const{ assert(v); staticunsigned lim = 1 << 21; static vector<modint> inv{0, 1}; if (v >= lim) returnqpow(*this, mod - 2); inv.reserve(v + 1); while (v >= inv.size()) { int m = inv.size(); inv.resize(m << 1); for (int i = m; i < m << 1; i++)inv[i] = (mod - mod / i) * inv[mod % i]; } return inv[v]; } template <classT, must_int<T> = 0> friend modint qpow(modint a, T b) {modint r = 1;for (; b; b >>= 1, a *= a)if (b & 1) r *= a;return r;} friend modint operator+(modint lhs, const modint &rhs) { return lhs += rhs; } friend modint operator-(modint lhs, const modint &rhs) { return lhs -= rhs; } friend modint operator*(modint lhs, const modint &rhs) { return lhs *= rhs; } friend modint operator/(modint lhs, const modint &rhs) { return lhs /= rhs; } friendbooloperator==(const modint &lhs, const modint &rhs) { return lhs.v == rhs.v; } friendbooloperator!=(const modint &lhs, const modint &rhs) { return lhs.v != rhs.v; } }; constint MOD = 998244353; using mint = modint<MOD>;
inline mint C(int n,int r){ static vector<mint> f{1, 1}, finv{1, 1}; while(n >= f.size()){ int m = f.size(); f.resize(m << 1), finv.resize(m << 1); for (int i = m; i < m << 1; i++)f[i]=f[i-1]*i,finv[i]=finv[i-1]/i; } return (r<0)?0:(f[n]*finv[r]*finv[n-r]); }
const mint G = 3, INVG = mint{3}.inv();
constint N = 2e6+5; mint pow10[N]; voidNTT(vector<mint>& f,int n,bool flag){ vector<int> rev(n); for(int i=0;i<n;i++){ rev[i]=rev[i>>1]>>1; if(i&1)rev[i]|=n>>1; } for(int i=0;i<n;i++){ if(i<rev[i])swap(f[i],f[rev[i]]); } for(int p=2;p<=n;p<<=1){ mint g = qpow((flag?INVG:G),(MOD-1)/p); for(int j=0;j<n;j+=p){ mint gnow = 1; for(int k=j;k<(j|p>>1);k++){ mint t = f[k|p>>1] * gnow; f[k|p>>1] = f[k] - t; f[k] = f[k] + t; gnow *= g; } } }
mint invN = qpow(mint{n}, MOD-2); if(flag)for(int i=0;i<n;i++)f[i]*=invN; }
vector<mint> f[7],g[7],h[7]; int cnt[7];
int len[N]; mint fact[N]; mint coef[7];
intmain(){ ios::sync_with_stdio(0);cin.tie(0); int n;cin>>n; for(int i=1;i<=n;i++){ len[i]=len[i/10]+1; cnt[len[i]]++; } pow10[0]=1; for(int i=1;i<N;i++)pow10[i]=pow10[i-1]*10; fact[0]=1; for (int i =1; i <=n; i++)fact[i]=fact[i-1]*i;