#include using namespace std; template istream &operator>>(istream &is, vector &v) { for (T &in : v) is >> in; return is; } template ostream &operator<<(ostream &os, const vector &v) { for (int i = 0; i < (int)v.size(); i++) os << v[i] << (i + 1 != (int)v.size() ? " " : ""); return os; } #define OVERLOAD_REP(_1, _2, _3, name, ...) name #define REP1(i, n) for (auto i = std::decay_t{}; (i) != (n); ++(i)) #define REP2(i, l, r) for (auto i = (l); (i) != (r); ++(i)) #define rep(...) OVERLOAD_REP(__VA_ARGS__, REP2, REP1)(__VA_ARGS__) #define sum(l) accumulate(l.begin(), l.end(), 0) #define all(...) std::begin(__VA_ARGS__), std::end(__VA_ARGS__) #define rall(...) std::rbegin(__VA_ARGS__), std::rend(__VA_ARGS__) using ull = unsigned long long; using ll = long long; using vi = vector; using vl = vector; using vll = vector; using vvi = vector; using vvl = vector; using vvll = vector; using vs = vector; using pii = pair; using vpii = vector; const ll MOD = 998244353; ll inv2, inv6, inv30; template< typename T > T mod_pow(T x, T n, const T &p) { T ret = 1; while(n > 0) { if(n & 1) (ret *= x) %= p; (x *= x) %= p; n >>= 1; } return ret; } template< typename T > T floor_sqrt(T x) { T y = sqrt(x); while (y * y > x) y--; while ((y + 1) * (y + 1) <= x) y++; return y; } ll sum1(ull n) { ll x = n % MOD; ll y = (n + 1) % MOD; return x * y % MOD * inv2 % MOD; } ll sum2(ull n) { ll x = n % MOD; ll y = (n + 1) % MOD; ll z = (2 * x + 1) % MOD; return x * y % MOD * z % MOD * inv6 % MOD; } ll sum3(ull n) { ll t = sum1(n); return t * t % MOD; } ll sum4(ull n) { ll x = n % MOD; ll y = (n + 1) % MOD; ll z = (2 * x + 1) % MOD; ll w = (3 * x % MOD * x % MOD + 3 * x - 1 + MOD) % MOD; return x * y % MOD * z % MOD * w % MOD * inv30 % MOD; } ll F(ull n) { if (n == 0) return 0; ull s = floor_sqrt(n); ull t = s - 1; ll res = 0; res += 2 * sum4(t) % MOD; res %= MOD; res += 3 * sum3(t) % MOD; res %= MOD; res += sum2(t); res %= MOD; ull l = s * s; ll part = (sum1(n) - sum1(l - 1) + MOD) % MOD; part = part * (s % MOD) % MOD; res += part; res %= MOD; return res; } int main() { cin.tie(0); ios::sync_with_stdio(false); ull N; cin >> N; inv2 = mod_pow(2LL, MOD - 2, MOD); inv6 = mod_pow(6LL, MOD - 2, MOD); inv30 = mod_pow(30LL, MOD - 2, MOD); vector> ev; for (ull a = 2; a * a * a <= N; a++) { ull x = a * a * a; ll fac = (a % MOD) * mod_pow((ll)a - 1, MOD - 2, MOD) % MOD; while (x <= N) { ev.push_back({x, fac}); x *= a; } } sort(all(ev)); ll ans = 0; ll cur = 1; ull prev = 1; int i = 0; while (i < ev.size()) { ull x = ev[i].first; if (prev <= x - 1) { ll block = (F(x - 1) - F(prev - 1) + MOD) % MOD; ans = (ans + cur * block) % MOD; } while (i < ev.size() && ev[i].first == x) { cur = cur * ev[i].second % MOD; i++; } prev = x; } if (prev <= N) { ll block = (F(N) - F(prev - 1) + MOD) % MOD; ans = (ans + cur * block) % MOD; } cout << ans << '\n'; return 0; }