voidsieve() { H[1] = mu[1] = 1; for (int i = 2; i < N; ++ i) { if (!st[i]) prime[cnt ++] = i, H[i] = i, mu[i] = -1; for (int j = 0; j < cnt && i * prime[j] < N; ++ j) { H[i * prime[j]] = H[i]; st[i * prime[j]] = true; if (i % prime[j] == 0) break; mu[i * prime[j]] = -mu[i], H[i * prime[j]] *= prime[j]; } } for (int i = 1; i < N; ++ i) iH[i] = qpow(H[i]); for (int i = 1; i < N; ++ i) { if (!mu[i]) continue; if (mu[i] > 0) { for (int j = 1; i * j < N; ++ j) adj(H1[i * j] += iH[j] - Mod); } else { for (int j = 1; i * j < N; ++ j) adj(H1[i * j] -= iH[j]); } } for (int i = 1; i < N; ++ i) for (int j = 1; i * j < N; ++ j) if (mu[i * j]) fac[i * j].push_back(i); }
inlineintgetid(int x){ return x <= sq ? id1[x] : id2[n / x]; } inlineintloc(int x){ return std::lower_bound(a + 1, a + tot + 1, x, std::greater<int>()) - a; } inlineintsum1(int x){ return x * (x + 1LL) / 2 % Mod; } inlineintsum2(int x){ return x * (x + 1LL) % Mod * (x << 1 | 1) % Mod * (Mod + 1) / 6 % Mod; }
voidMin25_init() { sq = std::sqrt(n), tot = 0; for (int l = 1, r, t; l <= n; l = r + 1) { t = n / l, r = n / t; a[++ tot] = t; if (t <= sq) id1[t] = tot; else id2[r] = tot; } for (int i = 0; i < cnt; ++ i) adj(sp1[i] = sp1[i - 1] + prime[i] - Mod), sp2[i] = (sp2[i - 1] + (LL) prime[i] * prime[i]) % Mod; for (int i = 1; i <= tot; ++ i) psum1[i] = sum1(a[i]) - 1, psum2[i] = sum2(a[i]) - 1; for (int i = 0; i < cnt; ++ i) { LL le = (LL) prime[i] * prime[i]; for (int j = 1, p = prime[i]; j <= tot && a[j] >= le; ++ j) psum1[j] = (psum1[j] + (LL) (sp1[i - 1] + Mod - psum1[getid(a[j] / p)]) * p) % Mod, psum2[j] = (psum2[j] + (LL) (sp2[i - 1] + Mod - psum2[getid(a[j] / p)]) * p * p) % Mod; } for (int j = 1, x; j <= tot; ++ j) adj(f1[j] = psum1[j] - psum1[x = loc(std::sqrt(a[j]))]), adj(f2[j] = psum2[x] - psum2[j]); for (int i = cnt - 1; ~i; -- i) for (int j = 1, p = prime[i]; j <= tot && a[j] >= (LL) p * p; ++ j) { LL cur = p; int v, nxt; for (int e = 1; cur * p <= a[j]; ++ e, cur *= p) { int nxt = a[j] / cur, v; if (nxt < p * p) adj(v = psum1[getid(nxt)] - sp1[i]); else v = f1[getid(nxt)]; f1[j] = (f1[j] + (v + 1LL) * p) % Mod; } if ((nxt = a[j] / p) < p * p) adj(v = sp2[i] - psum2[getid(nxt)]); else v = f2[getid(nxt)]; adj(f1[j] += p - Mod); f2[j] = (f2[j] + (Mod - p * p) * (v + 1LL)) % Mod; } for (int j = 1; j <= tot; ++ j) f1[j] ++, f2[j] ++; }
inlineintgetF1(int n, int d) { if (!n) return0; if (n == 1) return H[d]; if (d == 1) return f1[getid(n)]; if (mf1[d].count(n)) return mf1[d][n]; int res = 0; for (int T : fac[d]) res = (res + (LL) H1[T] * getF1(n / T, T)) % Mod; return mf1[d][n] = (LL) res * H[d] % Mod; }
inlineintgetF2(int n, int d) { if (!n) return0; if (d == 1) return f2[getid(n)]; if (!mu[d]) return0; if (mf2[d].count(n)) return mf2[d][n]; int res = 0; for (int k : fac[d]) if (mu[k] > 0) adj(res += getF2(n / k, k) - Mod); elseif (mu[k]) adj(res -= getF2(n / k, k)); res = (LL) res * H[d] % Mod * H[d] % Mod; if (mu[d] < 0) adj(res = -res); return mf2[d][n] = res; }
voidwork() { std::cin >> n; Min25_init(); B = n / (int) (std::pow(n, 1. / 3) + 1), B = std::max(B, 1); int res = 0; for (int i = 1, v; i <= B; ++ i) if (mu[i] > 0) v = getF1(n / i, i), res = (res + (LL) v * v) % Mod; elseif (mu[i]) v = getF1(n / i, i), res = (res + (LL) (Mod - v) * v) % Mod; int lim = n / B; for (int T1 = 1; T1 <= lim; ++ T1) for (int T2 = 1; T2 <= lim; ++ T2) { LL Lcm = (LL) T1 / Gcd(T1, T2) * T2, mul = (LL) H1[T1] * H1[T2] % Mod, tmp; if (!mu[Lcm]) continue; for (int i = T1, ed = lim; i <= ed; i += T1) for (int j = T2; j <= ed; j += T2) { tmp = mul * H[i] % Mod * H[j] % Mod; res = (res + tmp * getF2(n / std::max(i, j) / Lcm, Lcm)) % Mod; if (B >= Lcm) res = (res + tmp * (Mod - getF2(B / Lcm, Lcm))) % Mod; } } std::cout << res << '\n'; }