#include using namespace std; using ull = unsigned long long; using u128 = __uint128_t; static const long long MOD = 998244353; long long mod_pow(long long a, long long e) { long long r = 1 % MOD; while (e > 0) { if (e & 1) r = (long long)((__int128)r * a % MOD); a = (long long)((__int128)a * a % MOD); e >>= 1; } return r; } long long mod_inv(long long a) { return mod_pow(a, MOD - 2); } const long long INV2 = mod_inv(2); const long long INV6 = mod_inv(6); const long long INV30 = mod_inv(30); long long sum_arith(ull x) { if (x == 0) return 0; u128 a = x, b = x + 1; if ((a & 1) == 0) a >>= 1; else b >>= 1; return (long long)((a * b) % MOD); } long long prefix_T(ull M) { if (M == 0) return 0; ull s = sqrt((long double)M); while ((u128)(s + 1) * (s + 1) <= M) ++s; while ((u128)s * s > M) --s; ull m = s - 1; long long n = m % MOD; long long n1 = (n + 1) % MOD; long long two_n1 = (2 * n + 1) % MOD; long long poly = ((3LL * n % MOD * n) % MOD + 3LL * n - 1 + MOD) % MOD; long long S1 = (long long)((__int128)n * n1 % MOD * INV2 % MOD); long long S2 = (long long)((__int128)n * n1 % MOD * two_n1 % MOD * INV6 % MOD); long long S3 = (long long)((__int128)S1 * S1 % MOD); long long S4 = (long long)((__int128)n * n1 % MOD * two_n1 % MOD * poly % MOD * INV30 % MOD); long long full_blocks = (2LL * S4 + 3LL * S3 + S2) % MOD; ull sq = s * s; long long tail = (sum_arith(M) - sum_arith(sq - 1) + MOD) % MOD; long long tail_part = (long long)((__int128)(s % MOD) * tail % MOD); return (full_blocks + tail_part) % MOD; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); ull N; cin >> N; vector> events; events.reserve(1100000); for (ull a = 2;; ++a) { u128 p = (u128)a * a * a; if (p > N) break; long long ratio = (long long)((__int128)(a % MOD) * mod_inv((a - 1) % MOD) % MOD); while (p <= N) { events.push_back({(ull)p, ratio}); p *= a; } } sort(events.begin(), events.end(), [](const auto& x, const auto& y) { return x.first < y.first; }); ull prev = 1; long long coeff = 1; long long ans = 0; auto add_interval = [&](ull L, ull R) { if (L > R) return; long long block = (prefix_T(R) - prefix_T(L - 1) + MOD) % MOD; ans = (ans + (long long)((__int128)coeff * block % MOD)) % MOD; }; size_t i = 0; while (i < events.size()) { ull v = events[i].first; add_interval(prev, v - 1); while (i < events.size() && events[i].first == v) { coeff = (long long)((__int128)coeff * events[i].second % MOD); ++i; } prev = v; } add_interval(prev, N); cout << ans % MOD << '\n'; return 0; }