#include // cin, cout #include // vector #include // (このコードでは不要だが一般的に使う) #include // (このコードでは不要だが一般的に使う) using namespace std; using ll = long long; #define rep(i,x,lim) for(ll i = (x);i < (ll)(lim);i++) const ll big2 = 998244353; // 正しい modpow ll modpow(ll x, ll n, ll m) { ll res = 1; x %= m; while (n > 0) { if (n & 1) res = (res * x) % m; x = (x * x) % m; n >>= 1; } return res; } // --- バグ: mod を取らない単純な pow を実装しようとした --- ll naive_pow(ll k, ll i) { ll res = 1; for (ll j = 0; j < i; j++) { // k=2, i=100 の時点でもう long long を超える // N=10^12 なら i は 3*10^5 になるため、即座にオーバーフロー // オーバーフローチェック (簡易) if (k > 0 && res > numeric_limits::max() / k) { // 本来はここでエラー処理だが、競技プログラミングだと無視されがち // 結果、オーバーフローして負の値などになる } res *= k; } return res; } // -------------------------------------------------------- ll nosimple_wa4(ll n){ ll ans = 0; ll temp = n; for(ll i=1;i*i<=n;i++){ ll k = i; ll up=n/k; ll down=n/(k+1); if(k==1) ans = (ans + (up-down)) % big2; else { ll a = modpow(k, down + 1, big2); ll b = modpow(k, up - down, big2); ll inv = modpow(k - 1, big2 - 2, big2); ans = (ans + a * (b - 1 + big2) % big2 * inv % big2) % big2; } temp = n / (i + 1); } rep(i,1,temp+1){ ll k = n/i; // --- バグ: modpow ではなく、オーバーフローする naive_pow を使った --- ans = (ans + naive_pow(k, i)) % big2; // ------------------------------------------------------------- } return (ans % big2 + big2) % big2; } int main(){ ll N; cin >> N; cout << nosimple_wa4(N) << endl; }