use proconio::input; const M: i64 = 998244353; const INV_2: i64 = 499122177; const INV_20: i64 = 149736653; fn f(n: usize) -> i64 { let m = n.isqrt() as i64 % M; let n = n as i64 % M; let m2 = m*m % M; // (m-1) * m * (m+1) * (m*m*8 - m*5 - 2) / 20 + m * (-m*m + n) * (m*m + n - 1) / 2 let t = (m2-1) * m % M * (8*m2 - 5*m - 2) % M * INV_20; let t2 = m * (n - m2) % M * (m2 + n - 1) % M * INV_2; (t+t2) % M } fn main() { input! { mut N: usize } N += 1; let mut stk = vec![(N, 0)]; for k in 3..=60 { for n in 2usize.. { let x = n.saturating_pow(k); if N <= x { break; } stk.push((x, n)); } } stk.sort_unstable(); stk.reverse(); let mut ans = 0; let mut L = 1; let mut cur = 1i64; let mut inv = vec![0, 1]; for i in 2..=1000000 { inv.push(M - (M/i as i64 * inv[M as usize%i] % M)); } for i in 1..=1000000 { assert!(i as i64*inv[i] % 998244353 == 1); } while L != N { while let Some((_, n)) = stk.pop_if(|e| e.0 == L) { cur = cur * inv[n-1] % M * n as i64 % M; } let R = stk.last().unwrap().0.min(N); ans = (ans + (f(R) - f(L)) * cur) % M; L = R; } println!("{}", (ans+M)%M); }