#pragma GCC optimize(2)
#include <iostream>
#include <vector>
#include <cmath>
#include <utility>
#include <functional>
#include <algorithm>
#include <ctime>
using namespace std;
using u32 = unsigned int;
using u64 = unsigned long long;
using i64 = long long;
vector<int> pi, pos;
vector<u32> phi, primes;
vector<vector<int>> h;
void sieve(int v) {
pi.resize(v + 1);
phi.resize(v + 1);
pos.resize(v + 1);
primes.push_back(1);
phi[1] = 1;
for (int i = 2, t; i <= v; ++i) {
if (!phi[i]) pos[i] = primes.size(), primes.push_back(i), phi[i] = i - 1;
for (int j = 1; j <= pos[i] && (t = i * primes[j]) <= v; ++j) {
pos[t] = j;
if (j == pos[i]) {
phi[t] = phi[i] * primes[j];
break;
}
else
phi[t] = phi[i] * (primes[j] - 1);
}
}
for (int id = 1; id < primes.size(); ++id) pi[primes[id]] = 1;
for (int i = 1; i <= v; ++i) pi[i] += pi[i - 1];
h.resize(pi[v] + 1);
for (int i = 2; i <= v; ++i) h[pos[i]].push_back(i);
}
u32 solve(const u64 N) {
const int v = sqrt(N + 0.5);
const int n_6 = pow(N + 0.5, 1.0 / 6) * 0.4;
const int n_4 = sqrt(v + 0.5);
const int K = n_6 * v, limit = min(int(pow(N, 1.0 / 3) * pow(log(N), 4.0 / 3) * 0.75), v);
const int B = N / K, B2 = N / limit;
clock_t clk = clock();
sieve(B2);
vector<u32> s0(v + 1), s1(v + 1), l0(v + 1), l1(v + 1);
const auto divide = [](u64 n, u64 d) -> u64 {return double(n) / d; };
for (int i = 1; i <= v; ++i) s0[i] = i, s1[i] = u64(i) * (i + 1) / 2;
for (int i = 1; i <= v; ++i) l0[i] = N / i, l1[i] = (N / i) * (N / i + 1) / 2;
for (int id = 1; id <= pi[n_6]; ++id) {
const u32 p = primes[id], t = v / p;
const i64 M = N / p;
for (int i = 1; i <= t; ++i)
l0[i] -= l0[i * p], l1[i] -= l1[i * p] * p;
for (int i = t + 1; i <= v; ++i)
l0[i] -= s0[divide(M, i)], l1[i] -= s1[divide(M, i)] * p;
for (int i = v, j = t; j; --j)
for (int e = j * p; i >= e; --i)
s0[i] -= s0[j], s1[i] -= s1[j] * p;
}
vector<u32> sf(v + 1), lf(v + 1);
function <void(u64, int, u32)> dfs = [&](u64 n, int beg, u32 coeff) -> void {
if (n <= v) sf[n] += coeff - n + 1;
else lf[divide(N, n)] += coeff - n + 1;
int m = K / n;
for (int i = beg + 1; i <= pi[v]; ++i) {
if (primes[i] > m) break;
u64 q = 1;
for (; q * primes[i] <= m; q *= primes[i])
dfs(n * q * primes[i], i, coeff * q * (primes[i] - 1));
}
};
dfs(1, pi[n_6], 1);
for (int i = 1; i <= v; ++i) sf[i] += sf[i - 1];
lf[v] += sf[v];
for (int i = v - 1; i > B; --i) lf[i] += lf[i + 1];
for (int i = 1; i <= v; ++i) sf[i] += s1[i] - s0[i], lf[i] += l1[i] - l0[i];
vector<int> roughs;
for (int i = n_6 + 1; i <= v; ++i)
if (s0[i] != s0[i - 1]) roughs.push_back(i);
roughs.push_back(v + 1);
for (int i = B; i >= 1; --i) {
const u64 m = divide(N, i);
const int u = sqrt(m + 0.5), t = divide(v, i);
int k = 0, l;
lf[i] = l1[i] - l0[i] + s0[u] * sf[u];
for (; (l = roughs[k]) <= t; ++k)
lf[i] -= lf[i * l] + (sf[l] - sf[l - 1]) * l0[i * l];
for (; (l = roughs[k]) <= u; ++k)
lf[i] -= sf[divide(m, l)] + (sf[l] - sf[l - 1]) * s0[divide(m, l)];
}
fprintf(stderr, "sieve_large done %lf\n", double(clock() - clk) / CLOCKS_PER_SEC);
clk = clock();
for (int id = pi[n_6]; id; --id) {
const u32 p = primes[id], t = v / p;
const u64 M = N / p;
for (int i = 1; i <= t; ++i) lf[i] -= lf[i * p];
for (int i = t + 1; i <= v; ++i) lf[i] -= sf[divide(M, i)];
for (int i = v, j = t; j; --j)
for (int c = j * p; i >= c; --i) sf[i] -= sf[j];
for (int j = 1, i = p; j <= t; ++j) {
const u32 c = p * sf[j];
for (int e = min<u32>(v + 1, i + p); i < e; ++i) sf[i] += c;
}
for (int i = v; i > t; --i) lf[i] += p * sf[divide(M, i)];
for (int i = t; i; --i) lf[i] += p * lf[i * p];
}
fprintf(stderr, "sieve_small done %lf\n", double(clock() - clk) / CLOCKS_PER_SEC);
clk = clock();
u32 ans = lf[1];
const auto ff = [&](i64 n, int k) -> double {
double P = 1;
i64 x = 1;
while (k <= pi[v] && x * primes[k] <= n) {
x *= primes[k];
P = P * primes[k] / (primes[k] - 1);
++k;
}
return P;
};
vector<u32> f(v + 1);
for (int id = 1; id <= pi[v]; ++id) f[primes[id]] += primes[id] - 1;
for (int i = 1; i <= v; ++i) f[i] += f[i - 1];
int lim = 0;
vector<vector<pair<u64, u64>>> d1(pi[v] + 1);
function <void(u64, int, u64)> dfs4 = [&](u64 d, int beg, u64 coeff) -> void {
u64 m = divide(N, d);
double g = d * 1. / coeff;
if (floor(g) == floor(g * ff(m, beg + 1))) return;
for (int i = beg + 1; i <= pi[v]; ++i) {
u64 pr = primes[i];
if (pr * pr > m) break;
double g1 = g * pr / (pr - 1);
if (floor(g1) != floor(g))
d1[i].push_back(make_pair(d, coeff)), d* pr <= limit && (lim = max(lim, i));
u64 q = 1;
for (; q * pr <= m; q *= pr)
dfs4(d * q * pr, i, coeff * q * (pr - 1));
}
int left = min<i64>(v, (floor(g) + 1) * 1. / (floor(g) + 1 - g));
left = min<i64>(left, m);
int right = max<i64>(primes[beg], sqrt(m));
if (left > right) ans += coeff * (f[left] - f[right]);
};
dfs4(1, 0, 1);
fprintf(stderr, "dfs done %lf\n", double(clock() - clk) / CLOCKS_PER_SEC);
clk = clock();
for (int id = 1; id <= lim; ++id) {
const u32 p = primes[id], t = v / p;
const u64 M = N / p;
for (auto d : d1[id])
ans += d.second * (d.first <= v ? lf[d.first] : sf[divide(N, d.first)]);
for (int i = 1; i <= t; ++i) lf[i] -= p * lf[i * p];
for (int i = t + 1; i <= v; ++i) lf[i] -= p * sf[divide(M, i)];
for (int i = v, j = t; j; --j)
for (int c = j * p; i >= c; --i) sf[i] -= p * sf[j];
for (int j = 1, i = p; j <= t; ++j)
for (int e = min<int>(v + 1, i + p); i < e; ++i) sf[i] += sf[j];
for (int i = v; i > t; --i) lf[i] += sf[divide(M, i)];
for (int i = t; i; --i) lf[i] += lf[i * p];
for (auto d : d1[id])
ans -= d.second * (d.first <= v ? lf[d.first] : sf[divide(N, d.first)]);
}
fprintf(stderr, "dp done %lf\n", double(clock() - clk) / CLOCKS_PER_SEC);
clk = clock();
vector<u32> bit(B2 + 1);
const auto add = [&](int x, const u32 cnt) -> void {
while (x <= B2) bit[x] += cnt, x += x & -x;
};
const auto query = [&](int x) -> u32 {
u32 ans = 0;
while (x) ans += bit[x], x ^= x & -x;
return ans;
};
add(1, 1);
for (int id = pi[B2]; id > pi[v]; --id)
for (auto r : h[id]) add(r, phi[r]);
for (int id = pi[v]; id > lim; --id) {
const u32 p = primes[id];
const u64 m = divide(N, p);
//while (h[i].first > id) add(h[i].second, phi[h[i].second]), --i;
for (auto d : d1[id]) {
u32 n = m / d.first, phi0 = p - 1;
while (n) {
ans += phi0 * d.second * query(n);
n /= p;
phi0 *= p;
}
}
for (auto r : h[id]) add(r, phi[r]);
//ans += (p - 1) * d.second * (1 + f[divide(m, d.first)] - f[p] + p);
}
fprintf(stderr, "bit done %lf\n", double(clock() - clk) / CLOCKS_PER_SEC);
return N * (N + 1) / 2 - ans;
}
signed main() {
u64 n;
cin >> n;
cout << solve(n);
return 0;
}