# 法 (mod) big2 = 998244353 def simple(n): """ O(N * logN) のナイーブな実装 (C++の simple 関数に相当) sum_{i=1}^{n} (floor(n/i))^i """ ans = 0 for i in range(1, n + 1): k = n // i # k^i % big2 を計算 term = pow(k, i, big2) ans = (ans + term) % big2 return ans def nosimple(n): """ O(sqrt(N) * logN) の高速な実装 (C++の nosimple 関数に相当) """ ans = 0 temp = n # 第2ループの上限 (n // (i+1) で更新) # --- 第1ループ (i*i <= n の範囲) --- # floor(n/i) の値が k (k <= sqrt(N)) となる i の区間についてまとめて計算 i = 1 while i * i <= n: k = i # C++コードのループ変数 i を k (底) と読み替える up = n // k # floor(n/i)=k となる最大の i down = n // (k + 1) # floor(n/i)=k となる最小の i の一つ手前 # 計算対象: sum_{j=down+1}^{up} k^j if k == 1: # k=1 (公比が1) の場合 # 1 を (up - down) 回足す ans = (ans + (up - down)) % big2 else: # k > 1 (等比数列の和の公式) # 初項 a = k^(down + 1) a = pow(k, down + 1, big2) # 項数 num = up - down num_terms = up - down # 公比の項 b = k^num b = pow(k, num_terms, big2) # (k-1) の逆元 (フェルマーの小定理) # C++の (/(i-1)) に相当 inv_k_minus_1 = pow(k - 1, big2 - 2, big2) # a * (b - 1) * (k - 1)^-1 term = (b - 1 + big2) % big2 # (b - 1) term = (term * inv_k_minus_1) % big2 # * (k - 1)^-1 term = (a * term) % big2 # * a ans = (ans + term) % big2 temp = down i += 1 # --- 第2ループ (i が 1 から temp (約sqrt(N)) まで) --- # floor(n/i) の値が k (k > sqrt(N)) となる i について計算 for i in range(1, temp + 1): k = n // i # 底 # (n/i)^i % big2 term = pow(k, i, big2) ans = (ans + term) % big2 return ans # --- メイン処理 (C++の main 関数に相当) --- if __name__ == "__main__": N = int(input()) # C++のmain関数は nosimple のみを呼び出している print(nosimple(N))