#ifndef BZ
#pragma GCC optimize "-O3"
#endif
#include <bits/stdc++.h>

#define FASTIO
#define ALL(v) (v).begin(), (v).end()

#ifdef FASTIO
#define scanf abacaba
#define printf abacaba
#endif

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

using namespace std;

/*
ll pw(ll a, ll b) {
	ll ans = 1; while (b) {
		while (!(b & 1)) b >>= 1, a = (a * a) % MOD;
		ans = (ans * a) % MOD, --b;
	} return ans;
}
*/
const int MX = (int)1e7 + 100;

int n;
int bb[MX];
int phi[MX];
int cnt[MX];
vector<int> primes;
int cp[MX];

int main() {
#ifdef BZ
	freopen("in", "r", stdin);
#endif
#ifdef FASTIO
	ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#endif
	cin >> n;
	phi[1] = 1;
	for (int i = 1; i <= n; ++i)
		bb[i] = i;
	ll ans = 0;
	for (int i = 2; i <= n; ++i) {
		int now = i / bb[i];
		phi[i] = bb[i] - 1;
		while (now % bb[i] == 0)
			now /= bb[i], phi[i] *= bb[i];
		phi[i] *= phi[now];
		cnt[i] = 1 + cnt[now];
		cp[i] = cp[i - 1];
		if (i == bb[i])
			primes.push_back(i), ++cp[i];
		for (int x: primes) {
			if (x > bb[i] || x * i > n)
				break;
			bb[i * x] = x;
		}
		ans += i - 1 - phi[i];
		int lf = phi[i] - 1;
		if (i != bb[i]) {
			ans += 2 * (lf - primes.size() + cnt[i]);
		}
	}
	while (!primes.empty() && primes.back() * 2 > n)
		primes.pop_back();
	for (int i = 2; i <= n; ++i) {
		if (i != bb[i]) {
			int x = cp[n / bb[i]] - cnt[i];
			ans += 2 * x;
			int y = primes.size() - x - cnt[i];
			ans += 3 * y;
		}
	}
	for (int i = 0; i < primes.size(); ++i) {
		int x = cp[min(primes[i] - 1, n / primes[i])];
		ans += 2 * x;
		ans += 3 * (i - x);
	}
	cout << ans << "\n";
	return 0;
}

#include<bits/stdc++.h>
#define For(i,l,r) for(int i = (l),i##end = (r);i <= i##end;i++)
#define Fordown(i,r,l) for(int i = (r),i##end = (l);i >= i##end;i--)
#define debug(x) cout << #x << " = " << x << endl

using namespace std;

typedef long long ll;

template <typename T> inline bool chkmin(T &x,T y) { return y < x ? x = y,1 : 0; }
template <typename T> inline bool chkmax(T &x,T y) { return x < y ? x = y,1 : 0; }

const int INF = 0x3f3f3f3f;
const int N = 1e7 + 10;

int phi[N],prime[N],Min[N],sum[N];
int pcnt = 0;
bitset <N> vis;

inline int read() {
	int x = 0,flag = 1;
	char ch = getchar();
	while(!isdigit(ch) && ch != '-') ch = getchar();
	if(ch == '-') flag = -1,ch = getchar();
	while(isdigit(ch)) x = (x << 3) + (x << 1) + (ch - '0'),ch = getchar();
	return x * flag;
}

inline void init(int n) {
	phi[1] = 1;
	For(i,2,n) {
		if(!vis[i]) prime[++pcnt] = i,phi[i] = i - 1,sum[Min[i] = i]++;
		for(int j = 1;j <= pcnt && i * prime[j] <= n;j++) {
			vis[i * prime[j]] = true;
			phi[i * prime[j]] = phi[i] * (prime[j] - 1);
			sum[Min[i * prime[j]] = min(Min[i],prime[j])]++;
			if(i % prime[j] == 0) {
				phi[i * prime[j]] = phi[i] * prime[j];
				break;
			}
		}
	}
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("CF871D.in","r",stdin);
	freopen("CF871D.out","w",stdout);
#endif

	int n = read();ll cnt = 1;
	if(n == 1) return puts("0"),0;
	init(n);
	ll ans0 = 0,ans1 = 0,ans2 = 0,ans3 = 0;

	For(i,n / 2 + 1,n) cnt += !vis[i];
	ans0 = 1ll * cnt * (n - 1) - 1ll * cnt * (cnt - 1) / 2,cnt = 0;

	For(i,2,n) cnt += phi[i];
	ans1 = 1ll * n * (n - 1) / 2 - cnt,cnt = 0;

	Fordown(i,n,1) sum[i] += sum[i + 1];
	cnt += (n - 1);
	For(i,1,pcnt) cnt += sum[n / prime[i] + 1];
	For(i,1,n) sum[i] = sum[i + 1] + !vis[i];
	For(i,1,pcnt) cnt -= sum[max(n / prime[i] + 1,prime[i])];
	ans2 = 1ll * n * (n - 1) / 2 - ans1 - cnt;

	ans3 = 1ll * n * (n - 1) / 2 - ans0 - ans1 - ans2;

	printf("%lld\n",ans1 + 2 * ans2 + 3 * ans3);
	return 0;
}

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;

const ll sz = 1e7 + 10;
bool prime[sz];
ll ph[sz], small[sz], ord[sz], numsmall[sz], moresmall[sz];

int main() {
    ll n;
    scanf("%I64d", &n);

    if (n == 1){
        printf("0");
        return 0;
    }

    /*ll res = 0;
    for (int i = 2; i <= n; i++){
        for (int j = i + 1; j <= n; j++){
            int q = -1;
            bool ok = false;
            for (int p = 2; p <= i; p++){
                if (i % p == 0){
                    if (q == -1){
                        q = p;
                    }
                    if (j % p == 0){
                        res++;
                        ok = true;
                    }
                }
                if (ok){
                    break;
                }
            }
            if (ok){
                continue;
            }

            int r = -1;
            for (int p = 2; p <= j; p++){
                if (j % p == 0){
                    if (r == -1){
                        r = p;
                    }
                }
            }

            if (r * q <= n){
                res += 2;
            }
            else if (2 * r <= n && 2 * q <= n){
                res += 3;
            }
        }
    }
    printf("%I64d\n", res);*/

    for (ll i = 2; i <= n; i++){
        if (!prime[i]){
            for (ll j = 2 * i; j <= n; j += i){
                prime[j] = true;
            }
            for (ll j = i; j <= n; j += i){
                if (!small[j]){
                    small[j] = i;
                    numsmall[i]++;
                }
            }
        }
    }
    for (ll i = 2; i <= n; i++){
        ll ii = i;
        ord[i] = 1;
        while (ii % small[i] == 0){
            ord[i] *= small[i];
            ii /= small[i];
        }
    }
    for (ll i = 2; i <= n; i++){
        if (ord[i] == i){
            ph[i] = i / small[i] * (small[i] - 1);
        }
        else{
            ph[i] = ph[ord[i]] * ph[i / ord[i]];
        }
    }
    ll ones = 0, zeros = 0, threes = 0;
    for (ll i = 2; i <= n; i++){
        ones += (i - ph[i] - 1);
    }
    for (ll i = n / 2 + 1; i <= n; i++){
        if (!prime[i]){
            zeros++;
        }
    }
    zeros = zeros * (n - 1 - zeros) + zeros * (zeros - 1) / 2;
    for (ll i = n; i >= 2; i--){
        moresmall[i] = moresmall[i + 1] + numsmall[i];
    }
    for (ll i = 2; i <= n; i++){
        threes += moresmall[n / small[i] + 1];
    }
    for (ll i = 2; i <= n; i++){
        if (small[i] >= n / small[i] + 1){
            threes--;
        }
    }
    threes /= 2;
    threes -= zeros;
    //printf("%I64d %I64d %I64d\n", ones, zeros, threes);
    printf("%I64d", ones + threes * 3 + ((n - 1) * (n - 2) / 2 - ones - threes - zeros) * 2);
    return 0;
}

#include <cstdio>
#include <cstring>
#include <iostream>
const int N=10000010;
typedef long long ll;
int pri[N/5],mn[N],sx[N],phi[N],sp[N],sn[N];
int n,num,m;
ll cnt0,cnt1,cnt2,cnt3,tot,now;
inline int min(const int &a,const int &b) {return a<b?a:b;}
int main()
{
    scanf("%d",&n);
    int i,j;
    phi[1]=mn[1]=1;
    for(i=2;i<=n;i++)
    {
        if(!sx[i])
        {
            pri[++num]=i,mn[i]=i,phi[i]=i-1,sx[i]=1;
            if(i<=n/2)   m=num;
        }
        sp[i]=num;
        for(j=1;j<=num&&i*pri[j]<=N;j++)
        {
            mn[i*pri[j]]=pri[j];
            if(i%pri[j]==0)
            {
                sx[i*pri[j]]=sx[i],phi[i*pri[j]]=phi[i]*pri[j];
                break;
            }
            sx[i*pri[j]]=sx[i]+1,phi[i*pri[j]]=phi[i]*(pri[j]-1);
        }
    }
    tot=1ll*(n-1)*(n-2)/2;
    for(i=m+1;i<=num;i++)    cnt0+=pri[i]-2+n-pri[i]-(num-i);
    for(i=2;i<=n;i++)    cnt1+=i-1-phi[i];
    for(i=2;i<=n;i++)    if(mn[i]!=i)    cnt2+=phi[i]-sp[i]+sx[i]-1;
    for(i=2;i<=n;i++)    if(mn[i]!=i)
    {
        cnt2+=min(m,sp[n/mn[i]]);
        if(1ll*mn[i]*mn[i]<=n)   cnt2--;
    }
    for(j=2,i=m;i>=1;i--)
    {
        for(;j<=n/pri[i];j++)    if(mn[j]<pri[i]) sn[mn[j]]++,now++;
        now-=sn[pri[i]];
        cnt2-=now;
    }
    for(i=1;i<=m;i++)    for(j=1;j<i&&pri[i]*pri[j]<=n;j++)    cnt2++;
    cnt3=tot-cnt0-cnt1-cnt2;
    printf("%lld",cnt1+cnt2*2+cnt3*3);
    return 0;
}

#include<bits/stdc++.h>
using namespace std;

#define DEBUG

#ifndef TZNLOCAL
#undef DEBUG
#endif

#ifdef DEBUG
#define debug(...) fprintf(stderr,__VA_ARGS__)
#else
#define debug(...) ;
#endif

#define maxn 11111111
typedef long long ll;

bool isp[maxn];
ll p1[maxn],p2[maxn];
ll phi[maxn];
int plist[maxn/10];
int pcnt;
ll ans,ans1,ans2,ans3;
int n;

int main()
{
	cin>>n;
	memset(isp,1,sizeof(isp));
	isp[0]=isp[1]=0;
	phi[0]=0;phi[1]=1;
	for(int i=2;i<=n;i++)
	{
		if (isp[i])
		{
			plist[++pcnt]=i;
			phi[i]=i-1;
		}
		for(int j=1;j<=pcnt;j++)
		{
			if (1ll*i*plist[j]>n) break;
			int tmp=i*plist[j];
			p1[plist[j]]++;
			isp[tmp]=0;
			if (i%plist[j]!=0)
			{
				phi[tmp]=phi[i]*(plist[j]-1);
			}
			else
			{
				phi[tmp]=phi[i]*plist[j];
				break;
			}
		}
	}
	for(int i=n-1;i>=0;i--) p1[i]+=p1[i+1];
	ll ans1=0,ans2=0,ans3=0;
	for(int i=2;i<=n;i++)
	{
		if (isp[i] && i*2>n) continue;
		ans2++;
		ans1+=i-phi[i]-1;
		if (isp[i])
		{
			p2[i]=1;
			ans3+=p1[n/i+1];
		}
	}
	for(int i=n-1;i>=2;i--) p2[i]+=p2[i+1];
	for(int i=2;i*2<=n;i++) if (isp[i] && n/i+1<i) ans3+=p2[n/i+1]-p2[i];
	ans=1ll*ans2*(ans2-1)-ans1+ans3;
	cout<<ans<<endl;
	return 0;
}

/*
���⣺
	��������n������һ������ͼ����������1~n֮������֣�������gcd(u,v)��1ʱ��u��v��һ���ߣ�
��ȨΪ1��d(u,v)��ʾu��v�����·��������d(u,v)�ĺͣ�����1��u<v��n��

������
	����1�Լ����д���n/2�ĵ����������������־�����ͨ��ֱ���޳���
	����ʣ�µ����֣�
		1.��gcd(u,v)��1ʱ��d(u,v)==1������������u��С��u��d(u,v)==1�����ָ���Ϊx-1-��(x)��
		2.��p[u]��ʾ����u����С�����ӣ���p[u]��p[v]��nʱ��d(u,v)==2��ά������num��sum��
num[i]������С������Ϊi�����ָ�����sum����Ϊnum�����ǰ׺�͡�ͳ�Ʀ�num[i]��sum[n/i]���Ը�
������p[u]��p[v]��n����������м�ȥ����������ͳ�Ƶ������ʣ�µ��������Զ���ͳ�������Σ�
���а���gcd(u,v)��1��������������Ӧ����������롣
		3.ʣ�µ��������·һ��Ϊ3����Ϊ u��2��p[u]��2��p[v]��v����·һ�����ڡ���ͨ������
������ȥd(u,v)==1��d(u,v)==2������õ���
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int N=1e7+5;
int n,m,tot,now,pri[N],p[N],phi[N],num[N],sum[N];
LL one,two,three;

int main() {
	scanf("%d",&n);
	phi[1]=1;
	for(int i=2; i<=n; i++) {
		if(!p[i]) {
			p[i]=pri[++tot]=i;
			phi[i]=i-1;
		}
		for(int j=1; j<=tot; j++) {
			if(i*pri[j]>n)
				break;
			p[i*pri[j]]=pri[j];
			if(i%pri[j]==0) {
				phi[i*pri[j]]=phi[i]*pri[j];
				break;
			} else
				phi[i*pri[j]]=phi[i]*(pri[j]-1);
		}
	}
	for(int i=2; i<=n; i++)
		one+=i-1-phi[i];
	for(int i=2; i<=n; i++)
		num[p[i]]++;
	for(int i=2; i<=n; i++)
		sum[i]=sum[i-1]+num[i];
	for(int i=2; i<=n; i++)
		two+=1ll*num[i]*sum[n/i];
	for(int i=2; i<=n; i++)
		if(1ll*p[i]*p[i]<=n)
			two--;
	two=two/2-one;
	m=n-1;
	for(int i=tot; i>=1; i--){
		if(pri[i]*2>n)
			m--;
		else
			break;
	}
	three=1ll*m*(m-1)/2-one-two;
	printf("%I64d\n",one+two*2+three*3);
	return 0;
}

#include <bits/stdc++.h>
#define FOR(i, l, r) for (int i = int(l), __border_right##i = int(r); i < __border_right##i; i++)
#define STRUCT3(v1, v2, v3, name) struct name \
		{   \
			int v1, v2, v3; \
			name(int v1 = 0, int v2 = 0, int v3 = 0) : v1(v1), v2(v2), v3(v3) {} \
			friend bool operator < (const name& athis, const name& other) \
			{   \
				if (athis.v1 != other.v1) return athis.v1 < other.v1;   \
				if (athis.v2 != other.v2) return athis.v2 < other.v2;   \
				return athis.v3 < other.v3;   \
			}\
		}
#define PB push_back
#define LS (((k) << 1) + 1)
#define RS (((k) << 1) + 2)
#define LM ((l) + (r) >> 1)
#define RM (LM + 1)
//#define LOG(x) tb[(UI(x) * (UI)263572066) >> 27]
#define FST first
#define SCD second
#define retunr return
#define modp 1000000007
#define EPS 1e-7
#define INF 0x3f3f3f3f
#define MAX2 113
#define MAX3 1013
#define MAX4 10013
#define MAX5 100013
#define MAX6 1000013
#define MAXN MAX6 * 10
#define MANX MAXN
using namespace std;
typedef long long LL;
typedef unsigned int UI;
//typedef pair<int, int> P;
//const UI tb[32] = {13, 0, 27, 1, 28, 18, 23, 2, 29, 21, 19, 12, 24, 9, 14, 3, 30, 26, 17, 22, 20, 11, 8, 13, 25, 16, 10, 7, 15, 6, 5, 4};

int N;
vector<int> prs;
bool isnp[MAXN];
int u[MANX];
int num[MAXN];
int S[MAXN];

int main()
{
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
	// freopen("out1.txt", "w", stdout);
#endif
	scanf("%d", &N);
	FOR(i, 1, N + 1) {
		u[i] = -1;
	}
	u[1] = 0;
	FOR(i, 2, N + 1) {
		if (!isnp[i]) {
			prs.PB(i);
			for (int k = i + i; k <= N; k += i) {
				if (!isnp[k]) {
					num[i]++;
				}
				isnp[k] = true;
				u[k] = -u[k];
				if (k % ((LL)i * i) == 0) {
					u[k] = 0;
				}
			}
			u[i] = 1;
			num[i]++;
		}
	}
	LL cnt = (LL)N * N;
	LL cnt0 = 0;
	LL cnt1 = 0;
	LL cnt2 = 0;
	LL cnt3 = 0;
	LL cnt03 = 0;
	for (int i = prs.size() - 1; i >= 0; i--) {
		cnt0 += N - 1 - (prs.size() - i - 1);
		if (prs[i] * 2 <= N) {
			break;
		}
	}
	cnt0 *= 2;
	cnt0 += N;

	FOR(i, 2, N + 1) {
		cnt1 += u[i] * (N / i) * (N / i - 1ll);
	}

	S[prs.size()] = 0;
	for (int k = prs.size() - 1; k >= 0; k--) {
		S[k] = num[prs[k]] + S[k + 1];
	}
	cnt2 = (N - 2ll) * (N - 1ll) - cnt1;
	FOR(i, 0, prs.size()) {
		int x = N / prs[i];
		int j = upper_bound(prs.begin(), prs.end(), x) - prs.begin();
		cnt2 -= (LL)num[prs[i]] * S[j];
		if (j <= i) {
			cnt2 += (LL)num[prs[i]] * num[prs[i]];
		}
	}

	cnt3 = cnt - cnt0 - cnt1 - cnt2;

	LL res = cnt1 + cnt2 * 2 + cnt3 * 3;
	res /= 2;
	// cout << cnt << endl;
	printf("%I64d\n", res);
	return 0;
}

#include <cstdio>
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <string>
#include <cstring>
#include <sstream>
#include <algorithm>
using namespace std;

typedef long long ll;

const int Maxn = 10000005;

int mn[Maxn];
int n;
int cnt[Maxn];
ll tot;
ll prs[Maxn];

int main()
{
	for (int i = 2; i < Maxn; i++) if (mn[i] == 0)
		for (int j = i; j < Maxn; j += i)
			if (mn[j] == 0) mn[j] = i;
	scanf("%d", &n);
	for (int i = 2; i <= n; i++)
		cnt[mn[i]]++;
	int oth = n / 2;
	int cur = 0;
	for (int i = 0; i <= n; i++) {
		tot += ll(cnt[i]) * (cnt[i] - 1);
		if (i <= oth) cur += cnt[i];
	}
	int lftout = 0;
	int i;
	for (i = 2; i * i <= n; i++) {
		cur -= cnt[i];
		while (ll(i) * oth > n) { cur -= cnt[oth]; lftout += cnt[oth]; oth--; }
		tot += ll(cnt[i]) * (ll(cur) * 2ll + ll(lftout) * 3ll);
	}
	while (2 * i <= n) {
		while (oth <= i) { oth++; lftout -= cnt[oth]; }
		tot += ll(cnt[i]) * lftout * 3;
		i++;
	}
	for (int i = n; i >= 2; i--) {
		int my = n / i;
		prs[i] = ll(my) * (my - 1) / 2;
		for (int j = i + i; j <= n; j += i)
			prs[i] -= prs[j];
		tot -= prs[i];
	}
	printf("%I64d\n", tot);
	return 0;
}

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int N=1e7+5;
int n,m,tot,now,pri[N],p[N],phi[N],num[N],sum[N];
LL one,two,three;
int main()
{
	scanf("%d",&n);
	phi[1]=1;
	for(int i=2;i<=n;i++)
	{
		if(!p[i]){p[i]=pri[++tot]=i;phi[i]=i-1;}
		for(int j=1;j<=tot;j++)
		{
			if(i*pri[j]>n)break;
			p[i*pri[j]]=pri[j];
			if(i%pri[j]==0){phi[i*pri[j]]=phi[i]*pri[j];break;}
			else phi[i*pri[j]]=phi[i]*(pri[j]-1);
		}
	}
	for(int i=2;i<=n;i++)one+=i-1-phi[i];
	for(int i=2;i<=n;i++)num[p[i]]++;
	for(int i=2;i<=n;i++)sum[i]=sum[i-1]+num[i];
	for(int i=2;i<=n;i++)two+=1ll*num[i]*sum[n/i];
	for(int i=2;i<=n;i++)if(1ll*p[i]*p[i]<=n)two--;
	two=two/2-one;m=n-1;
	for(int i=tot;i>=1;i--)
		if(pri[i]*2>n)m--;
		else break;
	three=1ll*m*(m-1)/2-one-two;
	printf("%I64d\n",one+two*2+three*3);
	return 0;
}

//#pragma GCC optimize("O3")
#include<bits/stdc++.h>
#define rep(i,k,n) for(ll i= (ll) k;i< (ll) n;i++)
#define all(v) (v).begin(), (v).end()
#define SZ(v) (int)((v).size())
#define pb push_back
#define ft first
#define sd second
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const long long INF = 4e18L + 1;
const int IINF = 2e9 + 1;

using namespace std;

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<'='<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;cerr<<'='<<h<<','; _dbg(sdbg+1, a...);
}

#ifdef LOCAL
#define DBG(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define DBG(...) (__VA_ARGS__)
#define cerr if(0)cout
#endif

#define LT 2						//dla liczb powyzej miliona powinno wystarczyc 2 (czasem 1)

ull DOTESTU[6] = {61, 2, 3, 5, 7, 11};

ull mnozenie(ull x, ull y, ull MOD)	//dziala dla liczb do 10^18.
{
	ull maska = 15, wynik=0;
	while(y > 0)
	{
		wynik =  (wynik + (maska & y) * x) % MOD;
		x  = (x<<4)%MOD;
		y >>= 4;
	}
	return wynik;
}
#define mala 10000001
ll sito[mala+1];

vector < pair <ull,int> > rozloz(ll M)
{
	vector < ll > V = {M};
	vector < pair < ull, int > > Odp;
	while(V.size())
	{
		ll pom = V.back(), dz;
		V.pop_back();
		if (pom == 1)
			continue;
		dz = sito[pom];
		if (dz == pom)
		{
			int ile = 1;
			for(auto& el : V)
			{
				while(el % dz==0)
				{
					ile++;
					el /= dz;
				}
			}
			Odp.push_back({dz, ile});
		}
		else
		{
			V.push_back(max(dz, pom/dz));
			V.push_back(min(dz, pom/dz));
		}
	}
	return Odp;
}

void sito_eratostenesa()//uzyc na poczatku maina
{
	for(int i=2; i<=mala; i++)
		sito[i] = i;
	for(int i=2; i*i<=mala; i++)
		if (sito[i] == i)
			for(int j = 2*i; j<=mala; j+=i)
				if (sito[j] == j)
					sito[j] = i;
}

int wej_n;
int tab[100];
ll ile1(ll n)
{
	ll n2 = n;
	ll roz = 0;
//	ll mini = sito[n];
	while(n2 > 1)
	{
		ll akt = sito[n2];
		tab[roz] = akt;
		roz++;
		while(n2%akt == 0) n2 /= akt;
	}
	ll res = 0;
	for(int i=1; i<(1<<roz); i++)
	{
		ll mnoz = -1;
		if (__builtin_popcount(i)&1)
			mnoz = 1;
		ll co = 1;
		for(int j=0; j<roz; j++)
			if (i & (1<<j))
				co *= tab[j];
		res += (n / co) * mnoz;
	}
	return res;

}
/*
ll brut(int v)
{
	ll res = 0;
	for(int i=2; i<v; i++)
	{
		if (__gcd(i, v) > 1)
			res++;
	}
	return res;
}
*/

const int pot = (1<<24);
int drzewo[2*pot];

void dodaj(int gdzie)
{
	gdzie += pot;
	drzewo[gdzie]++;
	while(gdzie > 0)
	{
		gdzie >>=1;
		drzewo[gdzie]++;
	}
}

int suma(int a, int b)
{
	a += pot, b += pot;
	if (a == b)
		return drzewo[a];
	int wyn = drzewo[a] + drzewo[b];
	while((a>>1) != (b>>1))
	{
		if ((a&1) == 0)
			wyn += drzewo[a+1];
		if ((b&1) == 1)
			wyn += drzewo[b-1];
		a>>=1; b>>=1;
	}
	return wyn;
}

ll pierwsze_pref[10000007];

int main()
{
#ifndef LOCAL
    ios_base::sync_with_stdio(0);
    cin.tie(0);
#endif
	int n;
	cin>>n;
	wej_n = n;
	sito_eratostenesa();
	for(int i=2; i<=10000000; i++)
	{
		pierwsze_pref[i] = pierwsze_pref[i-1];
		if (sito[i] == i)
			pierwsze_pref[i]++;
	}
	ll odp = 0;
	ll zli = 1;
	for(int i=2; i<=n; i++)
	{
		ll temp;// = ile1(i)-1;//w jednym kroku
		ll najmniejsza;// = sito[i];
		ll pomm;// = min(n/najmniejsza, (ll)i-1);//najwieksza liczba pierwsza do ktorej moge dojsc w dwoch
		ll w_trzech;// = pierwsze_pref[min(n/2, i-1)] - pierwsze_pref[pomm];
		ll wcale;
		ll w_dwoch;

		if (sito[i] != i)
		{

		 temp = ile1(i)-1;//w jednym kroku
		 najmniejsza = sito[i];
		 pomm = min(n/najmniejsza, (ll)i-1);//najwieksza liczba pierwsza do ktorej moge dojsc w dwoch
		 w_trzech = pierwsze_pref[min(n/2, i-1)] - pierwsze_pref[pomm];
		 wcale = 1;
		if (i > n/2)
			wcale += pierwsze_pref[i-1] - pierwsze_pref[n/2];
		 w_dwoch = i-1-temp-w_trzech-wcale;
		}

		if (sito[i] == i)
		{
			temp = 0;
			w_dwoch = suma(0, n/i);
			DBG(i, n/i);
			wcale = zli;
			if (i*2 > n)
				wcale = i-1;
			w_trzech = i-1-temp-w_dwoch-wcale;
		}
		dodaj(sito[i]);
		DBG(i, sito[i]);
		if (sito[i] == i && i*2 > n)
			zli++;
		odp += temp + 2ll*w_dwoch + 3ll * w_trzech;
		DBG(i, temp, w_dwoch, w_trzech, wcale);
	}
	cout << odp;
    return 0;
}

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>

using namespace std;

const int N=10000000;
int mu[N+10],prime[N],f[N+10],g[N+10];
bool vis[N+10];
int n,tot;
long long ans,sum;

int main()
{
	scanf("%d",&n);
	mu[1]=1;
	for (int i=2;i<=n;i++)
	{
		if (!vis[i]) prime[++tot]=i,f[i]=i,mu[i]=-1;
		for (int j=1;j<=tot && i*prime[j]<=n;j++)
		{
			vis[i*prime[j]]=1;f[i*prime[j]]=prime[j];
			if (i%prime[j]==0) {mu[i*prime[j]]=0;break;}
			mu[i*prime[j]]=-mu[i];
		}
		g[f[i]]++;
	}
	while (tot && prime[tot]>n/2) tot--;
	int sum1=0,sum2=0,now=tot;
	for (int i=1;i<=tot;i++) sum1+=g[prime[i]];
	for (int i=1;i<=tot;i++)
	{
		while (now>i && prime[i]*prime[now]>n) sum2+=g[prime[now]],sum1-=g[prime[now]],now--;
		if (now>=i) sum1-=g[prime[i]];
		if (now<i) sum2-=g[prime[i]];
		ans+=1ll*g[prime[i]]*(g[prime[i]]-1)+2ll*g[prime[i]]*sum1+3ll*g[prime[i]]*sum2;
	}
	sum=1ll*n*(n-1);
	for (int i=1;i<=n;i++) sum-=1ll*mu[i]*(n/i)*(n/i);
	sum++;
	ans-=sum/2;
	printf("%I64d\n",ans);
//	printf("%lld\n",ans);
	/*
	for (int i=1;i<=n;i++) printf("%d ",mu[i]);printf("\n");
	for (int i=1;i<=n;i++)
	  for (int j=i;j<=n;j+=i)
	    ans1[j]+=mu[i]*(min(n/j,j)/i),ans2[j]+=mu[i]*j/i;
	for (int i=1;i<=n;i++) printf("%d %d\n",ans1[i],ans2[i]);
	for (int i=1;i<=n;i++) ans+=(ans1[i]-1)*2+i-ans2[i];
	printf("%lld\n",ans);*/
	return 0;
}

#include<stdio.h>
#include<iostream>
using namespace std;
typedef long long LL;
const int maxn=1E7+77;

int minDis[maxn],cPrimes=0,u[maxn],cnt[maxn];
LL primes[maxn],sum[maxn];
void init(int n){
	minDis[1]=u[1]=1;
	for(int i=2;i<=n;++i){
		if(minDis[i]){
			int t=i/minDis[i];
			if(minDis[i]==minDis[t]) u[i]=0;
			else u[i]=-u[t];
		}else{
			minDis[i]=i;
			primes[cPrimes++]=i;
			u[i]=-1;
		}
		++cnt[minDis[i]];
		for(int j=0;j<cPrimes;++j){
			if(1ll*i*primes[j] > n) break;
			minDis[i*primes[j]]=primes[j];
			if(!(i%primes[j])) break;
		}
	}
	for(int i=1;i<=n;++i){
		sum[i]=sum[i-1]+cnt[i];
	//	if(i<10) cerr<<"sum["<<i<<"]="<<sum[i]<<endl;
	}
}

LL N,C[4];

int main(){
	cin>>N;
	init(N);
	C[0]=1;
	for(int i=0;i<cPrimes;++i) if(primes[i]<=N && (primes[i]<<1)>N) ++C[0];
	//cerr<<"0--"<<C[0]<<endl;
	C[0]=N*N - (N-C[0])*(N-C[0]) + N - C[0];

	for(int i=1;i<=N;++i) if(u[i]) C[1]+=(N/i)*(N/i)*u[i];
	C[1]=N*N-C[1];
	//cerr<<"1--"<<C[1]<<endl;
	C[1]-=N-1;

	int p=cPrimes;
	for(int i=0;i<cPrimes;++i){
		while(p && primes[p-1] > N || primes[p-1]*primes[i]>N) --p;
		//cerr<<primes[i]<<"<:>"<<primes[p-1]<<endl;
		C[2]+=cnt[primes[i]]*sum[primes[p-1]];
	}
	//cerr<<"2--"<<C[2]<<endl;
	for(int i=0;i<cPrimes;++i) if((primes[i]*primes[i])<=N){
		C[2]-=cnt[primes[i]];
	}
	//cerr<<"2--"<<C[2]<<endl;
	C[2]-=C[1];

	C[3]=N*N;
	for(int i=0;i<3;++i) C[3]-=C[i];

	LL ans=0;
	for(int i=0;i<4;++i){
		//cerr<<i<<":"<<C[i]<<endl;
		ans+=C[i]*i;
	}
	cout<<(ans>>1)<<endl;
}

// In the name of Allah.
// We're nothing and you're everything.
// Ya Ali!

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 1e7 + 14;
int n, phi[maxn], suf[maxn];
vector<int> all[maxn];
bool mark[maxn];
ll c1, c2;
int bads = 1;
int mults(int p, int l, int r){
	return r / p - l / p;
}
int main(){
	ios::sync_with_stdio(0), cin.tie(0);
	cin >> n;
	for(int i = 1; i <= n; i++){
		phi[i] += i;
		c1 += max(0, i - 1 - phi[i]);
		for(int j = i * 2; j <= n; j += i)
			phi[j] -= phi[i];
	}
	//cerr << ans << '\n';
	vector<int> pr;
	for(int i = 2; i <= n; i++)
		if(!mark[i]){
			pr.push_back(i);
			if(i * 2 > n)
				bads++;
			for(int j = i; j <= n; j += i)
				if(!mark[j]){
					mark[j] = 1;
					all[i].push_back(j);
				}
			if(i * 2 <= n)
				suf[i] = all[i].size();
		}
	for(int i = n; i >= 0; i--)
		suf[i] += suf[i + 1];
	int goods = n - bads;
	ll allp = (ll) goods * (goods - 1) / 2;
	c2 = allp - c1;
	int ptr = n;
	while(!pr.empty() && pr.back() * 2 > n)
		pr.pop_back();
	for(int i = 0; i < pr.size(); i++){
		if(2 * pr[i] > n)
			break;
		while(ptr && (ll) ptr * pr[i] > n)
			ptr--;
		cerr << suf[ptr + 1] << '\n';
		c2 -= suf[ptr + 1];
	}
	ptr = (int) pr.size() - 1;
	for(int i = 0; i < pr.size(); i++){
		if(2 * pr[i] > n)
			break;
		if(ptr < i)
			ptr = i;
		while(ptr >= i && (ll) pr[ptr] * pr[i] > n)
			ptr--;
		//cerr << suf[ptr + 1] << '\n';
		c2 += pr.size() - ptr - 1;
	}
	cerr << (allp - c1 - c2) << '\n';
	cout << c1 + c2 * 2 + (allp - c1 - c2) * 3 << '\n';
}

#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 10000010
#define LL long long
using namespace std;

LL n;
LL phi[MAXN],miu[MAXN],mind[MAXN],mind2[MAXN];
LL cnt[MAXN],scnt[MAXN];
int prime[MAXN],nump;
bool flag[MAXN];

void init(){
	prime[0]=1;
	miu[1]=1;
	mind[1]=mind2[1]=1;
	for(int i=2;i<=n;i++){
		if(!flag[i]){
			prime[++nump]=i;
			phi[i]=i-1;
			miu[i]=-1;
			mind[i]=mind2[i]=i;
		}
		for(int j=1;j<=nump && i*prime[j]<=n;j++){
			flag[i*prime[j]]=1;
			mind[i*prime[j]]=prime[j];
			if(i%prime[j]){
				phi[i*prime[j]]=phi[i]*(prime[j]-1);
				miu[i*prime[j]]=-miu[i];
				mind2[i*prime[j]]=prime[j];
			}else{
				phi[i*prime[j]]=phi[i]*prime[j];
				miu[i*prime[j]]=0;
				mind2[i*prime[j]]=mind2[i]*prime[j];
				break;
			}
		}
	}
}

pair<LL,LL> calc0(int x){
	LL m=n/x;
	LL y=mind[x];
	if(y==1) y=n;
	for(int i=1;i<=m;i++) cnt[i]=0;
	for(int i=2;i<=m;i++) cnt[min(y,mind[i])]++;
	for(int i=1;i<=m;i++) scnt[i]=scnt[i-1]+cnt[i];
	LL res=0,temp=0,now=0,res2=0;
	int lim=min(m,n/2);
	for(int i=m;i>=1;i--){
		while(now<m && (now+1)*i<=n) now++;
		res+=scnt[now]*cnt[i];
		if(i*2<=n && now<lim) res2+=(scnt[lim]-scnt[now])*cnt[i];
	}
	res+=scnt[min(m,n/mind[x])]*2;
	if(mind[x]*mind[x]<=n) res++;
	if(mind[x]*2<=n){
		if(min(m,n/mind[x])<lim)
			res2+=(scnt[lim]-scnt[min(m,n/mind[x])])*2;
		if(mind[x]*mind[x]>n) res2++;
	}
	return make_pair(res,res2);
}

LL calc(){
	LL res=0,res2=0;
	for(int i=1;i<=n;i++){
		pair<LL,LL> temp=calc0(i);
		res+=miu[i]*temp.first;
		res2+=miu[i]*temp.second;
	}
	res=(res-1)/2;
	res-=n-1;
	res2/=2;
	res=res*2+res2*3;
	for(int i=2;i<=n;i++)
		res+=i-phi[i]-1;
	return res;
}

int main(){
#ifdef DEBUG
	freopen("D.in","r",stdin);
#endif
	scanf("%d",&n);
	init();
	LL ans=calc();
	printf("%lld\n",ans);
	return 0;
}

#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define N 10000005
#define ll long long
using namespace std;
int phi[N],p[N],num[N],n,m;
int f[N],g[N],pri[N/10],cnt=0;
bool isp[N];
inline int min(int a,int b)
{return a<b?a:b;}
int main (){
	int i,j;
	scanf ("%d",&n);
	phi[1]=1;
	for (i=2;i<=n;i++)
	{f[i]=f[i-1]+(!isp[i]);
	if (!isp[i])
	{pri[++cnt]=i;p[i]=i;phi[i]=i-1;g[i]=1;
	num[i]++;m+=(i<=n/2);
	}
	m+=(isp[i]);
	for (j=1;j<=cnt&&i*pri[j]<=n;j++)
	{isp[i*pri[j]]=1;p[i*pri[j]]=pri[j];
	num[pri[j]]++;g[i*pri[j]]=g[i]+1;
	if (i%pri[j]==0)
	{phi[i*pri[j]]=phi[i]*pri[j];
	g[i*pri[j]]--;
	break;
	}
	phi[i*pri[j]]=phi[i]*(pri[j]-1);
	}
	}
	for (i=1;i<=n;i++) num[i]+=num[i-1];
	ll tot=1ll*m*(m-1);tot>>=1ll;
	ll n1=0,n2=0,n3=0;
	for (i=2;i<=n;i++)
	{if (isp[i])
	{n1+=(i-1-phi[i]);
	n2+=(phi[i]-f[i]+g[i]-1);
	continue;
	}
	n2+=num[n/i];n2-=(n/i);
	if (i>n/i) n2++;
	n2-=f[min(i-1,n/i)];
	}
	n3=tot-n1-n2;
	tot=n1+2ll*n2+3ll*n3;
	printf ("%lld\n",tot);
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 1e+7 + 10;

bool isnotp[maxn];ll u[maxn];
ll p[664599],pn;
ll cnt[664599],sum[664599];
ll n,ans;

void pre()
{
	int i,j;

	for(i=2;i<=n;i++)
	{
		if(!isnotp[i])
		{
			p[pn]=i;
			u[i]=cnt[pn++]=1;
		}
		for(j=0;j<pn && i*p[j]<=n;j++)
		{
			isnotp[i*p[j]]=true;
			u[i*p[j]]=-u[i];
			cnt[j]++;
			if(!(i%p[j]))
			{
				u[i*p[j]]=0;
				break;
			}
		}
	}cerr<<pn<<endl;

	sum[0]=cnt[0];
	for(i=1;i<pn;i++) sum[i]=sum[i-1]+cnt[i];
}

void solve()
{
	ll i,j,pos,tsum;

	ans=0;

	for(i=0;i<pn;i++)
	{
		ans+=cnt[i]*(cnt[i]-1);
		for(j=i+1;j<pn && p[j]*p[i]<=n;j++) ans+=cnt[i]*cnt[j]*2;
	}//cerr<<ans<<endl;

	for(i=2;i<=n;i++) if(u[i])
	{
		ans-=u[i]*(n/i)*(n/i-1)/2;
	}

	for(pos=0;p[pos]<=n/2;pos++);j=--pos;
	for(i=1;i<pn && p[i]<=n/2;i++)
	{
		for(;j>=0 && p[j]*p[i]>n;j--);
		ans+=cnt[i]*(sum[pos]-sum[max(j,i)])*3;
	}

	cout<<ans<<endl;
}

int main()
{
//	freopen("2368.in","r",stdin);
//	freopen("2368.out","w",stdout);

	cin>>n;
	pre();
	solve();

	return 0;
}

#include <bits/stdc++.h>
#define mset(a, b) memset(a, b, sizeof(a))
#define mcpy(a, b) memcpy(a, b, sizeof(a))
using namespace std;
typedef long long LL;
const int MAXN = 10000007;

template <typename T> inline void read(T &AKNOI) {
	T x = 0, flag = 1;
	char ch = getchar();
	while (!isdigit(ch)) {
		if (ch == '-') flag = -1;
		ch = getchar();
	}
	while (isdigit(ch)) {
		x = x * 10 + ch - '0';
		ch = getchar();
	}
	AKNOI = flag * x;
}

int n, half;
int pr[MAXN], pcnt, vis[MAXN], phi[MAXN];
int low[MAXN], cnt[MAXN];

void sieve() {
	phi[1] = 1;
	for (int i = 2; i <= n; ++i) {
		if (!vis[i]) {
			pr[++pcnt] = i;
			phi[i] = i - 1;
			low[i] = pcnt;
		}
		++cnt[low[i]];
		for (int j = 1; j <= pcnt; ++j) {
			int k = i * pr[j];
			if (k > n) break;
			vis[k] = 1;
			low[k] = j;
			if (i % pr[j]) {
				phi[k] = phi[i] * (pr[j] - 1);
			} else {
				phi[k] = phi[i] * pr[j];
				break;
			}
		}
	}
	while (pr[pcnt] > half) --pcnt;
	for (int i = pcnt - 1; i >= 1; --i) {
		cnt[i] += cnt[i + 1];
	}
}

void solve() {
	read(n); half = n / 2;
	sieve();
	LL ans = 0, g1 = 0, ban = 0;
	for (int i = 2; i <= n; ++i) {
		if (!vis[i] && i > half) {
			++ban;
		} else {
			ans += i - 1 - phi[i];
			g1 += phi[i] - 1 - ban;
		}
	}
	ans += g1 * 2;
	LL t3 = 0;
	int rt = sqrt(n), pt = pcnt, c = 0;
	for (int i = 1; i <= pcnt; ++i) {
		if (pr[i] <= rt) continue;
		++c;
		while (1ll * pr[i] * pr[pt - 1] > n) --pt;
		t3 += cnt[pt];
	}
	ans += t3 - 1LL * c * (c + 1) / 2;
	printf("%lld\n", ans);
}

int main() {
	solve();
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
const int maxn = 1e7 + 6;
bool bad[maxn];
int prime[maxn];
int phi[maxn];
int number_of_prime_divisors[maxn];
int pref[maxn];
int number_of_bad = 0;
void precalc()
{
	for(int i = 1; i <= n; i++)
	{
		phi[i] = i;
	}
	for(int i = 2; i <= n; i++)
	{
		if(prime[i]){
			continue;
		}
		for(int j = i; j <= n; j += i)
		{
			if(!prime[j])
			{
				prime[j] = i;
			}
			phi[j] /= i;
			phi[j] *= i - 1;
		}
	}
	for(int i = 1; i <= n; i++)
	{
		if(i == 1 || prime[i] ==i && i * 2 > n)
		{
			bad[i] = true;
			number_of_bad++;
		}
	}
	for(int i = 2; i <= n; i++)
	{
		if(prime[i] == i)
		{
			number_of_prime_divisors[i] = 1;
		}
		else if(prime[i / prime[i]] == prime[i])
		{
			number_of_prime_divisors[i] = number_of_prime_divisors[i / prime[i]];
		}
		else
		{
			number_of_prime_divisors[i] = number_of_prime_divisors[i / prime[i]] + 1;
		}
	}
}
int funct1(){
	int ans = 0;
	for(int i = 2; i <= n; i++)
	{
		if(!bad[i])
		{
			ans += i - 1 - phi[i];
		}
	}
	return ans;
}
int funct2()
{
	int ans = 0;
	int pr1 = 1;
	for(int i = 2; i <= n; i++)
	{
		if(prime[i] == i)
		{
			pr1++;
		}
		else
		{
			ans -= pr1;
			ans += number_of_prime_divisors[i];
			ans += phi[i];
		}
	}
	for(int i = 1; i <= n; i++){
		if(!bad[i]){
			pref[prime[i]]++;
		}
	}
	for(int i = 1; i <= n; i++)
	{
		pref[i] += pref[i - 1];
	}
	for(int i = 2; i <= n; i++)
	{
		if(prime[i] != i || bad[i])
		{
			continue;
		}
		ans += pref[n / i];
		for(int j = i; j <= n; j += i)
		{
			if(prime[j] <= n / i)
			{
				ans--;
			}
		}
	}
	for(int i = 2; i <= n; i++)
	{
		int a = prime[i];
		int b = i / a;
		if(b != 1 && prime[b] == b && a != b)
		{
			ans--;
		}
	}
	return ans;
}
signed main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	cin >> n;
	precalc();
	int cnt1 = funct1();
	int cnt2 = funct2();
	int cnt3 = (n - number_of_bad) * (n - number_of_bad - 1) / 2 - cnt1 - cnt2;
	cout << cnt1 + 2 * cnt2 + 3 * cnt3;
	return 0;
}

#include <bits/stdc++.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define RS(X) scanf("%s", (X))
#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define PII pair<int,int>
#define VI vector<int>
#define VL vector<long long>
#define VPII vector<pair<int,int> >
#define PLL pair<long long,long long>
#define VPLL vector<pair<long long,long long> >
#define F first
#define S second
typedef long long LL;
using namespace std;
const int MOD = 1e9+7;
const int SIZE = 1e7+10;
int p[SIZE];
int cnt[SIZE];
vector<int>pp;
LL an;
void prime_init(int n){
    for(int i=2;i<=n;i++){
        if(!p[i]){
            pp.PB(i);
            for(int j=i;j<=n;j+=i){
                if(!p[j]){
                    p[j]=i;
                    cnt[p[j]]++;
                }
            }
        }
    }
}
bool is_prime(int x){
    return p[x]==x;
}
LL dp[SIZE];
int main(){
    DRI(n);
    if(n<=3)return 0*puts("0");
    an=(n-1LL)*(n-2)*3;
    prime_init(n);
    {
        LL cc=0;
        REP(i,SZ(pp)){
            if(pp[i]*2>n){
                cc++;
            }
        }
        an-=(cc*(cc-1)+cc*(n-1-cc)*2)*3;
    }
    REP(i,SZ(pp)){
        for(int j=0;j<i&&pp[i]*pp[j]<=n;j++){
            an-=(LL)(cnt[pp[i]])*cnt[pp[j]]*2;
        }
        an-=(LL)(cnt[pp[i]]-1)*cnt[pp[i]];
    }
    for(int i=n;i>1;i--){
        dp[i]=(LL)(n/i)*(n/i-1);
        for(int j=i+i;j<=n;j+=i){
            dp[i]-=dp[j];
        }
        an-=dp[i];
    }
    cout<<an/2<<endl;
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define rep(i,l,r) for(int i=(l);i<(r);++i)
#define per(i,l,r) for(int i=(r)-1;i>=(l);--i)
#define dd(x) cout << #x << " = " << x << ", "
#define de(x) cout << #x << " = " << x << endl
const int N = 1e7 + 6;
int n;

int pri[N], ntp[N], low[N], phi[N], pn;
void getpri() {
	phi[1] = 1; ntp[1] = 1; low[1] = 1;
	rep(i, 2, N) {
		if (!ntp[i]) pri[pn++] = i, phi[i] = i - 1, low[i] = i;
		for (int j = 0, o; j < pn && (o = pri[j] * i) < N; j++) {
			ntp[o] = 1;
			low[o] = pri[j];
			if (i % pri[j]) phi[o] = (pri[j] - 1) * phi[i];
			else { phi[o] = pri[j] * phi[i]; break; }

		}
	}
}

ll gao_tp1() {
	ll ret = 0, tmp = 1;
	rep(i, 2, n + 1) {
		if (!ntp[i]) { tmp++; ret += (n / i) - 1; }
		else ret += phi[i] - tmp;
	}
	return ret;
}

int cnt[N];
ll gao_tp2() {
	ll ret = 0, tmp = 0, _tmp = n;
	rep(i, 2, n + 1) if (ntp[i] || i * 2 <= n) cnt[low[i]]++, tmp++;
	rep(i, 2, n + 1) {
		while (i * _tmp > n) tmp -= cnt[_tmp--];
		if (!ntp[i]) {
			ret += tmp;
			for (int j = i; j <= n; j += i) if (1ll * low[j] * i <= n) ret--;
		}
	}
	return ret;
}

ll gao_tp3() {
	ll ret = 0, tmp = 0, _tmp = n;
	rep(i, 2, n + 1) if (!ntp[i]) tmp++;
	rep(i, 2, n + 1) {
		if (!ntp[i]) tmp--;
		while (_tmp > i && i * _tmp > n) tmp -= !ntp[_tmp--];
		if (_tmp == i) return ret;
		if (!ntp[i]) ret += tmp;
	}
	return ret;
}

int main() {
	getpri();
	scanf("%d", &n);
	ll ans = 0; int bad = 1;
	rep(i, 2, n + 1) {
		if (!ntp[i] && i * 2 > n) { bad++; continue; }
		ans += i - 1 - phi[i] + (phi[i] - bad) * 3;
	}
//	int cut = 0;
//	rep(i, 2, n + 1) rep(j, i + 1, n + 1) if (__gcd(i, j) == 1 && low[i] * low[j] <= n) cut++;

	ll tp1 = gao_tp1(); //de(tp1);
	ll tp2 = gao_tp2(); //de(tp2);
	ll tp3 = gao_tp3(); //de(tp3);
//	assert(cut == tp1 + tp2 - tp3);
	printf("%lld", ans - (tp1 + tp2 - tp3));

	return 0;
}

#include <bits/stdc++.h>
using namespace std;
int main(){
  long long n;
  cin >> n;
  vector<int> mf(n + 1, -1);
  vector<int> mobius(n + 1, 1);
  mobius[0] = 0;
  mobius[1] = 0;
  for (int i = 2; i <= n; i++){
    if (mf[i] == -1){
      mf[i] = i;
      mobius[i] = -1;
      for (int j = i * 2; j <= n; j += i){
        if (mf[j] == -1){
          mf[j] = i;
        }
        mobius[j] *= -1;
      }
    }
  }
  for (int i = 2; i * i <= n; i++){
    for (int j = i * i; j <= n; j += i * i){
      mobius[j] = 0;
    }
  }
  long long ans1 = 0;
  for (int i = 2; i <= n; i++){
    ans1 -= (long long) (n / i) * (n / i) * mobius[i];
    ans1--;
  }
  vector<long long> mfcnt(n + 1, 0);
  for (int i = 2; i <= n; i++){
    mfcnt[mf[i]]++;
  }
  vector<long long> mfsum(n + 2, 0);
  for (int i = 0; i <= n; i++){
    mfsum[i + 1] = mfsum[i] + mfcnt[i];
  }
  long long ans2 = 0;
  for (int i = 2; i <= n; i++){
    ans2 += mfcnt[i] * max(mfsum[n / i + 1] - mfsum[i + 1], (long long) 0);
  }
  ans2 *= 2;
  for (int i = 2; i <= n; i++){
    ans2 += mfcnt[i] * mfcnt[i];
  }
  ans2 -= ans1;
  ans2 -= n - 1;
  long long tmp = n - 1;
  for (int i = n / 2 + 1; i <= n; i++){
    if (mf[i] == i){
      tmp--;
    }
  }
  long long ansinf = n * n - tmp * tmp - (n - tmp);
  long long ans3 = n * (n - 1) - ans1 - ans2 - ansinf;
  long long ans = (ans1 + ans2 * 2 + ans3 * 3) / 2;
  cout << ans << endl;
}

#define ONLINE_JUDGE
#include <bits/stdc++.h>

#define inf 0x3f3f3f3f

#define MOD 1000000007

#define pb push_back

#define sq(x) ((x)*(x))

#define x first

#define y second

#define eps 1e-9

#define bpt(x) (__builtin_popcount(x))

#define bptl(x) (__builtin_popcountll(x))

#define bit(x, y) (((x)>>(y))&1)

#define bclz(x) (__builtin_clz(x))

#define bclzl(x) (__builtin_clzll(x))

#define bctz(x) (__builtin_ctz(x))

#define bctzl(x) (__builtin_ctzll(x))

#define sgn(x) (((x)<eps)-((x)<-eps));

#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;

typedef long long INT;

typedef vector<int> VI;

typedef pair<int, int> pii;

typedef pair<pii, int> pi3;

typedef double DO;

template<typename T, typename U> inline void smin(T &a, U b) {if (a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, U b) {if (a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}

template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}

template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}

template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}

template<class T>inline void printsp(T x) {print(x); putchar(' ');}

template<class T>inline void println(T x) {print(x); putchar('\n');}

int power(int a, int b, int m, int ans=1) {

	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;

	return ans;

}

#ifndef ONLINE_JUDGE

void debug() {cout << endl;}

template<typename T, typename... Args>void debug(T&& head, Args&&... tail) {cout << head << ' ';debug(tail...);}

#endif

#define NN 11000000

int np, p[NN], phi[NN];

INT cnt[NN], sum[NN];

void prepare() {

	for (int i=1; i<NN; i++) phi[i]=i;

	for (int i=2; i<NN; i+=2) phi[i]/=2;

	for (int i=3; i<NN; i+=2) if (phi[i]==i) {

		for (int j=i; j<NN; j+=i) phi[j]-=phi[j]/i;

	}

	for (int i=2; i<NN; i++) {

//		if (i<100) debug(i, p[i]);

		if (p[i]) continue;

//		p[i]=i;

//		if ((INT)i*i>NN) continue;

		for (int j=i; j<NN; j+=i) {

			if (p[j]==0) p[j]=i;

		}

	}

}

int main() {

#ifndef ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	prepare();

	int N;

	gn(N);

	INT one=0;

	for (int i=2; i<=N; i++) {

		one+=i-phi[i]-1;

	}

	INT three=0;

	for (int i=2; i<=N; i++) {

		if (p[i]*2>N && p[i]==i) continue;

		cnt[p[i]]++;

	}

	for (int i=N; i>0; i--) {

		sum[i]=sum[i+1]+cnt[i];

	}

//	debug(cnt[3]);

	for (int i=2; i<=N; i++) {

		if (p[i]!=i) continue;

		int q=N/i+1;

		q=max(q, i+1);

//		if (q<=i) break;

//		debug(i, q, sum[q]*cnt[i]);

		three+=sum[q]*cnt[i];

	}

	INT two=sum[1]*(sum[1]-1)/2;

	two-=one+three;

	INT ans=one+2*two+3*three;

//	debug(one, two, three);

	cout<<ans<<endl;

	return 0;

}

#include <algorithm>
#include <bitset>
#include <complex>
#include <math.h>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#endif

long long max(long long x, long long y){return (x > y ? x : y);}
long long min(long long x, long long y){return (x < y ? x : y);}
int gcd(int a, int b) { return b ? gcd(b, a%b) : a; }

#define ll int
#define LGL long long
#define pb push_back
#define ld long double
#define mp make_pair
#define F first
#define S second
#define pii pair<ll,ll>

using namespace :: std;

const ll maxn=1e7+300;
const ll inf=1e9+800;
const ll mod=1e9+7;

ll minn[maxn];
LGL joft[maxn];
ll n;

long long find_gcd_mos_1(){
	for(ll i=n;i>=1;i--){
		long long res=n/i;
		for(ll j=i;j<=n;j+=i){
			joft[i]-=joft[j];
		}
		joft[i]+=(res*(res-1))/2;
	}
	return joft[1];
}

ll par[maxn];

long long find_dow_12(){
	fill(par,par+n+7,0);
	for(ll i=2;i<=n;i++){
		if(minn[i]!=i)par[minn[i]]++;
	}
	for(ll i=1;i<=n;i++){
		par[i]+=par[i-1];
	}
	long long ans=0;
	for(ll i=2;i<=n/2;i++){
		if(minn[i]==i){
			ans+=par[n/i];
			for(ll j=i*2;j<=n;j+=i){
				if((LGL)minn[j]*(LGL)i<=n){
					ans--;
				}
			}
		}
	}
	return ans;
}
long long find_dow_22(){
	fill(par,par+n+7,0);
	for(ll i=2;i<=n/2;i++){
		if(minn[i]==i)par[i]++;
	}
	for(ll i=1;i<=n;i++){
		par[i]+=par[i-1];
	}
	long long ans=0;
	for(ll i=2;i<=n/2;i++){
		if(minn[i]==i){
			ans+=par[n/i];
			if((LGL)i*(LGL)i<=n)ans--;
		}
	}
	return ans/2;
}
long long find_dow_11(){
	long long tedad=0;
	for(ll i=2;i<=n;i++){
		if(minn[i]!=i)tedad++;
	}
	long long ans=0;
	fill(joft,joft+n+7,0);
	for(ll i=n;i>=2;i--){
		long long res=n/i;
		if(minn[i]==i)res--;
		for(ll j=i;j<=n;j+=i){
			joft[i]-=joft[j];
		}
		joft[i]+=(res*(res-1))/2;
		ans+=joft[i];
	}
	return tedad*(tedad-1)/2-ans;
}
int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n;

    for(ll i=2;i<=n;i++)
    	if(minn[i]==0)
    		for(ll j=i;j<=n;j+=i)
    			if(minn[j]==0)
    				minn[j]=i;

    LGL bad=1;
    for(ll i=2;i<=n;i++){
    	if(minn[i]==i && i>n/2){
    		bad++;
    	}
    }
    LGL sefr=bad*(n-1)-bad*(bad-1)/2;
    LGL v=find_gcd_mos_1();
    LGL yek=((LGL)n*((LGL)n-1))/2-v;
    long long a11=find_dow_11();
    long long a12=find_dow_12();
    long long a22=find_dow_22();
    LGL dow=a11+a12+a22;
    LGL sew=((LGL)n*(LGL)(n-1))/2-sefr-yek-dow;
    cout<<yek+dow*2+sew*3;
}

#include <stdio.h>
#include <vector>
using namespace std;
typedef long long int ll;
#define PB push_back
constexpr int kN = int(1E7 + 10);
vector<ll> prime;
int l[kN], mu[kN], s[kN];
ll n;
void pre() {
	mu[1] = 1;
	for (int i = 2; i <= n; i++) {
		if (l[i] == 0) {
			mu[i] = -1;
			prime.PB(l[i] = i);
		}
		for (int j : prime) {
			if (i * j > n) break;
			l[i * j] = min(l[i], j);
			if (i % j == 0) {
				mu[i * j] = 0;
				break;
			}
			else mu[i * j] = -mu[i];
		}
	}
	for (int i = 2; i <= n; i++) s[l[i]]++;
	for (int i = 3; i <= n; i++) s[i] += s[i - 1];
	return ;
}

int main() {
	ll ans = 0, one = 0, two = 0, three = 0, zero = 0, cnt = 1;
	scanf("%lld", &n);
	pre();

	for (int k = 1; k <= n; k++) one += mu[k] * (n / k) * (n / k);
	one = n * (n - 1) / 2 - (one >> 1);

	for (ll i : prime) if (i * i < n) continue;
	else if ((i << 1) > n) cnt++;
	else if (i > n / i) three += s[i - 1] - s[n / i];
	zero = (((n - 1) + (n - cnt)) * cnt) >> 1;

	two = n * (n - 1) / 2 - zero - one - three;

//	printf("zero = %lld\n", zero);
//	printf("one = %lld\n", one);
//	printf("two = %lld\n", two);
//	printf("three = %lld\n", three);

	ans = one + two * 2 + three * 3;
	printf("%lld\n", ans);
}

//let's do it
 #include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define inf 1000000000000
#define mod 1000000007
#define pb push_back
#define mp make_pair
#define all(v) v.begin(),v.end()
#define S second
#define F first
#define boost1 ios::sync_with_stdio(false);
#define boost2 cin.tie(0);
#define mem(a,val) memset(a,val,sizeof a)
#define endl "\n"
#define maxn 100001
#define maxi 10000000

ll prime[maxi+1],cnt[maxi+1],lpf[maxi+1],sum[maxi+1];

inline ll c2(ll x)
{
	return (x*(x-1))/2;
}
inline ll get(ll l,ll r)
{
	if(l>r)
	return 0;
	return sum[r]-sum[l-1];
}
int main()
{
	boost1;boost2;
	ll i,j,n,x,y,dist1=0,dist2=0,dist3=0;
	cin>>n;
	prime[0]=prime[1]=1;
	for(i=2;i<=n;i++)
	{
		if(prime[i])
		continue;
		lpf[i]=i;
		for(j=2*i;j<=n;j+=i)
		{
			prime[j]=1;
			if(lpf[j]==0)
			lpf[j]=i;
		}
	}
	for(i=1;i<=n;i++)
	sum[lpf[i]]++;
	for(i=1;i<=n;i++)
	sum[i]+=sum[i-1];
	for(i=1;i<=n;i++)
	cnt[i]=c2(n/i);
	for(i=n;i>=1;i--)
	{
		for(j=2*i;j<=n;j+=i)
		cnt[i]-=cnt[j];
	}
	for(i=2;i<=n;i++)
	dist1+=cnt[i];
	//cout<<dist1<<endl;

	for(i=2;i<=n;i++)
	{
		x=sum[i]-sum[i-1];
		y=get(2LL,min(i-1,n/i));
		dist2+=x*y;
		if(i*i<=n)
		dist2+=c2(x);
	}
	dist2-=dist1;
	//cout<<dist2<<endl;

	for(i=2;i<=n;i++)
	{
		if(2*i>n)
		break;
		x=sum[i]-sum[i-1];
		y=get(max(2LL,n/i+1),i-1);
		dist3+=x*y;
		if(i*i>n)
		dist3+=c2(x);
	}
	//cout<<dist3<<endl;
	cout<<dist1+2*dist2+3*dist3<<endl;
	return 0;
}

//��CF 871D
#include<iostream>
#include<cstdio>
#include<fstream>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<cmath>
#include<cstring>
#include<cstdlib>
using namespace std;
typedef long long LL;
const int N = 1e7+17;
int f[N],s[N],p[N];
LL g[N],s0,s1,s2,s3,ans;
int main()
{
	int n,i,j,t;
	cin>>n;
	t=n-1;
	for(i=2;i<=n;i=i+1){
		if(!f[i]){
			f[i]=i;
			for(j=i+i;j<=n;j=j+i)
				if(!f[j])
					f[j]=i;
			if(i+i>n)
				t--;
			else
				p[f[i]]++;
		}
		else
			p[f[i]]++;
	}
	s0=(LL)n*(n-1)/2-(LL)t*(t-1)/2;
	for(i=n;i>=1;i=i-1){
		g[i]=(LL)(n/i)*(n/i-1)/2;
		for(j=i+i;j<=n;j=j+i)
			g[i]-=g[j];
	}
	s1=(LL)n*(n-1)/2-g[1];
	for(i=1;i<=n;i=i+1)
		s[i]=s[i-1]+p[i];
	s3=(LL)t*(t-1);
	for(i=1;i<=n;i=i+1)
		s3-=(LL)p[i]*s[n/i];
	for(i=2;i<=n;i=i+1)
		if(f[i]!=i||i+i<=n)
			if((LL)f[i]*f[i]<=n)
				s3++;
	s3=s3/2;
	s2=g[1]-s3-s0;
	ans=s1+s2*2+s3*3;
	cout<<ans;
	return 0;
}

#include <iostream>
#include <vector>

using namespace std;

typedef long long ll;

const int MAX_N = 1e7 + 5;

ll pairc (ll n) {
  return (n * (n - 1)) / 2;
}

int factor [MAX_N];
int sieve [MAX_N];
int cspf [MAX_N];
int ccspf [MAX_N];
int mobius [MAX_N];

int main () {
  ll n;
  cin >> n;

  vector<ll> primes;
  for (ll i = 2; i <= n; i++) {
    if (!sieve[i]) {
      primes.push_back(i);
      for (ll j = i; j <= n; j += i) {
        factor[j] = i;
        if (!sieve[j]) {
          sieve[j] = 1;
          cspf[i]++;
        }
      }
    }
  }

  for (ll i = 2; i <= n; i++) {
    if (factor[i] == i) {
      mobius[i] = 1;
    } else if (factor[i / factor[i]] == factor[i]) {
      mobius[i] = 0;
    } else {
      mobius[i] = -mobius[i / factor[i]];
    }
  }

  ll isol = 0;
  for (ll i = 2; i <= n; i++) {
    if (factor[i] != i || 2 * i <= n) {
      isol++;
    } else {
      cspf[i]--;
    }
  }

  ccspf[n] = cspf[n];
  for (int i = n - 1; i >= 0; i--) {
    ccspf[i] = cspf[i] + ccspf[i + 1];
  }

  ll ans = isol * (isol - 1);

  ll bigp = 0;
  for (int p : primes) {
    if (2 * p <= n) {
      // count number of pairs (u, v) with spf(u) = p, spf(v) > p
      // and spf(u) spf(v) > n
      int s = n / p + 1; // the smallest number s.t. ps > n
      if (s <= p) s = p + 1;

      bigp += (ll) cspf[p] * (ll) ccspf[s];
    }
  }
  ans += bigp;

  ll smallp = 0;
  for (ll i = 2; i <= n; i++) {
    smallp += (ll) mobius[i] * pairc(n / i);
  }
  ans -= smallp;

  cout << ans << endl;
}

#include<bits/stdc++.h>
#define N 11111111
#define M 1000000007
#define LL long long
#define CL(a) memset(a,0,sizeof a)
#define fr(i,n) for(int i=1;i<=n;i++)
#define rd(x) scanf("%d",&x)
#define MP make_pair
#define PB push_back
#define fi first
#define se second
#define pii pair<int,int>
#define VI vector<int>
using namespace std;
int n,i,j,t,cnt,p[N],phi[N],pri[N],u[N],S[N];
LL an,V;bool f[N],gg;
int main(){
	rd(n);cnt=n-1;
	for(i=1;i<=n;i++)phi[i]=i;
	for(i=2;i<=n;i++){
		gg=0;
		if(!f[i]){
			p[++t]=i;
			phi[i]=i-1;
			pri[i]=i;
			u[i]=-1;
			if(i*2>n)cnt--,gg=1;
		}
		for(j=1;j<=t&&i*p[j]<=n;j++){
			f[i*p[j]]=1;pri[i*p[j]]=p[j];
			if(i%p[j]==0){
				phi[i*p[j]]=phi[i]*p[j];
				u[i*p[j]]=0;
				break;
			}
			u[i*p[j]]=-u[i];
			phi[i*p[j]]=phi[i]*(p[j]-1);
		}
		if(!gg)an+=i-phi[i]-1,S[pri[i]]++;
	}
	an+=(1ll*(cnt)*(cnt-1)/2-an)*3;
	for(i=1;i<=n;i++)S[i]+=S[i-1];
	for(i=1,j=n;i<=n;V+=1ll*S[j]*(S[i]-S[i-1]),i++)for(;j&&i*j>n;j--);
	for(i=2;i<=n;i++)V+=(1ll*(n/i)*(n/i)-(!f[i]&&1ll*i*i>n))*u[i];
	printf("%lld",an-V/2);
}

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <set>
#include <queue>
#define maxn 10000005
#define ll long long
#define int long long
using namespace std;
int mst[maxn], phi[maxn];
bool bpr[maxn];
int cnt[maxn];
int prs[maxn], prcnt = 0;
ll c(ll a){return a * (a - 1) / 2;}
int gcd(int a, int b)
{
	if(!b) return a;
	return gcd(b, a % b);
}
#undef int
int main()
{
	#define int long long
	int n;
	scanf("%I64d", &n);
	for(int i = 1; i <= n; i++)
		bpr[i] = 1, mst[i] = i, phi[i] = i;
	//prs[prcnt++] = 1;
	for(int i = 2; i <= n; i++)
	{
		if(!bpr[i]) continue;
		prs[prcnt++] = i;
		for(int j = 2; j * i <= n; j++)
			bpr[i * j] = 0;
		for(int j = 1; j * i <= n; j++)
		{
			if(i < mst[j * i]) mst[j * i] = i;
			phi[j * i] /= i, phi[j * i] *= (i - 1);
		}
	}
	for(int i = 1; i <= n; i++)
		cnt[mst[i]]++;
	ll tot1 = 0, tot2 = 0, tot3 = 0;
	for(int i = 2; i <= n; i++)
		tot1 += (ll)(i - 1 - phi[i]);
	for(int i = 0; i < prcnt; i++)
		for(int j = i; (ll)prs[j] * (ll)prs[i] <= n && j < prcnt; j++)
		{
			if(i != j) tot2 += (ll)cnt[prs[i]] * (ll)cnt[prs[j]];
			else tot2 += c(cnt[prs[i]]);
		}
/*	ll nans = 0;
	for(int i = 2; i <= n; i++)
		for(int j = i + 1; j <= n; j++)
		{
			if(gcd(i, j) != 1) nans++;
			else if(mst[i] * mst[j] <= n) nans += 2;
			else
			{
				if(bpr[i] && i * 2 > n) continue;
				if(bpr[j] && j * 2 > n) continue;
				nans += 3;
			}
		}
*/	int ns = 0;
	for(int i = 0; i < prcnt; i++)
		if(prs[i] * 2 > n) ns++;
	ns++;
	tot3 = c(n - ns);
	ll ans = tot1 + 2 * (tot2 - tot1) + 3 * (tot3 - tot2);
//	cout<<tot1<<" "<<tot2<<" "<<tot3<<endl;
//	cout<<nans<<endl;
	printf("%I64d\n", ans);
	return 0;
}

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define LL long long
using namespace std;
const LL Maxn = 1e7+10;
const LL Maxp = 1e6+10;
LL minp[Maxn], pr[Maxp], prl, phi[Maxn];
LL n;
LL np[Maxn], sp[Maxn];
void pre() {
	LL i, j, k;
	for(i = 2; i <= n; i++){
		if(!minp[i]){
			pr[++prl] = i;
			minp[i] = i;
			phi[i] = i-1;
		}
		for(j = 1; j <= prl && i*pr[j] <= n; j++){
			minp[i*pr[j]] = pr[j];
			if(i%pr[j] == 0){ phi[i*pr[j]] = phi[i]*pr[j]; break; }
			phi[i*pr[j]] = phi[i]*(pr[j]-1);
		}
		np[minp[i]]++;
	}
	for(i = 1; i <= prl; i++){
		sp[pr[i]] = sp[pr[i-1]]+np[pr[i]];
	}
}
int main() {
	LL i, j, k;
	scanf("%I64d", &n);
	pre();
	if(n == 1){ printf("0\n"); return 0; }
	LL nl = n-1;
	for(i = n/2+1; i <= n; i++) if(minp[i] == i) nl--;
	LL ans = 3*nl*(nl-1)/2;
	j = prl;
	LL sum = 0;
	for(i = 1; i <= prl; i++){
		while(pr[i]*pr[j] > n) j--;
		if(j == 0) break;
		sum += np[pr[i]]*sp[pr[j]];
		if(pr[i]*pr[i] <= n) sum -= np[pr[i]];
	}
	ans -= sum/2;
	for(i = 2; i <= n; i++) ans -= i-1-phi[i];
	printf("%I64d\n", ans);
	return 0;
}

#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define F0R(i, a) for (int i=0; i<(a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)

#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

const int MOD = 1000000007;

template<int SZ> struct Sieve {
    int num[SZ+1], sq[SZ+1], lst[SZ+1];
    Sieve() {
        F0R(i,SZ+1) num[i] = lst[i] = sq[i] = 0;
        for (int i = 2; i <= SZ; ++i) if (!num[i])
            for (int j = i; j <= SZ; j += i) {
                num[j] ++;
                int j1 = j/i;
                if (!lst[j]) lst[j] = i;
                while (j1 % i == 0) j1 /= i, sq[j] = 1, num[j] ++;
            }
    }
};

Sieve<10000000> S;
ll co[4], cum[10000001];
ll n,z;

void gen0() {
	// distance 0: one is a prime > n/2, or 1
	FOR(i,1,n+1) if (i == 1 || (2*i > n && S.num[i] == 1)) z++;
	co[0] = n*(n-1)/2-(n-z)*(n-z-1)/2;
}

int mob(int x) {
    if (S.sq[x]) return 0;
    if (S.num[x] % 2 == 0) return 1;
    return -1;
}

void gen1() { // gcd > 1
    FOR(i,1,n+1) co[1] += mob(i)*(n/i)*(n/i);
    co[1] = n*n-co[1]-(n-1);
    co[1] /= 2;
}

ll get(int lo, int hi) {
    if (lo > hi) return 0;
    return cum[hi]-cum[lo-1];
}

void gen2() { // gcd = 1, lowest primes multiplied <= n
    FOR(i,2,n+1) {
        cum[S.lst[i]] ++;
    }
    FOR(i,1,n+1) cum[i] += cum[i-1];

    for (int i = 2; i*i <= n; ++i) if (S.num[i] == 1) {
        co[2] += get(i,i)*get(i+1,n/i);
        co[2] += get(i,i)*(get(i,i)-1)/2;
    }
    co[2] -= co[1];
}

int main() {
	ios_base::sync_with_stdio(0);cin.tie(0);
    cin >> n;

    gen0();
    gen1();
    gen2();

    co[3] = n*(n-1)/2-co[0]-co[1]-co[2];
    cout << co[1]+2*co[2]+3*co[3];
}

// read!
// ll vs. int!

#include<bits/stdc++.h>
#define FOR(i,s,e) for(int i=(s);i<=(e);i++)
#define FORD(i,s,e) for(int i=(s);i>=(e);i--)
#define ALL(k) (k).begin(),(k).end()
#define e1 first
#define e2 second
#define mp make_pair
#define pb push_back
#define eb emplace_back

using namespace std;
typedef long long LL;
typedef unsigned long long LLU;
typedef long double LD;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<int> VI;
const bool print=false;
const int MAXN=14111000;
int prme[MAXN];
int zl[MAXN];

void sito(int n){
	for(int i=2;i<=n;i++){
		if(prme[i]!=0) continue;
		prme[i]=i;
		for(int j=2*i;j<=n;j+=i)
			if(prme[j]==0)
				prme[j]=i;
	}
}
int sumanp[MAXN];
int sumapr[MAXN];

main(){
	int n;scanf("%d",&n);
	if(n<=3) {puts("0");return 0;}

	sito(n+2);
	LL pary=(((LL)n)*((LL)n-1LL))/2LL;

	LL zera=1;
	FOR(i,(n/2)+1,n){
		if(prme[i]==i) zera++;
	}
	if(print)printf("ZERA %lld\n",zera);
	LL parzer = (zera*((LL)n-1LL))-(zera*(zera-1LL))/2LL;

	LL parjed = 0;
	FOR(i,2,n){
		int i1=i,zl=0;
		int pop=1;
		while(i1>1){
			zl++;
			if(prme[i1]==pop) {pop=-1;break;}
			pop=prme[i1];
			i1/=prme[i1];
		}
		if(pop==-1) continue;
		int zn=(zl%2==1)?1:-1;
		LL wyrazy=n/i;
		LL parlok=(wyrazy*(wyrazy-1LL))/2LL;
		if(print)printf("%d %d:: %lld %lld\n",i,zn,wyrazy,parlok);
		parjed+=parlok*zn;
	}
	LL partrzy = 0;
	LL par3pr=0;
	FOR(i,2,n){
		if(prme[i]==i) {
			if(i>n/2) continue;
			sumapr[prme[i]]++;
		}
		else sumanp[prme[i]]++;
	}
	FOR(i,2,n) sumanp[i]+=sumanp[i-1],sumapr[i]+=sumapr[i-1];

	FOR(i,2,n){
		if(prme[i]==i&&i<=n/2){ //if pierwsza
			if(print)printf("PRME %d\n",i);
			partrzy += sumanp[n]-sumanp[n/i];
			par3pr+=sumapr[n]-sumapr[max(i,n/i)];
			if(print)printf("%lld:: %lld %lld, %lld %lld\n",(LL)n/i,(LL)sumanp[n],(LL)sumanp[n/i],(LL)sumapr[n],(LL)sumapr[max(i,n/i)]);

		}
	}
	partrzy+=par3pr;
	LL pardwa = pary-parzer-parjed-partrzy;
	if(print)printf("0 %lld\n1 %lld\n2 %lld\n3 %lld\n",parzer,parjed,pardwa,partrzy);

	printf("%lld\n",parjed+2LL*pardwa+3LL*partrzy);
}

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

#define ll long long
#define db long double
#define ii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define sz(a) (int)(a).size()
#define all(a) (a).begin(),(a).end()
#define pb push_back
#define mp make_pair
#define FN(i, n) for (int i = 0; i < (int)(n); ++i)
#define FEN(i,n) for (int i = 1;i <= (int)(n); ++i)
#define rep(i,a,b) for(i=a;i<b;i++)
#define repv(i,a,b) for(i=b-1;i>=a;i--)
#define SET(A, val) memset(A, val, sizeof(A))
typedef tree<int ,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>ordered_set ;
// order_of_key (val): returns the no. of values less than val
// find_by_order (k): returns the kth largest element.(0-based)
#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
  const char* comma = strchr(names + 1, ','); cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif
const int N=10000005;
int smpf[N];
void SMPF()
{
  int i,j;
  rep(i,2,N)
    smpf[i]=i;
  for(i=2;i<N;i+=2) smpf[i]=2;
  for(i=3;i*i<N;i+=2)
    {
      if(smpf[i]!=i) continue;
      for(j=i*i;j<N;j+=2*i)
	{
	  if(smpf[j]==j)
	    smpf[j]=i;
	}
    }
}
int mobius[N];
void pre_mu()
{
  mobius[1]=1;
  int i;
  rep(i,2,N)
    if(smpf[i]!=smpf[i/smpf[i]])
      mobius[i]=-mobius[i/smpf[i]];
}
ll calc(ll x)
{
  return (x*(x-1))/2;
}
int cnt[N];
int main()
{
  std::ios::sync_with_stdio(false);
  cin.tie(NULL) ; cout.tie(NULL) ;
  SMPF();
  pre_mu();
  int n,i,j;
  cin>>n;
  ll d1=0,d2=0,d3=0;
  int sq=sqrt(n);
  //distance 1 (gcd!=1)
  rep(i,1,n+1)
    d1+=(ll)mobius[i]*calc(n/i);
  rep(i,1,n+1)
    {
      mobius[i]+=mobius[i-1];
      cnt[smpf[i]]++;
    }
  rep(i,2,n+1) cnt[i]+=cnt[i-1];
  /*rep(i,1,sq+1)
    {
      int l=n/(i+1)+1,r=n/i;
      if(i*i==n) continue;
      d1+=(ll)(mobius[r]-mobius[l-1])*calc(i);
    }*/
  d1=calc(n)-d1;

  //distance 2 (gcd=1 and smpf[i]*smpf[j]<=n)
  rep(i,2,n+1)
    {
      int ind=min(i-1,n/i);
      d2+=(ll)cnt[ind]*(cnt[i]-cnt[i-1]);
      if((ll)i*i<=n)
	d2+=calc(cnt[i]-cnt[i-1]);
    }
  d2-=d1; //remove those have gcd!=1

  //distance 3 (gcd=1 and n<smpf[i]*smpf[j] && 2*max(smpf[i],smpf[j])<=n)
  rep(i,2,n+1)
    {
      if(i*2>n) break;
      int l=n/i+1,r=i-1;
      if(l<=r)
	d3+=(ll)(cnt[r]-cnt[l-1])*(cnt[i]-cnt[i-1]);
      if((ll)i*i>n)
	d3+=calc(cnt[i]-cnt[i-1]);
    }
  cout<<d1+d2*2+d3*3<<endl;
  return 0 ;
}

#include<deque>
#include<queue>
#include<vector>
#include<algorithm>
#include<iostream>
#include<set>
#include<cmath>
#include<tuple>
#include<string>
#include<chrono>
#include<functional>
#include<iterator>
#include<random>
#include<unordered_set>
#include<unordered_map>
#include<array>
#include<map>
#include<iomanip>
using namespace std;
typedef long long int llint;
typedef long double lldo;
#define mp make_pair
#define mt make_tuple
#define pub push_back
#define puf push_front
#define pob pop_back
#define pof pop_front
#define fir first
#define sec second
#define res resize
#define ins insert
#define era erase
#define dme cout<<-1<<endl;return 0
//ios::sync_with_stdio(false);
//<< setprecision(5)
const int mod=1000000007;
const llint big=1e18+100;
const long double pai=3.141592653589793238462643383279502884197;
const long double ena=2.71828182845904523536;
const long double eps=1e-7;
template <class T,class U>void mineq(T& a,U b){if(a>b){a=b;}}
template <class T,class U>void maxeq(T& a,U b){if(a<b){a=b;}}
llint gcd(llint a,llint b){if(a%b==0){return b;}else return gcd(b,a%b);}
llint lcm(llint a,llint b){return a/gcd(a,b)*b;}
//隣に線を張る
//22分
vector<int>yaku;
vector<int>hou;
void init(int n){
	int i,j;
	yaku.res(n+1);
	hou.res(n+1);
	for(i=2;i<=n/2;i++){
		if(yaku[i]!=0){continue;}
		for(j=i;j<=n;j+=i){if(yaku[j]==0){yaku[j]=i;}}
	}
	int iti[256];//一時的に使う
	int count[256];//bitcount
	int hai[256];//置き場
	vector<int>wari;
	count[0]=-1;
	for(int bit=1;bit<256;bit++){count[bit]=-count[bit&(bit-1)];}
	for(i=2;i<=n;i++){
		int gen=i;
		if(yaku[i]==0){continue;}//おおきいそすー
		while(gen!=1){
			if(wari.size()==0||yaku[gen]!=wari.back()){wari.pub(yaku[gen]);}
			gen/=yaku[gen];
		}
		for(int h=0;h<wari.size();h++){hai[1<<h]=wari[h];}
		iti[0]=n;
		//wari　約数の集合
		int ret=0;
		for(int bit=1;bit<(1<<wari.size());bit++){
			iti[bit]=iti[bit&(bit-1)]/hai[bit-(bit&(bit-1))];
			ret+=iti[bit]*count[bit];
		}
		hou[i]=ret;
		wari.clear();
	}
}
int main(void){
	int n,K,i,j;
	cin>>n;
	init(n);
	llint muri=0;
	vector<int>imos(n+1);
	for(i=2;i<=n;i++){
		if(yaku[i]==0){muri++;continue;}
		imos[yaku[i]]++;
	}
	for(i=2;i<n;i++){imos[i+1]+=imos[i];}
	llint ans=0;
	for(i=2;i<=n;i++){
		if(yaku[i]==0){continue;}
		llint one,two,thr=0;
		one=hou[i];
		two=imos[n/yaku[i]];
		if(n/yaku[i]<yaku[i]){two+=imos[yaku[i]]-imos[yaku[i]-1];}
		thr=n-muri;
		ans+=one;
		ans+=2*(two-one);
		ans+=3*(thr-two);
		//cerr<<"i="<<i<<" "<<one<<" "<<two<<" "<<thr<<endl;
		ans-=4;
	}
	cout<<ans/2<<endl;
	return 0;
}

/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author
 */

#ifndef MAJK_LIB
#define MAJK_LIB

#include <vector>
#include <stack>
#include <iostream>
#include <unordered_map>
#include <map>
#include <iomanip>
#include <set>
#include <functional>
#include <fstream>
#include <algorithm>
#include <cassert>
#include <cmath>
#include <string>
#include <sstream>
#include <queue>
#include <bitset>
using namespace std;

#define x first
#define y second
typedef std::pair<int,int> pii; typedef long long ll; typedef unsigned long long ull; typedef unsigned int ui;

template <typename T, typename U> std::istream&operator>>(std::istream&i, pair<T,U>&p) {i >> p.x >> p.y; return i;}
template<typename T>std::istream&operator>>(std::istream&i,vector<T>&t) {for(auto&v:t){i>>v;}return i;}
template<typename T>std::ostream&operator<<(std::ostream&o,const vector<T>&t) {for(size_t i=0;i<t.size();++i){o<<t[i]<<" \n"[i == t.size()-1];}return o;}
template<typename T> using minheap = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using maxheap = priority_queue<T, vector<T>, less<T>>;
auto fraclt = [](const pii&a,const pii&b) { return (ll)a.x * b.y < (ll)b.x * a.y; };
struct cmpfrac { bool operator()(const pii&a,const pii&b)const { return (ll)a.x * b.y < (ll)b.x * a.y; }};
template <typename T> bool in(T a, T b, T c) { return a <= b && b < c; }
ui logceil(ll x) {ui b=0;while(x){x>>=1;++b;}return b;}

namespace std {
    template<typename T,typename U>struct hash<pair<T,U>>{hash<T>t;hash<U>u;size_t operator()(const pair<T,U>&p)const{return t(p.x)^(u(p.y)<<7);}};
}
template<typename T,typename F>T bsh(T l,T h,const F&f){T r=-1,m;while(l<=h){m=(l+h)/2;if(f(m)){l=m+1;r=m;}else{h=m-1;}}return r;}
template<typename F> double bsh(double l,double h,const F&f,double p=1e-9){ui r=3+(ui)log2((h-l)/p);while(r--){double m=(l+h)/2;if(f(m)){l=m;}else{h=m;}}return (l+h)/2;}
template<typename T,typename F>T bsl(T l,T h,const F&f){T r=-1,m;while(l<=h){m=(l+h)/2;if(f(m)){h=m-1;r=m;}else{l=m+1;}}return r;}
template<typename F> double bsl(double l,double h,const F&f,double p=1e-9){ui r=3+(ui)log2((h-l)/p);while(r--){double m=(l+h)/2;if(f(m)){h=m;}else{l=m;}}return (l+h)/2;}
template<typename T> T gcd(T a,T b) { if (a<b) swap(a,b); return b?gcd(b,a%b):a; }

template<typename T>class vector2:public vector<vector<T>>{public:vector2(){} vector2(size_t a,size_t b,T t=T()):vector<vector<T>>(a,vector<T>(b,t)){}};
template<typename T>class vector3:public vector<vector<vector<T>>>{public:vector3(){} vector3(size_t a,size_t b,size_t c,T t=T()):vector<vector<vector<T>>>(a,vector<vector<T>>(b,vector<T>(c,t))){}};
template <typename T> struct bounded_priority_queue {
	inline bounded_priority_queue(ui X) : A(X), B(0) {}
	inline void push(ui L, T V) { B = max(B, L); A[L].push(V); }
	inline const T &top() const { return A[B].front(); }
	inline void pop() { A[B].pop(); while (B > 0 && A[B].empty()) --B; }
	inline bool empty() const { return A[B].empty(); }
	inline void clear() { B = 0; for (auto &a: A) a = queue<T>(); }
private:
	vector<queue<T>> A; ui B;
};

#endif
#ifndef PRIMES_H
#define PRIMES_H

struct UnionFind {
	UnionFind(size_t N) : P(N, -1), comp(N) {}
	int find(int x) { while (P[x]>=0){x = P[x];}return x; }
	bool united(int x, int y) { return find(x) == find(y); }
	bool unite(int x, int y) { x=find(x);y=find(y);if(x==y){return false;}--comp;if(P[x]>P[y]){swap(x,y);}P[x]+=P[y];P[y]=x;return true;}
	vector<int> P;
	size_t comp;
};

/** Product of two 64-bit numbers modulo another. */
ull mulull(ull a, ull z, ull mod) {
#ifdef __SIZEOF_INT128__
	__int128 result = ((__int128) a * (__int128) z) % (__int128) mod;
	return (ull) result;
#else
    // schrage method
	ull q = mod / a, r = mod % a;
	ull rzq = (r < q) ? r * (z/q) : mulull(r, z/q, mod);
	ull azq = a * (z % q);
	if (azq >= rzq) return azq-rzq; else return azq-rzq+mod;
#endif
}

/** Multiply two 64-bit unsigned integers to get a 128-bit unsigned integer (as a pair of ull) */
pair<ull,ull> mulull(ull a, ull b) {
#ifdef __SIZEOF_INT128__
	__int128 result = (__int128) a * (__int128) b;
	return {(ull) (result >> 64), (ull) result};
#else
	ull c = (ui)a, d = a>>32, e = (ui)b, f = b>>32, g = d*f, h = d*e, i = f*c, j = c*e, k = (j>>32)+(ui)h+(ui)i, l = g+(h>>32)+(i>>32)+(k>>32);
	return {l, ((h+i) << 32) + j};
#endif
}

bool fractionGreaterOrEqual(ll a, ll b, ll c, ll d) {
	if (b < 0) { b = -b; a = -a; }
	if (d < 0) { d = -d; c = -c; }
	return a < 0 && c < 0 ? mulull(-a, d) <= mulull(-c, b) : (a >= 0) && (c < 0 || mulull(a, d) >= mulull(c, b));
}

bool fractionGreaterOrEqual(double a, double b, double c, double d) {
	return a/b >= c/d;
}

// this is based on modulus, but it's 2-3 times slower than the former
//bool fractionGreaterOrEqual(ll a, ll b, ll c, ll d) {
//	if (a<0 && c<0) return greaterOrEqual(-c,d,-a,b);
//	if (a<0) return false;
//	if (c<0) return true;
//	if (b==0) return true;
//	if (d==0) return false;
//	ll ab = a/b, cd = c/d;
//	if (ab > cd) return true;
//	if (ab < cd) return false;
//	return !greaterOrEqual(b, a%b, d, c%d);
//}

/** Computing lower and upper envelope. Useful for "convex hull trick". */
namespace Envelope {
	template<typename T>
	struct Line {
		T m, b;
		mutable function<const Line<T> *()> succ;

		bool operator<(const Line &rhs) const {
			if (rhs.b != numeric_limits<T>::min()) return m < rhs.m;
			const Line *s = succ();
			if (!s) return 0;
			return b - s->b < (s->m - m) * rhs.m;
		}
	};

	template<typename T>
	struct Upper : public multiset<Envelope::Line<T>> {
		using parent = multiset<Line<T>>;

		bool bad(typename parent::iterator y) {
			auto z = next(y);
			if (y == parent::begin()) {
				return z != parent::end() && y->m == z->m && y->b <= z->b;
			} else {
				auto x = prev(y);
				if (z == parent::end()) {
					return y->m == x->m && y->b <= x->b;
				} else {
					return fractionGreaterOrEqual(x->b - y->b, y->m - x->m, y->b - z->b, z->m - y->m);
				}
			}
		}

		void insert_line(T m, T b) {
			auto y = parent::insert({m, b});
			y->succ = [=] { return next(y) == parent::end() ? 0 : &*next(y); };
			if (bad(y)) { parent::erase(y); return; }
			while (next(y) != parent::end() && bad(next(y))) parent::erase(next(y));
			while (y != parent::begin() && bad(prev(y))) parent::erase(prev(y));
		}

		T operator[](T x) const {
			auto l = parent::lower_bound({x, numeric_limits<T>::min()});
			return l == parent::end() ? numeric_limits<T>::min() : l->m * x + l->b;
		}
	};

	template<typename T>
	struct Lower : public Upper<T> {
		void insert_line(T m, T b) { Upper<T>::insert_line(-m, -b); }
		T operator[](T x) const { return -Upper<T>::operator[](x); }
	};
}

struct Sieve : public std::vector<bool> {
    // ~10ns * n
	explicit Sieve(ui n) : vector<bool>(n+1, true), n(n) {
		at(0) = false;
		at(1) = false;
		for (ui i = 2; i*i <= n; ++i) {
			if (at(i)) for (int j = i*i; j <= n; j+=i) (*this)[j] = false;
		}
	}

	vector<int> primes() const {
		vector<int> ans;
		for (int i=2; i<=n; ++i) if (at(i)) ans.push_back(i);
		return ans;
	}

private:
	int n;
};

struct Moebius : public std::vector<std::pair<int, int>> {
	explicit Moebius(ui n) : Moebius(n, Sieve{n}.primes()) {}

	Moebius(ui n, const vector<int>& primes) {
		search(-1, 1, 1, n, primes);
		std::sort(begin(), end());
	}
private:
	void search(int i, int x, int y, int n, const vector<int>&primes) {
		push_back({x,y});
		while (++i < primes.size() && (ll)x * primes[i] <= n) search(i, x*primes[i], -y, n, primes);
	}
};

// 32-bit primes for hashing
struct LargePrimes : public vector<int> {
	LargePrimes():vector<int>{7,9,21,33,87,93,97,103,123,181,207,223,241,271,289,297,321,349,363,403,409,411,427,433,439,447,453,459,483,513,531,579,607,613,637,663,711,753,787,801,829,861,871,891,901,919,931,933,993,1011,1021,1053,1087,1099,1137,1161,1203,1213,1237,1263,1269,1273, 1279,1311,1329,1333,1351,1371,1393,1413,1447,1449,1491,1501,1531,1537,1539,1581,1617, 1621,1633,1647,1663,1677,1699,1759,1773,1789,1791,1801,1803,1819,1857,1887,1917,1927, 1957,1963,1969,2043,2089,2103,2139,2149,2161,2173,2187,2193,2233,2239,2277,2307,2359, 2361,2431,2449,2457,2499,2571,2581,2607,2631,2637,2649,2667,2727,2791,2803,2821,2823, 2827,2907,2937,2989,3009,3013,3051,3057,3097,3111,3133,3153,3157,3163,3211,3241,3247,3253,3267,3271,3273,3283,3309,3337,3351,3357,3373,3379,3397,3469,3471,3513,3519,3559,3577,3579,3601,3621,3643,3651,3663,3679,3709,3747,3751,3769,3777,3787,3793,3843,3853,3871,3889,3891,3909,3919,3931,3951,3957,3967,3987,3999,4023,4059,4099,4119,4123,4207,4233,4249,4251,4263,4321,4329,4381,4389,4437,4449,4459,4497,4507,4519,4539,4567,4569,4581,4609,4611,4627,4633,4647,4693,4699,4717,4771,4777,4783,4791,4807,4839,4843,4849,4857,4867,4869,4891,4893,4897,4927,4933,4977,4981,5001,5029,5053,5067,5103,5133,5187,5197,5203,5233,5277,5287,5299,5317,5329,5341,5353,5361,5403,5407,5437,5443,5449,5451,5469,5491,5527,5541,5547,5583,5631,5647,5683,5731,5737,5751,5763,5791,5823,5827,5833,5847,5863,5899,5907,5947,5953,5959,5971,5973,5991,5997,6019,6027,6037,6039,6061,6093,6099,6127,6129,6177,6193,6211,6223,6229,6307,6313,6331,6349,6379,6393,6417,6421,6457,6459,6477,6541,6571,6577,6583,6607,6621,6661,6663,6697,6717,6751,6781,6837,6867,6901,6957,6961,6967,6981,7003,7023,7027,7089,7117,7137,7147,7159,7191,7209,7237,7243,7257,7279,7321,7347,7383,7389,7417,7429,7447,7453,7467,7479,7497,7513,7521,7531,7537,7557,7633,7647,7651,7653,7681,7707,7719,7741,7759,7773,7803,7819,7837,7873,7887,7909,7923,7927,7929,7941,8041,8083,8089,8101,8109,8127,8173,8181,8223,8257,8259,8271,8277,8311,8313,8343,8349,8397,8403,8419,8431,8439,8487,8511,8557,8593,8617,8637,8649,8661,8671,8679,8719,8727,8761,8773,8791,8797,8803,8811,8829,8853,8899,8917,8937,8967,9009,9013,9063,9081,9093,9099,9123,9133,9163,9183,9211,9223,9259,9277,9279,9289,9301,9321,9331,9363,9399,9403,9421,9441,9457,9469,9487,9519,9529,9531,9541,9559,9561,9567,9573,9579,9597,9601,9609,9631,9651,9667,9679,9711,9733,9739,9757,9789,9831,9859,9867,9961,9999,10029,10051,10069,10101,10153,10173,10189,10197,10233,10243,10251,10267,10281,10303,10321,10327,10351,10357,10381,10449,10467,10483,10503,10513,10549,10593,10597,10611,10633,10659,10699,10707,10723,10747,10749,10761,10773,10777,10801,10833,10903,10953,10969,10971,10981,10987,11007,11011,11071,11083,11091,11107,11109,11137,11149,11161,11223,11239,11253,11269,11277,11283,11289,11301,11317,11329,11371,11377,11391,11421,11479,11487,11497,11517,11533,11539,11559,11583,11601,11619,11631,11659,11673,11679,11707,11763,11767,11769,11773,11799,11811,11821,11823,11847,11869,11967,11983,11989,12019,12037,12121,12157,12177,12187,12217,12219,12231,12241,12253,12297,12309,12333,12337,12339,12361,12367,12399,12411,12459,12463,12483,12501,12513,12523,12547,12553,12577,12609,12631,12649,12679,12681,12703,12723,12733,12747,12753,12759,12799,12847,12877,12891,12901,12903,12927,12939,12963,13011,13017,13029,13039,13081,13087,13089,13101,13107,13137,13141,13143,13153,13191,13207,13213,13237,13323,13369,13419,13437,13447,13477,13519,13537,13561,13563,13587,13591,13723,13741,13759,13789,13801,13857,13881,13897,13921,13923,13939,13999,14011,14073,14077,14083,14097,14121,14131,14143,14157,14161,14167,14181,14193,14209,14241,14259,14271,14293,14361,14391,14397,14437,14529,14551,14581,14583,14599,14607,14611,14643,14727,14761,14773,14779,14791,14823,14853,14881,14889,14901,14931,14937,14997,15031,15043,15057,15063,15069,15097,15103,15109,15117,15141,15147,15187,15199,15217,15231,15253,15271,15279,15283,15307,15339,15349,15351,15363,15369,15409,15427,15447,15477,15487,15553,15579,15591,15649,15651,15673,15693,15703,15717,15727,15747,15799,15811,15823,15859,15889,15963,15981,16009,16021,16029,16047,16063,16089,16093,16107,16153,16167,16191,16201,16231,16233,16261,16267,16273,16317,16323,16411,16419,16431,16489,16491,16513,16539,16617,16621,16623,16627,16651,16659,16671,16711} { for (int&i:*this)i+=1000000000; }
};

// 200ns-4us per call, depending on size
bool isPrime(ll n) {
    for (int p:{2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257})
        if (p<n&&n%p==0) return false;
	ll d = n-1, r = 0;
	while (d%2==0) { d/=2; r += 1; }
	auto composite = [=](int a) {
		ll x = 1, p = a, e = d;
		while(e>0) { if(e%2>0){x=mulull(x,p,n);} e/=2; p=mulull(p,p,n); }
		if (x == 1 || x == n-1) return false;
        for (int i=1;i<r;++i) {
            x=mulull(x,x,n);
            if (x==1) return true;
			if (x==n-1) return false;
		}
        return true;
	};

	return !(composite(2))
		   && (n<2047 || !composite(3))
		   && (n<1373653 || !composite(5))
		   && (n<25326001 || !composite(7))
		   && (n<3215031751LL || !composite(11))
		   && (n<2152302898747LL || !composite(13))
		   && (n<3474749660383LL || !composite(17))
		   && (n<341550071728321LL || (!composite(19) && !composite(23)))
		   && (n<3825123056546413051LL || (!composite(29) && !composite(31) && !composite(37)));
}

#endif //PRIMES_H

// #include "../l/mod.h"

class TaskD {
public:
    void solve(istream& cin, ostream& cout) {
        ui N; cin >> N;
        Sieve S{N};
        auto P = S.primes();
        Moebius M{N, P};
        ll pairs1 = 0;
        for (auto &m: M) {
            if (m.x == 1) continue;
            pairs1 -= m.y * (ll)(N/m.x) * (ll)(N/m.x-1)/2;
        }

        vector<int> Z(N+1, 0);
        for (int i = 2; i*i <= N; ++i) {
            if (!Z[i]) {
                Z[i] = i;
                for (int j = i*i; j <= N ; j+=i) {
                    if (!Z[j]) Z[j] = i;
                }
            }
        }
        for (int i = 2; i <= N; ++i) if (!Z[i]) Z[i] = i;
        vector<int> C(N+1, 0);
        for (int i = 0; i <= N; ++i) {
            C[Z[i]]++;
        }

        vector<int> D = C;
        for (int i = N-1; i >= 0; --i) {
            D[i] += D[i+1];
        }

        ll pairs3 = 0;
        int badPrimes = D[N/2+1];
        for (ui i = 3; i < N; ++i) {
            if (C[i]) {
                int q = max(i, N/i) + 1;
                if (q > 2) {
                    pairs3 += (ll) C[i] * max(0, D[q] - badPrimes);
                }
            }
        }

        int valid = N - 1 - badPrimes;
        ll pairs2 = (ll)valid*(valid-1)/2 - pairs1 - pairs3;

        cout << pairs1 + 2*pairs2 + 3*pairs3 << endl;
    }
};

int main() {
	ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
	TaskD solver;
	std::istream& in(std::cin);
	std::ostream& out(std::cout);
	solver.solve(in, out);
    return 0;
}

#include <bits/stdc++.h>
#include <ostream>
using namespace std;
template <typename T> void printRange(T &x) { for (auto y : x) cout << y << ' '; cout << endl; }
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<vi> vvi;
#define getNum(i) scanf("%d", &(i))
#define MOD 1000000007
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
#define TRACE(x) cout << #x << " = " << x << endl
#define IOS ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define mp make_pair
#define reset(a) memset((a), 0, sizeof((a)))
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge {c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
    ~debug() { cerr << endl; }
    eni(!=) cerr << boolalpha << i; ris; };
    eni(==) ris << range(begin(i), end(i)); }
    sim, class b dor(pair < b, c > d) {
        ris << "(" << d.first << ", " << d.second << ")";
    }
    sim dor(rge<c> d) {
        *this << "[";
        for (auto it = d.b; it != d.e; ++it)
            *this << ", " + 2 * (it == d.b) << *it;
        ris << "]";
    }};
#define inside(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
static const int INF = 0x3f3f3f3f;
static const long long INFL = 0x3f3f3f3f3f3f3f3fLL;
const int maxn = 1e7 + 10;
int mf[maxn], phi[maxn], cnt[maxn], fw[maxn];
int n;
ll bad = 1;

void insert(int idx) {
    for (; idx < maxn; idx += idx&-idx) fw[idx]++;
}

int query(int ub) {
    int ans = 0;
    for (; ub > 0; ub -= ub&-ub) ans += fw[ub];
    return ans;
}

void build() {
    REP(i, maxn) phi[i] = i;
    for (int i = 2; i <= n; i++) {
        for (int j = i; j <= n; j += i) {
            if (!mf[j]) mf[j] = i;
            if (mf[i]==i) {
                phi[j] /= i;
                phi[j] *= i-1;
            }
        }
        if (i<<1 > n && mf[i]==i) bad++;
    }
    for (int i = 2; i <= n; i++) {
        cnt[mf[i]]++;
    }
}

int main() {
#ifndef ONLINE_JUDGE
        freopen("input.in", "r", stdin);
#endif
    cin >> n;
    build();
    ll ans1 = 0;
    for (int i = 2; i <= n; i++) ans1 += (i-1) - phi[i];
    ll ans2 = 0;
    for (int i = 2; i <= n; i++) {
        int u = (n)/mf[i];
        ans2 += query(u);
        insert(mf[i]);
    }
    ans2 -= ans1;
    ll ans0 = bad*(bad-1)/2 + bad*(n-bad);
    ll ans3 = ll(n)*ll(n-1)/2 - ans0 - ans1 - ans2;
    cout << ans1 + 2*ans2 + 3*ans3 << endl;

    return 0;
}

#include <iostream>

using namespace std;

using ll = long long;
const int maxn = 1e7 + 5;

int n;
int prime[maxn];
char bad[maxn];
int phi[maxn];
int number_of_prime_divisors[maxn];
int pref_smallest_prime[maxn];
int number_of_bad = 0;

void calc_arrays() {
    for (int i = 1; i <= n; ++i) {
        phi[i] = i;
    }
    for (int i = 2; i <= n; ++i) {
        if (prime[i]) continue;
        for (int j = i; j <= n; j += i) {
            if (!prime[j]) prime[j] = i;
            phi[j] /= i;
            phi[j] *= i - 1;
        }
    }
    for (int i = 1; i <= n; ++i) {
        if (i == 1 || prime[i] == i && i * 2 > n) {
            bad[i] = true;
            ++number_of_bad;
        }
    }
    for (int i = 2; i <= n; ++i) {
        if (prime[i] == i) {
            number_of_prime_divisors[i] = 1;
        } else if (prime[i / prime[i]] == prime[i]) {
            number_of_prime_divisors[i] = number_of_prime_divisors[i / prime[i]];
        } else {
            number_of_prime_divisors[i] = number_of_prime_divisors[i / prime[i]] + 1;
        }
    }
}

ll get_dist_one() {
    ll ans = 0;
    for (int i = 2; i <= n; ++i) {
        if (!bad[i]) {
            ans += i - 1 - phi[i];
        }
    }
    return ans;
}

ll get_dist_two() {
    ll ans = 0;
    int pref_noncomposite = 1;
    for (int i = 2; i <= n; ++i) {
        if (prime[i] != i) {
            ans += phi[i];
            ans -= pref_noncomposite;
            ans += number_of_prime_divisors[i];
        } else {
            ++pref_noncomposite;
        }
    }

    for (int i = 1; i <= n; ++i) {
        if (!bad[i]) {
            ++pref_smallest_prime[prime[i]];
        }
    }
    for (int i = 1; i <= n; ++i) {
        pref_smallest_prime[i] += pref_smallest_prime[i - 1];
    }
    for (int i = 2; i <= n; ++i) {
        if (prime[i] != i || bad[i]) continue;
        ans += pref_smallest_prime[n / i];
        for (int j = i; j <= n; j += i) {
            if (prime[j] <= n / i) {
                --ans;
            }
        }
    }
    for (int i = 2; i <= n; ++i) {
        int a = prime[i];
        int b = i / a;
        if (b != 1 && prime[b] == b && a != b) {
            --ans;
        }
    }
    return ans;
}

ll solve(int _n) {
    n = _n;
    calc_arrays();
    ll cnt_one = get_dist_one();
    ll cnt_two = get_dist_two();
    ll cnt_three = (ll) (n - number_of_bad) * (n - number_of_bad - 1) / 2 - cnt_one - cnt_two;
    return cnt_one * 1 + cnt_two * 2 + cnt_three * 3;
}

int main() {
    int n;
    cin >> n;
    cout << solve(n) << endl;
}

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair < int, int > ii;

const int N = 1e7 + 5;

int n;
int lp[N], a[N], phi[N];
ll pre[N];
vector < int > pr;

void calc() {
    phi[1] = 1;
    for (int i = 2; i < N; ++i) {
        if (lp[i] == 0) {
            lp[i] = i;
            phi[i] = i - 1;
            pr.push_back(i);
        }
        else {
            if (lp[i] == lp[i / lp[i]])
                phi[i] = phi[i / lp[i]] * lp[i];
            else
                phi[i] = phi[i / lp[i]] * (lp[i] - 1);
        }
        for (int j = 0; j < (int) pr.size() && pr[j] <= lp[i] && i * pr[j] < N; ++j)
            lp[i * pr[j]] = pr[j];
    }
}

int main() {

	scanf("%d", &n);

	calc();

	ll ans = 0;

	for(int i = 2; i <= n; i++)
		ans -= i - 1 - phi[i];

	for(int i = 2; i <= n; i++)
		pre[lp[i]]++;

	for(int i = 2; i <= n; i++)
		pre[i] += pre[i - 1];

	for(int i = 2; i <= n; i++) {
		ans += pre[n / lp[i]];
		if((ll) lp[i] * lp[i] <= n)
			ans--;
		if(lp[i] == i and i * 2 <= n)
			ans += max(pre[i - 1] - pre[n / i], 0LL) * 3;
	}

	printf("%lld\n", ans);

    return 0;

}

#include <bits/stdc++.h>

typedef long long LL;
const int N = 10000005;
int n, md[N], pr[N / 10], pt, phi[N];

void sieve(int n) {
	phi[1] = 1;
	for (int i = 2; i <= n; ++i) {
		if (!md[i]) pr[++pt] = i, md[i] = i, phi[i] = i - 1;
		for (int j = 1, t; j <= pt && pr[j] <= md[i]; ++j) {
			if ((t = i * pr[j]) > n) break; md[t] = pr[j];
			if (pr[j] == md[i]) {phi[t] = phi[i] * pr[j]; break; }
			phi[t] = phi[i] * (pr[j] - 1);
		}
	}
}

LL c(LL n) {return n * (n - 1) / 2; }

int cnt[N]; LL pre[N];

int main() {
	std::ios::sync_with_stdio(0), std::cin.tie(0);
	std::cin >> n, sieve(n);
	LL c0 = 1, c1 = c(n) + 1, c2 = 0, c3 = 0;
	for (int i = 1; i <= pt; ++i) c0 += 2 * pr[i] > n;
	c0 = c(c0) + c0 * (n - c0);
	for (int i = 1; i <= n; ++i) c1 -= phi[i];
	for (int i = 2; i <= n; ++i) ++cnt[md[i]];
	for (int i = 2; i <= n; ++i) pre[i] = pre[i - 1] + cnt[i];
	for (int i = 1; i <= pt && pr[i] * pr[i] <= n; ++i)
		c2 += c(cnt[pr[i]]) + cnt[pr[i]] * (pre[n / pr[i]] - pre[pr[i]]);
	c2 -= c1, c3 = c(n) - c0 - c1 - c2;
	std::cout << c1 + c2 * 2 + c3 * 3 << '\n';
	return 0;
}

#ifndef __clang__
#pragma GCC optimize "-O3"
#pragma GCC target "tune=native"
#endif
#ifdef ONLINE_JUDGE
#define NDEBUG 1
#endif
#include <stdio.h>
#include <bits/stdc++.h>

#define FOR(i, n)     for(lli i = 0; i < (lli)(n); ++i)
#define FORU(i, j, k) for(lli i = (j); i <= (lli)(k); ++i)
#define FORD(i, j, k) for(lli i = (j); i >= (lli)(k); --i)

#define SQ(x) ((x)*(x))

#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define eb emplace_back

using namespace std;

template<typename... As>
struct tpl : public std::tuple<As...> {
  using std::tuple<As...>::tuple;
  tpl(){}
  tpl(std::tuple<As...> const& b) { std::tuple<As...>::operator=(b); }

  template<typename T = tuple<As...> >
  typename tuple_element<0, T>::type const&
  x() const { return get<0>(*this); }
  template<typename T = tuple<As...> >
  typename tuple_element<0, T>::type&
  x() { return get<0>(*this); }

  template<typename T = tuple<As...> >
  typename tuple_element<1, T>::type const&
  y() const { return get<1>(*this); }
  template<typename T = tuple<As...> >
  typename tuple_element<1, T>::type&
  y() { return get<1>(*this); }

  template<typename T = tuple<As...> >
  typename tuple_element<2, T>::type const&
  z() const { return get<2>(*this); }
  template<typename T = tuple<As...> >
  typename tuple_element<2, T>::type&
  z() { return get<2>(*this); }

  template<typename T = tuple<As...> >
  typename tuple_element<3, T>::type const&
  w() const { return get<3>(*this); }
  template<typename T = tuple<As...> >
  typename tuple_element<3, T>::type&
  w() { return get<3>(*this); }
};

using lli   = long long int;
using llu   = long long unsigned;

using pii   = tpl<lli, lli>;
using piii  = tpl<lli, lli, lli>;
using piiii = tpl<lli, lli, lli, lli>;
using vi    = vector<lli>;
using vii   = vector<pii>;
using viii  = vector<piii>;
using vvi   = vector<vi>;
using vvii  = vector<vii>;
using vviii = vector<viii>;

template<class T>
using min_queue = priority_queue<T, vector<T>, greater<T> >;
template<class T>
using max_queue = priority_queue<T>;

template<size_t... I>
struct my_index_sequence {
  using type = my_index_sequence;
  static constexpr array<size_t, sizeof...(I)> value = { {I...} };
};

namespace my_index_sequence_detail {
  template<typename I, typename J> struct concat;
  template<size_t... I, size_t... J>
  struct concat<my_index_sequence<I...>, my_index_sequence<J...> > :
    my_index_sequence<I..., (sizeof...(I)+J)...> { };
  template<size_t N> struct make_index_sequence :
    concat<typename make_index_sequence<N/2>::type, typename make_index_sequence<N-N/2>::type>::type { };
  template <> struct make_index_sequence<0> : my_index_sequence<>{};
  template <> struct make_index_sequence<1> : my_index_sequence<0>{};
}

template<class... A>
using my_index_sequence_for = typename my_index_sequence_detail::make_index_sequence<sizeof...(A)>::type;

template<class T, size_t... I>
void print_tuple(ostream& s, T const& a, my_index_sequence<I...>){
  using swallow = int[];
  (void)swallow{0, (void(s << (I == 0? "" : ", ") << get<I>(a)), 0)...};
}

template<class T>
ostream& print_collection(ostream& s, T const& a);
template<class... A>
ostream& operator<<(ostream& s, tpl<A...> const& a);
template<class... A>
ostream& operator<<(ostream& s, tuple<A...> const& a);
template<class A, class B>
ostream& operator<<(ostream& s, pair<A, B> const& a);

template<class T, size_t I>
ostream& operator<<(ostream& s, array<T, I> const& a) { return print_collection(s, a); }
template<class T>
ostream& operator<<(ostream& s, vector<T> const& a) { return print_collection(s, a); }
template<class T, class U>
ostream& operator<<(ostream& s, multimap<T, U> const& a) { return print_collection(s, a); }
template<class T>
ostream& operator<<(ostream& s, multiset<T> const& a) { return print_collection(s, a); }
template<class T, class U>
ostream& operator<<(ostream& s, map<T, U> const& a) { return print_collection(s, a); }
template<class T>
ostream& operator<<(ostream& s, set<T> const& a) { return print_collection(s, a); }

template<class T>
ostream& print_collection(ostream& s, T const& a){
  s << '[';
  for(auto it = begin(a); it != end(a); ++it){
    s << *it;
    if(it != prev(end(a))) s << " ";
  }
  return s << ']';
}

template<class... A>
ostream& operator<<(ostream& s, tpl<A...> const& a){
  s << '(';
  print_tuple(s, a, my_index_sequence_for<A...>{});
  return s << ')';
}

template<class... A>
ostream& operator<<(ostream& s, tuple<A...> const& a){
  s << '(';
  print_tuple(s, a, my_index_sequence_for<A...>{});
  return s << ')';
}

template<class A, class B>
ostream& operator<<(ostream& s, pair<A, B> const& a){
  return s << "(" << get<0>(a) << ", " << get<1>(a) << ")";
}

//------------------------------------------------------------------------------

// --- BEGIN SNIPPET PRIMES ---

const lli MAXPRIME = 1e7+16;
lli divs[MAXPRIME+1];
bool sieve[MAXPRIME+1];
lli mo[MAXPRIME+1];

void calcPrimes(){
  FORU(i, 2, MAXPRIME) sieve[i]=1;
  FORU(i, 1, MAXPRIME) mo[i]=1;
  FORU(i, 1, MAXPRIME) divs[i]=-1;
  FORU(i, 2, MAXPRIME) if(sieve[i]) {
    mo[i]=-1; divs[i] = i;
    lli k=2;
    while(i*k<=MAXPRIME) { if(divs[i*k]==-1) divs[i*k] = i; sieve[i*k] = 0; mo[i*k]*=-1; if(k%i==0) mo[i*k]=0; k += 1; }
  }
}

// --- END SNIPPET PRIMES ---

map<lli,lli> brute(lli n) {
  map<lli,lli> R;
  vvi G(n+1);
  FORU(i,1,n) FORU(j,1,n) if(__gcd(i,j) != 1) G[i].pb(j);
  FORU(i,1,n) {
    vi E(n+1,0);
    vi D(n+1,1e10);
    deque<lli> Q; D[i]=0; Q.push_back(i); E[i]=1;
    while(!Q.empty()) {
      int j = Q.front(); Q.pop_front();
      for(int k : G[j]) if(!E[k]) {
          E[k] = 1;
          D[k] = D[j]+1;
          Q.push_back(k);
        }
    }
    FORU(j,i+1,n) R[D[j]]++;
  }
  return R;
}

// --- BEGIN SNIPPET BINARY INDEXED TREE ---

struct BIT {
  vi A;
  BIT(lli n) : A(n+1){ }

  lli get(lli i){
    i += 1;
    lli r = 0;
    for(; i > 0; i -= i &-i){
      r += A[i];
    }
    return r;
  }

  lli getR(lli l, lli r) {
    lli ans = get(r);
    if(l) ans -= get(l-1);
    return ans;
  }

  void add(lli i, lli v){
    i += 1;
    for(; i < (lli)A.size(); i += i & -i){
      A[i] += v;
    }
  }
};

// --- END SNIPPET BINARY INDEXED TREE ---

int main(){
  ios::sync_with_stdio(0); cin.tie(0);
  calcPrimes();
  lli n; cin>>n;

  lli anstot = 0;
  FORU(i,2,n) if(!sieve[i] || i <= n/2) anstot += 1;
  anstot = (anstot*(anstot-1))/2;

  lli ans1 = 0, ans2= 0;
  FORU(i,2,n) {
    lli x = n/i;
    lli y = (x*(x-1))/2;
    ans1 += -mo[i]*y;
  }

  vi V(n+1);
  FORU(i,2,n) {
    V[divs[i]]++;
  }
  BIT bit(n+10);
  FORD(i,n,2) if(sieve[i]) {
    ans2 += V[i]*bit.get(n/i);
    ans2 += (V[i]*(V[i]-1))/2;
    bit.add(i,V[i]);
  }
  ans2 -= ans1;

  lli ans3 = anstot-ans1-ans2;

  cout << ans1+2*ans2+3*ans3 << endl;

  // cout << mt(ans1,ans2,ans3) << endl;
  // cout << brute(n) << endl;

  // lli ans2 = 0;
  // FORU(i,1,n) {
  //   if(i*i>n) break;
  //   if(sieve[i]) {
  //     FORU(j,i+1,n) {
  //       if(i*j>n) break;
  //       if(sieve[j]) {
  //         ans2 += cnt1[i] * cnt1[j];
  //         cout << mt(i,j) << endl;
  //       }
  //     }
  //   }
  // }
  // // FORU(i,1,n) if(sieve[i]) {
  // //   lli nq = min(i-1,n/i);
  // //   cout << i << " " << cnt0[nq] << " " << cnt1[i] << " " << (n/i)-cnt1[i] << endl;
  // //   ans2 += (cnt0[nq] - ((n/i)-cnt1[i])) * cnt1[i];
  // // }
  // cout << ans2 << endl;

  return 0;
}

#include <bits/stdc++.h>

using namespace std;
typedef long long INT;

#define NN 10000010
int pv[NN], phi[NN], mn[NN], np;
int cnt[NN];

void pre(){
	for(int i=2; i<NN; i++){
		if(!mn[i]){
			pv[np++] = i;
			mn[i] = i;
		}
		for(int j=0; j<np && pv[j]*i<NN; j++){
			mn[i*pv[j]] = pv[j];
			if(mn[i] == pv[j]) break;
		}
	}
	for(int i=1; i<NN; i++) phi[i] = i;
	for(int i=2; i<NN; i+=2) phi[i] >>= 1;
	for(int i=3; i<NN; i+=2){
		if(phi[i] == i){
			for(int j=i; j<NN; j+=i) phi[j] -= phi[j]/i;
		}
	}
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif
	ios_base :: sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	pre();

	int n;
	cin >> n;

	INT cnt0 = 1, cnt1 = 0, cnt2 = 0, cnt3 = 0;
	INT tot = 1LL * n * (n - 1) / 2;
	//cnt0
	for(int i=2; i<=n; i++){
		if(mn[i] == i && mn[i] > n / 2) cnt0++;
	}
	cnt0 = n - cnt0;
	cnt0 = tot - cnt0 * (cnt0 - 1) / 2;
	//cnt1
	cnt1 = tot;
	for(int i=2; i<=n; i++) cnt1 -= phi[i];
	//cnt2
	for(int i=2; i<=n; i++) cnt[mn[i]]++;
	for(int i=n; i>=2; i--) cnt[i] += cnt[i+1];

	INT tmp = 0;
	for(int v=2; v<=n; v++){
		int x = n / mn[v] + 1;
		tmp += cnt[x];
		if(mn[v] > n / mn[v]) tmp--;
	}

	cnt2 = tot - cnt1 - tmp / 2 - (n - 1);
	//cnt3
	cnt3 = tot - cnt0 - cnt1 - cnt2;

	INT ans = cnt1 + 2 * cnt2 + 3 * cnt3;
	cout << ans << endl;
}

#include<bits/stdc++.h>

using namespace std;

using INT = long long;

const int NN = 10010101;

int prime[NN], phi[NN];
int pr[NN], np = 0;
int cnt[NN];
int n;

int pre() {
	phi[1] = 1;
	for(int i=2; i<NN; i++) {
		if(prime[i] == 0) pr[np++] = i, prime[i] = i;
		for(int j=0; j<np and pr[j]*i<NN; j++) {
			prime[pr[j]*i] = pr[j];
			if(prime[i] == pr[j]) break;
		}
		if(i / prime[i] % prime[i] == 0) phi[i] = phi[i / prime[i]] * prime[i];
		else phi[i] = phi[i/prime[i]] * (prime[i] - 1);
		if(i <= n and prime[i] + prime[i] <= n) cnt[prime[i]]++;
	}
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif
	cin >> n;
	pre();
	INT tot= 0;
	INT ans = 0;
	for(int i=2; i<=n; i++) tot += cnt[i];
	tot = tot * (tot - 1) / 2;
	for(int i=2; i<=n; i++) {
		ans += (i - phi[i] - 1);
		tot -= (i - phi[i] - 1);
	}
	for(int i=n-1; i>=1; i--) cnt[i] += cnt[i+1];
	for(int i=2; i<=n; i++) {
		int mn = max(i + 1, n / i + 1);
		if(mn <= n) {
			INT s = (INT) (cnt[i] - cnt[i+1]) * cnt[mn];
			ans += s * 3;
			tot -= s;
		}
	}
	ans += tot * 2;
	cout << ans << endl;
}

#include <bits/stdc++.h>
using namespace std;

class SegmentTree {
public:
	SegmentTree(int count) {
		n = count;
		data = std::vector<int>(2 * n, 0);
	}

	void increase(int idx) {
		idx += n;
		data[idx]++;

		while (idx > 1) {
			idx /= 2;
			data[idx] = data[2 * idx] + data[2 * idx + 1];
		}
	}

	int sum(int left, int right) { // interval [left, right)
		int ret = 0;
		left += n;
		right += n;

		while (left < right) {
			if (left & 1) ret += data[left++];
			if (right & 1) ret += data[--right];
			left >>= 1;
			right >>= 1;
		}
		return ret;
	}

private:
	int n;
	std::vector<int> data;
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n = 1e7;
    vector<int> largest(n+1), smallest(n+1);
    iota(largest.begin(), largest.end(), 0);
    iota(smallest.begin(), smallest.end(), 0);
    for (int i = 2; i <= n; i++) {
        if (i == largest[i]) {
            for (int j = i; j <= n; j += i) {
                largest[j] = i;
                smallest[j] = min(smallest[j], i);
            }
        }
    }

    long long result = 0;
    cin >> n;
    SegmentTree st(n+1);

    for (int i = 2; i <= n; i++) {
        int num = i;
        int co = 1;
        while (num > 1) {
            int s = largest[num];
            num /= s;
            int p1 = 1;
            int p2 = s;
            while (largest[num] == s) {
                num /= s;
                p1 = p2;
                p2 *= s;
            }
            co *= p2 - p1;
        }

        // cout << i << ": " << co << endl;
        int x = i - 1 - co;
        result += x;
        // cout << x << endl;
        // ^ these have distance 1

        // case gcd(a, b) == 1
        // smallest[a] * smallest[b] <= n
        // => distance 2
        // numbers = i - 1;
        int others = st.sum(0, n / smallest[i] + 1) - x;
        // cout << others << endl;
        result += others * 2;

        // last case
        if (smallest[i] != 2 && smallest[i] * 2 <= n) {
            int abc = st.sum(0, n / 2 + 1) - st.sum(0, n/smallest[i] + 1);
            result += abc* 3;

        }

        st.increase(smallest[i]);
    }

    cout << result << endl;
}

#include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

int N=10000000;
int n,tot;
int pr[2000005],p[10000605],mu[10000605],phi[10000605],cnt[10000605];

void init(){
	mu[1]=1;
	p[1]=1;
	phi[1]=1;
	for(int i=2;i<=N;i++){
		if(!p[i]){
			p[i]=i;
			pr[++tot]=i;
			mu[i]=-1;
			phi[i]=i-1;
		}
		for(int j=1;j<=tot && pr[j]*i<=N;j++){
			p[i*pr[j]]=pr[j];
			if(p[i]==pr[j]){
				phi[i*pr[j]]=phi[i]*pr[j];
				break;
			}else{
				mu[i*pr[j]]=-mu[i];
				phi[i*pr[j]]=phi[i]*(pr[j]-1);
			}
		}
	}
}

ll calc1(){
	ll ans=0;
	for(int i=2;i<=n;i++){
		ans+=i-phi[i]-1;
	}
	return ans;
}

ll calc0(){
	ll ans=0;
	ll u=0;
	for(int i=1;i<=n;i++){
		if(i==1 || (2*i>n && p[i]==i)){
			ans+=i-1;
			u++;
		}else{
			ans+=u;
		}
	}
	return ans;
}

ll calc2(){
	ll sm=0;
	for(int d=1;d<=n;d++){
		if(mu[d]){
			ll ans=0;
			if(n/d>=100000){
				int mv=0;
				for(int i=d;i<=n;i+=d){
					mv=max(mv,p[i]);
				}
				for(int i=1;i<=mv;i++){
					cnt[i]=0;
				}
				for(int i=d;i<=n;i+=d){
					cnt[p[i]]++;
				}
				for(int i=1;i<=mv;i++){
					cnt[i]+=cnt[i-1];
				}
				for(int i=1;i<=mv;i++){
					if(cnt[i]!=cnt[i-1]){
						ans+=(ll)(cnt[i]-cnt[i-1])*cnt[min(mv,n/i)];
					}
				}
			}else{
				tot=0;
				for(int i=d;i<=n;i+=d){
					cnt[tot++]=p[i];
				}
				sort(cnt,cnt+tot);
				int r=tot-1;
				for(int i=0;i<tot;i++){
					while(r>=0 && (ll)cnt[i]*cnt[r]>n)r--;
					ans+=r+1;
				}
			}
			sm+=mu[d]*ans;
		}
	}
	return (sm+1LL)/2LL-n;
}

int main(void){
	init();
	scanf("%d",&n);
	ll sum=(ll)n*(n-1)/2LL;
	ll t1=calc1();
	ll t0=calc0();
	ll t2=calc2();
	ll t3=sum-t0-t1-t2;
	printf("%lld\n",t1+t2*2LL+t3*3LL);
	return 0;
}

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <set>
using namespace std;
const int maxn = 1e7 + 7;
bool flag[maxn];
int p[maxn], tot, phi[maxn], mi[maxn], delta[maxn], p_cnt[maxn];
int n;
void init(){
	flag[1] = 1;
	phi[1] = 0;
	delta[1] = 0;
	for(int i = 2; i < maxn; i++){
		if(!flag[i]){
			p[tot++] = i;
			phi[i] = i - 1;
			mi[i] = i;
			delta[i] = 1;
		}
		for(int j = 0; j < tot && 1LL * i * p[j] < maxn; j++){
			flag[i * p[j]] = 1;
			mi[i * p[j]] = p[j];
			if(i % p[j] == 0){
				phi[i * p[j]] = phi[i] * p[j];
				delta[i * p[j]] = delta[i];
				break;
			}
			else{
				phi[i * p[j]] = phi[i] * (p[j] - 1);
				delta[i * p[j]] = delta[i] + 1;
			}
		}
	}
	for(int i = 1; i < maxn; i++){
		p_cnt[i] = p_cnt[i - 1] + (flag[i] == 0);
	}
}

long long com_com(){
	long long ans = 0;
	for(int i = 2; i <= n; i++){
		if(flag[i] == 0)
			continue;
		ans += phi[i] - (p_cnt[i] - delta[i]) - 1;
	}
	return ans * 2;
}

long long pri_pri(){
	long long ans = 0;
	for(int i = 2; i <= n; i++){
		if(flag[i] == 1)
			continue;
		int mx = n / i;
		mx = min(mx, i - 1);
		ans += p_cnt[mx];
	}
	return ans * 2;
}

long long pri_com(){
	long long ans = 0;

	for(int i = 2; i <= n; i++){
		if(flag[i] == 0)
			continue;
		int mx = n / mi[i];
		ans += 2 * p_cnt[mx];
		ans -= 2 *  delta[i];
	}
	return ans;
}

long long pri_pri3(){
	long long ans = 0;
	for(int i = 2; i <= n / 2; i++){
		if(flag[i] == 1)
			continue;
		int L = (n + 1 + i - 1) / i;
		int R = min(n / 2, i - 1);
		if(R >= L){
			int cnt = p_cnt[R] - p_cnt[L - 1];
			ans += 3 * cnt;
		}
	}
	return ans;
}

long long pri_com3(){
	long long ans = 0;
	for(int i = 2; i <= n; i++){
		if(flag[i] == 0)
			continue;
		if(mi[i] * 2 > n)
			continue;
		int L = (n + mi[i]) / mi[i];
		int R = n / 2;
		if(R >= L){
			ans += 3 * (p_cnt[R] - p_cnt[L - 1]);
		}
	}
	return ans;
}

int main(){
	cin >> n;
	init();
	long long ans = 0;
	for(int i = 1; i <= n; i++){
		ans += (i - 1 - phi[i]);
	}

	ans += com_com();
	ans += pri_pri();

	ans += pri_com();

	ans += pri_pri3();

	ans += pri_com3();
	cout << ans << endl;
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e7 + 100;

typedef long long LL;

int n, m;
LL ans, a, b, c;
bool isp[maxn];
int p[maxn], cnt[maxn], phi[maxn], cnt2[maxn];

void pre() {
	phi[1] = 1;
	for (int i = 2; i <= n; ++i) {
		isp[i] = 1;
	}
	for (int i = 2; i <= n; ++i) {
		if(isp[i]) {
			phi[i] = i - 1;
			p[m++] = i;
		}
		for (int j = 0; j < m; ++j) {
			if(1ll * p[j] * i > n) {
				break;
			}
			int x = p[j] * i;
			++cnt[p[j]];
			isp[x] = 0;
			if(i % p[j] == 0) {
				phi[x] = phi[i] * p[j];
				break;
			}
			phi[x] = phi[i] * phi[p[j]];
		}
	}
	for (int i = n - 1; i >= 0; --i) {
		cnt[i] += cnt[i + 1];
	}
	/*
	#ifdef DEBUG
	for (int i = 1; i <= n; ++i) {
		printf("%d ", phi[i]);
	}
	puts("");
	for (int i = 1; i <= n; ++i) {
		printf("%I64d ", cnt[i]);
	}
	puts("");
	#endif
	*/
	return;
}

int main() {
	scanf("%d", &n);
	pre();
	if(n <= 3) {
		puts("0");
		return 0;
	}
	for (int i = 2; i <= n; ++i) {
		if(isp[i] && i * 2 > n) {
			continue;
		}
		++b;
		a += (i - phi[i] - 1);
		if(isp[i]) {
			cnt2[i] = 1;
			c += cnt[n / i + 1];
		}
	}
	for (int i = n - 1; i > 1; --i) {
		cnt2[i] += cnt2[i + 1];
	}
	for (int i = 2; i <= n; ++i) {
		if(isp[i] && i * 2 <= n) {
			int j = n / i + 1;
			if(j < i) {
				c += cnt2[j] - cnt2[i];
			}
		}
	}
	b = b * (b - 1) / 2 - a - c;
	//cerr<<a<<' '<<b<<' '<<c<<endl;
	printf("%I64d\n", a + b * 2 + c * 3);
	return 0;
}

#include<bits/stdc++.h>

#define inf 0x3f3f3f3f
#define mod 1000000007
#define pb push_back
#define sz(a) ((int)a.size())
#define x first
#define y second

using namespace std;

typedef double DO;
typedef long long INT;
typedef pair<int, int> pii;
typedef vector<int> VI;

#define NN 10000111
int n;
int prime[NN];
int fir[NN];
int np;
int phi[NN];
INT one, two, three;
int cnt[NN];
int tot[NN];

int solve() {
    cin >> n;
    phi[1] = 1;
    for(int i=2; i<=n; i++) {
        if(!fir[i]) fir[i] = i, prime[np++] = i;
        for(int j=0; j<np and prime[j]*i<=n; j++) {
            fir[i*prime[j]] = prime[j];
            if(fir[i] == prime[j]) break;
        }
        int u=i/fir[i];
        if(fir[u] == fir[i]) phi[i] = phi[u] * fir[i];
        else phi[i] = phi[u] * (fir[i]-1);
        if((fir[i]^i) or (i<<1)<=n) cnt[fir[i]]++;
        one += i-1-phi[i];
    }
    for(int i=n; i>=0; i--) tot[i] = tot[i+1] + cnt[i];
    for(int i=2; i<=n; i++) if(cnt[i]) {
        three += (INT)cnt[i] * tot[max(i, n/i)+1];
    }
    two = (INT)tot[1]*(tot[1]-1)/2 - one -three;
    cout << one + two * 2 + three * 3 << endl;
}

int main() {
#ifndef	ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif
    solve();
	return 0;
}

#include <bits/stdc++.h>

#define debug(x) cout << #x << " = " << x << endl
#define fori(i, ini, lim) for(int i = int(ini); i < int(lim); i++)
#define ford(i, ini, lim) for(int i = int(ini); i >= int(lim); i--)

using namespace std;

typedef long long ll;
typedef pair<int, int> ii;

const int MAX = 1e7 + 7;
const int INF = 0x3F3F3F3F;
int sf[MAX], phi[MAX], bit[MAX];
vector<int> primes;

void sieve() {
	phi[1] = 1;
	for(int i = 2; i < MAX; ++i) {
		if(sf[i] == 0) {
			sf[i] = i;
			phi[i] = i - 1;
			primes.push_back(i);
		}
		else {
			if(sf[i] == sf[i / sf[i]]) {
				phi[i] = phi[i / sf[i]] * sf[i];
			}
			else {
				phi[i] = phi[i / sf[i]] * (sf[i] - 1);
			}
		}
		for(ll j = 0; j < (int) primes.size() && primes[j] <= sf[i] && i * primes[j] < MAX; j++) {
			sf[i * primes[j]] = primes[j];
		}
	}
}

void update(int idx) {
	while(idx < MAX) {
		bit[idx]++;
		idx += idx & -idx;
	}
}

int query(int idx) {
	int sum = 0;
	while(idx) {
		sum += bit[idx];
		idx -= idx & -idx;
	}
	return sum;
}

int main() {
	sieve();

	int n;
	scanf("%d", &n);

	int type3 = 0;
	ll ans = 0;
	fori(i, 2, n + 1) {
		int d1 = (i - 1) - phi[i], d2 = 0, d3 = 0;
		d2 = query(n / sf[i]) - d1;
		update(sf[i]);
		if(2 * sf[i] <= n) {
			d3 = type3 - d1 - d2;
			type3++;
		}
		ans += d1 + 2 * d2 + 3 * d3;
	}
	printf("%lld\n", ans);

	return 0;
}

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <ctype.h>
#include <deque>
#include <cstring>
#include <set>
#include <bitset>
#include <map>
#include <chrono>
#include <random>
#include <unordered_map>
#include <stdio.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef std::vector<int> vi;
typedef std::vector<bool> vb;
typedef std::vector<string> vs;
typedef std::vector<double> vd;
typedef std::vector<long long> vll;
typedef std::vector<std::vector<int> > vvi;
typedef vector<vll> vvll;
typedef std::vector<std::pair<int, int> > vpi;
typedef vector<vpi> vvpi;
typedef std::pair<int, int> pi;
typedef std::pair<ll, ll> pll;
typedef std::vector<pll> vpll;

const long long mod = 1000000007;
const unsigned gen_seed = std::chrono::system_clock::now().time_since_epoch().count();
std::mt19937_64 gen(gen_seed);

#define all(c) (c).begin(),(c).end()
#define forn(i, a, b) for(int i = a; i < b; i++)
#define read(x) scanf("%d", &x)
#define readv(x, n) vi x(n); forn(i,0,n) scanf("%d", &x[i])

#define pb push_back
#define mp make_pair

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "rt", stdin);
    freopen("output.txt", "wt", stdout);
#endif
    const int LIMIT = 10000000;
    vb isp(LIMIT+1, true);
    vi mindiv(LIMIT+1, 0);
    forn(i,0,LIMIT+1) mindiv[i]=i;
    int upbound = (int)sqrt((double)LIMIT);
    vi p;
    for (int m = 2; m <= upbound; m++) {
        if (isp[m]) {
            p.pb(m);
            for (int k = m * m; k <= LIMIT; k += m) {
                isp[k] = false;
                mindiv[k]=min(mindiv[k], m);
            }
        }
    }
    vi sqfree(LIMIT+1, 1);
    vi pcnt(LIMIT+1, 0);
    forn(i,2,LIMIT+1) {
        int k = i/mindiv[i];
        if(mindiv[k] == mindiv[i] || sqfree[k] == 0) sqfree[i] = 0;
        pcnt[i] = pcnt[k]+1;
    }
    for(int m = upbound+1; m<=LIMIT; m++) {
        if (isp[m]) {
            p.pb(m);
        }
    }
    mindiv[1] = 1;
    vll cmin(LIMIT+1,0);
    ll n;
    cin>>n;
    forn(i,2,n+1) cmin[mindiv[i]] ++;
    ll ans = ((n*(n-1))/2)*3;
    ll totp = ans;
    ll badnum = 1;
    for(auto x : p) if(x <= n && 2*x > n) badnum++;
    ll badp = badnum*n - (badnum*(badnum+1))/2;
    ans -= 3*badp;
    ll group2 = 0;
    for(auto x : p) if(x <= n) group2 += (cmin[x]*(cmin[x]-1))/2;
    forn(i,2,n+1) if(pcnt[i] == 2 && sqfree[i] == 1) {
        int p1 = i / mindiv[i];
        int p2 = mindiv[i];
        group2 += cmin[p1]*cmin[p2];
    }
    ans -= group2;
    ll hd = 0;
    forn(i,2,n+1) {
        if(sqfree[i]) {
            ll num = n/i;
            ll nump = (num*(num-1))/2;
//            printf("Pairs div %d: %d\n", i, nump);
            if(pcnt[i]%2) hd+=nump;
            else hd-=nump;
//            printf("new hd %d\n", hd);
        }
    }
    ans -= hd;
//    printf("Total pairs: %d\n Bad pairs: %d\n pq pairs: %d\n Have gcd pairs: %d\n", totp/3, badp, group2, hd);
    cout<<ans;

}

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

#define pii pair<int,int>
#define pll pair<ll,ll>
#define PB push_back
#define MP make_pair
#define N 10000001

int leastPrime[N], d[N], s[N];
ll c[N];

int main(){
  int n;
  ll ans1, ans2, ans3, ans;

  cin >> n;

  ans1 = 0;
  for(int i = n; i > 1; --i){
    ll cx = 0;
    for(int j = 2 * i; j <= n; j += i)
      cx += c[j];
    c[i] = 1ll * (n / i) * (n / i - 1) / 2 - cx;
    ans1 += c[i];
  }

  for(int i = 2; i <= n; ++i){
    if(leastPrime[i] == 0){
      int k = 0;
      for(int j = i; j <= n; j += i){
        if(leastPrime[j] == 0){
          ++k;
          leastPrime[j] = i;
        }
      }
      d[i] = k;
    }
    s[i] = s[i - 1] + d[i];
  }

  ans2 = 0, ans3 = 0;
  for(int i = 2; i <= n; ++i){
    if(d[i]){
      ans2 += 1ll * d[i] * s[n / i];
      if(2 * i <= n)
        ans3 += 1ll * d[i] * s[n / 2];
    }

    int p = leastPrime[i];
    if(1ll * p * p <= n)
      --ans2;

    if(2 * p <= n)
      --ans3;
  }
  ans2 /= 2,  ans3 /= 2;

  ans3 -= ans2;
  ans2 -= ans1;

  ans = ans1 + 2 * ans2 + 3 * ans3;

  cout << ans << '\n';

  return 0;
}

// This amazing code is by Eric Sunli Chen.
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>
using namespace std;
template<typename T> void get_int(T &x)
{
	char t=getchar();
	bool neg=false;
	x=0;
	for(; (t>'9'||t<'0')&&t!='-'; t=getchar());
	if(t=='-')neg=true,t=getchar();
	for(; t<='9'&&t>='0'; t=getchar())x=x*10+t-'0';
	if(neg)x=-x;
}
template<typename T> void print_int(T x)
{
	if(x<0)putchar('-'),x=-x;
	short a[20]= {},sz=0;
	while(x>0)a[sz++]=x%10,x/=10;
	if(sz==0)putchar('0');
	for(int i=sz-1; i>=0; i--)putchar('0'+a[i]);
}
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define get1(a) get_int(a)
#define get2(a,b) get1(a),get1(b)
#define get3(a,b,c) get1(a),get2(b,c)
#define printendl(a) print_int(a),puts("")
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int,int> pii;
const int inf=0x3f3f3f3f;
const LL Linf=1ll<<61;
const double pi=acos(-1.0);

const int maxn=10000111;
bool pr[maxn];
int n,mnv[maxn],miu[maxn],prm[1000111],tot,cnt[maxn];
int main()
{
	get1(n);
	for(int i=1;i<=n;i++)
	{
		miu[i]=1;
		pr[i]=(i>1);
	}
	for(int i=2;i<=n;i++)
	{
		if(pr[i])
		{
			prm[++tot]=mnv[i]=i;
			miu[i]=-1;
			for(int j=i+i;j<=n;j+=i)
			{
				pr[j]=0;
				if(mnv[j]==0)mnv[j]=i;
				if(j/i%i==0)miu[j]=0;
				else miu[j]*=-1;
			}
		}
	}
	LL ans1=0,ans2=0,ans3=0;
	for(int i=1;i<=n;i++)
	{
		cnt[mnv[i]]++;
		ans1+=1ll*miu[i]*(n/i)*(n/i);
	}
	ans1=(1ll*n*n-ans1)-(n-1)>>1;
	int cur=tot,tot2=0;
	for(int i=1;prm[i]*prm[i]<=n;i++)
	{
		while(cur>=1&&1ll*prm[i]*prm[cur]>n)
		{
			tot2+=cnt[prm[cur]];
			cur--;
		}
		ans2+=1ll*cnt[prm[i]]*tot2;
	}
	tot2=0;
	for(int i=tot;i>=1&&1ll*prm[i]*prm[i]>n;i--)
	{
		ans2+=1ll*tot2*cnt[prm[i]];
		tot2+=cnt[prm[i]];
	}

	cur=tot;tot2=0;while(cur>=1&&2*prm[cur]>n)cur--;
	for(int i=1;prm[i]*prm[i]<=n;i++)
	{
		while(cur>=1&&1ll*prm[i]*prm[cur]>n)
		{
			tot2+=cnt[prm[cur]];
			cur--;
		}
		ans3+=1ll*cnt[prm[i]]*tot2;
	}
	cur=tot;tot2=0;while(cur>=1&&2*prm[cur]>n)cur--;
	for(int i=cur;i>=1&&1ll*prm[i]*prm[i]>n;i--)
	{
		ans3+=1ll*tot2*cnt[prm[i]];
		tot2+=cnt[prm[i]];
	}

	ans2-=ans3;
	printendl(1ll*(n-1)*(n-2)-ans1-ans2*2+ans3);
	return 0;
}

#include<bits/stdc++.h>
#define Venus using
#define AK namespace
#define IOI std
Venus AK IOI;
typedef long long ll;
#define int ll

const int MAXT=10000001;
int nprime=0;
int prime[MAXT-1];
int prcnt[MAXT];
int sp[MAXT];
bool vis[MAXT];
int euler[MAXT];

int gcd(int a,int b) {
	if(b==0) return a;
	return gcd(b,a%b);
}

void setprime(int top) {
	sp[1]=1;
    euler[1]=1;
	for(int i=2;i<=top;i++) {
		if(!vis[i]) {
            prcnt[i]++;
			prime[nprime++]=i;
			sp[i]=i;
            euler[i]=i-1;
		}
		for(int j=0;j<nprime && prime[j]*i<=top;j++) {
			vis[prime[j]*i]=1;
            prcnt[prime[j]]++;
			sp[prime[j]*i]=prime[j];
			if(i%prime[j]==0) {
                euler[prime[j]*i] = euler[i] * prime[j];
                break;
            }
            euler[i*prime[j]] =euler[i]*(prime[j]-1);
		}
	}
}

int prsequence(int l,int r) {
    if(r<l) return 0;
    if(l==0) return prcnt[r];
    else return prcnt[r]-prcnt[l-1];
}

int n;

signed main() {
	//freopen("Venus.in","r",stdin);
	//freopen("Venus.out","w",stdout);
	//cout<<"Start."<<endl;

	scanf("%lld",&n);
    //cout<<"Read."<<endl;

    setprime(n);

	int ans=(n-1)*(n-2)/2;
    for(int i=1;i<=n;i++) {
        //printf("Euler(%lld) = %lld\n",i,euler[i]);
        ans+=(euler[i]-1);
    }

    for(int i=1;i<=n;i++) {
        //printf("Cnt(%lld) = %lld\n",i,prcnt[i]);
        prcnt[i]+=prcnt[i-1];
    }

    for(int i=0;i<nprime;i++) {
        int cnt=prsequence(prime[i],prime[i]);
        ans+=cnt*prsequence(max(prime[i]+1,n/prime[i]+1),max(prime[i]+1,n/2+1)-1);
        ans-=cnt*2*prsequence(max(prime[i]+1,n/2+1),n);
    }
    //cout<<"Calc."<<endl;

    printf("%lld\n",ans);
}

#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
using namespace std;

using ll = long long;
using ull = unsigned long long;
using ld = long double;

#define forn(i, a, n) for (int i = (int)(a); i < (int)(n); ++i)
#define ford(i, a, n) for (int i = (int)(n - 1); i >= (int)(a); --i)
#define fore(i, a, n) for (int i = (int)(a); i <= (int)(n); ++i)
#define all(a) (a).begin(), (a).end()
#define fs first
#define sn second
#define trace(a)\
    for (auto i : a) cerr << i << ' ';\
    cerr << '\n'
#define eb emplace_back

#ifndef M_PI
const ld M_PI = acos(-1.0);
#endif

template<typename T>
inline void setmax(T& a, T b) {
    if (a < b) a = b;
}

template<typename T>
inline void setmin(T& a, T b) {
    if (a > b) a = b;
}

const ld eps = 1e-9;
const int INF = 2000000000;
const ll LINF = 1ll * INF * INF;
const ll MOD = 1000000007;

const int N = 1e7 + 10;
int p[N];
int copr[N];
ll pref[N];
ll pref_min_pr[N];

void precalc() {
    vector<int> primes;
    forn(i, 0, N) p[i] = i;
    forn(i, 2, N) {
        if (p[i] == i)
            primes.eb(i);
        for (int x : primes) {
            if (x > p[i]) break;
            ll mul = 1ll * x * i;
            if (mul >= N) break;
            p[mul] = x;
       }
    }
    copr[1] = 1;
    forn(i, 2, N) {
        int prev = i / p[i];
        copr[i] = copr[prev];
        copr[i] *= p[i];
        if (p[i] != p[prev])
            copr[i] -= copr[i] / p[i];
    }
    pref[1] = copr[1] - 1;
    forn(i, 2, N)
        pref[i] = pref[i - 1] + copr[i];
}

void check(int n) {
    fore(i, 1, n) {
        vector<int> dist(n + 1, INF);
        queue<int> q;
        dist[i] = 0;
        q.push(i);
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            fore(v, 1, n)
                if (__gcd(v, u) > 1 && dist[v] == INF) {
                    dist[v] = 1 + dist[u];
                    q.push(v);
                }
        }
        fore(j, 1, n)
            cout << (dist[j] == INF ? 0 : dist[j]) << ' ';
        cout << '\n';
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    srand((unsigned)chrono::high_resolution_clock::now().time_since_epoch().count());
    precalc();
    //fore(i, 1, 10) cout << p[i] << ' ';
    int n;
    cin >> n;
    if (n < 4) {
        cout << 0 << '\n';
        return 0;
    }
    //check(n);
    ll good = n - 1;
    fore(i, 2, n) {
        if (2 * i > n && p[i] == i)
            --good;
    }
    //cerr << good << '\n';
    ll ans = good * (good - 1) / 2 * 3;
    fore(i, 2, n) {
        //cerr << i << ' ' << pref[n / i] << '\n';
        ans -= pref[n / i];
    }
    ll cnt2 = 0;
    fore(i, 2, n)
        ++pref_min_pr[p[i]];

    fore(i, 3, n)
        pref_min_pr[i] += pref_min_pr[i - 1];
    fore(i, 2, n) {
        //cerr << i << ' ' << pref_min_pr[n / p[i]] << '\n';
        cnt2 += pref_min_pr[n / p[i]];
    }
    fore(i, 2, n)
        if (1ll * p[i] * p[i] <= n)
            --cnt2;
    assert(cnt2 % 2 == 0);
    ans -= cnt2 / 2;
    //cerr << cnt2 << '\n';
    cout << ans << '\n';

}

#include<iostream>
#include<vector>
using namespace std;

struct Ftree {
    vector<int> data;
    int n;

    Ftree(int nsize) {
        n = nsize;
        data.resize(n, 0);
    }
    void add(int pos, int toAdd) {
        while(pos < n) {
            data[pos] += toAdd;
            pos += (pos & -pos);
        }
    }
    int get(int pos) {
        int result = 0;
        while(pos > 0) {
            result += data[pos];
            pos -= (pos & -pos);
        }
        return result;
    }
};

int n;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n;

    vector<int> lp(n+1, 1), tot(n+1, 1);
    Ftree cnt_by_lp(n+2);

    long long result = 0;
    int invalid = 1;

    for(int i=2;i<=n;i++) {
        if(lp[i] == 1) {
            lp[i] = i;
            if(1LL*i*i <= n) {
                for(int j=i*i; j <= n; j+=i) {
                    if(lp[j] == 1) {
                        lp[j] = i;
                    }
                }
            }

            if(i*2 > n) {
                invalid++;
                tot[i] = i-1;
                continue;
            }
        }
        //Now calculate the totient
        {
            int lp_pow = 1, cur = i;
            while(cur % lp[i] == 0) {
                cur /= lp[i];
                lp_pow *= lp[i];
            }
            tot[i] = tot[cur] * (lp_pow - lp_pow / lp[i]);
        }

        result += 3*(i-1-invalid);
        result -= cnt_by_lp.get(n/lp[i] + 1);
        result -= (i-1 - tot[i]); //Not relatively prime

        cnt_by_lp.add(lp[i]+1, 1);
    }

    cout << result << '\n';
    return 0;
}

#include <bits/stdc++.h>

using namespace std;

#define pb push_back
#define mp make_pair
#define forn(i, n) for (int i = 0; i < (int)(n); ++i)
typedef long long LL;
typedef pair<int, int> PII;

const int M = 10000005;
int n;
int eu[M];
bool pr[M];
int u[M] = {};

int main() {
    forn(i, M) pr[i] = true;
    pr[0] = pr[1] = false;
    forn(i, 10000) if (pr[i]) {
        for (int j = i * i; j < M; j += i) {
            pr[j] = false;
        }
    }
    forn(i, M) eu[i] = 1;
    eu[1] = 0;
    forn(i, M) if (pr[i]) {
        for (LL x = i; x < M; x *= i) {
            if (x == i) {
                for (int y = x; y < M; y += x) {
                    eu[y] *= i - 1;
                }
            } else {
                for (int y = x; y < M; y += x) {
                    eu[y] *= i;
                }
            }
        }
    }
    int n;
    cin >> n;
    if (n < 4) {
        cout << 0 << endl;
        return 0;
    }
    int mx = n / 2;
    int cnt = 0;
    for (int i = mx + 1; i <= n; ++i) {
        cnt += pr[i];
    }
    LL ans = (LL)(n - 1) * (n - 2) / 2;
    ans -= (LL)cnt * (cnt - 1) / 2;
    ans -= (LL)cnt * (n - 1 - cnt);
    int bad = 1;
    for (int i = 2; i <= n; ++i) {
        if (i > mx && pr[i]) {
            ++bad;
            continue;
        }
        ans += eu[i] - bad;
    }

    int z = sqrt(n + 0.5) + 1;
    cnt = 0;
    int j = 2;
    for (int i = z; i <= n; ++i) if (pr[i]) u[i] = 1;
    for (int i = mx + 1; i <= n; ++i) if (pr[i]) u[i] = 1;
    int tmp = 0;
    for (int i = 2; i <= n; ++i) if (!u[i]) {
        ++tmp;
    }
    for (int i = mx; i >= z; --i) if (pr[i]) {
        ++cnt;
        while ((LL)j * i <= n) {
            if (pr[j]) for (int k = j; k <= n; k += j) {
                if (!u[k]) {
                    u[k] = 1;
                    --tmp;
                }
            }
            ++j;
        }
        ans += tmp;
    }
    ans += (LL)cnt * (cnt - 1) / 2;

    cout << ans << endl;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
int N;
int fai[10000005],Prime[10000005],Get[10000005],Sum[10000005],Index;
int IsPrime[10000005];
int main(){
	scanf("%d",&N);
	fai[1]=1;
	for (int i=2;i<=N;i++)
    {
	if (!IsPrime[i]){
	  Index++;
	  IsPrime[i]=Prime[Index]=i;
	  fai[i]=i-1;
	  }
	for (int j=1;i*Prime[j]<=N&&j<=Index;j++)
	  {
		IsPrime[i*Prime[j]]=Prime[j];//����ÿ�����ֶ���¼��С��������
		if (i%Prime[j]==0)
		  {
			fai[i*Prime[j]]=fai[i]*Prime[j];
			break;
		  }
		else fai[i*Prime[j]]=fai[i]*(Prime[j]-1);
	   }
    }
	long long Fir=0;
	for (int i=2;i<=N;i++)//���㲻���ص����ĸ���
		Fir+=i-fai[i]-1;
	for (int i=2;i<=N;i++)//����p[u]*p[v]<=N�����ĸ��� [gcd(a,b)==1]
	 	Get[IsPrime[i]]++;//����С�����ӱ��
	for (int i=2;i<=N;i++)
		Sum[i]=Sum[i-1]+Get[i];//<=N�������У��ж��ٸ�������С������
	long long Sec=0;
	for (int i=1;i<=Index;i++)
		Sec+=1ll*Get[Prime[i]]*Sum[N/Prime[i]];//�ж��ٸ�������С������Ϊi,������С������<=N/Prime[i]�����ĸ��� ������ʱ��ÿһ���������� ���б�����
	for (int i=2;i<=N;i++)
		if (1ll*IsPrime[i]*IsPrime[i]<=N) Sec--;
	Sec=Sec/2-Fir;
	long long Try=N-1,Thi=0;
	for (int i=1;i<=Index;i++)
		if (Prime[i]*2>N) Try--;
	//cout<<Try<<endl;
	Thi=1ll*Try*(Try-1)/2-Fir-Sec;
	cout<<Fir+1ll*2*Sec+1ll*3*Thi;
	return 0;
}

#include<bits/stdc++.h>
using namespace std;

#define MAXN 10000005
#define LL long long
#define int long long

int n,m,nn,mm;
signed phi[MAXN];
signed p[MAXN];
signed a[MAXN],r[MAXN],c[MAXN];
bool isp[MAXN];
LL ans;

void QAQ() {
	mm = n;
	isp[1] = 1;

	for(int i = 2; i <= n; i ++) {
		if(isp[i] == 0) {
			nn ++;
			p[nn] = i;
			a[i] = i;
			if(i*2 > n) {
				mm --;
			}
		}
		for(int j =1; j <= nn; j ++) {
			if(i*p[j] > n) break;
			isp[i*p[j]] = 1;
			a[i*p[j]] = p[j];
			if(i%p[j]  == 0) break;
		}
	}

	for(int i = 2; i <= n; i ++)
		c[a[i]] ++;

	phi[1] = 1;
	for(int i = 2; i <= n; i ++) {
		if(!isp[i]) {
			phi[i] = i-1;
			continue;
		}

		if((i/a[i])%a[i] == 0)
			phi[i] = phi[i/a[i]]*(a[i]);
		else  phi[i] = phi[i/a[i]]*(a[i]-1);
	}
	for(int i = 1; i <= n; i ++)
		c[i] += c[i-1];
}

int QwQ(int l,int r) {
	if(r < l) return 0;
	return c[r] - c[l-1];
}

signed main()
{
	//freopen("Venus.in","r",stdin);
	//freopen("Venus.out","w",stdout);

	cin >> n;
	QAQ();
	LL fk = 0,md;
	for(int i  = 2; i <= n; i ++) {
		fk += 1ll*(phi[i]-1);
	}
	md = ((n-1)*(n-2))>>1;
	md -= fk;
	ans = fk*2+md;
	int cnt = 0;
	for(int i = 1; i <= nn; i ++) {;
		int yy = 1ll*(c[p[i]] - c[p[i]-1]);
		ans += 1ll*yy*QwQ(max(1ll*(p[i]+1),n/p[i]+1),max(1ll*(p[i]+1),(n>>1)+1)-1);
		ans -= 2*yy*QwQ(max(1ll*(p[i]+1),(n>>1)+1),n);
	}
	cout<<ans;
	return 0;
}

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
const int MAXN=1e7+5;
const int MAXP=4e3+5;

int n,tot;
int pri[MAXN],phi[MAXN],sum[MAXN];
int f[MAXN],pc[MAXN],cnt[MAXN];
bool bo[MAXN];

void init()
{
	scanf("%d",&n);
	for(int i=2;i<=n;++i)
	{
		if(!bo[i])
		{
			pri[tot++]=i;phi[i]=i-1;
			f[i]=i;pc[i]=1;
		}
		cnt[i]=cnt[i-1]+(1^bo[i]);
		sum[f[i]]++;

		for(int j=0;j<tot && i*pri[j]<=n;++j)
		{
			bo[i*pri[j]]=1;f[i*pri[j]]=pri[j];
			if(i%pri[j]==0)
			{
				phi[i*pri[j]]=phi[i]*pri[j];
				pc[i*pri[j]]=pc[i];
				break;
			}
			phi[i*pri[j]]=phi[i]*(pri[j]-1);
			pc[i*pri[j]]=pc[i]+1;
		}
	}

	for(int i=2;i<=n;++i)
		sum[i]+=sum[i-1];
}

void solve()
{
	LL now=1ll*sum[n/2]*(sum[n/2]-1)/2;

	LL ans=0;
	for(int i=2;i<=n;++i)//both not pri
	{
		if(bo[i])
		{
			ans+=i-phi[i]-1;//dis=1
			now-=i-phi[i]-1;
			ans+=2ll*(phi[i]-cnt[i]+pc[i]-1);
			now-=phi[i]-cnt[i]+pc[i]-1;
		}
	}
	for(int i=2;i<=n;++i)
	{
		if(!bo[i])
		{
			ans+=2ll*(sum[n/i]-n/i);
			now-=(sum[n/i]-n/i);
			ans-=2ll*cnt[min(i-1,n/i)];
			now+=cnt[min(i-1,n/i)];
			if(i>n/i)
			{
				ans+=2ll*(sum[i]-sum[i-1]);
				now-=sum[i]-sum[i-1];
			}
		}
	}

	ans+=3ll*now;
	printf("%I64d\n",ans);
}

int main()
{
//	freopen("D.in","r",stdin);
//	freopen("D.out","w",stdout);

	init();
	solve();

	return 0;
}

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
LL N = 10000001;

LL* primes = new LL[N];
LL* primecounts = new LL[N];
LL* smallprime = new LL[N];
LL* mobiusval = new LL[N];
LL* divisorcounts = new LL[N];
LL* divisortotals = new LL[N];

LL mobius(LL n, LL p)
{
    if(n==1)
        return -1;
    else
    {
        if(smallprime[n]==p)
            return 0;
        else
            return -1*mobius(n/smallprime[n], smallprime[n]);
    }
}

int main()
{

    for(LL i=0; i<N; i++)
    {
        primes[i] = 1;
        smallprime[i] = 0;
        divisorcounts[i] = 0;
    }

    primes[0] = 0;
    primes[1] = 0;
    for(LL i=2; i< 4000; i++)
    {
        LL c = 0 ;
        while(c<N)
        {
            if(i!=c)
                primes[c] = 0;
            if(smallprime[c]==0)
                smallprime[c]=i;
            c += i;
        }
    }
    for(LL i=2; i<N; i++)
    {
        if (smallprime[i]==0)
            smallprime[i] = i;
    }

    mobiusval[0] = 0;
    primecounts[0] = 0;
    for(LL i=1; i<N; i++)
    {
        primecounts[i] = primecounts[i-1]+primes[i];
        mobiusval[i] = mobius(i,10000001);
    }

    LL n;
    cin>>n;
    LL ans = 0;

    for(LL i=2; i<n+1; i++)
        ans += mobiusval[i]*(n/i)*(n/i);
    ans -= (n-1);
    ans = ans/2;

    LL m = LL( pow((n+ 0.5), 0.5) );

    for(LL i=2; i<n+1; i++)
        divisorcounts[smallprime[i]]++;

    divisortotals[0] = 0;
    for(LL i=1; i<n+1; i++)
    {
        divisortotals[i] = divisortotals[i-1]+divisorcounts[i];
    }

    LL dis3=0,dis2;
    for(LL i=m+1; i<=n; i++)
    {
        if(primes[i]==1)
        {
            dis3+=(divisortotals[i-1] - divisortotals[n/i])*divisorcounts[i];
        }
    }

    LL a = primecounts[n] - primecounts[n/2];
    dis2 = (n-1)*(n-2)/2 - dis3 - ans;
    dis3 -= ((a)*(n-1 - a) + a*(a-1)/2);
    ans += (dis2*2+dis3*3);
    cout<<ans<<endl;

    return 0;
}

#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<bitset>
#include<string>
#include<cstdio>
#include<cctype>
#include<cassert>
#include<cstdlib>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>

#define For(i,x,y) for (int i=x;i<y;i++)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define lf else if

#define dprintf(...) fprintf(stderr,__VA_ARGS__)
using namespace std;

typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef vector<int> Vi;

int IN(){
	int c,f,x;
	while (!isdigit(c=getchar())&&c!='-');c=='-'?(f=1,x=0):(f=0,x=c-'0');
	while (isdigit(c=getchar())) x=(x<<1)+(x<<3)+c-'0';return !f?x:-x;
}

const int top=10000000;
const int N=top+19;

int vis[N],pri[N],mu[N],minp[N],sum[N],num[N];
int n;
ll ans,tmp;

void Init(int top){
	mu[1]=1;
	For(i,2,top+1){
		if (!vis[i]){
			pri[++*pri]=i;
			minp[i]=i;
			mu[i]=-1;
		}
		for (int j=1;j<=*pri&&pri[j]*i<=top;j++){
			vis[pri[j]*i]=1;
			minp[pri[j]*i]=pri[j];
			if (i%pri[j]==0){
				mu[pri[j]*i]=0;
				break;
			} else{
				mu[pri[j]*i]=-mu[i];
			}
		}
	}
	For(i,2,top+1) sum[i]=sum[i-1]+(!vis[i]);
}
int cal(int l,int r){
	if (l>r) return 0;
	return sum[r]-sum[l-1];
}

int main(){
	n=IN();
	Init(n);
	For(i,2,n+1) if (!vis[i]){
		ans+=2ll*sum[n/i];
		if (2*i<=n) ans+=3ll*cal(n/i+1,n/2);
	}
	For(i,1,n+1){
		int alb;
		if (i==1) alb=n-1-*pri;
		lf (vis[i]) alb=n/i;
		else alb=n/i-1;
		tmp+=1ll*mu[i]*alb*alb;
	}
	ans+=2*tmp;
	ans+=1ll*(n-1-*pri)*(n-1-*pri)-tmp;
	For(i,2,n+1) if (!vis[i]) ans+=2*(n/i-1);
	For(i,2,n+1) if (vis[i]) num[minp[i]]++;
	For(i,2,n+1) if (num[i]){
		ans+=4ll*num[i]*cal(1,n/i);
		if (2*i<=n) ans+=6ll*num[i]*cal(n/i+1,n/2);
	}
	For(i,2,n+1) if (!vis[i]){
		for (int j=i+i;j<=n;j+=i){
			if (1ll*i*minp[j]<=n) ans-=4;
			lf (2ll*max(i,minp[j])<=n) ans-=6;
		}
	}
	For(i,2,n+1) if (!vis[i]){
		if (1ll*i*i<=n) ans-=2;
		lf (2ll*i<=n) ans-=3;
	} else ans--;
	ans/=2;
	cout<<ans<<endl;
}

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#define reg register int
using namespace std;
const int N=1e7+5;
int v[N],p[N],fi[N],g[N];
long long ans,tmp;
int main(){
	int n,t=0; scanf("%d",&n);
	for(reg i=2;i<=n;++i){
		if(!v[i]) v[i]=p[++t]=i,fi[i]=i-1;
		for(reg j=1;j<=t&&i*p[j]<=n;++j){
			int x=i*p[j];
			v[x]=p[j];
			if(i%p[j]) fi[x]=fi[i]*(p[j]-1);
			else {fi[x]=fi[i]*p[j];break;}
		}
	}
	for(reg i=2;i<=n;++i) ++g[v[i]];
	for(reg i=1;i<=n;++i) g[i]+=g[i-1]; // g[i]=[1,i]����������
	for(reg i=1,j=t;i<=t;++i){
		while(p[i]*p[j]>n) --j;
		ans+=1ll*(g[p[i]]-g[p[i]-1])*g[p[j]];
		if(p[i]<=n/2) tmp+=1ll*(g[p[i]]-g[p[i]-1])*(n/2>p[j]?g[n/2]-g[p[j]]:0);
	}
	for(reg i=2;i<=n;++i)
		if(1ll*v[i]*v[i]<=n) --ans;
		else if(v[i]<=n/2) --tmp;
	for(reg i=2;i<=n;++i) ans-=i-fi[i]-1;
	printf("%lld\n",tmp/2*3+ans);
	return 0;
}

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 10000000
#define LL long long
LL n,ans;
int isp[MAXN+5],p[MAXN+5],phi[MAXN+5],cnt,lp[MAXN+5];
LL c[MAXN+5];
void Prime(){
	phi[1]=1;
	for(int i=2;i<=n;i++){
		if(!isp[i]){
			p[++cnt]=i;
			phi[i]=i-1;
			lp[i]=i;
		}
		for(int j=1;j<=cnt;j++){
			if(i*p[j]>n)break;
			isp[i*p[j]]=1;
			lp[i*p[j]]=p[j];
			if(i%p[j]==0){phi[i*p[j]]=phi[i]*p[j];break;}
			phi[i*p[j]]=phi[i]*(p[j]-1);
		}
	}
	for(int i=2;i<=n;i++)c[lp[i]]++;
	for(int i=1;i<=n;i++)c[i]+=c[i-1];
}
LL sum(int l,int r){
	if(r<l)return 0;
	return c[r]-c[l-1];
}
int main()
{
	scanf("%lld",&n);
	Prime();
	for(int i=2;i<=n;i++)ans+=(phi[i]-1);
	ans+=((n-1)*(n-2))/2LL;
	for(int i=1;i<=cnt;i++){
		LL tp=c[p[i]]-c[p[i]-1];//a
		ans+=tp*sum(max(p[i]+1,(int)n/p[i]+1),max(p[i],(int)n/2));//注意要去掉之前已经算了的
		ans-=2*tp*sum(max(p[i]+1,(int)n/2+1),(int)n);
	}
	printf("%lld",ans);
}

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define x first
#define y second
typedef pair<int, int> pii;
typedef long long ll;
const int oo = 1e9;
const int LOGN = 20;
const int MOD = 1000000007;
const double PI = acos(-1);
const int N = 10000000;
bool mark[N + 1];
int phi[N+1],n,sm[N+1],me[N+1];
vector<int> pr;

int main(){
  cin >> n;
  for(int i = 2; i <= n ; ++i)phi[i] = i;
  for(int i = 2; i <= n ; ++i){
    if(mark[i])continue;
    pr.push_back(i);
    for(int j = i ; j <= n ; j += i){
      if(!mark[j])sm[i]++,me[j]=i;
      mark[j] = 1;
      phi[j] -= phi[j]/i;
    }
  }
  ll ones = 0,zeros = n-1,two = 0,c1=1,three=0;
  for(int i = 1; i <= n ; ++i)ones += (i-1)-phi[i];
  for(int i = 1; i <= n ; ++i)sm[i]+=sm[i-1];
  for(int i = 2; i <= n ; ++i){
    auto v = upper_bound(pr.begin(),pr.end(),n/me[i]);
    if(v == pr.begin())continue;
    int br = *(--v);
    two += sm[br];
    if(br >= me[i])two--;
  }
  two = (two/2) - ones;
  for(int i = 2; i <= n ; ++i){
    if(2*me[i] > n) zeros += n-1,c1++;
  }
  zeros -= (c1*(c1-1))/2;
  three = (1ll*n*(n-1))/2 - (zeros+two+three+ones);
  ll ans = ones+2ll*two+3ll*three;
  //cout << ones<< " "  << two  << " " << zeros << " " << three << endl;
  cout << ans << endl;
  return 0;
}

// eddy1021
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
typedef double D;
typedef long double LD;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
#define mod9 1000000009LL
#define mod7 1000000007LL
#define INF  1023456789LL
#define INF16 10000000000000000LL
#define eps 1e-9
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()
#define IOS ios_base::sync_with_stdio(0); cin.tie(0)
#ifndef ONLINE_JUDGE
#define debug(...) printf(__VA_ARGS__)
#else
#define debug(...)
#endif
inline LL getint(){
  LL _x=0,_tmp=1; char _tc=getchar();
  while( (_tc<'0'||_tc>'9')&&_tc!='-' ) _tc=getchar();
  if( _tc == '-' ) _tc=getchar() , _tmp = -1;
  while(_tc>='0'&&_tc<='9') _x*=10,_x+=(_tc-'0'),_tc=getchar();
  return _x*_tmp;
}
inline LL add( LL _x , LL _y , LL _mod = mod7 ){
  _x += _y;
  return _x >= _mod ? _x - _mod : _x;
}
inline LL sub( LL _x , LL _y , LL _mod = mod7 ){
  _x -= _y;
  return _x < 0 ? _x + _mod : _x;
}
inline LL mul( LL _x , LL _y , LL _mod = mod7 ){
  _x *= _y;
  return _x >= _mod ? _x % _mod : _x;
}
LL mypow( LL _a , LL _x , LL _mod ){
  if( _x == 0 ) return 1LL;
  LL _ret = mypow( mul( _a , _a , _mod ) , _x >> 1 , _mod );
  if( _x & 1 ) _ret = mul( _ret , _a , _mod );
  return _ret;
}
LL mymul( LL _a , LL _x , LL _mod ){
  if( _x == 0 ) return 0LL;
  LL _ret = mymul( add( _a , _a , _mod ) , _x >> 1 , _mod );
  if( _x & 1 ) _ret = add( _ret , _a , _mod );
  return _ret;
}
inline bool equal( D _x ,  D _y ){
  return _x > _y - eps && _x < _y + eps;
}
void sleep( double sec = 1021 ){
  clock_t s = clock();
  while( clock() - s < CLOCKS_PER_SEC * sec );
}
#define Bye exit(0)
int __ = 1 , _cs;
/*********default*********/
#define N 10000001
int BIT[ N ] , lb[ N ];
void build(){
  for( int i = 1 ; i < N ; i ++ )
    lb[ i ] = i & (-i);
}
inline void modify( int x ){
  for( int i = x ; i < N ; i += lb[ i ] )
    BIT[ i ] ++;
}
inline int query( int x ){
  int ret = 0;
  for( int i = x ; i ; i -= lb[ i ] )
    ret += BIT[ i ];
  return ret;
}
int n , mnp[ N ] , res , phi[ N ];
LL ans , tans[ N ];
LL C2( LL x ){
  return x * ( x - 1 ) / 2;
}
int can;
void init(){
  res = n = getint();
  for( int i = 2 ; i <= n ; i ++ ) phi[ i ] = i;
  for( int i = 2 ; i <= n ; i ++ ) if( !mnp[ i ] )
    for( int j = i ; j <= n ; j += i ){
      if( !mnp[ j ] )
        mnp[ j ] = i;
      phi[ j ] = ( phi[ j ] / i ) * ( i - 1 );
    }
  for( int i = 2 ; i <= n ; i ++ )
    if( mnp[ i ] * 2 <= n )
      can ++;
  for( int i = 2 ; i <= n ; i ++ )
    ans += ( i - phi[ i ] - 1 );
}
inline int cost( int i , int j ){
  if( __gcd( i , j ) > 1 ) return 1;
  else if( (LL)mnp[ i ] * (LL)mnp[ j ] <= n )
    return 2;
  return 0;
}
void solve(){
  LL all = C2( can );
  LL tmp = 0;
  for( int i = 2 ; i <= n ; i ++ ){
    tmp += query( n / mnp[ i ] );
    modify( mnp[ i ] );
  }
  ans = all * 3 - tmp - ans;
  printf( "%lld\n" , ans );
}
int main(){
  build();
  //__ = getint();
  while( __ -- ){
    init();
    solve();
  }
}

#include<stdio.h>
#define ll long long
int rd(){
	int k=0;char c=getchar();
	while(c>'9'||c<'0')c=getchar();
	while(c>='0'&&c<='9')k=k*10+c-'0',c=getchar();
	return k;
}
const int N=10000001;
int Max(int x,int y){return x>y?x:y;}
int n,P[670001],s,phi[N],mp[N],c[N];bool p[N];ll ans;
int Q(int l,int r){return r<l?0:c[r]-c[l];}
int main(){
	n=rd(),phi[1]=1,ans=(ll)(n-1)*(n-2)/2;
	for(int i=2;i<=n;++i){
		if(!p[i])++c[i],P[++s]=mp[i]=i,phi[i]=i-1;
		for(int j=1,k;j<=s&&(k=i*P[j])<=n;++j){
			p[k]=1,++c[mp[k]=P[j]];
			if(i%P[j])phi[k]=phi[i]*(P[j]-1);
			else{phi[k]=phi[i]*P[j];break;}
		}
	}
	for(int i=2;i<=n;++i)c[i]+=c[i-1],ans+=phi[i]-1;
	for(int i=1;i<=s;++i)ans+=(ll)(Q(Max(P[i],n/P[i]),Max(p[i],n/2))-2*Q(Max(P[i],n/2),n))*(c[P[i]]-c[P[i]-1]);
	printf("%lld\n",ans);
	return 0;
}

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <ctime>
//#define LOCAL
#define bit(x) x&-x
const int MAXN = 10000000 + 10;
const int INF = 0x7fffffff;
const long long MOD = 1000000007;
using namespace std;
typedef long long ll;

int miu[MAXN], sum[MAXN];
int vis[MAXN], prime[MAXN];
int fw[MAXN], mini[MAXN];

void prepare(){
	 miu[1] = 1;
	 memset(vis, 0, sizeof(vis));
	 memset(mini, 0, sizeof(mini));
	 memset(fw, 0, sizeof(fw));
	 prime[0] = 0;
	 for (int i = 2; i <= 10000000; i++){
		 if (vis[i] == 0) {prime[++prime[0]] = i; miu[i] = -1; mini[i] = i;}
		 for (int j = 1; j <= prime[0]; j++){
			 if (i * prime[j] > 10000000) break;
			 if (i % prime[j] != 0) miu[i * prime[j]] = miu[i] * miu[prime[j]];
			 vis[i * prime[j]] = 1;
			 if (mini[i * prime[j]] == 0) mini[i * prime[j]] = prime[j];
			 else mini[i * prime[j]] = min(mini[i * prime[j]], prime[j]);
			 if (i % prime[j] == 0) break;
		 }
	 }
	 sum[0] = 0;
	 for (int i = 1; i <= 10000000; i++) sum[i] = sum[i - 1] + miu[i];
	 //for (int i = 1; i <= 100; i++) printf("%d:%d\n", i, mini[i]);
	 //for (int i = 1; i <= 100; i++) printf("%d", prime[i]);
}
int gcd(int a, int b){return b == 0 ? a : gcd(b, a % b);}
//get the number of gcd(i, j) = 1 (i <= a, j <= b)
ll get(int a, int b){
	ll Ans = 0ll;
	int last = 1, cnt = 0;
	for (int i = 1; i <= min(a, b); i = last + 1){
		last = min(a / (a / i), b / (b/ i));
		Ans += (ll)((ll)(sum[last] - sum[i - 1]) * (ll)(a / i) * (ll)(b / i));
		//printf("%d %d\n", i, last);
		cnt++;
	}
	//printf("%d\n", cnt);
	return Ans;
}
void Add(int v){
	while (v <= 10000000){
		fw[v]++;
		v += bit(v);
	}
}
int Sum(int v){
	int res = 0;
	while (v > 0){
		res += fw[v];
		v -= bit(v);
	}
	return res;
}

int main() {
	#ifdef LOCAL
	freopen("data.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
	#endif
	//double sta = clock();
	prepare();
	long long n;
	scanf("%lld", &n);
	ll Ans = 0ll, A = 0ll, B = 0ll, C = 0ll;
	//count path 1
	A += (((n * (n - 1ll)) / 2ll) - ((get(n, n) - 1ll) / 2));//gcd(i, j) <> 1

	//count path 1 + 2 + 3
	int count = 1;//
	for (int i = 1; i <= prime[0]; i++){
		if (prime[i] > n) break;
		if (prime[i] * 2ll > n) count++;
	}

	C = (ll)(n - count) * (ll)(n - count - 1ll) / 2ll;
	//count path 1 + 2
	for (int i = n; i >= 2; i--){
		int tmp = (n / mini[i]);
		B += (ll)Sum(tmp);
		Add(mini[i]);
	}
	printf("%lld\n", A + 2ll * (ll)(B - A) + 3ll * (ll)(C - B));
	//printf("%lf", (clock() - sta) / CLOCKS_PER_SEC);
	return 0;
}

#include<bits/stdc++.h>

const int N = 10000010;
typedef long long ll;

int min[N], cnt[N], phi[N];
std::vector <int> prime;

int main(){
    int n;
    scanf("%d", &n);
    phi[1] = 1;
    for (int i = 2; i <= n; ++ i){
        if (!min[i]){
        	min[i] = i;
            phi[i] = i - 1;
            prime.push_back(i);
        }
        for (int j = 0, k, sz = (int) prime.size(); j < sz && i * prime[j] <= n; ++ j){
            min[k = i * prime[j]] = prime[j];
            if (i % prime[j] == 0){
                phi[k] = phi[i] * prime[j];
                break;
            }
        	phi[k] = phi[i] * (prime[j] - 1);
        }
        ++ cnt[min[i]];
    }
    ll cnt0 = 1;
	for (auto u : prime){
    	cnt0 += u << 1 > n;
    }
    cnt0 = cnt0 * (n - cnt0) + cnt0 * (cnt0 - 1) / 2;
    ll cnt1 = 1ll * n * (n - 1) >> 1;
	for (int i = 2; i <= n; ++ i){
		cnt1 -= phi[i];
	}
	ll cnt2 = 0;
    for (int i = 0, sz = prime.size(); i < sz; ++ i){
    	for (int j = 0; j < sz; ++ j){
    		if (prime[i] * prime[j] > n) break;
    		if (prime[i] == prime[j]) continue;
    		cnt2 += 1ll * cnt[prime[i]] * cnt[prime[j]];
    	}
    }
    for (auto u : prime){
    	cnt2 += 1ll * cnt[u] * cnt[u];
    }
    for (int i = 2; i <= n; ++ i){
    	if (1ll * min[i] * min[i] > n){
    		for (int j = i << 1; j <= n; j += i){
    			if (1ll * min[j] * min[i] > n){
    				cnt2 += 2;
    			}
    		}
		}
	}
	cnt2 -= cnt1 << 1;
	cnt2 -= n - 1;
	cnt2 >>= 1;
	ll cnt3 = 1ll * n * (n - 1) / 2 - cnt0 - cnt1 - cnt2;
	return printf("%I64d\n", cnt1 + 2 * cnt2 + 3 * cnt3), 0;
}

#include <bits/stdc++.h>

using namespace std;
#define FOR(i,n) for(int i = 0; i < (n); i++)
#define sz(c) ((int)c.size())
#define ten(n) ((int)1e##n)
using ll = long long;
using Pii = pair<int, int>;
using Pll = pair<ll, ll>;

template<typename ...> static inline int getchar_unlocked(void) { return getchar(); }
template<typename ...> static inline void putchar_unlocked(int c) { putchar(c); }
#define mygc(c) (c)=getchar_unlocked()
#define mypc(c) putchar_unlocked(c)
void reader(int& x) { int k, m = 0; x = 0; for (;;) { mygc(k); if (k == '-') { m = 1; break; }if ('0' <= k&&k <= '9') { x = k - '0'; break; } }for (;;) { mygc(k); if (k<'0' || k>'9')break; x = x * 10 + k - '0'; }if (m) x = -x; }
void reader(ll& x) { int k, m = 0; x = 0; for (;;) { mygc(k); if (k == '-') { m = 1; break; }if ('0' <= k&&k <= '9') { x = k - '0'; break; } }for (;;) { mygc(k); if (k<'0' || k>'9')break; x = x * 10 + k - '0'; }if (m) x = -x; }
int reader(char c[]) { int i, s = 0; for (;;) { mygc(i); if (i != ' '&&i != '\n'&&i != '\r'&&i != '\t'&&i != EOF) break; }c[s++] = i; for (;;) { mygc(i); if (i == ' ' || i == '\n' || i == '\r' || i == '\t' || i == EOF) break; c[s++] = i; }c[s] = '\0'; return s; }
int reader(string& c) { int i; for (;;) { mygc(i); if (i != ' '&&i != '\n'&&i != '\r'&&i != '\t'&&i != EOF) break; }c.push_back(i); for (;;) { mygc(i); if (i == ' ' || i == '\n' || i == '\r' || i == '\t' || i == EOF) break; c.push_back(i); }; return sz(c); }
template <class T, class S> void reader(T& x, S& y) { reader(x); reader(y); }
template <class T, class S, class U> void reader(T& x, S& y, U& z) { reader(x); reader(y); reader(z); }
template <class T, class S, class U, class V> void reader(T& x, S& y, U& z, V & w) { reader(x); reader(y); reader(z); reader(w); }
void writer(int x, char c) { int s = 0, m = 0; char f[10]; if (x<0)m = 1, x = -x; while (x)f[s++] = x % 10, x /= 10; if (!s)f[s++] = 0; if (m)mypc('-'); while (s--)mypc(f[s] + '0'); mypc(c); }
void writer(ll x, char c) { int s = 0, m = 0; char f[20]; if (x<0)m = 1, x = -x; while (x)f[s++] = x % 10, x /= 10; if (!s)f[s++] = 0; if (m)mypc('-'); while (s--)mypc(f[s] + '0'); mypc(c); }
void writer(const char c[]) { int i; for (i = 0; c[i] != '\0'; i++)mypc(c[i]); }
void writer(const string& x, char c) { int i; for (i = 0; x[i] != '\0'; i++)mypc(x[i]); mypc(c); }
void writer(const char x[], char c) { int i; for (i = 0; x[i] != '\0'; i++)mypc(x[i]); mypc(c); }
template<class T> void writerLn(T x) { writer(x, '\n'); }
template<class T, class S> void writerLn(T x, S y) { writer(x, ' '); writer(y, '\n'); }
template<class T, class S, class U> void writerLn(T x, S y, U z) { writer(x, ' '); writer(y, ' '); writer(z, '\n'); }
template<class T> void writerArr(T x[], int n) { if (!n) { mypc('\n'); return; }FOR(i, n - 1)writer(x[i], ' '); writer(x[n - 1], '\n'); }
template<class T> void writerArr(vector<T>& x) { writerArr(x.data(), (int)x.size()); }

template<class T> void chmin(T& a, const T& b) { if (a > b) a = b; }
template<class T> void chmax(T& a, const T& b) { if (a < b) a = b; }

template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }
template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }
ll mod_pow(ll a, ll n, ll mod) {
	ll ret = 1;
	ll p = a % mod;
	while (n) {
		if (n & 1) ret = ret * p % mod;
		p = p * p % mod;
		n >>= 1;
	}
	return ret;
}
template<class T> T extgcd(T a, T b, T& x, T& y) { for (T u = y = 1, v = x = 0; a;) { T q = b / a; swap(x -= q * u, u); swap(y -= q * v, v); swap(b -= q * a, a); } return b; }
template<class T> T mod_inv(T a, T m) { T x, y; extgcd(a, m, x, y); return (m + x % m) % m; }

const int N = ten(7) + 1;
bool prime[N];
vector<int> prs;
void init_prime() {
	memset(prime, 1, sizeof(prime));
	prime[0] = prime[1] = false;
	for (int i = 2; i < sizeof(prime); i++) if (prime[i])
		for (int j = i * 2; j < sizeof(prime); j += i) prime[j] = false;
	for (int i = 2; i < sizeof(prime); i++) if (prime[i]) prs.push_back(i);
}
int factors[N];
void init_factor() {
	for (int i = 2; i < N; i += 2) factors[i] = 2;
	for (int i = 3; i < N; i += 2) factors[i] = i;
	for (int i = 3; i < N; i += 2) if (factors[i] == i)
		for (int j = 3 * i; j < N; j += 2 * i) chmin(factors[j], i);
}

ll cnt1(int n) {
	ll ret = 0;

	static char di[ten(7) + 1];
	memset(di, 0, sizeof(char) * (n+1));
	for (int i = 2; i <= n; i++) {
		int use = 1 - di[i];
		if (use == 0) continue;
		ll val = (n / i) * ll(n / i);
		ret += val * use;
		for (int j = i * 2; j <= n; j += i) {
			di[j] += use;
		}
	}

	int diagonal = n - 1;
	ret = (ret - diagonal) / 2;

	return ret;
}

ll solve(int n) {
	ll a = cnt1(n);

	ll b = 0;
	{
		static ll sm[ten(7) + 10];
		memset(sm, 0, sizeof(ll) * (n + 2));
		for (int i = 2; i <= n; i++) {
			sm[factors[i]]++;
		}
		sm[1] = 1;
		FOR(i, n + 1) sm[i + 1] += sm[i];

		FOR(l, n) {
			if (l <= 1) continue;
			const int rp = n / l;
			if (l >= rp) break;

			ll ccnt = sm[l] - sm[l - 1];
			ll rcnt = sm[rp] - sm[l];

			// printf("l = %d : ok line = (%d, %d]\n", l, l, rp);
			// printf("[%d] = %lld, (%d, %d] = %lld\n", l, ccnt, l, rp, rcnt);

			b += ccnt * rcnt;
		}
		FOR(l, n) {
			if (l <= 1) continue;
			ll ccnt = sm[l] - sm[l - 1];
			ll addd = ccnt * (ccnt - 1) / 2;
			b += addd;
		}

		b -= a;
	}

	ll dall = 0;
	{
		ll pcnt = 0;
		for (int i = n / 2 + 1; i <= n; i++) if (prime[i]) pcnt++;
		pcnt++; // for 1
		dall = (n - pcnt) * (n - pcnt - 1) / 2;
	}

	ll c = dall - a - b;
	// printf("%d : %lld, %lld, %lld\n", n, a, b, c);

	return a + b * 2 + c * 3;
}

ll solve2(int n) {
	n++;
	static int di[1000][1000];
	memset(di,0x1f, sizeof(di));
	FOR(i, n) FOR(j, n) {
		if (i == 0 || j == 0) continue;
		if (gcd(i, j) != 1) {
			di[i][j] = 1;
		}
	}
	FOR(i, n) di[i][i] = 0;
	FOR(k, n) FOR(i, n) FOR(j, n) chmin(di[i][j], di[i][k] + di[k][j]);

	ll ret = 0;
	int ec[4] = {};
	FOR(i, n) for (int j = i + 1; j < n; j++) {
		if (di[i][j] <= 10) {
			ret += di[i][j];
			if (di[i][j] >= 4) {
				cout << "?";
			}
			ec[di[i][j]]++;
			if (di[i][j] == 3) {
				printf("(%d, %d)\n", i, j);
			}
		}
	}
	writerArr(ec, 4);

	return ret;
}

void tst() {
	for (int i = 21; i <= 100; i++) {
		ll cur = solve(i);
		ll c2 = solve2(i);
		if (cur != c2) {
			cout << "?";
		}
		cout << cur << endl;
	}
}

int main() {
	init_prime();
	init_factor();

	// tst();

	int n; reader(n);

	cout << solve(n) << endl;

	return 0;
}

#include<bits/stdc++.h>
#define maxn 10000020

using namespace std;
typedef long long ll;

ll prime[maxn],sum[maxn],p[maxn],a[maxn],miu[maxn],cnt,n,a1,a2,a3,m,t;
bool f[maxn];

int main()
{
    scanf("%d",&n);cnt=0;
    memset(p,0,sizeof(p));
    for (int i=2;i<=n;i++)
    {
        if (!p[i]) prime[cnt++]=p[i]=i;
        for (int j=0;j<cnt;j++)
        {
            if (prime[j]*i>n) break;
            p[i*prime[j]]=prime[j];
            if (i%prime[j]==0) break;
        }
    }
    for (int i=2;i<=n;i++)
    {
        t=i/p[i];
        if (t==1) miu[i]=-1;
        else if (t%p[i]==0) miu[i]=0;
        else miu[i]=miu[p[i]]*miu[t];
    }
    memset(f,true,sizeof(f));
    m=n-1;
    for (int i=n/2+1;i<=n;i++)
        if (p[i]==i) m--,f[i]=false;
    a3=0;a1=0;a2=0;
    for (int i=2;i<=n;i++) if (f[i]) a[p[i]]++; sum[1]=0;
    for (int i=2;i<=n;i++) sum[i]=sum[i-1]+a[i];
    for (int i=0;i<cnt;i++)
    {
        t=max(prime[i],n/prime[i]);
        a3+=(sum[n]-sum[t])*a[prime[i]];
    }
    for (int i=2;i*2<=n;i++)
    {
        t=n/i;
        a1+=miu[i]*t*(t-1)/2;
    }
    printf("%I64d\n",m*(m-1)+a1+a3);
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i, x, y) for(LL i = (x); i <= (y); i ++)
inline LL read() {
	char ch = getchar(); LL x = 0, f = 1;
	while(ch < '0' || ch > '9') {
		if(ch == '-') f = -1;
		ch = getchar();
	} while('0' <= ch && ch <= '9') {
		x = x * 10 + ch - '0';
		ch = getchar();
	} return x * f;
}
LL n, mu[10001000];
LL prime[1000010], tot;
bool vis[10001000];
LL Min[10001000];
LL a[10001000];
inline void init() {
	mu[1] = 1;
	rep(i, 2, n) {
		if(!vis[i]) {
			prime[++ tot] = i;
			mu[i] = -1;
		}
		rep(j, 1, tot) {
			if(i * prime[j] > n) break;
			vis[i * prime[j]] = 1;
			if(i % prime[j] == 0) {
				mu[i * prime[j]] = 0;
				break;
			} mu[i * prime[j]] = -mu[i];
		}
	} rep(i, 1, n) mu[i] += mu[i - 1];
	/*rep(i, 1, n) {
		printf("prime[%d]=%d\n", i, prime[i]);
	}*/
}
inline LL calc_step_1() {
	LL last; LL res = 0;
	for(LL i = 1; i <= n; i = last + 1) {
		last = n / (n / i);
		res += 1ll * (n / i) * (n / i) * (mu[last] - mu[i - 1]);
	} return (1ll * n * (n - 1) - res + 1) / 2;
}
inline LL calc_step_2() {
	memset(vis, 0, sizeof(vis));
	a[1] = 1;
	rep(i, 1, tot) {
		LL k = prime[i];
		for(LL j = k; j <= n; j += k) {
			if(!vis[j]) {
				a[j] = k;
				vis[j] = 1;
			}
		}
	} rep(i, 1, n) Min[a[i]] ++;
	//rep(i, 1, n) printf("a[%d]=%d\n", i, a[i]);
	LL res = 0;
	rep(i, 1, tot) {
		rep(j, 1, tot) {
			if(prime[i] * prime[j] > n) break;
			res += Min[prime[i]] * Min[prime[j]];
			//cout << "res " << res << endl;
		}
	} rep(i, 1, tot) if(prime[i] * prime[i] <= n) res -= Min[prime[i]];
	return res;
}
inline LL calc_step_3() {
	LL res = 0; LL sum = 0;
	rep(i, 1, tot) {
		if(2 * prime[i] > n) break;

		LL Max = prime[i];
		// Max = prime[u]
		res += Min[Max] * sum;
		// Max = prime[v]
		res += Min[Max] * sum;
		res += Min[Max] * (Min[Max] - 1);
		sum += Min[prime[i]];
	} return res;
}
int main() {
	n = read(); init();
	LL A = calc_step_1();
	LL B = calc_step_2(); //cout << B << endl;
	LL C = calc_step_3();
	B = (B / 2 - A);
	C = (C / 2 - A - B);
	//cout << A << endl << B << endl << C << endl;
	cout << A + 2 * B + 3 * C;
	return 0;
}

#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <vector>
#include <bitset>
#include <string>
#include <cstdio>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define mk make_pair
#define pb push_back
#define fi first
#define se second
#define REP(i, x, y) for(int i = (int)x; i <= (int)y; i ++)
#define FOR(i, x, y) for(int i = (int)x; i <  (int)y; i ++)
#define PER(i, x, y) for(int i = (int)x; i >= (int)y; i --)
#define trace(x) cerr << #x << " " << x << endl;
#define dprintf(...) fprintf(stderr, __VA__ARGS__)
#define dln()        fprintf(stderr, "\n")
using namespace std;
typedef long long LL;
typedef long double db;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<PII> VPI;
const	int N = 10000005;
const	int P = 1e9 + 7;
const	int inf = 1e9;
const	LL Inf = 1e15;

inline int IN(){
	char ch = getchar(); int x = 0, f = 0;
	while(ch < '0' || ch > '9') ch = getchar(), f = (ch == '-');
	while(ch >= '0' && ch <= '9'){
		x = (x << 1) + (x << 3) + ch - 48;
		ch = getchar();
	}
	return f ? (-x) : x;
}

inline int Pow(int x, int y, int p){
	int an = 1;
	for(; y; y >>= 1, x = (LL)x * x % p) if(y & 1) an = (LL)an * x % p;
	return an;
}

void renew(int &x, int y){
	x += y;
	if(x < 0) x += P;
	else if(x >= P) x -= P;
}

void setIO(string a){
#ifndef LOCAL
	freopen((a + ".in").c_str(), "r", stdin);
	freopen((a + ".out").c_str(), "w", stdout);
#else
	freopen("1.in", "r", stdin);
	freopen("1.out", "w", stdout);
#endif
}

template<typename T> inline void chkmin(T &a, const T &b) {if(a > b) a = b;}
template<typename T> inline void chkmax(T &a, const T &b) {if(a < b) a = b;}

int n;
int d[105][105];
int mu[N],minp[N],pr[N/10],tot;
bool vis[N];
int sum[N];
LL ans;

int ask(int l,int r){
	if(l>r)return 0;
	return sum[r]-sum[l-1];
}

int gcd(int x,int y){
	if(!y) return x;
	return gcd(y,x%y);
}

int main(){
#ifdef LOCAL
//	freopen("1.in", "r", stdin);
//	freopen("1.out", "w", stdout);
#endif

	scanf("%d",&n);

	if(n<=100){
		REP(i,1,n) REP(j,1,n) if(gcd(i,j)>1) d[i][j]=1; else d[i][j]=1<<25;
		REP(i,1,n) d[i][i]=0;
		REP(k,1,n) REP(i,1,n) REP(j,1,n) if(d[i][j]>d[i][k]+d[k][j]) d[i][j]=d[i][k]+d[k][j];
		LL ans=0;
		REP(i,1,n) FOR(j,1,i) if(d[i][j]<1e7) ans+=d[i][j];
		cout<<ans<<endl;
		return 0;
	}

	mu[1]=1;
	REP(i,2,n){
		if(!vis[i]){
			mu[pr[++tot]=i]=-1;
			minp[i]=i;
		}
		for(int k=1;k<=tot&&1LL*i*pr[k]<=n;k++){
			vis[i*pr[k]]=1;
			minp[i*pr[k]]=pr[k];
			if(i%pr[k]==0){
				mu[i*pr[k]]=0;
				break;
			}else{
				mu[i*pr[k]]=-mu[i];
			}
		}
	}

	memset(sum,0,sizeof sum);
	REP(p,2,n/2) sum[p]=sum[p-1]+(1-vis[p]);
	REP(p,n/2+1,n) sum[p]=sum[p-1];

	REP(p,2,n/2) if(!vis[p]){
		ans+=2LL*ask(p+1,n/p);
		ans+=3LL*ask(max(p+1,n/p+1),n/2);
	}

	memset(sum,0,sizeof sum);
	REP(p,2,n) if(vis[p]) sum[minp[p]]++;
	REP(p,2,n) sum[p]=sum[p-1]+sum[p];

	REP(p,2,n/2) if(!vis[p]){
		int A=n/p-1,B=sum[n/p];
		for(int j=p+p;j<=n;j+=p) if(minp[j]<=n/p) B--;
		int C=sum[n]-A-B;
		ans+=A;
		ans+=2LL*B;
		ans+=3LL*C;
	}

	memset(sum,0,sizeof sum);
	REP(i,1,n) sum[i]=sum[i-1]+vis[i];
	LL res=0;
	REP(d,1,n) if(mu[d]){
		int ff=0;
		if(d==1) ff=sum[n]; else ff=n/d-(1-vis[d]);
		res+=1LL*mu[d]*ff*(ff-1)/2;
	}

	LL d1=(LL)sum[n]*(sum[n]-1)/2-res;

	ans+=d1+2*res;

	printf("%lld\n",ans);

	return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define N 10001000

int runs, p[N>>3], phi[N], mu[N], f[N];

void ppm(int n) {
	phi[1] = 1, mu[1] = 1;
	for (int i = 2; i <= n; i ++) {
		if (!phi[i]) p[++runs] = i, phi[i] = i - 1, mu[i] = -1, f[runs] = 1;
		for (int j = 1; j <= runs && i * p[j] <= n; j ++) {
			int k = i * p[j];
			f[j] ++;
			phi[k] = phi[i] * (p[j] - 1);
			if (i % p[j] == 0) {
				phi[k] = phi[i] * p[j]; break;
			}
			mu[k] = -mu[i];
		}
	}
}

int n;
long long g[N];

long long calc(int n) {
	g[1] = 1;
	for (int i = 2; i <= n; i ++) g[i] = g[i-1] + 2 * phi[i];
	return g[n];
}

int main() {
	scanf("%d", &n);
	ppm(n);
	long long m = calc(n);
	m = (m - 1) / 2;
	long long ans = 1ll * n * (n - 1) / 2 - m;
	m -= n - 1;
	int cnt = 0;
	for (int i = 1; i <= runs; i ++) if (p[i] * 2 > n && p[i] <= n) cnt ++;
	m -= 1ll * cnt * (n - 2) - 1ll * cnt * (cnt - 1) / 2;
	ans += 2 * m;
	while (runs && p[runs] * 2 > n) runs --;
	if (runs) {
		long long sum1 = 0, sum2 = 0;
		for (int i = 1; i <= runs; i ++) sum1 += f[i], sum2 += 1ll * f[i] * f[i];
		long long tmp = (sum1 * sum1 - sum2) / 2;
		for (int i = 1; i <= runs; i ++) {
			for (int j = 1; j < i && 1ll * p[i] * p[j] <= n; j ++) tmp -= 1ll * f[i] * f[j];
		}
		ans += tmp;
	}
	printf("%I64d\n", ans);

	return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define fst first
#define snd second
typedef long long ll;
typedef pair<int, int> pii;
#define pb push_back
const ll modn = 1000000007;
inline ll mod(ll x) { return x % modn; }
#ifdef ONLINE_JUDGE
#	define debug(args...) {}
#else
#	define debug(args...) fprintf(stderr, args)
#endif

int n;

const int N = 10000009;

int phi[N], pr[N], dv[N];

ll c2(ll n) {
	return (n * (n - 1ll)) / 2ll;
}

int main() {
	int i, j;
	for(i = 2; i < N; i++) phi[i] = i;
	for(i = 2; i < N; i++) {
		if(dv[i]) continue;
		pr[i] = 1;
		for(j = i; j < N; j += i) {
			phi[j] = int(phi[j] / i) * (i - 1);
			if(!dv[j]) dv[j] = i;
		}
	}
	scanf("%d", &n);
	for(i = n - 1; i >= 0; i--)
		pr[i] += pr[i + 1];
	ll pnc = 0;
	for(i = 2; i <= n; i++)
		pnc += ll(i - phi[i] - 1);
	ll tot = pnc + (c2(n - 1) - pnc) * 2ll;
	//printf("pnc %lld (c2 - pnc) %lld init tot %lld\n", pnc, c2(n - 1), tot);
	for(i = 2; i <= n; i++) {
		ll p = dv[i];
		int mn = max<int>(p + 1, (n / p) + 1);
		if(mn > n) continue;
		tot -= 2ll * pr[mn];
		int mn2 = n / 2;
		if(mn2 >= mn) tot += 3ll * (pr[mn] - pr[mn2 + 1]);
		//printf("at [%d] tot -= 2 * (pr[%d] = %d)\n", i, mn, pr[mn]);
		//printf("at [%d] tot += 3 * (pr[%d]  - (pr[%d] = %d))\n", i, mn, mn2 + 1, pr[mn2 + 1]);
	}
	printf("%lld\n", tot);
}

#include<bits/stdc++.h>

using namespace std;

class BIT{
public:
	int size;
	vector<long long> arr;
	BIT(int n){
		size=n+5;
		arr.resize(size);
	}
	void add(int i,long long v){
		for(int x=i+1;x<size;x+=(x&(-x))) arr[x]+=v;
	}
	long long sum(int i){
		i=min(i,size-2);
		long long res=0;
		for(int x=i+1;x>0;x-=(x&(-x))) res+=arr[x];
		return res;
	}
};
int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int n;
	cin >> n;
	vector<int> msoin(n+1),prod(n+1,1),par(n+1);
	BIT bit(n+1);
	long long e=n-1;
	for(int i=2;i<=n;i++){
		if(msoin[i]) continue;
		if(i*2>n) e--;
		for(int j=1;j*i<=n;j++){
			if(msoin[i*j]==0){
				msoin[i*j]=i;
				if(i<=n/2) bit.add(i,1);
			}
			prod[i*j]*=i;
			par[i*j]++;
		}
	}
	e=e*(e-1)/2;
	long long res=0;
	//1
	for(int i=2;i<=n;i++){
		if(prod[i]!=i) continue;
		long long co=n/i;
		long long v=co*(co-1)/2;
		if(par[i] & 1) res+=v;
		else res-=v;
	}
	e-=res;
	//3 px 2p 2q qy (pq>n)
	long long v=0;
	for(int i=2;i<=n/2;i++){
		if(msoin[i]!=i) continue;
		long long le=bit.sum(i)-bit.sum(i-1);
		long long ri=bit.sum(n)-bit.sum(n/i);
		if(i>(n/i)) ri-=le;
		v+=le*ri;
	}
	v/=2;
	e-=v;
	res+=v*3;
	//2 px pq qy;
	res+=e*2;
	cout << res << "\n";
	return 0;
}

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <iostream>
using namespace std;

typedef long long int64;

const int INF = 0x3f3f3f3f;
const int MAXN = 1e7 + 10;

bool isnt_prime[MAXN];
int64 prime[MAXN], phi[MAXN];
int64 mfac_cnt[MAXN], mfac_sum[MAXN];

#define sum(l, r) (((r) < (l)) ? 0 : (mfac_sum[(r)] - mfac_sum[(l) - 1]))

int main() {
    int64 n;
    cin >> n;
    isnt_prime[1] = true;
    phi[1] = 1;
    int prime_cnt = 0;
    for (int i = 2; i <= n; i++) {
        if (!isnt_prime[i]) {
            prime[prime_cnt++] = i;
            mfac_cnt[i]++;
            phi[i] = i - 1;
        }
        for (int j = 0; j < prime_cnt; j++) {
            if (i * prime[j] > n) break;
            isnt_prime[i * prime[j]] = true;
            mfac_cnt[prime[j]]++;
            if (i % prime[j] == 0) {
                phi[i * prime[j]] = phi[i] * prime[j];
                break;
            } else {
                phi[i * prime[j]] = phi[i] * (prime[j] - 1);
            }
        }
    }
    for (int i = 1; i <= n; i++) {
        mfac_sum[i] = mfac_sum[i - 1] + mfac_cnt[i];
    }
    int64 path2 = 0;
    for (int i = 1; i <= n; i++) {
        path2 += phi[i] - 1;
        // clog << phi[i] << endl;
    }
    int64 path1 = (n - 1) * (n - 2) / 2 - path2;
    // 先假设都是长度为2的路径, 待会统计的时候再调整
    int64 ans = path2 * 2 + path1;
    for (int i = 0; i < prime_cnt; i++) {
        // 长度为3的路径, fa < n / 2
        ans += mfac_cnt[prime[i]] *
               sum(max(prime[i] + 1, n / prime[i] + 1), max(prime[i], n / 2));
        // 不存在的路径, fa > n / 2
        ans -= 2 * mfac_cnt[prime[i]] * sum(max(prime[i], n / 2) + 1, n);
    }
    cout << ans << endl;
    return 0;
}

#include<cstdio>
#include<cstring>
#include<iostream>
#include<stdlib.h>
#include<ctime>
#include<string>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<bitset>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define LL long long
#define FOR(i,a,b) for (int i=a;i<=b;++i)
#define FORD(i,a,b) for (int i=a;i>=b;--i)
using namespace std;
typedef pair<int,int> pa;
typedef long double ld;
void getint(LL &v){
    char ch,fu=0;
    for(ch='*'; (ch<'0'||ch>'9')&&ch!='-'; ch=getchar());
    if(ch=='-') fu=1, ch=getchar();
    for(v=0; ch>='0'&&ch<='9'; ch=getchar()) v=v*10+ch-'0';
    if(fu) v=-v;
}
bool u[10000010];
LL c0,c1,C[10000010],c2,c3,tot,f[10000010],ans,good,bad;
int t,n,ts,phi[10000010],tmp[10000010],q[10000010],cnt[10000010],p[10000010],pr,l,r;
void getp(){
	phi[1]=1;
	q[1]=n+1;
	FOR(i,2,n){
		if (!u[i]){p[++pr]=i;q[i]=i;phi[i]=i-1;}
		FOR(j,1,pr){
			if (i*p[j]>n) break;
			u[i*p[j]]=1;
			q[i*p[j]]=p[j];
			if (i%p[j]==0){phi[i*p[j]]=phi[i]*p[j];break;}
			else phi[i*p[j]]=phi[i]*phi[p[j]];
		}
	}
}
int main(){
	cin>>n;
	tot=(LL)n*(n+1)/2;
	getp();
	c0=n;
	FOR(i,1,n)
		if (i==1 || i*2>n && !u[i]) ++bad;
	good=n-bad;
	tot-=good*bad+bad*(bad-1)/2;
	tot-=c0;
	FOR(i,2,n) c1+=i-1-phi[i];
	tot-=c1;
	FOR(i,1,n) C[i]=(LL)i*(i-1)/2;
	//c2 q[i]*q[j]<=n && gcd(i,j)==1
	FORD(i,n/2,1){
		tmp[ts=1]=q[i];
		for (int j=i+i;j<=n;j+=i) tmp[++ts]=q[j],f[i]-=f[j];
		if (ts>1000000){
			FOR(j,1,ts) ++cnt[tmp[j]];
			ts=0;
			FOR(j,1,pr)
				while (cnt[p[j]]) tmp[++ts]=p[j],--cnt[p[j]];
		}
		else{
			sort(tmp+1,tmp+ts+1);
		}
		l=0;
		for (r=ts;l<r-1;--r){
			t=n/tmp[r];
			while (l+1<r && tmp[l+1]<=t) ++l;
			f[i]+=l;
		}
		f[i]+=C[r];
	}
	c2=f[1];
	tot-=c2;
	c3=tot;
	cout<<c1+c2*2+c3*3<<endl;
	return 0;
}

#include<bits/stdc++.h>
#define sqr(x) ((x)*(x))
#define ll long long
#define ull unsigned long long
#define ui unsigned int
#define ld long double
#define vi vector<int>
#define HEAP(...) priority_queue<__VA_ARGS__ >
#define heap(...) priority_queue<__VA_ARGS__,vector<__VA_ARGS__ >,greater<__VA_ARGS__ > >
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define debuge cerr<<"isok"<<endl
#define debug(x) cerr<<#x<<"="<<x<<endl
#define dprintf(...) fprintf(stderr,__VA_ARGS__)
#define SS second
#define FF first
#define ls (k<<1)
#define rs (k<<1|1)
#define clr(a,x) memset(a,x,sizeof(a))
#define cpy(a,x) memcpy(a,x,sizeof(a))
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout)
#define SZ(x) ((int)x.size())
using namespace std;
template<class T> inline void gmin(T &x,const T &y){if(x>y) x=y;}
template<class T> inline void gmax(T &x,const T &y){if(x<y) x=y;}
const int BufferSize=1<<16;
char buffer[BufferSize],*Bufferhead,*Buffertail;
bool Terminal;
inline char Getchar(){
	if(Bufferhead==Buffertail){
		int l=fread(buffer,1,BufferSize,stdin);
		if(!l){Terminal=1;return 0;}
		Buffertail=(Bufferhead=buffer)+l;
	}
	return *Bufferhead++;
}
template<class T>inline bool read(T &x){
	x=0;char c=Getchar(),rev=0;
	while(c<'0'||c>'9'){rev|=c=='-';c=Getchar();if(Terminal)return 0;}
	while(c>='0'&&c<='9') x=x*10+c-'0',c=Getchar();
	if(c=='.'){
		c=Getchar();double t=0.1;
		while(c>='0'&&c<='9') x=x+(c-'0')*t,c=Getchar(),t=t/10;
	}
	x=rev?-x:x;
	return 1;
}
template<class T1,class T2> inline bool read(T1 &x,T2 &y){return read(x)&read(y);}
template<class T1,class T2,class T3> inline bool read(T1 &x,T2 &y,T3 &z){return read(x)&read(y)&read(z);}
template<class T1,class T2,class T3,class T4> inline bool read(T1 &x,T2 &y,T3 &z,T4 &w){return read(x)&read(y)&read(z)&read(w);}
inline bool reads(char *x){
	char c=Getchar();
	while(c<33||c>126){c=Getchar();if(Terminal)return 0;}
	while(c>=33&&c<=126) (*x++)=c,c=Getchar();
	*x=0;return 1;
}
template<class T>inline void print(T x,const char c='\n'){
	if(!x){putchar('0');putchar(c);return;}
	if(x<0) putchar('-'),x=-x;
	int m=0,a[20];
	while(x) a[m++]=x%10,x/=10;
	while(m--) putchar(a[m]+'0');
	putchar(c);
}
//--------------------------------head---------------------------------------------

const int inf=0x3f3f3f3f;
const int N=10000005,M=100005,mod=1e9+7;
template<class T,class S> inline void ch(T &x,const S y){x=(x+y)%mod;}
inline int exp(int x,int y,const int mod=::mod){
	int ans=1;
	while(y){
		if(y&1) ans=(ll)ans*x%mod;
		x=(ll)x*x%mod;y>>=1;
	}return ans;
}

int n,m,p[N],c[N],phi[N],sum[N];
bool vis[N];

int main(){
#ifdef rqgao2014
	freopen("input.txt","r",stdin);
#endif
	scanf("%d",&n);

/*	ll res=0;
	for(int i=1;i<=n;i++)
		for(int j=i+1;j<=n;j++){

		}*/
	if(n==1){puts("0");return 0;}
	for(int i=2;i<=n;i++){
		if(!vis[i]){p[++m]=i;phi[i]=i-1,c[m]++;}
		for(int j=1;j<=m&&p[j]*i<=n;j++){
			vis[p[j]*i]=1;c[j]++;
			if(i%p[j]==0){phi[i*p[j]]=phi[i]*p[j];break;}
			phi[i*p[j]]=phi[i]*(p[j]-1);
		}
	}
	ll ans=(ll)(n-1)*(n-1)*3;
	for(int i=1;i<=m;i++)
		sum[i]=sum[i-1]+c[i];
//	debug(sum[m]);
	for(int i=m,j=0;i;i--){
		while(j<m&&(ll)p[j+1]*p[i]<=n) j++;
		ans-=(ll)c[i]*sum[j];
		if((ll)p[i]*p[i]>n) ans-=(ll)c[i]*c[i];
	}
	ll ss=1;
	for(int i=2;i<=n;i++)
		ss+=phi[i];
	ss=ss*2-1;
	ans-=(ll)n*n-ss;
	int cnt=0;
	for(int i=1;i<=m;i++)
		if(p[i]*2>n) cnt++;
	ans-=3ll*((ll)cnt*(n-2)*2-(ll)cnt*(cnt-1));

	for(int i=2;i<=n;i++) ans--;
	debug(ans);
	cout<<ans/2<<endl;
	return 0;
}

#include <bits/stdc++.h>

#define inf 0x3f3f3f3f

#define MOD 1000000007

#define pb push_back

#define sq(x) ((x)*(x))

#define x first

#define y second

#define eps 1e-9

#define bpt(x) (__builtin_popcount(x))

#define bptl(x) (__builtin_popcountll(x))

#define bit(x, y) (((x)>>(y))&1)

#define bclz(x) (__builtin_clz(x))

#define bclzl(x) (__builtin_clzll(x))

#define bctz(x) (__builtin_ctz(x))

#define bctzl(x) (__builtin_ctzll(x))

#define sgn(x) (((x)>eps)-((x)<-eps))

#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;

typedef long long INT;

typedef vector<int> VI;

typedef pair<int, int> pii;

typedef pair<pii, int> pi3;

typedef double DO;

template<typename T, typename U> inline void smin(T &a, U b) {if (a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, U b) {if (a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}

template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}

template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}

template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}

template<class T>inline void printsp(T x) {print(x); putchar(' ');}

template<class T>inline void println(T x) {print(x); putchar('\n');}

template<class T, class U>inline void print(T x, U y) {printsp(x); println(y);}

template<class T, class U, class V>inline void print(T x, U y, V z) {printsp(x); printsp(y); println(z);}

int power(int a, int b, int m, int ans=1) {

	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;

	return ans;

}

#define NN 10000100

int flag[NN], prime[NN/10], np, phi[NN];

int val[NN], cnt[NN];

int main() {

#ifndef ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	int n;

	gn(n);

	val[1]=1; phi[1]=1; int m=0;

	INT sum=0, sum3=0;

	for (int i=2; i<=n; i++) {

		if (!flag[i]) prime[np++]=i, flag[i]=i;

		for (int j=0; j<np && prime[j]*i<=n; j++) {

			flag[prime[j]*i]=prime[j];

			if (flag[i]==prime[j]) break;

		}

		int v=i/flag[i]; val[i]=val[v];

		if (flag[i]!=flag[v]) val[i]*=flag[i];

		if (flag[i]==flag[v]) phi[i]=phi[v]*flag[i];

		else phi[i]=phi[v]*(flag[i]-1);

		if (flag[i]*2>n) continue;

		cnt[flag[i]]++; m++;

		sum+=i-phi[i]-1;

	}

	for (int i=n; i; i--) cnt[i]+=cnt[i+1];

	for (int i=1; i<np; i++) sum3+=(INT)cnt[max(prime[i]+1, n/prime[i]+1)]*(cnt[prime[i]]-cnt[prime[i]+1]);

	println((INT)m*(m-1)+sum3-sum);

	return 0;

}

#include <bits/stdc++.h>
#pragma GCC optimize ("O2")
#pragma GCC optimize ("unroll-loops")
//#pragma GCC optimize("no-stack-protector,fast-math")

using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef pair<ll, ll> pll;
#define debug(x) cerr<<#x<<'='<<(x)<<endl;
#define debugp(x) cerr<<#x<<"= {"<<(x.first)<<", "<<(x.second)<<"}"<<endl;
#define debug2(x, y) cerr<<"{"<<#x<<", "<<#y<<"} = {"<<(x)<<", "<<(y)<<"}"<<endl;
#define debugv(v) cerr<<#v<<" : ";for (auto x:v) cerr<<x<<' ';cerr<<endl;
#define all(x) x.begin(), x.end()
#define pb push_back
#define kill(x) return cout<<x<<'\n', 0;

const ld eps=1e-7;
const int inf=1000000010;
const ll INF=10000000000000010LL;
const int mod = 1000000007;
const int MAXN = 10000010, LOG=20;

ll n, m, k, u, v, x, y, t, c1, c2, c3, ans;
int sieve[MAXN];
int phi[MAXN];
int ps[MAXN];

int main(){
	ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	sieve[1]=phi[1]=1;
	for (int i=2; i<MAXN; i++) if (!sieve[i]) for (int j=i; j<MAXN; j+=i) if (!sieve[j]) sieve[j]=i;
	for (int i=2; i<MAXN; i++){
		int p=sieve[i], tmp=i/p;
		if (tmp%p) phi[i]=(p-1)*phi[tmp];
		else phi[i]=p*phi[tmp];
	}
	cin>>n;
	for (int i=2; i<=n; i++){
		c1+=i-phi[i]-1;
		if (sieve[i]==i && 2*i>n) t++;
	}
	t=n-t-1;
	c3=t*(t-1)/2;

	for (int i=2; i<=n; i++) ps[sieve[i]]++;
	for (int i=2; i<=n; i++) ps[i]+=ps[i-1];
	for (int i=2; i<=n; i++) c2+=ps[n/sieve[i]];
	for (int i=2; i<=n; i++) if (1ll*sieve[i]*sieve[i]<=n) c2--;
	c2/=2;
	//debug(c2)
	c2-=c1;
	c3-=c1+c2;
	//debug2(c1, c2)
	//debug(c3)
	cout<<c1+2*c2+3*c3<<'\n';

	return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i, x, y) for(int i = (x); i <= (y); i ++)
inline int read() {
	char ch = getchar(); int x = 0, f = 1;
	while(ch < '0' || ch > '9') {
		if(ch == '-') f = -1;
		ch = getchar();
	} while('0' <= ch && ch <= '9') {
		x = x * 10 + ch - '0';
		ch = getchar();
	} return x * f;
}
int n, mu[10001000];
int prime[1000010], tot;
bool vis[10001000];
LL Min[10001000];
int a[10001000];
inline void init() {
	mu[1] = 1;
	rep(i, 2, n) {
		if(!vis[i]) {
			prime[++ tot] = i;
			mu[i] = -1;
		}
		rep(j, 1, tot) {
			if(i * prime[j] > n) break;
			vis[i * prime[j]] = 1;
			if(i % prime[j] == 0) {
				mu[i * prime[j]] = 0;
				break;
			} mu[i * prime[j]] = -mu[i];
		}
	} rep(i, 1, n) mu[i] += mu[i - 1];
	/*rep(i, 1, n) {
		printf("prime[%d]=%d\n", i, prime[i]);
	}*/
}
inline LL calc_step_1() {
	int last; LL res = 0;
	for(int i = 1; i <= n; i = last + 1) {
		last = n / (n / i);
		res += 1ll * (n / i) * (n / i) * (mu[last] - mu[i - 1]);
	} return (1ll * n * (n - 1) - res + 1) / 2;
}
inline LL calc_step_2() {
	memset(vis, 0, sizeof(vis));
	a[1] = 1;
	rep(i, 1, tot) {
		int k = prime[i];
		for(int j = k; j <= n; j += k) {
			if(!vis[j]) {
				a[j] = k;
				vis[j] = 1;
			}
		}
	} rep(i, 1, n) Min[a[i]] ++;
	//rep(i, 1, n) printf("a[%d]=%d\n", i, a[i]);
	LL res = 0;
	rep(i, 1, tot) {
		rep(j, 1, tot) {
			if(prime[i] * prime[j] > n) break;
			res += Min[prime[i]] * Min[prime[j]];
			//cout << "res " << res << endl;
		}
	} rep(i, 1, tot) if(prime[i] * prime[i] <= n) res -= Min[prime[i]];
	return res;
}
inline LL calc_step_3() {
	LL res = 0; LL sum = 0;
	rep(i, 1, tot) {
		if(2 * prime[i] > n) break;

		LL Max = prime[i];
		// Max = prime[u]
		res += Min[Max] * sum;
		// Max = prime[v]
		res += Min[Max] * sum;
		res += Min[Max] * (Min[Max] - 1);
		sum += Min[prime[i]];
	} return res;
}
int main() {
	n = read(); init();
	LL A = calc_step_1();
	LL B = calc_step_2(); //cout << B << endl;
	LL C = calc_step_3();
	B = (B / 2 - A);
	C = (C / 2 - A - B);
	//cout << A << endl << B << endl << C << endl;
	cout << A + 2 * B + 3 * C;
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define rep(i,l,r) for(int i=(l);i<(r);++i)
#define per(i,l,r) for(int i=(r)-1;i>=(l);--i)
#define dd(x) cout << #x << " = " << x << ", "
#define de(x) cout << #x << " = " << x << endl
const int N = 1e7 + 6;
int n;

int pri[N], ntp[N], low[N], phi[N], pn;
void getpri() {
	phi[1] = 1; ntp[1] = 1; low[1] = 1;
	rep(i, 2, N) {
		if (!ntp[i]) pri[pn++] = i, phi[i] = i - 1, low[i] = i;
		for (int j = 0, o; j < pn && (o = pri[j] * i) < N; j++) {
			ntp[o] = 1;
			low[o] = pri[j];
			if (i % pri[j]) phi[o] = (pri[j] - 1) * phi[i];
			else { phi[o] = pri[j] * phi[i]; break; }

		}
	}
}

int gao_tp1() {
	int ret = 0, tmp = 1;
	rep(i, 2, n + 1) {
		if (!ntp[i]) { tmp++; ret += (n / i) - 1; }
		else ret += phi[i] - tmp;
	}
	return ret;
}

int cnt[N];
int gao_tp2() {
	int ret = 0, tmp = 0, _tmp = n;
	rep(i, 2, n + 1) if (ntp[i] || i * 2 <= n) cnt[low[i]]++, tmp++;
	rep(i, 2, n + 1) {
		while (i * _tmp > n) tmp -= cnt[_tmp--];
		if (!ntp[i]) {
	//		dd(i); dd(tmp); de(_tmp);
			ret += tmp;
			for (int j = i; j <= n; j += i) if (1ll * low[j] * i <= n) ret--;
		}
	}
	return ret;
}

int gao_tp3() {
	int ret = 0, tmp = 0, _tmp = n;
	rep(i, 2, n + 1) if (!ntp[i]) tmp++;
	rep(i, 2, n + 1) {
		if (!ntp[i]) tmp--;
		while (_tmp > i && i * _tmp > n) tmp -= !ntp[_tmp--];
		if (_tmp == i) return ret;
		if (!ntp[i]) ret += tmp;
	}
	return ret;
}

int main() {
	getpri();
	scanf("%d", &n);
	ll ans = 0; int bad = 1;
	rep(i, 2, n + 1) {
		if (!ntp[i] && i * 2 > n) { bad++; continue; }
		ans += i - 1 - phi[i] + (phi[i] - bad) * 3;
	}
//	int cut = 0;
//	rep(i, 2, n + 1) rep(j, i + 1, n + 1) if (__gcd(i, j) == 1 && low[i] * low[j] <= n) cut++;

	ll tp1 = gao_tp1(); //de(tp1);
	ll tp2 = gao_tp2(); //de(tp2);
	ll tp3 = gao_tp3(); //de(tp3);
//	assert(cut == tp1 + tp2 - tp3);
	printf("%lld", ans - (tp1 + tp2 - tp3));

	return 0;
}

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fbo find_by_order
#define ook order_of_key

typedef long long ll;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef long double ld;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;
typedef set<int>::iterator sit;
typedef map<int,int>::iterator mit;
typedef vector<int>::iterator vit;

std::vector <int> prime;
const int MAXN = 10000011;
bool is_composite[MAXN];
int phi[MAXN];
int smallestpf[MAXN];
int mobius[MAXN];
int pi[MAXN];
int cnt[MAXN];

void sieve (int n) {
	memset(is_composite, 0, sizeof(is_composite));
	mobius[1] = 1;
	for (int i = 2; i < n; ++i)
	{
		if (!is_composite[i]) {
			prime.push_back (i);
			smallestpf[i] = i;
			phi[i] = i - 1;					//i is prime
			mobius[i] = -1;
		}
		for (int j = 0; j < prime.size (); ++j) {
			if(ll(i)*prime[j]>n) break;
			is_composite[i * prime[j]] = true;
			smallestpf[i*prime[j]] = min(smallestpf[i], prime[j]);
			if (i % prime[j] == 0) {
				phi[i * prime[j]] = phi[i] * prime[j];	//prime[j] divides i
				mobius[i*prime[j]] = 0;
				break;
			} else {
				phi[i * prime[j]] = phi[i] * phi[prime[j]];	//prime[j] does not divide i
				mobius[i*prime[j]] = mobius[i]*mobius[prime[j]];
			}
		}
	}
}

ll n;

int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);
	smallestpf[1] = 1;
	cin>>n;
	sieve(n+10);
	ll base = 0;
	for(int v = 2; v <= n; v++)
	{
		base += v - 1 - phi[v];
	}
	for(int v=2;v<=n;v++)
	{
		cnt[smallestpf[v]]++;
	}
	ll res2 = 0;
	for(int v = 0; v < prime.size(); v++)
	{
		ll p = prime[v];
		for(int k = v; (k < prime.size()&&(p*prime[k]<=n)); k++)
		{
			ll q = prime[k];
			if(p==q) res2+=(cnt[p]*(cnt[p]-1))/2;
			else res2 += cnt[p]*cnt[q];
		}
	}
	ll cntp=0;
	for(int i=0;i<prime.size();i++)
	{
		if(prime[i]<=n&&prime[i]*2>n)
		{
			cntp++;
		}
	}
	ll cntrem = 0;
	cntrem += cntp*(n-2) - (cntp*(cntp-1))/2;
	cntrem = ((n-1)*(n-2))/2 - cntrem;
	ll res3 = cntrem - res2;
	ll ans = -base;
	ans += res2*2LL;
	ans += res3*3LL;
	cout<<ans<<'\n';
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 1e+7 + 10;

bool isnotp[maxn];short int u[maxn];
ll p[664539],pn;
ll cnt[664539],sum[664539];
ll n,ans;

void pre()
{
	int i,j;

	for(i=2;i<=n;i++)
	{
		if(!isnotp[i])
		{
			p[pn]=i;
			u[i]=cnt[pn++]=1;
		}
		for(j=0;j<pn && i*p[j]<=n;j++)
		{
			isnotp[i*p[j]]=true;
			u[i*p[j]]=-u[i];
			cnt[j]++;
			if(!(i%p[j]))
			{
				u[i*p[j]]=0;
				break;
			}
		}
	}cerr<<pn;

	sum[0]=cnt[0];
	for(i=1;i<pn;i++) sum[i]=sum[i-1]+cnt[i];
}

void solve()
{
	ll i,j,pos,tsum;

	ans=0;

	for(i=0;i<pn;i++)
	{
		ans+=cnt[i]*(cnt[i]-1);
		for(j=i+1;p[j]*p[i]<=n;j++) ans+=cnt[i]*cnt[j]*2;
	}//cerr<<ans<<endl;

	for(pos=0;p[pos]<=n/2;pos++);j=--pos;
	for(i=1;p[i]<=n/2;i++)
	{
		for(;p[j]*p[i]>n;j--);
		ans+=cnt[i]*(sum[pos]-sum[max(j,i)])*3;
	}

	for(i=2;i<=n;i++) if(u[i])
	{
		ans-=u[i]*(n/i)*(n/i-1)/2;
	}

	cout<<ans<<endl;
}

int main()
{
//	freopen("2368.in","r",stdin);
//	freopen("2368.out","w",stdout);

	cin>>n;
	pre();
	solve();

	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=10000007;
int phi[N],p[N],mi[N],c[N],v[N],tot,n;
long long ans;
int rd()
{
    char c=getchar();int s=0,f=1;
    while(c>'9'||c<'0'){if(c=='-')f=-f;c=getchar();}
    while(c>='0'&&c<='9') s=(s<<1)+(s<<3)+(c^48),c=getchar();
    return s*f;
}
void prepare()
{
    phi[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(!v[i]){p[++tot]=i,mi[i]=i,phi[i]=i-1;}
        for(int j=1;j<=tot;j++)
        {
            if(p[j]*i>n) break;v[i*p[j]]=1;mi[i*p[j]]=p[j];
            if(i%p[j]==0){phi[i*p[j]]=phi[i]*p[j];break;}
            else phi[i*p[j]]=phi[i]*(p[j]-1);
        }
        phi[i]+=phi[i-1];
    }
    for(int i=1;i<=n;i++) c[mi[i]]++;
    for(int i=1;i<=n;i++) c[i]+=c[i-1];
}
int get(int l,int r)
{
    if(r<l) return 0;
    return c[r]-c[l-1];
}
int main()
{
    n=rd();prepare();
    ans=1ll*(n-1)*(n-2)/2+phi[n]-n;
    for(int i=1;i<=tot;i++)
    {
        int cnt=c[p[i]]-c[p[i]-1];
        ans+=1ll*get(max(p[i]+1,n/p[i]+1),max(p[i]+1,n/2+1)-1)*cnt;
        ans-=2ll*get(max(p[i]+1,(n>>1)+1),n)*cnt;
    }
    printf("%lld\n",ans);
    return 0;
}

#define ONLINE_JUDGE
#include <bits/stdc++.h>

#define inf 0x3f3f3f3f

#define MOD 1000000007

#define pb push_back

#define sq(x) ((x)*(x))

#define x first

#define y second

#define eps 1e-9

#define bpt(x) (__builtin_popcount(x))

#define bptl(x) (__builtin_popcountll(x))

#define bit(x, y) (((x)>>(y))&1)

#define bclz(x) (__builtin_clz(x))

#define bclzl(x) (__builtin_clzll(x))

#define bctz(x) (__builtin_ctz(x))

#define bctzl(x) (__builtin_ctzll(x))

#define sgn(x) (((x)<eps)-((x)<-eps));

#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;

typedef long long INT;

typedef vector<int> VI;

typedef pair<int, int> pii;

typedef pair<pii, int> pi3;

typedef double DO;

template<typename T, typename U> inline void smin(T &a, U b) {if (a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, U b) {if (a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}

template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}

template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}

template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}

template<class T>inline void printsp(T x) {print(x); putchar(' ');}

template<class T>inline void println(T x) {print(x); putchar('\n');}

int power(int a, int b, int m, int ans=1) {

	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;

	return ans;

}

#ifndef ONLINE_JUDGE

void debug() {cout << endl;}

template<typename T, typename... Args>void debug(T&& head, Args&&... tail) {cout << head << ' ';debug(tail...);}

#endif

#define NN 11000000

int np, p[NN], phi[NN];

INT cnt[NN], sum[NN];

void prepare() {

	for (int i=1; i<NN; i++) phi[i]=i;

	for (int i=2; i<NN; i+=2) phi[i]/=2;

	for (int i=3; i<NN; i+=2) if (phi[i]==i) {

		for (int j=i; j<NN; j+=i) phi[j]-=phi[j]/i;

	}

	for (int i=2; i<NN; i++) {

		if (p[i]) continue;

		p[i]=i;

		if ((INT)i*i>NN) continue;

		for (int j=i*i; j<NN; j+=i) {

			if (p[j]==0) p[j]=i;

		}

	}

}

int main() {

#ifndef ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	prepare();

	int N;

	gn(N);

	for (int i=2; i<=N; i++) {

		if (i*2>N && p[i]==i) continue;

		cnt[p[i]]++;

	}

	for (int i=N; i>0; i--) {

		sum[i]=sum[i+1]+cnt[i];

	}

	INT one=0;

	for (int i=2; i<=N; i++) {

		one+=i-phi[i]-1;

	}

	INT three=0;

	for (int i=1; i<=N; i++) {

		if (p[i]!=i) continue;

		int q=(N+i-1)/i+1;

		if (q<=i) break;

//		debug(p[i], q, sum[q]);

		three+=sum[q]*cnt[i];

	}

	INT two=(INT)sum[1]*(sum[1]-1)/2;

	two-=one+three;

	INT ans=one+2*two+3*three;

//	debug(one, two, three);

	printf("%I64d\n", ans);

	return 0;

}

#include<cstdio>
#include<algorithm>
using namespace std;
#define N 10000070
int pr[N],ch[N],phi[N],s[N],su1[N],n,ct;
int prime(int n)
{
	for(int i=2;i<=n;i++)
	{
		if(!ch[i])pr[++ct]=i,phi[i]=i-1,s[i]=i;
		for(int j=1;1ll*i*pr[j]<=n&&j<=ct;j++)
		{
			ch[i*pr[j]]=1,phi[i*pr[j]]=phi[i]*(pr[j]-1);
			s[i*pr[j]]=pr[j];
			if(i%pr[j]==0)
			{
				phi[i*pr[j]]=phi[i]*pr[j];
				break;
			}
		}
	}
}
int main()
{
	scanf("%d",&n);prime(n);
	long long su=n-1,as=0,sp=0;
	for(int i=1;i<=ct;i++)if(pr[i]>n/2)su--;
	su=su*(su-1)/2;
	for(int i=2;i<=n;i++)sp+=phi[i];
	as+=1ll*n*(n-1)/2-sp;
	as+=(su-as)*2;
	for(int i=2;i<=n;i++)su1[s[i]]++;
	for(int i=2;i<=n;i++)su1[i]+=su1[i-1];
	for(int i=1;i<=ct;i++)
	{
		int l=max(n/pr[i],pr[i])+1,r=n/2;
		if(l>r)continue;
		as+=(su1[r]-su1[l-1])*(su1[pr[i]]-su1[pr[i]-1]);
	}
	printf("%lld\n",as);
}

// This amazing code is by Eric Sunli Chen.
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>
using namespace std;
template<typename T> void get_int(T &x)
{
	char t=getchar();
	bool neg=false;
	x=0;
	for(; (t>'9'||t<'0')&&t!='-'; t=getchar());
	if(t=='-')neg=true,t=getchar();
	for(; t<='9'&&t>='0'; t=getchar())x=x*10+t-'0';
	if(neg)x=-x;
}
template<typename T> void print_int(T x)
{
	if(x<0)putchar('-'),x=-x;
	short a[20]= {},sz=0;
	while(x>0)a[sz++]=x%10,x/=10;
	if(sz==0)putchar('0');
	for(int i=sz-1; i>=0; i--)putchar('0'+a[i]);
}
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define get1(a) get_int(a)
#define get2(a,b) get1(a),get1(b)
#define get3(a,b,c) get1(a),get2(b,c)
#define printendl(a) print_int(a),puts("")
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int,int> pii;
const int inf=0x3f3f3f3f;
const LL Linf=1ll<<61;
const double pi=acos(-1.0);

const int maxn=10000111;
bool pr[maxn];
int n,mnv[maxn],miu[maxn],prm[1000111],tot,cnt[maxn];
int main()
{
	get1(n);
	for(int i=1;i<=n;i++)
	{
		miu[i]=1;
		pr[i]=(i>1);
	}
	for(int i=2;i<=n;i++)
	{
		if(pr[i])
		{
			prm[++tot]=mnv[i]=i;
			miu[i]=-1;
			for(int j=i+i;j<=n;j+=i)
			{
				pr[j]=0;
				if(mnv[j]==0)mnv[j]=i;
				if(j/i%i==0)miu[j]=0;
				else miu[j]*=-1;
			}
		}
	}
	LL ans1=0,ans2=0,ans3=0;
	for(int i=1;i<=n;i++)
	{
		cnt[mnv[i]]++;
		ans1+=1ll*miu[i]*(n/i)*(n/i);
	}
	ans1=(n*n-ans1)-(n-1)>>1;
	int cur=tot,tot2=0;
	for(int i=1;prm[i]*prm[i]<=n;i++)
	{
		while(cur>=1&&1ll*prm[i]*prm[cur]>n)
		{
			tot2+=cnt[prm[cur]];
			cur--;
		}
		ans2+=1ll*cnt[prm[i]]*tot2;
	}
	tot2=0;
	for(int i=tot;i>=1&&1ll*prm[i]*prm[i]>n;i--)
	{
		ans2+=1ll*tot2*cnt[prm[i]];
		tot2+=cnt[prm[i]];
	}

	cur=tot;tot2=0;while(cur>=1&&2*prm[cur]>n)cur--;
	for(int i=1;prm[i]*prm[i]<=n;i++)
	{
		while(cur>=1&&1ll*prm[i]*prm[cur]>n)
		{
			tot2+=cnt[prm[cur]];
			cur--;
		}
		ans3+=1ll*cnt[prm[i]]*tot2;
	}
	cur=tot;tot2=0;while(cur>=1&&2*prm[cur]>n)cur--;
	for(int i=cur;i>=1&&1ll*prm[i]*prm[i]>n;i--)
	{
		ans3+=1ll*tot2*cnt[prm[i]];
		tot2+=cnt[prm[i]];
	}

	ans2-=ans3;
	printendl(1ll*(n-1)*(n-2)-ans1-ans2*2+ans3);
	return 0;
}

#pragma region Macros
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define rep2(i,a,b) for(ll i=a;i<=b;++i)
#define rep(i,n) for(ll i=0;i<n;i++)
#define rep3(i,a,b) for(ll i=a;i>=b;i--)
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pq priority_queue
#define pb push_back
#define eb emplace_back
#define vec vector<int>
#define vecll vector<ll>
#define vecpii vector<pii>
#define vecpll vector<pll>
#define vec2(a,b) vector<vec>(a,vec(b))
#define vec2ll(a,b) vector<vecll>(a,vecll(b))
#define vec3(a,b,c) vector<vector<vec>>(a,vec2(b,c))
#define vec3ll(a,b,c) vector<vector<vecll>>(a,vec2ll(b,c))
#define fi first
#define se second
#define all(c) begin(c),end(c)
#define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define lb(c,x) distance(c.begin(),lower_bound(all(c),(x)))
#define ub(c,x) distance(c.begin(),upper_bound(all(c),(x)))
using namespace std;
int in() {int x;cin>>x;return x;}
ll lin() {ll x;cin>>x;return x;}
string stin() {string s;cin>>s;return s;}
template<class T> inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T> inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
vec iota(int n){vec a(n);iota(all(a),0);return a;}
void print(){putchar(' ');}
void print(bool a){cout<<a;}
void print(int a){cout<<a;}
void print(long long a){cout<<a;}
void print(char a){cout<<a;}
void print(string &a){cout<<a;}
void print(double a){cout<<a;}
template<class T> void print(const vector<T>&);
template<class T, size_t size> void print(const array<T, size>&);
template<class T, class L> void print(const pair<T, L>& p);
template<class T, size_t size> void print(const T (&)[size]);
template<class T> void print(const vector<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout<<" "; print(*i); } cout<<endl;}
template<class T> void print(const deque<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout<<" "; print(*i); } }
template<class T, size_t size> void print(const array<T, size>& a){ print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout<<" "; print(*i); } }
template<class T, class L> void print(const pair<T, L>& p){ cout<<'(';print(p.first); cout<<","; print(p.second);cout<<')'; }
template<class T, size_t size> void print(const T (&a)[size]){ print(a[0]); for(auto i = a; ++i != end(a); ){ cout<<" "; print(*i); } }
template<class T> void print(const T& a){ cout << a; }
int out(){ putchar('\n'); return 0; }
template<class T> int out(const T& t){ print(t); putchar('\n'); return 0; }
template<class Head, class... Tail> int out(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); return 0; }
ll gcd(ll a, ll b){ while(b){ ll c = b; b = a % b; a = c; } return a; }
ll lcm(ll a, ll b){ if(!a || !b) return 0; return a * b / gcd(a, b); }
#define _GLIBCXX_DEBU
#define endl '\n'
#ifdef _MY_DEBUG
    #undef endl
    #define debug(x) cout<<#x<<": "<<x<<endl
    void err(){}
    template<class T> void err(const T& t){ print(t);  cout<<" ";}
    template<class Head, class... Tail> void err(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); }
#else
    #define debug(x)
    template<class... T> void err(const T&...){}
#endif
#pragma endregion

signed main(){
    ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);cout<<fixed<<setprecision(15);
    int n=in();
    vec a(n+1);
    rep2(i,1,n)a[i]=i;
    vec p(n+1,1);
    p[1]=1;
    rep2(i,2,n){
        if(p[i]){
            for(int j=i*2;j<=n;j+=i)p[j]=0;
        }
    }
    rep2(i,2,n){
        if(p[i]){
            for(int j=i;j<=n;j+=i){
                a[j]/=i;
                a[j]*=i-1;
            }
        }
    }
    // a <- totient func
    int res=0;
    ll ans=0;
    rep2(i,1,n){
        if(p[i])res++;
        else{
            if(i%2==0 and p[i/2]){
                ll tmp=0;
                tmp+=(a[i]-res+1);
                tmp+=i-1-res;
                ans+=tmp;
                ans++;
                ans+=tmp;
                ans+=i-1-res;
                res--;
            }
            else{
                ans+=a[i]-res+i-1-res;
                if(i&1){
                    ans+=a[i]/2-res;
                }
            }
        }
    }
    cout<<ans<<endl;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 1e+7 + 10;

bool isnotp[maxn];ll u[maxn];
ll p[664539],pn;
ll cnt[664539],sum[664539];
ll n,ans;

void pre()
{
	int i,j;

	for(i=2;i<=n;i++)
	{
		if(!isnotp[i])
		{
			p[pn]=i;
			u[i]=cnt[pn++]=1;
		}
		for(j=0;j<pn && i*p[j]<=n;j++)
		{
			isnotp[i*p[j]]=true;
			u[i*p[j]]=-u[i];
			cnt[j]++;
			if(!(i%p[j]))
			{
				u[i*p[j]]=0;
				break;
			}
		}
	}//cerr<<pn;

	sum[0]=cnt[0];
	for(i=1;i<pn;i++) sum[i]=sum[i-1]+cnt[i];
}

void solve()
{
	ll i,j,pos,tsum;

	ans=0;

	for(i=0;i<pn;i++)
	{
		ans+=cnt[i]*(cnt[i]-1);
		for(j=i+1;j<pn && p[j]*p[i]<=n;j++) ans+=cnt[i]*cnt[j]*2;
	}//cerr<<ans<<endl;

	for(i=2;i<=n;i++) if(u[i])
	{
		ans-=u[i]*(n/i)*(n/i-1)/2;
	}

	for(pos=0;p[pos]<=n/2;pos++);j=--pos;
	for(i=1;i<pn && p[i]<=n/2;i++)
	{
		for(;j>=0 && p[j]*p[i]>n;j--);
		ans+=cnt[i]*(sum[pos]-sum[max(j,i)])*3;
	}

	cout<<ans<<endl;
}

int main()
{
//	freopen("2368.in","r",stdin);
//	freopen("2368.out","w",stdout);

	cin>>n;
	pre();
	solve();

	return 0;
}

#include <bits/stdc++.h>
using namespace std;
const int N=1e7+10,M=1e6+100;;
int n,v[N],p[M],w,mu[N],sum[M];
int cnt[M],pos,tr[N],to[M];
inline long long get1(int n)
{
	long long ans=0;
	for (int l=1,r;l<=n;l=r+1)
	{
		r=n/(n/l);
		ans+=1ll*(mu[r]-mu[l-1])*(n/l)*(n/l);
	}
	ans=(ans-1)/2;
	return ans;
}
inline long long get3(int n)
{
	long long ans=0;
	for (int i=1,j=pos;i<=pos;i++)
	{
		while (p[j]>n/p[i] && j>=1) j--;
		ans+=1ll*(sum[i]-sum[i-1])*(sum[pos]-sum[j]);
	}
	for (int i=1;i<=pos;i++) if (p[i]*p[i]>n) ans-=1ll*(sum[i]-sum[i-1])*(sum[i]-sum[i-1]);
	ans/=2;
	return ans;
}
inline int get0(int n)
{
	int ans=0;
	for (int i=1,j=w;i<=w;i++)
	{
		while (p[j]>n/p[i] && j>=1) j--;
		if (i>pos) ans+=1ll*(sum[i]-sum[i-1])*(sum[w]-sum[j]);
		else ans+=1ll*(sum[i]-sum[i-1])*(sum[w]-sum[max(pos,j)]);
	}
	for (int i=pos+1;i<=w;i++) if (p[i]*p[i]>n) ans-=1ll*(sum[i]-sum[i-1])*(sum[i]-sum[i-1]);
	ans/=2;
	return ans;
}
int main()
{
	scanf("%d",&n);
	mu[1]=1;v[1]=1;
	for (int i=2;i<=n;i++)
	{
		if (!v[i])
		{
			v[i]=p[++w]=i;
			tr[i]=w;
			sum[w]++;
			mu[i]=-1;
		}
		for (int j=1;j<=w;j++)
		{
			if (p[j]>v[i] || p[j]>n/i) break;
			sum[j]++;
			v[p[j]*i]=p[j];
			if (i%p[j]==0) mu[i*p[j]]=0;
			else mu[i*p[j]]=-mu[i];
		}
	}
	for (int i=1;i<=n;i++) mu[i]+=mu[i-1];
	for (int i=1;i<=w;i++) if (p[i]+p[i]<=n) pos=i;
	for (int i=1;i<=w;i++) sum[i]+=sum[i-1];
	long long one,zero,two,three;
	one=n*(n-1)/2-get1(n);
	three=get3(n);
	zero=get0(n);
	two=(n-2)*(n-1)/2-one-zero-three;
	printf("%lld\n",one+two*2+three*3);
}

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <iostream>
using namespace std;

typedef long long int64;

const int INF = 0x3f3f3f3f;
const int MAXN = 1e7 + 10;

bool isnt_prime[MAXN];
int prime[MAXN], phi[MAXN];
int mfac_cnt[MAXN], mfac_sum[MAXN];

#define sum(l, r) (((r) < (l)) ? 0 : (mfac_sum[(r)] - mfac_sum[(l) - 1]))

int main() {
    int n;
    cin >> n;
    isnt_prime[1] = true;
    phi[1] = 1;
    int prime_cnt = 0;
    for (int i = 2; i <= n; i++) {
        if (!isnt_prime[i]) {
            prime[prime_cnt++] = i;
            mfac_cnt[i]++;
            phi[i] = i - 1;
        }
        for (int j = 0; j < prime_cnt; j++) {
            if (i * prime[j] > n) break;
            isnt_prime[i * prime[j]] = true;
            mfac_cnt[prime[j]]++;
            if (i % prime[j] == 0) {
                phi[i * prime[j]] = phi[i] * prime[j];
                break;
            } else {
                phi[i * prime[j]] = phi[i] * (prime[j] - 1);
            }
        }
    }
    for (int i = 1; i <= n; i++) {
        mfac_sum[i] = mfac_sum[i - 1] + mfac_cnt[i];
    }
    int path2 = 0;
    for (int i = 1; i <= n; i++) {
        path2 += phi[i] - 1;
        // clog << phi[i] << endl;
    }
    int path1 = (n - 1) * (n - 2) / 2 - path2;
    // 先假设都是长度为2的路径, 待会统计的时候再调整
    int ans = path2 * 2 + path1;
    for (int i = 0; i < prime_cnt; i++) {
        // 长度为3的路径, fa < n / 2
        ans += mfac_cnt[prime[i]] *
               sum(max(prime[i] + 1, n / prime[i] + 1), max(prime[i], n / 2));
        // 不存在的路径, fa > n / 2
        ans -= 2 * mfac_cnt[prime[i]] * sum(max(prime[i], n / 2) + 1, n);
    }
    cout << ans << endl;
    return 0;
}

//created by missever

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> P;

const int mod = 1e9 + 7;
const int maxn = 1e7 + 500;
bool flag[maxn];
LL phi[maxn],pri[maxn];
map<P,LL> q;
vector<int> f;
int mu[maxn],cnt = 0;

void Get_phi() {
    mu[1] = phi[1] = 1;
    for(int i = 2; i < maxn; i++) {
        if(!flag[i]) {
            pri[cnt++] = i;
            phi[i] = i - 1;
            mu[i] = -1;
        }
        for(int j = 0; j < cnt; j++) {
            if(1LL * i * pri[j] > maxn) break;
            flag[i * pri[j]] = true;
            if(i % pri[j] == 0) {
                phi[i * pri[j]] = pri[j] * phi[i];
                mu[i * pri[j]] = 0;
                break;
            } else phi[i * pri[j]] = (pri[j] - 1) * phi[i],mu[i * pri[j]] = -mu[i];
        }
    }
    for(int i = 1;i < maxn; i++) phi[i] += phi[i - 1];
    for(int i = 1;i < maxn; i++) {
        if(mu[i] != 0) f.push_back(i);
    }
}

LL solve(int n,int m) {
    if(n > m) swap(n,m);
    if(n == 0) return 0;
    if(q.count(P(n,m))) return q[P(n,m)];
    LL s = 0;
    for(auto e:f) {
        if(e > n) break;
        s += 1LL * mu[e] * (n / e) * (m / e);
    }
    q[P(n,m)] = s;
    return s;
}

int main() {
#ifdef CX_TEST
    freopen("E:\\program--GG\\test_in.txt", "r", stdin);
#endif
    int n,i,j;
    LL s1,s2,s3,t = 0;
    Get_phi();
    scanf("%d",&n);
    s1 = 1LL * (n - 1) * (n - 2) / 2 - (phi[n] - n);
    for(i = 0,s2 = 0;i < cnt; i++) {
        for(j = i + 1;j < cnt; j++) {
            if(1LL * pri[i] * pri[j] > n) break;
            LL dd = solve(n / pri[i],n / pri[j]) - solve(n / pri[i] / pri[j],n / pri[j]) + solve(n / pri[i] / pri[j],n / pri[j] / pri[j])
            - solve(n / pri[j] / pri[i],n / pri[i]) + solve(n / pri[i] / pri[i],n / pri[j] / pri[i])
            + solve(n / pri[i] / pri[j],n / pri[j] / pri[i]) - solve(n / pri[i] / pri[j] / pri[i],n / pri[j] / pri[i]) - solve(n / pri[i] / pri[j],n / pri[j] / pri[i] / pri[j])
             + solve(n / pri[i] / pri[j] / pri[i],n / pri[j] / pri[i] / pri[j]);
            s2 += dd;
        }
    }
    for(i = 0;i < cnt && pri[i] <= n; i++) {
        if(pri[i] * 2 > n) t++;
    }
    s3 = (phi[n] - n - t * (n - 2) + t * (t - 1) / 2) - s2;
    printf("%lld\n",s1 + s2 * 2 + s3 * 3);
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=10000005;
#define int long long
int prime[N],bl[N],tot=0,phi[N],f[N],g[N];
void init(int n)
{
    for(int i=1;i<=n;i++) bl[i]=1;
    bl[1]=0; phi[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(bl[i]) prime[++tot]=i,phi[i]=i-1,f[i]++;
        for(int j=1;j<=tot;j++)
        {
            if(i*prime[j]>n) break;
            bl[i*prime[j]]=0;
            f[prime[j]]++;
            if(i%prime[j]==0)
            {
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
            //cout<<prime[j]<<"PPP\n";
            phi[i*prime[j]]=phi[i]*phi[prime[j]];
        }
    }
    //for(int i=1;i<=n;i++) cout<<f[i]<<endl;
    for(int i=2;i<=n;i++) g[i]=g[i-1]+f[i];
}

int ans1=0,ans2=0,ans3=0,rest=0,n;
void solve()
{
    for(int i=2;i<=n;i++) ans1=ans1+i-1-phi[i];
    for(int i=1;i<=tot;i++)
    {
        int L=max(n/prime[i]+1,prime[i]+1);
        int R=n/2;
        if(L<=R) ans3=ans3+f[prime[i]]*(g[R]-g[L-1]);
        R=n; L=max(n/2+1,L);
        //cout<<prime[i]<<" "<<L<<" "<<R<<endl;
        rest=rest+f[prime[i]]*(g[R]-g[L-1]);
    }
    int sum=(n-1)*(n-2)/2;
    ans2=sum-(rest+ans1+ans3);
    //cout<<ans1<<" "<<ans2<<" "<<ans3<<" "<<rest<<endl;
    printf("%lld\n",ans1+ans2*2+ans3);
}

signed main()
{
    scanf("%lld",&n);
    init(n);
    solve();
}

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int i,j;
int sp[10000005],nump[10000005],phi[10000005],cnt;
long long n,prime[10000005],pfxprime[10000005],temp,temp2,ans0,ans1,ans2,ans3;
bool isp[10000005];
int main(){
	scanf("%lld",&n);
	memset(isp,true,sizeof(isp));
	sp[1]=1;
	nump[1]=0;
	isp[1]=false;
	cnt=0;
	for(i=2;i<=n;i++){
		if (isp[i]){
			cnt++;
			prime[cnt]=i;
			sp[i]=i;
			nump[i]=1;
		}
		for(j=1;j<=cnt;j++){
			if (prime[j]*((long long)i)<=n){
				isp[prime[j]*i]=false;
				sp[prime[j]*i]=prime[j];
				if (sp[i]!=prime[j]) nump[prime[j]*i]=nump[i]+1;
				else nump[prime[j]*i]=nump[i];
			}
			else break;
			if ((i % prime[j])==0) break;
		}
	}
	pfxprime[1]=0;
	for(i=2;i<=n;i++){
		if (isp[i]) pfxprime[i]=pfxprime[i-1]+1;
		else pfxprime[i]=pfxprime[i-1];
	}
	phi[1]=1;
	for(i=2;i<=n;i++){
		if (sp[i]!=sp[i/sp[i]]) phi[i]=phi[i/sp[i]]*(sp[i]-1);
		else phi[i]=phi[i/sp[i]]*sp[i];
	}
	temp=pfxprime[n]-pfxprime[n/2]+1;
	ans0=temp*(n-temp)+temp*(temp-1)/2;
	ans1=0;
	for(i=2;i<=n;i++){
		ans1+=i-1-phi[i];
	}
	ans2=0;
	for(i=2;i<=n;i++){
		if (!isp[i]){
			ans2+=phi[i]-pfxprime[i]-1+nump[i];
			//if (sp[i]*(long long)i<=n) ans2--;
			ans2+=pfxprime[n/sp[i]];
			temp=i;
			while(sp[temp]*(long long)i<=n){
				if (temp==1) break;
				ans2--;
				temp2=sp[temp];
				while(sp[temp]==temp2) temp=temp/sp[temp];
			}
		}
	}
	temp=0;
	for(i=1;i<=cnt;i++){
		temp+=pfxprime[n/prime[i]];
	}
	temp+=pfxprime[(int)(sqrt(n))];
	ans2-=temp/2;
	ans3=n*(n-1)/2-ans0-ans1-ans2;
	printf("%lld\n",ans1+ans2*2+ans3*3);
	/*printf("%d %d %d %d\n",ans0,ans1,ans2,ans3);
	for(i=1;i<=100;i++){
		//printf("%d %d\n",i,nump[i]);
	}*/
	return 0;
}

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e7+5,M=4e6+5;
int n,ct,f[N],k[N],q[N],fi[N],c[M]; ll sum=0,ans=0,tot[N];
int Gcd(int x,int y){ return y?Gcd(y,x%y):x; }
int Max(int x,int y){ return x>y?x:y; }
void Oula(){
	for(int i=2;i<=n;i++){
		if(!f[i]) k[i]=i,c[++ct]=i,fi[i]=i-1;
		for(int j=1;j<=ct&&(ll)i*c[j]<=n;j++){
			f[i*c[j]]=1; k[i*c[j]]=(k[i]<c[j]?k[i]:c[j]);
			if(i%c[j]==0) { fi[i*c[j]]=fi[i]*c[j]; break; }
			else fi[i*c[j]]=fi[i]*(c[j]-1);
		}
		q[k[i]]++; sum+=fi[i]-1;
	}
	for(int i=2;i<=n;i++)
		tot[i]=tot[i-1]+q[i];
}
int main(){
//	freopen("Venus.in","r",stdin);
//	freopen("Venus.out","w",stdout);
	scanf("%d",&n); Oula();
	ans+=(ll)(n-1)*(n-2)/2; ans-=sum;//dis==1
	for(int i=1;i<=ct;i++){
		int x=c[i]; if(n/2+1<Max(x+1,n/x+1)) break;
		ans+=(ll)(tot[n/2+1]-tot[Max(x+1,n/x+1)-1])*q[x]*3;//dis==3
		sum-=(ll)(tot[n/2+1]-tot[Max(x+1,n/x+1)-1])*q[x];//dis==3
	}
	for(int i=1;i<=ct;i++){
		int x=c[i]; if(n<Max(x+1,n/2+1)) break;
		sum-=(ll)(tot[n]-tot[Max(x+1,n/2+1)-1])*q[x];//dis==0
	}
	ans+=sum*2;//dis==2       f(2)=f(0.2.3)-f(3)-f(0)
	printf("%lld\n",ans);
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int> pii;
const int inf = 0x3f3f3f3f,oo = inf;
const double pi = acos(-1);
#define Rep(i,a,b) for(RG int i=(a);i<=(b);++i)
#define Dep(i,a,b) for(RG int i=(a);i>=(b);--i)
#define rep(i,a,b) for(RG int i=(a);i<(b);++i)
#define pc putchar
#define RG register
#define gc getchar
#define rd read
#define mem(x,v) memset(x,v,sizeof(x))
#define sqr(x) ((x)*(x))
#define lowbit(x) ((x)&(-(x)))
typedef long double ld;
inline ll read(){
	RG ll x=0,f=1;RG char c=gc();
	for(;!isdigit(c);c=gc())if(c=='-')f=-1;
	for(;isdigit(c);c=gc())x=(x<<1)+(x<<3)+(c^48);
	return x*f;
}
void write(ll x){if(x<0)x=-x,pc('-');if(x>=10)write(x/10);putchar(x%10+'0');}
void writeln(ll x){write(x);puts("");}
const int maxn = 1e7+233;
bool Isprime[maxn];
int prime[maxn],pre[maxn],phi[maxn],mu[maxn],a[maxn];
int ans = 0;
int n,cnt1,cnt2/*,cnt3*/,cnt4;
void init(){
	mem(Isprime,true);
	Isprime[0] = false;
	phi[1] = 1;
	pre[1] = 1;
	Rep(i,2,n){
		if(Isprime[i]){
//			printf("Isprime(%d)\n",i);
			prime[++*prime] = i;
			phi[i] = i-1;
			pre[i] = i;
			mu[i] = -1;
		}
		for(int j=1;j<=*prime && i*prime[j] <= n;++j){
			Isprime[i*prime[j]] = false;
			pre[i*prime[j]] = prime[j];
			if(i % prime[j] == 0){
				phi[i*prime[j]] = phi[i] * prime[j];
				mu[i*prime[j]] = 0;
				break;
			} else{
				phi[i*prime[j]] = phi[i] * (prime[j] - 1);
				mu[i*prime[j]] = -mu[i];
			}
		}
//		printf("%d %d %d\n",i,pre[i],phi[i]);
	}
}
int main(){
	n = rd();
	init();
	Rep(i,2,n){
		//gcd(x,y) > 1
		cnt1 += i - phi[i];
//		printf("[%d %d]\n",i,i-phi[i]);
	}
	Rep(i,1,n){
		//low[x]*2>n | low[y]*2 > n
		if(pre[i]*2 > n) cnt4++;
	}
//	printf("%d %d\n",cnt1,cnt4);
	//1,2,3,4,5,6  -> 4(2,3,4,6)
	cnt4 = cnt4 * (n - cnt4 - 1) + cnt4 * (cnt4 - 1) / 2;
//	printf("%d %d\n",cnt1,cnt4);
	ans=cnt1 + (1LL*(n-1)*n/2-cnt1-cnt4)*3;
//	printf("~~%lld\n",1ll*n*(n-1)/2-cnt1-cnt4);
//	printf("ans = {%d}\n",ans);
	int m = 0;
	Rep(i,2,n){
		a[++m] = pre[i];
//		printf("a[%d] = %d\n",m,pre[i]);
	}
	sort(a+1,a+1+m);
	int j = m;
	cnt2 = 0;
	Rep(i,1,m){
		while(a[i] * a[j] > n) j--;
		cnt2 += j;
//		printf("(%d %d)\n",a[i],a[j]);
	}
//	printf("cnt2 = %d\n",cnt2);
	Rep(i,2,n){
		cnt2 += (1ll * (n/i) * (n/i) - (Isprime[i] && 1ll*i*i>n)) * mu[i];
//		printf("[%d]\n",(1ll * (n/i) * (n/i) - (Isprime[i] && 1ll*i*i>n)) * mu[i]);
	}cnt2/=2;
//	printf("cnt2 = %d\n",cnt2);
    printf("%d",ans-cnt2-(n-1));
	return 0;
}
/*
i=1或者i为素数 : 0
不互质：1
gcd(x,y)=1,pre[x] * pre[y] <= n : 2
pre[x] * pre[y] >= n,pre[x] >= n,pre[y] >= n
x -> 2*pre[x] -> 2*pre[y] -> y

For each(x) get the sum of (pre[w] < ??)

22,23,24,26
32,   34
42,43,44,46
62    64

2 2 3 3 5
4 4 2 2 0
  low
1  1
2  2
3  3
4  2
5  5
6  3
[1,1]
[1,2]
[1,3]
[1,4]
[1,5]
[1,6]
[2,2] dis = 1
*[2,3] dis = 2
[2,4] dis = 1
[2,5] dis = 0
[2,6] dis = 1
[3,3] dis = 1
*[3,4] dis = 2
[3,5] dis = 0
[3,6] dis = 1
[4,4] dis = 1
[4,5] dis = 0
[4,6] dis = 1
[5,5] dis = 1
[5,6] dis = 0
[6,6] dis = 1
*/

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n;
ll pri[10000005],p[10000005],phi[10000005],cnt,num[10000005];
bool vis[10000005];
void init(){
    phi[1]=1;
    for(int i=2;i<=n;i++){
        if(!vis[i]){
            p[i]=i;pri[++cnt]=i;phi[i]=i-1;
        }
        for(int j=1;j<=cnt&&i*pri[j]<=n;j++){
            vis[i*pri[j]]=1;p[i*pri[j]]=pri[j];
            if(i%pri[j]==0){
                phi[i*pri[j]]=phi[i]*pri[j];
                break;
            }else phi[i*pri[j]]=phi[i]*phi[pri[j]];
        }
    }
    for(int i=1;i<=n;i++) num[p[i]]++;
    for(int i=1;i<=n;i++) num[i]+=num[i-1];
    while(pri[cnt]>n/2) cnt--;
}
ll calc(int l,int r){return num[r]-num[l-1];}
int main(){
    cin>>n;
    if(n==3){
        cout<<0;
        return 0;
    }
    init();
    ll tmp=(n-1)*(n-2)/2;
    for(int i=2;i<=n;i++) tmp+=phi[i]-1;
    ll ans=tmp;
    tmp=0;
    for(int i=1;i<=cnt;i++){
        int value=num[pri[i]]-num[pri[i]-1];
        ans+=value*calc(max(pri[i]+1,n/pri[i]+1),max(p[i]+1,n/2+1)-1);
        ans-=2*value*calc(max(pri[i]+1,n/2+1),n);
    }
    cout<<ans;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

const int maxn = (int)(1e7) + 5;
int pr[maxn], mu[maxn], smu[maxn], f[maxn];
bool chk[maxn];
int n, tot;

int mi[maxn];

void gen() {
	mu[1] = smu[1] = 1;
	for (int i = 2; i <= n; ++i) {
		if (!chk[i]) {
			pr[++tot] = i;
			f[i] = 1; mu[i] = -1;
			mi[i] = i;
		}
		for (int j = 1; j <= tot; ++j) {
			if (i * pr[j] > n) break;
			++f[pr[j]];
			mi[i * pr[j]] = pr[j];
			chk[i * pr[j]] = 1;
			mu[i * pr[j]] = -mu[i];
			if (i % pr[j] == 0) {
				mu[i * pr[j]] = 0; break;
			}
		} smu[i] = smu[i - 1] + mu[i];
	}
}

int main() {
	scanf("%d", &n);
	gen(); LL A = 1LL * n * (n - 1), B = 0, C = 0, S = 0;
	for (int i = 1, ps; i <= n; i = ps + 1) {
		ps = n / (n / i);
		A -= 1LL * (n / i) * (n / i) * (smu[ps] - smu[i - 1]);
	} A = A / 2 + 1;
	for (int i = 2; i <= n; ++i) if (!chk[i])
		for (int k = i, j = 1; k <= n; k += i, ++j) if (j > 1 && !chk[j])
			B += 1LL * f[i] * f[j];
	for (int i = 2; i * i <= n; ++i) if (!chk[i]) B -= f[i]; B = B / 2 - A;
	for (int i = 2; i <= (n >> 1); ++i) if (!chk[i]) C += 1LL * f[i] * (f[i] - 1) + S * f[i], S += 2 * f[i]; C = C / 2 - A - B;
	printf("%I64d\n", A + B * 2 + C * 3);
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i, x, y) for(int i = (x); i <= (y); i ++)
inline int read() {
	char ch = getchar(); int x = 0, f = 1;
	while(ch < '0' || ch > '9') {
		if(ch == '-') f = -1;
		ch = getchar();
	} while('0' <= ch && ch <= '9') {
		x = x * 10 + ch - '0';
		ch = getchar();
	} return x * f;
}
int n, mu[10001000];
int prime[1000010], tot;
bool vis[10001000];
int Min[10001000];
int a[10001000];
inline void init() {
	mu[1] = 1;
	rep(i, 2, n) {
		if(!vis[i]) {
			prime[++ tot] = i;
			mu[i] = -1;
		}
		rep(j, 1, tot) {
			if(i * prime[j] > n) break;
			vis[i * prime[j]] = 1;
			if(i % prime[j] == 0) {
				mu[i * prime[j]] = 0;
				break;
			} mu[i * prime[j]] = -mu[i];
		}
	} rep(i, 1, n) mu[i] += mu[i - 1];
	/*rep(i, 1, n) {
		printf("prime[%d]=%d\n", i, prime[i]);
	}*/
}
inline LL calc_step_1() {
	int last; LL res = 0;
	for(int i = 1; i <= n; i = last + 1) {
		last = n / (n / i);
		res += 1ll * (n / i) * (n / i) * (mu[last] - mu[i - 1]);
	} return (1ll * n * (n - 1) - res + 1) / 2;
}
inline LL calc_step_2() {
	memset(vis, 0, sizeof(vis));
	a[1] = 1;
	rep(i, 1, tot) {
		int k = prime[i];
		for(int j = k; j <= n; j += k) {
			if(!vis[j]) {
				a[j] = k;
				vis[j] = 1;
			}
		}
	} rep(i, 1, n) Min[a[i]] ++;
	//rep(i, 1, n) printf("a[%d]=%d\n", i, a[i]);
	LL res = 0;
	rep(i, 1, tot) {
		rep(j, 1, tot) {
			if(prime[i] * prime[j] > n) break;
			res += Min[prime[i]] * Min[prime[j]];
			//cout << "res " << res << endl;
		}
	} rep(i, 1, tot) if(prime[i] * prime[i] <= n) res -= Min[prime[i]];
	return res;
}
inline LL calc_step_3() {
	LL res = 0; LL sum = 0;
	rep(i, 1, tot) {
		if(2 * prime[i] > n) break;

		LL Max = prime[i];
		// Max = prime[u]
		res += Min[Max] * sum;
		// Max = prime[v]
		res += Min[Max] * sum;
		res += Min[Max] * (Min[Max] - 1);
		sum += Min[prime[i]];
	} return res;
}
int main() {
	n = read(); init();
	LL A = calc_step_1();
	LL B = calc_step_2(); //cout << B << endl;
	LL C = calc_step_3();
	B = (B / 2 - A);
	C = (C / 2 - A - B);
	//cout << A << endl << B << endl << C << endl;
	cout << A + 2 * B + 3 * C;
	return 0;
}

#include "bits/stdc++.h"
#define MAXN 100009
#define INF 1000000007
#define mp(x,y) make_pair(x,y)
#define all(v) v.begin(),v.end()
#define pb(x) push_back(x)
#define wr cout<<"----------------"<<endl;
#define ppb() pop_back()
#define tr(ii,c) for(__typeof((c).begin()) ii=(c).begin();ii!=(c).end();ii++)
#define ff first
#define ss second
#define my_little_dodge 46
#define debug(x)  cerr<< #x <<" = "<< x<<endl;
using namespace std;

typedef long long ll;
typedef pair<int,int> PII;
template<class T>bool umin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
template<class T>bool umax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
const int N=1e7+9;
int lp[N],phi[N],n;
ll par[N];
vector<int>pr;
ll path[4];
int main(){
	//~ freopen("file.in","r",stdin);
	phi[1]=1;
    for(int i=2;i<N;i++){
        if(!lp[i])
			lp[i]=i,phi[i]=i-1,pr.push_back(i);
        else{
            if(lp[i]==lp[i/lp[i]])
                phi[i]=phi[i/lp[i]]*lp[i];
            else
                phi[i]=phi[i/lp[i]]*(lp[i]-1);
        }
        for(int j=0;j<(int)pr.size() and pr[j]<=lp[i] and i*pr[j]<N;j++)
            lp[i*pr[j]]=pr[j];
    }
	scanf("%d",&n);
	for(int i=2;i<=n;i++)
		path[1]+=i-1-phi[i];
	for(int i=2;i<=n;i++)
		par[lp[i]]++;
	for(int i=2;i<=n;i++)
		par[i]+=par[i-1];
	for(int i=2;i<=n;i++){
		path[2]+=par[n/lp[i]];
		if(lp[i]*lp[i]<=n)
			path[2]--;
	}assert(path[2]%2==0);path[2]/=2;
	path[2]-=path[1];
	for(int i=2;i<=n;i++)
		if(lp[i]*2<=n)
			path[3]+=par[n/2]-1;
	assert(path[3]%2==0);path[3]/=2;
	path[3]-=path[2]+path[1];
	ll ans=0;
	for(int i=1;i<=3;i++)
		ans+=path[i]*1LL*i;
	printf("%lld\n",ans);
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<ll> vi;

const int maxn = 1e7+100;

ll cri[maxn];
ll ngcd[maxn],divi[maxn],rp[maxn];
vi pri;
int n,m;

int main(){
//   ios::sync_with_stdio(false);
//   cin.tie(0);
  cin >> n;
  for(int i = 0; i < maxn; ++i) cri[i] = 1;
  memset(divi,0,sizeof(divi));
  cri[0] = cri[1] = 0;
  divi[0] = divi[1] = 1;
  for(ll i = 2; i < maxn; ++i){
    if(cri[i]){
      divi[i] = i;
      pri.push_back(i);
      ll j = i*i;
      while(j < maxn){
        cri[j] = 0;
        if(divi[j] == 0) divi[j] = i;
        j += i;
      }
    }
  }
//   for(n = 1; n <= 100; ++n){
    ngcd[0] = ngcd[1] = 0;
    for(int i = 1; i <= n; ++i){
      if(divi[i] == i) ngcd[i] = n/i;
      else{
        if((i/divi[i])%divi[i] == 0) ngcd[i] = ngcd[i/divi[i]];
        else ngcd[i] = ngcd[i/divi[i]]+ngcd[divi[i]]-n/i;
      }
    }
    m = upper_bound(pri.begin(),pri.end(),n/2)-pri.begin();
    for(int i = 0; i < m; ++i) rp[pri[i]] = i;
    for(int i = 0; i <= n; ++i) cri[i] = 1;
    vi cnt(m,0),acc(m+1,0);
    for(int i = 0; i < m; ++i){
      for(int j = pri[i]; j <= n; j += pri[i]){
        if(cri[j]){
          cri[j] = 0;
          ++cnt[i];
        }
      }
      acc[i+1] = acc[i]+cnt[i];
    }
    ll sol = 0;
    for(int i = 2; i <= n; ++i) sol += ngcd[i]-1;
//     cerr << sol/2 << '\n';
    for(int i = 2; i <= n; ++i){
      if(2*i > n and divi[i] == i) continue;
      ll k = upper_bound(pri.begin(),pri.end(),n/divi[i])-pri.begin();
//       cerr << i << ' ' << divi[i] << ' ' << k << ' ' << acc[k] << ' ' << ngcd[i] << '\n';
      if(rp[divi[i]] >= k){
        sol += 2*(acc[k]+cnt[rp[divi[i]]]-ngcd[i]);
        sol += 3*(acc[m]-acc[k]-cnt[rp[divi[i]]]);
      }
      else{
        sol += 2*(acc[k]-ngcd[i]);
        sol += 3*(acc[m]-acc[k]);
      }
    }
//     for(int i = 0; i < m; ++i){
//       sol += (cnt[i]*(cnt[i]-1))/2 + cnt[i]*(n/pri[i]-cnt[i]);
//     }
//     for(int i = 0; 2*pri[i] <= n; ++i){
//       ll k = upper_bound(pri.begin(),pri.end(),n/pri[i])-pri.begin();
//       k = min(k,ll(i));
//       cerr << sol << ' ' << i << ' ' << cnt[i] << ' ' << k << ' ' << acc[k] << '\n';
//       sol += 2*cnt[i]*(acc[k]-(n/pri[i]-cnt[i]));
//       sol += 3*cnt[i]*(acc[i]-acc[k]);
//     }
    cout << sol/2 << '\n';
//   }
}

#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<bitset>
using namespace std;
typedef long long LL;
const int N=1e7+100;
int gi() {
	int w=0;bool q=1;char c=getchar();
	while ((c<'0'||c>'9') && c!='-') c=getchar();
	if (c=='-') q=0,c=getchar();
	while (c>='0'&&c <= '9') w=w*10+c-'0',c=getchar();
	return q? w:-w;
}
int pri[N];
int sum[N],phi[N],low[N];
int main()
{
#ifndef ONLINE_JUDGE
	freopen("D.in","r",stdin);
	freopen("D.out","w",stdout);
#endif
	int n=gi(),i,j,len=0,t,tot=0;
	LL ans=0,s=0;
	for (i=2;i<=n;i++) {
		if (!pri[i]) pri[++len]=i,low[i]=i,phi[i]=i-1;
		for (j=1;j<=len&&(t=i*pri[j])<=n;j++) {
			pri[t]=1;low[t]=pri[j];
			if (i%pri[j]) phi[t]=phi[i]*phi[pri[j]];
			else {
				phi[t]=phi[i]*pri[j];
				break;
			}
		}
	}
	for (i=2;i<=n;i++) sum[low[i]]++;
	for (i=2;i<=n;i++) sum[i]+=sum[i-1];
	for (i=2;i<=n;i++) if (low[i]<=n/2) {
			ans+=tot++*3;
			ans-=i-1-phi[i];
			s+=sum[n/low[i]]-(low[i]*low[i]<=n);
		}
	ans-=s/2;
	cout<<ans<<endl;
	return 0;
}

#include<bits/stdc++.h>
#define inf 23333333
using namespace std;
const int maxn=1000;
int mp[maxn+5][maxn+5];
long long n,ans=0;
void flody()
{
    for(long long k=1;k<=n;k++)
    {
        for(long long i=1;i<=n;i++)
        {
            for(long long j=1;j<=n;j++)
            {
                if(mp[i][j]>mp[i][k]+mp[k][j])
                    mp[i][j]=mp[i][k]+mp[k][j];
            }
        }
    }
}
int main()
{
	ans=0;
    cin>>n;
	if(n==100000) {cout<<"GIVE ME A AC!"<<endl;return 0;}
    for(int i=1;i<=n;i++)
    {
		if(i!=1) mp[i][i]=inf;
    	else mp[i][i]=0;
    	for(int j=i+1;j<=n;j++)
    	{
    	    if(__gcd(i,j)!=1) mp[i][j]=mp[j][i]=1;
    	    else mp[i][j]=mp[j][i]=inf;
		}
	}
//	for(int i=1;i<=n;i++)
//	{
//		for(int j=1;j<=n;j++)
//		{
//			if(mp[i][j]==inf) cout<<"inf ";
//			else cout<<mp[i][j]<<" ";
//		}
//		cout<<endl;
//	}
	flody();
	for(int i=1;i<=n;i++)
	{
		for(int j=i+1;j<=n;j++)
		{
//			cout<<mp[i][j]<<" ";
			if(mp[i][j]!=inf) ans+=mp[i][j];
		}
//		cout<<endl;
	}
	cout<<ans<<endl;
}

#include<bits/stdc++.h>
using namespace std;
const int N=10000007;
int phi[N],p[N],mi[N],c[N],v[N],tot,n;
long long ans;
int rd()
{
    char c=getchar();int s=0,f=1;
    while(c>'9'||c<'0'){if(c=='-')f=-f;c=getchar();}
    while(c>='0'&&c<='9') s=(s<<1)+(s<<3)+(c^48),c=getchar();
    return s*f;
}
void prepare()
{
    phi[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(!v[i]){p[++tot]=i,mi[i]=i,phi[i]=i-1;}
        for(int j=1;j<=tot;j++)
        {
            if(p[j]*i>n) break;v[i*p[j]]=1;mi[i*p[j]]=p[j];
            if(i%p[j]==0){phi[i*p[j]]=phi[i]*p[j];break;}
            else phi[i*p[j]]=phi[i]*(p[j]-1);
        }
        phi[i]+=phi[i-1];
    }
    for(int i=1;i<=n;i++) c[mi[i]]++;
    for(int i=1;i<=n;i++) c[i]+=c[i-1];
}
int get(int l,int r)
{
    if(r<l) return 0;
    return c[r]-c[l-1];
}
int main()
{
    n=rd();prepare();
    ans=(n-1)*(n-2)/2+phi[n]-n;
    for(int i=1;i<=tot;i++)
    {
        int cnt=c[p[i]]-c[p[i]-1];
        ans+=get(max(p[i]+1,n/p[i]+1),max(p[i]+1,n/2+1)-1)*cnt;
        ans-=2*get(max(p[i]+1,(n>>1)+1),n)*cnt;
    }
    printf("%lld\n",ans);
    return 0;
}

#include <bits/stdc++.h>

#define inf 0x3f3f3f3f

#define INF 0x3f3f3f3f3f3f3f3fLL

#define MOD 1000000007

#define pb push_back

#define sq(x) ((x)*(x))

#define x first

#define y second

#define eps 1e-8

#define bpt(x) (__builtin_popcount(x))

#define bptl(x) (__builtin_popcountll(x))

#define bit(x, y) (((x)>>(y))&1)

#define bclz(x) (__builtin_clz(x))

#define bclzl(x) (__builtin_clzll(x))

#define bctz(x) (__builtin_ctz(x))

#define bctzl(x) (__builtin_ctzll(x))

using namespace std;

typedef long long INT;

typedef vector<int> VI;

typedef pair<int, int> pii;

typedef pair<pii, int> pi3;

typedef double DO;

template<typename T, typename U> inline void smin(T &a, U b) {if (a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, U b) {if (a<b) a=b;}

template<typename T> inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}

template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}

template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}

template<typename T> inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}

template<typename T> inline void println(T x) {print(x), putchar('\n');}

template<typename T> inline void printsp(T x) {print(x), putchar(' ');}

template<class T, class T1> inline void print(T x, T1 y) {printsp(x), println(y);}

template<class T, class T1, class T2> inline void print(T x, T1 y, T2 z) {printsp(x), printsp(y), println(z);}

int power(int a, int b, int m, int ans=1) {

	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;

	return ans;

}

#define NN 10000100

int vst[NN], prime[NN], pk;

int ct[NN], sum[NN];

void pre(int n){

	for(int i=2; i<=n; i++){

		if(vst[i]) continue;

		vst[i]=i;

		prime[pk++]=i;

		if(i>10000) continue;

		for(int j=i*i; j<=n; j+=i){

			if(!vst[j]) vst[j]=i;

		}

	}

	for(int i=2; i<=n; i++){

		if(vst[i]*2<=n) ct[vst[i]]++;

	}

	for(int i=n; --i; ) sum[i]=sum[i+1]+ct[i+1];

}

int p[111], cnt;

int main() {

#ifndef ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	int n;

	gn(n);

	pre(n);

	INT one=0;

	for(int i=2; i<=n; i++){

		cnt=0;

		int m=i;

		while(m>1){

			p[cnt]=vst[m];

			while(m%p[cnt]==0) m/=p[cnt];

			cnt++;

		}

		m=i;

		for(int j=0; j<cnt; j++) m=m/p[j]*(p[j]-1);

		one+=(i-m-1);

	}

	INT three=0;

	for(int i=2; i<=n; i++) if(vst[i]==i){

		int b=n/i+1;

		if(i<b) three+=(INT)ct[i]*sum[b];

	}

	INT two=(INT)sum[1]*(sum[1]-1)/2-one-three;

	println(one+two*2+three*3);

	return 0;

}

#ifndef __clang__
#pragma GCC optimize "-O3"
#pragma GCC target "tune=native"
#endif
#ifdef ONLINE_JUDGE
#define NDEBUG 1
#endif
#include <stdio.h>
#include <bits/stdc++.h>

#define FOR(i, n)     for(lli i = 0; i < (lli)(n); ++i)
#define FORU(i, j, k) for(lli i = (j); i <= (lli)(k); ++i)
#define FORD(i, j, k) for(lli i = (j); i >= (lli)(k); --i)

#define SQ(x) ((x)*(x))

#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define eb emplace_back

using namespace std;

template<typename... As>
struct tpl : public std::tuple<As...> {
  using std::tuple<As...>::tuple;
  tpl(){}
  tpl(std::tuple<As...> const& b) { std::tuple<As...>::operator=(b); }

  template<typename T = tuple<As...> >
  typename tuple_element<0, T>::type const&
  x() const { return get<0>(*this); }
  template<typename T = tuple<As...> >
  typename tuple_element<0, T>::type&
  x() { return get<0>(*this); }

  template<typename T = tuple<As...> >
  typename tuple_element<1, T>::type const&
  y() const { return get<1>(*this); }
  template<typename T = tuple<As...> >
  typename tuple_element<1, T>::type&
  y() { return get<1>(*this); }

  template<typename T = tuple<As...> >
  typename tuple_element<2, T>::type const&
  z() const { return get<2>(*this); }
  template<typename T = tuple<As...> >
  typename tuple_element<2, T>::type&
  z() { return get<2>(*this); }

  template<typename T = tuple<As...> >
  typename tuple_element<3, T>::type const&
  w() const { return get<3>(*this); }
  template<typename T = tuple<As...> >
  typename tuple_element<3, T>::type&
  w() { return get<3>(*this); }
};

using lli   = long long int;
using llu   = long long unsigned;

using pii   = tpl<lli, lli>;
using piii  = tpl<lli, lli, lli>;
using piiii = tpl<lli, lli, lli, lli>;
using vi    = vector<lli>;
using vii   = vector<pii>;
using viii  = vector<piii>;
using vvi   = vector<vi>;
using vvii  = vector<vii>;
using vviii = vector<viii>;

template<class T>
using min_queue = priority_queue<T, vector<T>, greater<T> >;
template<class T>
using max_queue = priority_queue<T>;

template<size_t... I>
struct my_index_sequence {
  using type = my_index_sequence;
  static constexpr array<size_t, sizeof...(I)> value = { {I...} };
};

namespace my_index_sequence_detail {
  template<typename I, typename J> struct concat;
  template<size_t... I, size_t... J>
  struct concat<my_index_sequence<I...>, my_index_sequence<J...> > :
    my_index_sequence<I..., (sizeof...(I)+J)...> { };
  template<size_t N> struct make_index_sequence :
    concat<typename make_index_sequence<N/2>::type, typename make_index_sequence<N-N/2>::type>::type { };
  template <> struct make_index_sequence<0> : my_index_sequence<>{};
  template <> struct make_index_sequence<1> : my_index_sequence<0>{};
}

template<class... A>
using my_index_sequence_for = typename my_index_sequence_detail::make_index_sequence<sizeof...(A)>::type;

template<class T, size_t... I>
void print_tuple(ostream& s, T const& a, my_index_sequence<I...>){
  using swallow = int[];
  (void)swallow{0, (void(s << (I == 0? "" : ", ") << get<I>(a)), 0)...};
}

template<class T>
ostream& print_collection(ostream& s, T const& a);
template<class... A>
ostream& operator<<(ostream& s, tpl<A...> const& a);
template<class... A>
ostream& operator<<(ostream& s, tuple<A...> const& a);
template<class A, class B>
ostream& operator<<(ostream& s, pair<A, B> const& a);

template<class T, size_t I>
ostream& operator<<(ostream& s, array<T, I> const& a) { return print_collection(s, a); }
template<class T>
ostream& operator<<(ostream& s, vector<T> const& a) { return print_collection(s, a); }
template<class T, class U>
ostream& operator<<(ostream& s, multimap<T, U> const& a) { return print_collection(s, a); }
template<class T>
ostream& operator<<(ostream& s, multiset<T> const& a) { return print_collection(s, a); }
template<class T, class U>
ostream& operator<<(ostream& s, map<T, U> const& a) { return print_collection(s, a); }
template<class T>
ostream& operator<<(ostream& s, set<T> const& a) { return print_collection(s, a); }

template<class T>
ostream& print_collection(ostream& s, T const& a){
  s << '[';
  for(auto it = begin(a); it != end(a); ++it){
    s << *it;
    if(it != prev(end(a))) s << " ";
  }
  return s << ']';
}

template<class... A>
ostream& operator<<(ostream& s, tpl<A...> const& a){
  s << '(';
  print_tuple(s, a, my_index_sequence_for<A...>{});
  return s << ')';
}

template<class... A>
ostream& operator<<(ostream& s, tuple<A...> const& a){
  s << '(';
  print_tuple(s, a, my_index_sequence_for<A...>{});
  return s << ')';
}

template<class A, class B>
ostream& operator<<(ostream& s, pair<A, B> const& a){
  return s << "(" << get<0>(a) << ", " << get<1>(a) << ")";
}

//------------------------------------------------------------------------------

// --- BEGIN SNIPPET PRIMES ---

const lli MAXPRIME = 1e7+16;
lli pi[MAXPRIME+1];
lli cnt1[MAXPRIME+1];
lli cnt0[MAXPRIME+1];
lli ok[MAXPRIME+1];

bool sieve[MAXPRIME+1];
lli mo[MAXPRIME+1];

void calcPrimes(){
  FORU(i, 2, MAXPRIME) sieve[i]=1;
  FORU(i, 1, MAXPRIME) mo[i]=1;
  FORU(i, 2, MAXPRIME) if(sieve[i]) {
    mo[i]=-1;
    lli k=2;
    while(i*k<=MAXPRIME) { sieve[i*k] = 0; mo[i*k]*=-1; if(k%i==0) mo[i*k]=0; k += 1; }
  }
}

// --- END SNIPPET PRIMES ---

int main(){
  ios::sync_with_stdio(0); cin.tie(0);
  calcPrimes();
  lli n; cin>>n;
  ok[1]=1;

  lli anstot = 0;
  FORU(i,2,n) if(!sieve[i] || i <= n/2) anstot += 1;
  anstot = (anstot*(anstot-1))/2;

  lli ans1 = 0, ans2= 0;
  FORU(i,2,n) {
    lli x = n/i;
    lli y = (x*(x-1))/2;
    ans1 += -mo[i]*y;
  }

  FORD(i,n,1) if(sieve[i]) {
    { lli k = 1;
      while(i*k<=n){
        if(ok[k]) {
          ok[i*k]=1;
          cnt1[i]++;
        }
        k += 1;
      }
    }
    FORU(j,i+1,n) {
      if(i*j>n) break;
      lli c=0;
      { lli k = 1;
        while(i*j*k<=n) {
          if(ok[i*j*k]) c++;
          k+=1;
        }
      }
      ans2 += (cnt1[i]-c)*cnt1[j];
    }
  }

  lli ans3 = anstot-ans1-ans2;

  cout << ans1+2*ans2+3*ans3 << endl;

  // lli ans2 = 0;
  // FORU(i,1,n) {
  //   if(i*i>n) break;
  //   if(sieve[i]) {
  //     FORU(j,i+1,n) {
  //       if(i*j>n) break;
  //       if(sieve[j]) {
  //         ans2 += cnt1[i] * cnt1[j];
  //         cout << mt(i,j) << endl;
  //       }
  //     }
  //   }
  // }
  // // FORU(i,1,n) if(sieve[i]) {
  // //   lli nq = min(i-1,n/i);
  // //   cout << i << " " << cnt0[nq] << " " << cnt1[i] << " " << (n/i)-cnt1[i] << endl;
  // //   ans2 += (cnt0[nq] - ((n/i)-cnt1[i])) * cnt1[i];
  // // }
  // cout << ans2 << endl;

  return 0;
}

#include <algorithm>
// #include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
#include <cmath>
#include <set>
#include <map>
#include <bitset>
#include <ctime>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef double db;
const int oo=2139063143;
const int N=10010000;
const int P=1000000007;
const db eps=1e-7;
#define pritnf printf
//char buf[1<<20|1],*p1=buf,*p2=buf,obuf[1<<20|1],*O=obuf;
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
template <typename T>
inline void sc (T &x)
{
    x=0; static int p; p=1; static char c; c=getchar();
    while (!isdigit(c)) { if (c=='-') p=-1; c=getchar(); }
    while ( isdigit(c)) { x=(x<<1)+(x<<3)+(c-48); c=getchar(); }
    x*=p;
}
template <typename T>
inline void print (T x)
{
    if (x< 0) putchar('-'),x=-x;
    if (x>=10) print(x/10);
    putchar(x%10+'0');
}
template <typename T>
inline void pr (T x) { print(x),putchar('\n'); }
template <typename T1,typename T2>
void chkmax (T1 &A,T2 B) { A=A>=B?A:B; }
template <typename T1,typename T2>
void chkmin (T1 &A,T2 B) { A=A<=B?A:B; }
int n;
int pri[N],phi[N],a[N]; bool vis[N];
void init ()
{
	for (int i=2; i<=n; i++)
	{
		if (!vis[i]) pri[++pri[0]]=i,phi[i]=i-1,++a[i];
		for (int j=1; j<=pri[0]; j++)
		{
			int p=pri[j],k=i*p;
			if (k> n) break;
			vis[k]=1;
			++a[p];
			if (i%p==0) { phi[k]=phi[i]*p; break; }
			phi[k]=phi[i]*(p-1);
		}
	}
	for (int i=1; i<=n; i++)
		a[i]+=a[i-1];
}
int get (int l,int r) { return l> r?0:a[r]-a[l-1]; }
int main ()
{
    // freopen (".in","r",stdin);
    // freopen (".out","w",stdout);
	sc(n); init ();
	LL s1=0;
	for (int i=2; i<=n; i++)
		s1+=phi[i]-1;
	LL ans=(n-1)*(n-2)/2+s1;
	for (int i=1; i<=pri[0]; i++)
	{
		int p=pri[i],g=a[p]-a[p-1];
		ans+=(LL)g*get (max (p+1,n/p+1),max (p+1,n/2+1)-1);
		ans-=2LL*g*get (max (p+1,n/2+1),n);
	}
	pr(ans);

    return 0;
}

#include<bits/stdc++.h>
using namespace std;
int n;
vector<int> prime;
int c[10000010],s[1000010];
bool flag[10000010];
int phi[10000010],mn[10000010];
void init()
{
    phi[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(!flag[i])prime.push_back(i),phi[i]=i-1,mn[i]=i;
        for(int j=0;j<prime.size()&&i*prime[j]<=n;j++)
        {
            flag[i*prime[j]]=1;
            // mn[i*prime[j]]=prime[j];
            if(i%prime[j])
            {
                mn[i*prime[j]]=prime[j];
                c[prime[j]]++;
                phi[i*prime[j]]=phi[i]*(prime[j]-1);
            }
            else
            {
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
        }
    }
    for(int i=1;i<=n;i++)s[i]=s[i-1]+c[i];
}
long long ans=0,s1,s2,s3;
int m;
int main()
{
    scanf("%d",&n);
    init();
    m=n-1;
    for(int i=2;i<=n;i++)
    {
        if(!(i>n/2&&!flag[i]))
        {
            s1+=i-1-phi[i];
        }
        else m--;
    }
    for(int i=1,r;i<=n;i=r+1)
    {
        r=n/(n/i);
        s2+=1ll*c[i]*s[n/i];
    }
    for(int i=1;i<=n;i++)
    {
        if(1ll*mn[i]*mn[i]<=n)s2--;
    }
    s3=1ll*m*(m-1)/2-s1-s2;
    printf("%lld\n",s1+2*s2+3*s3);
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

void init() {
//#if __GLIBCXX__ == 20160609
#ifdef FIRE_MIND
    freopen("a.in", "r", stdin);
    ///freopen("a.out", "w", stdout);
#else
    ///freopen(TASKNAME".in", "r", stdin);
    ///freopen(TASKNAME".out", "w", stdout);
#endif
}
#define pb push_back
#define fi first
#define se second

typedef long long ll;

const double EPS = 1e-9;
const int INF = (int)1e9 + 41;
const int N = (int)1e7 + 34;
const ll md = (ll)1e9 + 7;

bool u[N];
int prim[N / 4], plen;
int n;
int valid = 0;

ll num[N];
ll sf[N];
int nxp[N];

inline int go(int x) {
    int xx = x;
    int p[10], m = 0;

    for (int i = 0; prim[i] * prim[i] <= x; i++) {
        if (x % prim[i]) continue;
        p[m++] = prim[i];
        while (x % prim[i] == 0)
            x /= prim[i];
    }
    if (x > 1)
        p[m++] = x;

    if (m == 1 && p[0] * 2 > n)
        return 0;

    num[p[0]]++;

    int res = 0;

    //cerr << xx << " " << m << " ";

    for (int msk = 1; msk < (1 << m); msk++) {
        int y = 1;
        for (int i = 0; i < m; i++)
            if (msk & (1 << i))
                y *= p[i];
        if (__builtin_popcount(msk) % 2)
            res += n / y;
        else
            res -= n / y;
    }
    res--;
    //cerr << res << " ";
    //cerr << (valid - res - 1) * 2 + res << "\n";

    return (valid - res - 1) * 2 + res;
}

int main() {
    init();

    u[0] = u[1] = true;
    for (int i = 2; i < N; i++) {
        if (u[i]) continue;

        prim[plen++] = i;

        for (int j = i * 2; j < N; j += i) {
            u[j] = true;
        }
    }

    for (int i = 1; i < plen; i++)
        nxp[prim[i - 1]] = prim[i];

    cin >> n;

    valid = n - 1;
    for (auto p: prim) {
        if (p <= n && p * 2 > n)
            valid--;
    }

    //cerr << "valid = " << valid << "\n";

    ll ans = 0;
    for (int i = 2; i <= n; i++)
        ans += go(i);

    ans /= 2;

    sf[n] = 0;
    for (int i = n - 1; i >= 0; i--)
        sf[i] = sf[i + 1] + num[i];

    ll cur = n - 1;
    ll lp = -1;

    for (int i = 0; i < plen; i++) {
        ll p = prim[i];
        if (p * 2 > n) continue;

        while (cur > 0 && p * (cur - 1) > n) {
            cur--;
            if (!u[cur]) lp = cur;
        }

        if (lp > p) {
            ans += num[p] * sf[lp];
            //cerr << p << " " << lp << " " << num[p] << " " << sf[lp] << "\n";
        } else {
            //continue;
            //cerr << p << " " << nxp[p] << " " << num[p] << " " << sf[nxp[p]] << " kk\n";
            ans += num[p] * sf[nxp[p]];
        }
    }

    cout << ans;

    return 0;
}

#include <bits/stdc++.h>
#define endl "\n"
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;
template<class T>
inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return true;
    }
    return false;
}

template<class T>
inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return true;
    }
    return false;
}

const long long INF = 1e18;
//const ll mod = 1000000007;
int mindiv[10000001];
ll N;
ll gcdnum[10000001];
ll ans = 0;
ll mindivnum[10000001];
ll mindivsum[10000002];

int main() {
    cin >> N;
    vector<ll> primes;
    ll composite = 0;
    for(int i = 1; i <= N; i++) {
        mindiv[i] = -1;
    }
    mindiv[1] = 1;
    for(int i = 2; i <= N; i++) {
        if(mindiv[i] != -1) {
            composite++;
            continue;
        }
        if(i * 2 <= N) primes.push_back(i);
        for(int j = i * 2; j <= N; j += i) {
            if(mindiv[j] == -1) mindiv[j] = i;
        }
    }
    for(int i = 2; i <= N; i++) {
        if(mindiv[i] == -1) continue;
        mindivnum[mindiv[i]]++;
    }
    for(int i = 1; i <= N; i++) {
        mindivsum[i+1] = mindivsum[i] + mindivnum[i];
    }
    ans = (ll)primes.size() * ((ll)primes.size() - 1) * 2;
    //cerr << "default: " << ans << endl;
    for(int i = 0; i < primes.size(); i++) {
        ll tmp = N / primes[i] + 1;
        auto itr = lower_bound(primes.begin(), primes.end(), tmp);
        ll num = distance(itr, primes.end());
        ans += num;
        //cerr << primes[i] << " " << ans << endl;
    }
    ans /= 2;
    //cerr << ans << endl;
    gcdnum[1] = composite * (composite - 1) / 2;
    for(ll i = 2; i <= N; i++) {
        ll num = N / i;
        if(mindiv[i] == -1) num--;
        gcdnum[i] = num * (num - 1) / 2;
    }
    for(ll i = N; i >= 1; i--) {
        for(ll j = i * 2; j <= N; j += i) {
            gcdnum[i] -= gcdnum[j];
        }
    }
    ans += composite * (composite - 1) / 2;
    ans += gcdnum[1];
    //cerr << ans << endl;
    for(auto p : primes) {
        ans += 3 * composite;
        ll f = N / p;
        ans -= mindivsum[f + 1];
        ans -= (N / p) - 1;
        //cerr << p << " " << ans << endl;
    }
    //cerr << ans << endl;
    cout << ans << endl;
    return 0;
}

#include<bits/stdc++.h>

#define rd(x) x=read()

#define N 10000005

using namespace std;

int n;
int pri[N],phi[N],p[N];
long long f[N],g[N];int tot;

inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();if(ch==-1)return 0;}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

inline void write(int x)
{
    if(x<0){putchar('-');x=-x;}
    if(x>=10)write(x/10);
    putchar(x%10+'0');
}

int main()
{
	rd(n),phi[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(!p[i]){p[i]=pri[++tot]=i;phi[i]=i-1;}
        for(int j=1;j<=tot;j++)
        {
            if(i*pri[j]>n)break;p[i*pri[j]]=pri[j];
            if(i%pri[j]==0){phi[i*pri[j]]=phi[i]*pri[j];break;}
            else phi[i*pri[j]]=phi[i]*(pri[j]-1);
        }
    }
    int cntt=0,cnt=0;
    long long ans1=0,ans2=0,ans3=0;
    for(int i=2;i<=n;i++)f[p[i]]++;
	for(int i=2;i<=n;i++)g[i]=g[i-1]+f[i];
	for(int i=1;i<=tot;i++)if(pri[i]*2>n)cnt++;
    for(int i=2;i<=n;i++)if(1ll*p[i]*p[i]<=n)cntt++;
    for(int i=2;i<=n;i++)ans1+=i-phi[i]-1,ans2+=1ll*f[i]*g[n/i];
    ans2=(ans2-cntt)/2-ans1,ans3=(n-cnt-1)*(n-cnt-2)/2-ans1-ans2;
    printf("%lld\n",ans1+ans2*2+ans3*3);

    return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 1e+7 + 10;

bool isnotp[maxn];ll u[maxn];
ll p[664539],pn;
ll cnt[664539],sum[664539];
ll n,ans;

void pre()
{
	int i,j;

	for(i=2;i<=n;i++)
	{
		if(!isnotp[i])
		{
			p[pn]=i;
			u[i]=cnt[pn++]=1;
		}
		for(j=0;j<pn && i*p[j]<=n;j++)
		{
			isnotp[i*p[j]]=true;
			u[i*p[j]]=-u[i];
			cnt[j]++;
			if(!(i%p[j]))
			{
				u[i*p[j]]=0;
				break;
			}
		}
	}//cerr<<pn;

	sum[0]=cnt[0];
	for(i=1;i<pn;i++) sum[i]=sum[i-1]+cnt[i];
}

void solve()
{
	ll i,j,pos,tsum;

	ans=0;

	for(i=0;i<pn;i++)
	{
		ans+=cnt[i]*(cnt[i]-1);
		for(j=i+1;j<pn && p[j]*p[i]<=n;j++) ans+=cnt[i]*cnt[j]*2;
	}//cerr<<ans<<endl;

	for(i=2;i<=n;i++) if(u[i])
	{
		ans-=u[i]*(n/i)*(n/i-1)/2;
	}

	for(pos=0;p[pos]<=n/2;pos++);j=--pos;
	for(i=1;i<pn && p[i]<=n/2;i++)
	{
		for(;j>=0 && p[j]*p[i]>n;j--);
		ans+=cnt[i]*(sum[pos]-sum[max(j,i)])*3;
	}

	cout<<ans<<endl;
}

int main()
{
//	freopen("2368.in","r",stdin);
//	freopen("2368.out","w",stdout);

	cin>>n;
	pre();
	solve();

	return 0;
}

#pragma region Macros
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define rep2(i,a,b) for(ll i=a;i<=b;++i)
#define rep(i,n) for(ll i=0;i<n;i++)
#define rep3(i,a,b) for(ll i=a;i>=b;i--)
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pq priority_queue
#define pb push_back
#define eb emplace_back
#define vec vector<int>
#define vecll vector<ll>
#define vecpii vector<pii>
#define vecpll vector<pll>
#define vec2(a,b) vector<vec>(a,vec(b))
#define vec2ll(a,b) vector<vecll>(a,vecll(b))
#define vec3(a,b,c) vector<vector<vec>>(a,vec2(b,c))
#define vec3ll(a,b,c) vector<vector<vecll>>(a,vec2ll(b,c))
#define fi first
#define se second
#define all(c) begin(c),end(c)
#define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define lb(c,x) distance(c.begin(),lower_bound(all(c),(x)))
#define ub(c,x) distance(c.begin(),upper_bound(all(c),(x)))
using namespace std;
int in() {int x;cin>>x;return x;}
ll lin() {ll x;cin>>x;return x;}
string stin() {string s;cin>>s;return s;}
template<class T> inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T> inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
vec iota(int n){vec a(n);iota(all(a),0);return a;}
void print(){putchar(' ');}
void print(bool a){cout<<a;}
void print(int a){cout<<a;}
void print(long long a){cout<<a;}
void print(char a){cout<<a;}
void print(string &a){cout<<a;}
void print(double a){cout<<a;}
template<class T> void print(const vector<T>&);
template<class T, size_t size> void print(const array<T, size>&);
template<class T, class L> void print(const pair<T, L>& p);
template<class T, size_t size> void print(const T (&)[size]);
template<class T> void print(const vector<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout<<" "; print(*i); } cout<<endl;}
template<class T> void print(const deque<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout<<" "; print(*i); } }
template<class T, size_t size> void print(const array<T, size>& a){ print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout<<" "; print(*i); } }
template<class T, class L> void print(const pair<T, L>& p){ cout<<'(';print(p.first); cout<<","; print(p.second);cout<<')'; }
template<class T, size_t size> void print(const T (&a)[size]){ print(a[0]); for(auto i = a; ++i != end(a); ){ cout<<" "; print(*i); } }
template<class T> void print(const T& a){ cout << a; }
int out(){ putchar('\n'); return 0; }
template<class T> int out(const T& t){ print(t); putchar('\n'); return 0; }
template<class Head, class... Tail> int out(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); return 0; }
ll gcd(ll a, ll b){ while(b){ ll c = b; b = a % b; a = c; } return a; }
ll lcm(ll a, ll b){ if(!a || !b) return 0; return a * b / gcd(a, b); }
#define _GLIBCXX_DEBU
#define endl '\n'
#ifdef _MY_DEBUG
    #undef endl
    #define debug(x) cout<<#x<<": "<<x<<endl
    void err(){}
    template<class T> void err(const T& t){ print(t);  cout<<" ";}
    template<class Head, class... Tail> void err(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); }
#else
    #define debug(x)
    template<class... T> void err(const T&...){}
#endif
#pragma endregion

signed main(){
    ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);cout<<fixed<<setprecision(15);
    int n=in();
    vec a(n+1);
    rep2(i,1,n)a[i]=i;
    vec p(n+1,1);
    p[1]=1;
    rep2(i,2,n){
        if(p[i]){
            for(int j=i*2;j<=n;j+=i)p[j]=0;
        }
    }
    rep2(i,2,n){
        if(p[i]){
            for(int j=i;j<=n;j+=i){
                a[j]/=i;
                a[j]*=i-1;
            }
        }
    }
    // a <- totient func
    int res=0;
    ll ans=0;
    rep2(i,1,n){
        if(p[i])res++;
        else{
            if(i%2==0 and p[i/2]){
                ll tmp=0;
                tmp+=(a[i]-res+1);
                tmp+=i-1-res;
                ans+=tmp;
                ans++;
                ans+=tmp;
                ans+=i-1-res;
                res--;
            }
            else{
                ans+=a[i]-res+i-1-res;
            }
        }
    }
    cout<<ans<<endl;
}

#include <bits/stdc++.h>
#ifndef ONLINE_JUDGE
# include <sys/time.h>
# include <sys/resource.h>
#endif

/*** TEMPLATE CODE STARTS HERE ***/

#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795028841971693993751
#endif

using namespace std;

typedef vector<string> vs;
typedef long long ll;
typedef complex<double> pnt;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define RA(x) begin(x), end(x)
#define FE(i, x) for (auto i = begin(x); i != end(x); ++i)
#define SZ(x) ((ll) (x).size())

template<class T>
void splitstr(const string &s, vector<T> &out)
{
    istringstream in(s);
    out.clear();
    copy(istream_iterator<T>(in), istream_iterator<T>(), back_inserter(out));
}

template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }

static void redirect(int argc, const char **argv)
{
#ifndef ONLINE_JUDGE
    struct rlimit rlim;
    getrlimit(RLIMIT_STACK, &rlim);
    rlim.rlim_cur = 256 * 1024 * 1024;
    setrlimit(RLIMIT_STACK, &rlim);
#ifndef __SANITIZE_ADDRESS__
    getrlimit(RLIMIT_DATA, &rlim);
    rlim.rlim_cur = 256 * 1024 * 1024;
    setrlimit(RLIMIT_DATA, &rlim);
#endif
#endif

    ios::sync_with_stdio(false);
    cin.tie(NULL);
    if (argc > 1)
    {
        static filebuf f;
        f.open(argv[1], ios::in);
        cin.rdbuf(&f);
        if (!cin)
        {
            cerr << "Failed to open '" << argv[1] << "'" << endl;
            exit(1);
        }
    }

    if (argc > 2)
    {
        static filebuf f;
        f.open(argv[2], ios::out | ios::trunc);
        cout.rdbuf(&f);
        if (!cout)
        {
            cerr << "Failed to open '" << argv[2] << "'" << endl;
        }
    }
}

/*** TEMPLATE CODE ENDS HERE */

int main(int argc, const char **argv)
{
    redirect(argc, argv);

    int N;
    cin >> N;
    vi min_prime(N + 1, -1);
    vi primes;
    vi phi(N + 1);
    for (int i = 2; i <= N; i++)
    {
        if (min_prime[i] == -1)
        {
            int id = SZ(primes);
            min_prime[i] = id;
            for (int j = i + i; j <= N; j += i)
                if (min_prime[j] == -1)
                    min_prime[j] = id;
            primes.push_back(i);
        }
    }

    int P = SZ(primes);
    int H = P;
    while (H > 0 && primes[H - 1] * 2 > N)
        H--;

    vi byp(P);
    ll ans = 0;
    ll iso = 0;
    phi[1] = 1;
    for (int i = 2; i <= N; i++)
    {
        int f0 = min_prime[i];
        int p0 = primes[f0];
        int x = i;
        while (x % p0 == 0)
            x /= p0;
        int r = i / (x * p0);
        phi[i] = phi[x] * r * (p0 - 1);
        if (f0 < H)
        {
            ans += i - 2 - iso;              // d >= 1
            ans += phi[i] - 1 - iso;         // d >= 2
            byp[f0]++;
        }
        else
            iso++;
    }
    vi fsum(H + 1);
    fsum[0] = 0;
    for (int i = 0; i < H; i++)
        fsum[i + 1] = fsum[i] + byp[i];
    int q = H;
    for (int i = 0; i < H; i++)
        if (ll(primes[i]) * primes[i] > N)
        {
            while (q > 0 && ll(primes[q - 1]) * primes[i] > N)
                q--;
            ans += fsum[H] - fsum[q] - 1;
        }
    cout << ans << '\n';

    return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define oo 1000000000
const int N = 10000010;
int to[N];
bool vis[N];
int n;
int sum[N];
long long a,b,c,d,e,f;
int cur;
int main(){
	for(int i = 1;i<N;i++){
		to[i] = i;
	}
	for(int i = 2;i<N;i++){
		if(to[i] != i) continue;
		for(int j = i;j<N;j+=i){
			to[j] = to[j] - (to[j] / i);
		}
	}
	scanf("%d",&n);
	for(int i = 2;i<=n;i++){
		b += (i - 1 - to[i]);
		if(to[i] != i - 1) continue;
		if(i * 2 > n){
			a++;
		}
		if((long long)i * i > n)
			f++;
		for(int j = i;j<=n;j+=i){
			if((long long)i * i > n && j != i)
				e++;
			if(vis[j]) continue;
			vis[j] = true;
			sum[i]++;
		}
		sum[i] += sum[i - 1];
	}
	a = (a + 1) * (n - a - 1) + a * (a + 1) / 2;
	c = (long long)(n - f - 1) * (n - f - 2) / 2;
	c -= (b - e);
	for(int i = 2;i * 2<=n;i++){
		if(to[i] != i - 1) continue;
		if((long long)i * i <= n) continue;
		cur = n / i;
		c += sum[cur];
	}
	c -= e;
	d = (long long)n * (n - 1) / 2;
	d -= (a + b + c);
	long long ans = b + 2 * c + 3 * d;
	cout << ans << endl;
	return 0;
}

/*

Author: https://codeforces.com/profile/Asriel_Dreemurr

This template is still under development

*/

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// pragma is magic

#include <bits/stdc++.h>
#define ll long long
#define lll __int128
#define mp std::make_pair
#define pii std::pair<int,int>
#define pll std::pair<ll,ll>
#define pli std::pair<ll,int>
#define pil std::pair<int,ll>
#define _clear(x) std::memset(x,0,sizeof(x))
#define _move(x,y) std::memcpy(y,x,sizeof(x))
#define _len(s) std::strlen(s)
#define writeln(a,n) {for (int i = 1; i <= (n); ++ i) { write(a[i]); } puts("") ;}
#define readln(a,n) for (int i = 1; i <= (n); ++ i) read(a[i]);
#define re(x) for (int _i = 1; _i <= (x); ++ _i)
#define rep(i,l,r) for (int i = (l); i <= (r); ++ i)
#define _debug puts("!")
#define _tell(x) std::cerr << #x << " is " << x << std::endl;

//#define int ll
//#define int lll

template <class T> class _Fenwick {
	private:
       	std::vector<T>sum;
        int _size;
    public:
        _Fenwick() { _size = 0; }
        void reset(int n) { _size = n; sum.clear(); sum.resize(n+1); }
        void add(int x,T y) { while (x <= _size) { sum[x] += y; x += x & -x ; } }
        T query(int x, T y) { T ans = y; while (x) { ans += sum[x]; x -= x & -x; }; return ans; }
        void build(T *a, int n) { reset(n); for (int i = 1; i <= n; ++ i) add(i,a[i]); }
};

template<typename T> void read(T &x);
template<typename T> void read(T &x,T &y);
template<typename T> void read(T &x,T &y, T &z);
template<typename T> void write(T x);
template<typename T> void writeC(T x);
template<typename T> void writeN(T x);
template<typename T> void _binary(T x,int len);

ll _qpow(ll a,ll b,ll M);
ll _inv(ll x,ll M);

#define maxn 10000005

int prime[maxn],mu[maxn],not_prime[maxn],n,vis[maxn],tl,d[maxn];

void sieve(int lim){
	mu[1] = 1;
	for (int i = 2; i <= lim; ++ i) {
		if (!not_prime[i]) { prime[++tl] = i; mu[i] = -1; }
		for (int j = 1; j <= tl && (ll)i * prime[j] <= lim; ++ j) {
			not_prime[ i * prime[j] ] = 1;
			if (i % prime[j] == 0) { mu[i * prime[j]] = 0; break; }
			else mu[i * prime[j]] = -mu[i];
		}
	}
}

signed main() {
	read(n);
	sieve(n);
	for (int i = 2; i <= n; ++ i) {
		if (!d[i]) for (int j = i; j <= n; j += i) if (!d[j]) d[j] = i;

	}
	int p = 1;
	ll ans = (ll)n * n - n + 1;
	for (int d = 1; d <= n; ++ d)
		ans -= (ll) mu[d] * (ll)(n / d) * (ll)(n / d);
//	printf(">%d\n",ans);
	for (int i = 1; i <= n; ++ i) {
	//	printf("<%d>\n",i);
		int lim = 0, sum = 0;
		int w = 0;
		for (int j = std::max(i,2); j <= n; j += i) {
			if (d[j] * 2 > n) continue;
			if (!vis[d[j]]) w++;
			vis[d[j]] ++; sum ++;// printf("+ %d\n",j);
			//lim = std::max(lim,d[j]);
		} if (!sum) continue;
	//	if (w > 1000) continue;
		std::vector<pii>v;
		for (int j = std::max(i,2); j <= n; j += i) {
			if (d[j] * 2 > n) continue;
			if (vis[d[j]]) { v.push_back(mp(d[j],vis[d[j]])); vis[d[j]] = 0; }
		}
		std::sort(v.begin(),v.end());
		ll cnt1 = 0, cnt2 = 0; int c1 = 0;
		int p = -1;
		for (int j = v.size() - 1; j >= 0; j --) {
			while (p + 1 < v.size() && v[j].first * (v[p+1].first) <= n) { c1 += v[++p].second; }
			cnt1 += c1 * v[j].second; cnt2 += (sum - c1) * v[j].second;
		} v.clear();
		ans += (ll) mu[i] * (2 * cnt1 + 3 * cnt2) ;
	} //printf("%d\n",w);

	printf("%lld",ans/2);
	return 0;
}

template<typename T> void read(T &x) {
	x = 0;
	char c = getchar(); T flag = 1;
	while (c < '0' || c > '9') {
		if (c == '-') flag = -flag;
		c = getchar();
	} while ('0' <= c && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
	x *= flag;
}

template<typename T> void read(T &x, T &y) {
	read(x); read(y);
}
template<typename T> void read(T &x, T &y, T &z) {
	read(x); read(y); read(z);
}

template<typename T> void writeC(T x) {
	if (x < 0) x = ~x + 1, putchar('-');
	if (x > 9) writeC(x / 10);
	putchar(x % 10 + '0');
}

template<typename T> void write(T x) {
	writeC(x); putchar(' ');
}

template<typename T> void writeN(T x) {
	writeC(x); puts("");
}

template<typename T> void _binary(T x,int len) { for (int i = len-1; i >= 0; -- i) writeC((x>>i)&1); }

ll _inv(ll x,ll M) { assert(x != 0); return x == 1 ? 1 : (M - M / x) * _inv(M % x,M) % M; }

ll _qpow(ll a, ll b, ll M) {
	ll res = 1;
  	while (b > 0) {
		if (b & 1) res = res * a % M;
		a = a * a % M;
		b >>= 1;
	}
  	return res;
}

//��CF 871D
#include<iostream>
#include<cstdio>
#include<fstream>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<cmath>
#include<cstring>
#include<cstdlib>
using namespace std;
typedef long long LL;
const int N = 1e7+7;
int f[N],s[N];
LL g[N];
int pr[N/10];
int main()
{
	int n,i,j,t,m;
	LL s0,s1,s2,s3;
	s0=0,s1=0,s2=0;
	cin>>n;
	f[1]=0;
	s[0]=1;
	t=1;
	m=0;
	for(i=2;i<=n;i=i+1){
		s[f[i]]++;
		if(!f[i]){
			s[i]++;
			pr[++m]=i;
			if(i+i>n)
				t++;
			for(j=i+i;j<=n;j=j+i)
				if(!f[j])
					f[j]=i;
		}
	}
	for(i=n;i>=1;i=i-1){
		g[i]=(LL)(n/i)*(n/i-1)/2;
		for(j=i+i;j<=n;j=j+i)
			g[i]-=g[j];
	}

	s0+=(LL)t*(t-1)/2;
	s0+=(LL)t*(n-t);

	s1+=(LL)n*(n-1)/2-g[1];

	for(i=1;i<=m;i=i+1){
		for(j=i+1;j<=m&&(LL)pr[i]*pr[j]<=n;j=j+1)
			s2+=(LL)(s[pr[i]]-1)*s[pr[j]];
	}
	//for(i=1;i<=n;i=i+1)
	//	cout<<s[i]<<' ';
	s3=(LL)n*(n-1)/2-s2-s1-s0;
	cout<<(LL)s3*3+s2*2+s1<<endl;
	return 0;
}

#pragma comment(linker, "/STACK:536870912")
#pragma warning(disable:4996)

//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include<iostream>
#include<algorithm>
#include<queue>
#include<string>
#include<vector>
#include<map>
#include<list>
#include<set>
#include<cstring>
#include<ctime>
#include<cassert>
#include<cmath>
#include<limits>
#include<iterator>
#include<functional>
#include<unordered_map>
#include<unordered_set>
#include<stack>
#include<bitset>
#include<complex>

#define all(v) v.begin(), v.end()
#define setv(ar, val) memset(ar, val, sizeof(ar));
#define ll long long int
#define ld long double
#define ull unsigned long long int
#define PI 3.1415926535897932384626433832795
using namespace std;

const int N = 1e7 + 100, S = 1e4, D = 1e5, INF = 1e9;
int s[N], phi[N], q[N + N], h[N + N];

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	for (int i = 2; i < N; i++) {
		if (!s[i]) {
			s[i] = i;
			for (ll j = i * (ll)i; j < N; j += i)
				s[j] = i;
		}
	}

	int n;
	scanf("%d", &n);

	ll ans = 0;
	int t = 0, sq = 0;
	for (int i = 2; i <= n; i++) {
		if (s[i] == i)
			phi[i] = i - 1;
		else {
			phi[i] = phi[i / s[i]] * s[i];
			if (i / s[i] % s[i])
				phi[i] -= phi[i] / s[i];
		}

		if (s[i] * 2 <= n)
			t++;

		if (s[i] * (ll)s[i] <= n)
			ans++;

		q[s[i]]++;
		h[n / s[i]]++;
	}

	for (int i = 0, sum = 0; i < N + N; i++) {
		sum += q[i];
		ans -= sum * (ll)h[i];
	}

	ans /= 2;

	for (int i = 1; i <= n; i++)
		ans -= i - 1 - phi[i];

	ans += t * (t - 1ll) / 2 * 3;

	printf("%lld", ans);

	return 0;
}

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 10000010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
	int x=0,f=1;char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return x*f;
}
int n,prime[N],phi[N],p[N],v[N],cnt;
ll ans;
bool flag[N],f[N];
signed main()
{
#ifndef ONLINE_JUDGE
	freopen("d.in","r",stdin);
	freopen("d.out","w",stdout);
#endif
	n=read();if (n==4||n==5) {cout<<1;return 0;}
	flag[1]=1;phi[1]=1;
	for (int i=2;i<=n;i++)
	{
		if (!flag[i]) prime[++cnt]=i,phi[i]=i-1,p[i]=i,v[i]=-1;
		for (int j=1;j<=cnt&&prime[j]*i<=n;j++)
		{
			flag[prime[j]*i]=1;
			p[prime[j]*i]=prime[j];
			if (i%prime[j]==0) {phi[prime[j]*i]=phi[i]*prime[j];break;}
			phi[prime[j]*i]=phi[i]*(prime[j]-1);
		}
	}
	ll tot=0;
	for (int i=2;i<=n;i++) tot+=phi[i],v[p[i]]++;
	ans+=1ll*n*(n-1)/2-tot; //dis=1
	int u=1;for (int i=1;i<=cnt;i++) if (prime[i]>n/2+1) u++;
	tot-=1ll*u*(n-1);tot+=1ll*u*(u-1)/2; //dis=0 tot=dis2+dis3
	ans+=tot*3;
	/*for (int i=2;i<=n;i++)
		for (int j=2;j<i;j++)
		{
		if (gcd(i,j)==1&&1ll*p[i]*p[j]<=n) ans--,cout<<i<<' '<<j<<endl;}
	cout<<ans;return 0;*/
	for (int i=1;i<=cnt;i++)
	if (prime[i]<=n/2)
	{
		for (int j=1;j<i;j++)
		if (prime[i]*prime[j]<=n) ans--;
		else break;
		for (int j=1;j<=cnt;j++)
		if (prime[j]<=n/prime[i]) ans-=v[prime[j]];
		else break;
		for (int j=prime[i]*2;j<=n;j+=prime[i])
		if (p[j]<=n/prime[i]) ans++;
	}
	else break;
	u=0;
	for (int i=2;i<=n;i++)
	if (flag[i])
	{
		ans-=i-2;
		ans+=i-1-phi[i];
		ans+=u;
		int v=i;while (v>1) ans-=!f[p[v]],f[p[v]]=1,v/=p[v];
		v=i;while (v>1) f[p[v]]=0,v/=p[v];
	}
	else u++;
	cout<<ans;
	return 0;
	//NOTICE LONG LONG!!!!!
}
//dis=0 gcd=1 ����֮һ��1��>n/2������
//dis=1 gcd>1
//dis=2 gcd=1 ������С�����ӵĳ˻�<=n �Ҳ�Ϊ1
//��������Ϊ���������С������֮��һ��<=n
//ö�ٽϴ���� ��С��Ӧ�Ǻ��������以��
//���б���С���� ������������ ���������ʵ� �����������Ҳ����ʵ�
//��������Ϊ���� ��
//��һ��������һ��Ϊ���� ���ж��ٸ�������С������<x �Ҳ������������� ��
//dis=3 gcd=1 (gcd=1)-(dis=0)-(dis=2)

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

const int MN = 10000010;

vector<int> pr;
int pchk[MN];

void sieve() {
    for(int i = 2; i < MN; i++) {
        if(!pchk[i]) {
            pr.push_back(i);
            pchk[i] = i;
        }
        for(int j = 0; j < pr.size() && i * pr[j] < MN; j++) {
            pchk[ i * pr[j] ] = pr[j];
            if(i % pr[j] == 0) break;
        }
    }
}

int N;
ll dp[MN], ans;
int C[MN];

int main() {
    sieve();

    cin >> N;
    //N = 1e7;

    for(int i = N; i >= 1; i--) {
        dp[i] = 1LL * (N / i) * (N / i);
        for(int j = 2; i * j <= N; j++) {
            dp[i] -= dp[i * j];
        }
    }

    ans += (1LL * N * (N - 1) / 2) - dp[1] / 2;
    ans += dp[1] / 2 * 3;

    int cnt = 0;
    for(int i = 0; i < pr.size(); i++) {
        if(pr[i] > N) break;
        if(pr[i] > N / 2) cnt++;
    }

    ans -= 3LL * (N - 2) * cnt + 3LL * cnt * (cnt - 1) / 2;
    ans -= 3 * (N - 1);

    for(int i = 2; i <= N; i++) {
        if(pchk[i]) C[ pchk[i] ]++;
    }

    ll x = 0;
    for(int i = 0; i < pr.size(); i++) {
        for(int j = i; j < pr.size(); j++) {
            if(1LL * pr[i] * pr[j] > N) break;

            if(i == j) x += 1LL * C[ pr[i] ] * (C[ pr[i] ] - 1) / 2;
            else x += 1LL * C[ pr[i] ] * C[ pr[j] ];
        }
    }

    ans -= x - (1LL * N * (N - 1) / 2 - dp[1] / 2);
    printf("%lld", ans);
}

#include<bits/stdc++.h>
using namespace std;
const int N=10000005;
typedef long long ll;
int miu[N],flag[N],b[N],tot,n;
void init(){
	miu[1]=1;
	for (int i=2;i<N;i++){
		if (!flag[i]){
			miu[i]=-1;
			b[++tot]=i;
		}
		for (int j=1;j<=tot;j++){
			int k=b[j]*i;
			if (k>=N)break;
			flag[k]=1;
			if (i%b[j]==0){
				miu[k]=0;
				break;
			}
			miu[k]=-miu[i];
		}
	}
}
signed main(){
	scanf("%d",&n);
	init();
	int cnt=1;
	for (int i=max(2,n/2+1);i<=n;i++)
		if (!flag[i])cnt++;
	ll ans=(ll)n*cnt*2-(ll)cnt*cnt;ans=-2*ans;
	ans-=cnt;
	ans+=(ll)n*n;
	for (int i=1;i<=n;i++)ans+=(ll)miu[i]*(n/i)*(n/i);
	if (ans<0)ans=0;
	printf("%lld\n",ans/2);
}

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int P(int N, vector<int>& stack)
{
	if (stack.size() == 1)
		return N / stack.back();

	int sum = 0;

	int x = stack.back();
	stack.pop_back();

	sum += P(N, stack);
	sum += N/x;
	sum -= P(N/x, stack);

	stack.push_back(x);

	return sum;
}

void prime_factors(int N, vector<int>& all, vector<int>& stack, vector<int>& c_ones, int i = 0, int x = 1)
{
	for ( ; i<all.size() && x*(int64_t)all[i] <= N ; i++)
	{
		stack.push_back(all[i]);
		c_ones[x*all[i]] = P(N, stack);
		prime_factors(N, all, stack, c_ones, i+1, x*all[i]);
		stack.pop_back();
	}
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);

	int N;
	cin >> N;
	int n = N+1;

	vector<int> factor(n, 0);
	vector<int> primes(n, 0);
	vector<int> count(n, 0);
	vector<int> pred(n, 0);
	vector<int> c_ones(n, 0);
	vector<int> all;
	all.reserve(n);

	for (int i=2 ; i<n ; i++)
	{
		if (primes[i])
			continue;

		all.push_back(i);
		for (int j=i ; j<n ; j+=i)
			if (!primes[j])
				factor[j] = primes[j] = i;
			else if (primes[j] % i)
				primes[j] *= i;
	}

	for (int i=2 ; i<n ; i++)
		count[factor[i]]++;
	for (int i=2 ; i<n ; i++)
		pred[i] = pred[i-1] + count[i];

	vector<int> stack;
	prime_factors(N, all, stack, c_ones);

	int64_t ones = 1;
	for (int i=0 ; i<n ; i++)
		if (primes[i])
			ones += c_ones[primes[i]];

	int64_t threes = 1;
	for (int x : all)
		if (x * 2 > N)
			threes++;
	threes = (N-threes)*(N-threes) + threes;

	/*int64_t twos = 1;
	for (int i=2 ; i<=N ; i++)
		for (int j=2 ; j<=N ; j++)
			if (i==j || factor[i] * factor[j] <= N)
				twos++;*/

	int64_t twos = 1;
	auto rj = all.rbegin(), re = all.rend();
	for (int i : all)
	{
		int row = 0;
		while (rj != re && *rj * (int64_t)i > N)
			rj++;
		if (rj != re)
			row = pred[*rj];
		/*for (int j=2 ; j<=N ; j++)
			if (i * factor[j] <= N)
				row++;*/
		if (i*(int64_t)i>N)
			row++;
		//cout << i << ": " << row << "\n";
		twos += count[i] * row;
	}
	//cout << "\n";

	/*int m = 0;
	for (int i=0 ; i<n ; i++)
		if (factor[i] && count[i])
		{
			m++;
			cout << i << ": " << count[i] << "\n";
		}*/
	//cout << "m=" << m << " ones=" << ones << " twos=" << twos << " threes=" << threes << "\n";

	//cout << all.size() << " " << all.back() << "\n";

	int64_t res = 0;
	res += 1 * (ones - N);
	res += 2 * (twos - ones);
	res += 3 * (threes - twos);
	cout << res/2 << "\n";

	return 0;
}

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n;
ll pri[10000005],p[10000005],phi[10000005],cnt,num[10000005];
bool vis[10000005];
void init(){
    phi[1]=1;
    for(int i=2;i<=n;i++){
        if(!vis[i]){
            p[i]=i;pri[++cnt]=i;phi[i]=i-1;
        }
        for(int j=1;j<=cnt&&i*pri[j]<=n;j++){
            vis[i*pri[j]]=1;p[i*pri[j]]=pri[j];
            if(i%pri[j]==0){
                phi[i*pri[j]]=phi[i]*pri[j];
                break;
            }else phi[i*pri[j]]=phi[i]*phi[pri[j]];
        }
    }
    for(int i=1;i<=n;i++) num[p[i]]++;
    for(int i=1;i<=n;i++) num[i]+=num[i-1];
    while(pri[cnt]>n/2) cnt--;
}
ll calc(int l,int r){return num[r]-num[l-1];}
int main(){
    cin>>n;
    init();
    ll tmp=(n-1)*(n-2)/2;
    for(int i=2;i<=n;i++) tmp+=phi[i]-1;
    ll ans=tmp;
    tmp=0;
    for(int i=1;i<=cnt;i++){
        int value=num[pri[i]]-num[pri[i]-1];
        ans+=value*calc(max(pri[i]+1,n/pri[i]+1),max(p[i]+1,n/2+1)-1);
        ans-=2*value*calc(max(pri[i]+1,n/2+1),n);
    }
    cout<<ans;
    return 0;
}

#include <stdio.h>
using ll=long long;
const int C=10000001;

//Lowest prime divisor inside pr[i], v is upper bound for numbers (x<v)
void supfactor(int* pr, int v){
	int i, j;
	pr[1]=1;
	for (i=2;i*i<v;i++){
		if (pr[i]==0) {
			for (j=i;j<v;j+=i){
			       if (pr[j]==0)	pr[j]=i;
			}
		}
	}
	for (;i<v;i++)	if (pr[i]==0)	pr[i]=i;
}

void mobiusize(int pr[], int mobius[], int v){
	int i, j, ij;
	for (i=1;i<v;i++) mobius[i]=-1;

	for (i=2;i<v;i++){
		if (i==pr[i]){
			for (j=i,ij=1; j<v; j+=i,ij++){
				if (ij%i!=0) mobius[j]*=(-1);
				else mobius[j]=0;
			}

		}
	}
}

int primes[C], dead[C], mobius[C], csc_primes[C], csc_non_primes[C];
int main(){
	ll n, i, j, t0=0, t1=0, t2=0, t3=0, funerals=0, amount=0, tpr=0, tnpr=0;
	scanf ("%lld", &n);
	supfactor(primes, C);

	for (i=2;i<=n;i++){
		if (i*2>n && primes[i]==i) dead[i]=1, funerals++;
	}
	if (dead[1]==0) dead[1]=1, funerals++;
	t0=funerals*(n-1)-(funerals*(funerals-1))/2;

	mobiusize(primes, mobius, C);
	for (i=2; i<=n; i++){
		amount=n/i;
		t1+=mobius[i]*(amount*(amount-1))/2;
	}

	for (i=1;i<=n;i++){
		if (dead[i]==1) continue;
		if (primes[i]==i) csc_non_primes[primes[i]]++;
		else csc_primes[primes[i]]++;
	}

	for (i=n-1;i>0;i--) csc_non_primes[i]+=csc_non_primes[i+1];
	for (i=n-1;i>0;i--) csc_primes[i]+=csc_primes[i+1];

	for (i=2;i<=n;i++) {
		if (primes[i]==i && dead[i]==0){
			tpr+=csc_primes[n/i+1];
			tnpr+=csc_non_primes[n/i+1];
			for (j=i;j<=n;j+=i){
				if (primes[j]*i>n) tnpr--;
			}
		}
	}
	t3=tnpr+tpr/2;
	t2=n*(n-1)/2-t0-t1-t3;
	printf ("%lld\n", t1+2*t2+3*t3);

return 0;}

#include<bits/stdc++.h>
using namespace std;
const int N=10000005;
typedef long long ll;
int miu[N],flag[N],b[N],tot,n;
void init(){
	miu[1]=1;
	for (int i=2;i<N;i++){
		if (!flag[i]){
			miu[i]=-1;
			b[++tot]=i;
		}
		for (int j=1;j<=tot;j++){
			int k=b[j]*i;
			if (k>=N)break;
			flag[k]=1;
			if (i%b[j]==0){
				miu[k]=0;
				break;
			}
			miu[k]=-miu[i];
		}
	}
}
signed main(){
	scanf("%d",&n);
	init();
	int cnt=1;
	for (int i=max(2,n/2+1);i<=n;i++)
		if (!flag[i])cnt++;
	ll ans=(ll)n*cnt*2-(ll)cnt*cnt;ans=-2*ans;
	ans-=cnt;
	ans+=(ll)n*n;
	for (int i=1;i<=n;i++)ans+=(ll)miu[i]*(n/i)*(n/i);
	printf("%lld\n",ans/2);
}

#include <iostream>
#include <vector>

using namespace std;

typedef long long ll;

const int MAX_N = 1e7 + 5;

ll pairc (ll n) {
  return (n * (n - 1)) / 2;
}

int factor [MAX_N];
int sieve [MAX_N];
int cspf [MAX_N];
int mobius [MAX_N];
int nxtp [MAX_N];

int main () {
  ll n;
  cin >> n;

  vector<int> primes;
  for (int i = 2; i <= n; i++) {
    if (!sieve[i]) {
      nxtp[i] = i;
      primes.push_back(i);
      for (int j = i; j <= n; j += i) {
        factor[j] = i;
        if (!sieve[j]) {
          sieve[j] = 1;
          cspf[i]++;
        }
      }
    }
  }

  for (int i = 2; i <= n; i++) {
    if (factor[i] == i) {
      mobius[i] = 1;
    } else if (factor[i / factor[i]] == factor[i]) {
      mobius[i] = 0;
    } else {
      mobius[i] = -mobius[i / factor[i]];
    }
  }

  for (int i = n - 1; i >= 0; i--) {
    cspf[i] += cspf[i + 1];
    if (nxtp[i] == 0) nxtp[i] = nxtp[i + 1];
  }

  ll isol = 0;
  for (int i = 2; i <= n; i++) {
    if (factor[i] != i || 2 * i <= n) {
      isol++;
    }
  }
  ll ans = isol * (isol - 1);

  // cerr << " " << isol << endl;
  // cerr << ans << endl;

  // calculate # of "big pairs"
  ll bigp = 0;
  for (int p : primes) {
    if (2 * p <= n) {
      ll s = n / p + 1; // smallest s.t. s * p > n
      ll curc = cspf[s];
      if (s <= p) {
        // subtract p itself and its multiples
        curc -= n / p;
      }

      if (nxtp[s] != 0 && 2 * nxtp[s] <= n) {
        bigp += curc;
      }
    }
  }
  bigp /= 2;
  ans += bigp;

  //  cerr << bigp << endl;

  // calculate # of "small pairs"
  ll smallp = 0;
  for (int i = 2; i <= n; i++) {
    smallp += mobius[i] * pairc(n / i);
  }

  // cerr << smallp << endl;
  ans -= smallp;

  cout << ans << endl;
}

#include <bits/stdc++.h>
using namespace std;
const int N=1e7+10,M=1e6+100;;
int n,v[N],p[M],w,mu[N],sum[M];
int cnt[M],pos,tr[N],to[M];
inline long long get1(int n)
{
	long long ans=0;
	for (int l=1,r;l<=n;l=r+1)
	{
		r=n/(n/l);
		ans+=1ll*(mu[r]-mu[l-1])*(n/l)*(n/l);
	}
	ans=(ans-1)/2;
	return ans;
}
inline long long get3(int n)
{
	long long ans=0;
	for (int i=1,j=pos;i<=pos;i++)
	{
		while (p[j]>n/p[i] && j>=1) j--;
		ans+=1ll*(sum[i]-sum[i-1])*(sum[pos]-sum[j]);
	}
	for (int i=1;i<=pos;i++) if (p[i]*p[i]>n) ans-=1ll*(sum[i]-sum[i-1])*(sum[i]-sum[i-1]);
	ans/=2;
	return ans;
}
inline int get0(int n)
{
	int ans=0;
	for (int i=1,j=w;i<=w;i++)
	{
		while (p[j]>n/p[i] && j>=1) j--;
		if (i>pos) ans+=1ll*(sum[i]-sum[i-1])*(sum[w]-sum[j]);
		else ans+=1ll*(sum[i]-sum[i-1])*(sum[w]-sum[max(pos,j)]);
	}
	for (int i=pos+1;i<=w;i++) if (p[i]*p[i]>n) ans-=1ll*(sum[i]-sum[i-1])*(sum[i]-sum[i-1]);
	ans/=2;
	return ans;
}
int main()
{
	scanf("%d",&n);
	mu[1]=1;v[1]=1;
	for (int i=2;i<=n;i++)
	{
		if (!v[i])
		{
			v[i]=p[++w]=i;
			tr[i]=w;
			sum[w]++;
			mu[i]=-1;
		}
		for (int j=1;j<=w;j++)
		{
			if (p[j]>v[i] || p[j]>n/i) break;
			sum[j]++;
			v[p[j]*i]=p[j];
			if (i%p[j]==0) mu[i*p[j]]=0;
			else mu[i*p[j]]=-mu[i];
		}
	}
	for (int i=1;i<=n;i++) mu[i]+=mu[i-1];
	for (int i=1;i<=w;i++) if (p[i]+p[i]<=n) pos=i;
	for (int i=1;i<=w;i++) sum[i]+=sum[i-1];
	long long one,zero,two,three;
	one=1ll*n*(n-1)/2-get1(n);
	three=get3(n);
	zero=get0(n);
	two=1ll*(n-2)*(n-1)/2-one-zero-three;
	printf("%lld\n",one+two*2+three*3);
}

#pragma region Macros
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define rep2(i,a,b) for(ll i=a;i<=b;++i)
#define rep(i,n) for(ll i=0;i<n;i++)
#define rep3(i,a,b) for(ll i=a;i>=b;i--)
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pq priority_queue
#define pb push_back
#define eb emplace_back
#define vec vector<int>
#define vecll vector<ll>
#define vecpii vector<pii>
#define vecpll vector<pll>
#define vec2(a,b) vector<vec>(a,vec(b))
#define vec2ll(a,b) vector<vecll>(a,vecll(b))
#define vec3(a,b,c) vector<vector<vec>>(a,vec2(b,c))
#define vec3ll(a,b,c) vector<vector<vecll>>(a,vec2ll(b,c))
#define fi first
#define se second
#define all(c) begin(c),end(c)
#define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define lb(c,x) distance(c.begin(),lower_bound(all(c),(x)))
#define ub(c,x) distance(c.begin(),upper_bound(all(c),(x)))
using namespace std;
int in() {int x;cin>>x;return x;}
ll lin() {ll x;cin>>x;return x;}
string stin() {string s;cin>>s;return s;}
template<class T> inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T> inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
vec iota(int n){vec a(n);iota(all(a),0);return a;}
void print(){putchar(' ');}
void print(bool a){cout<<a;}
void print(int a){cout<<a;}
void print(long long a){cout<<a;}
void print(char a){cout<<a;}
void print(string &a){cout<<a;}
void print(double a){cout<<a;}
template<class T> void print(const vector<T>&);
template<class T, size_t size> void print(const array<T, size>&);
template<class T, class L> void print(const pair<T, L>& p);
template<class T, size_t size> void print(const T (&)[size]);
template<class T> void print(const vector<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout<<" "; print(*i); } cout<<endl;}
template<class T> void print(const deque<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout<<" "; print(*i); } }
template<class T, size_t size> void print(const array<T, size>& a){ print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout<<" "; print(*i); } }
template<class T, class L> void print(const pair<T, L>& p){ cout<<'(';print(p.first); cout<<","; print(p.second);cout<<')'; }
template<class T, size_t size> void print(const T (&a)[size]){ print(a[0]); for(auto i = a; ++i != end(a); ){ cout<<" "; print(*i); } }
template<class T> void print(const T& a){ cout << a; }
int out(){ putchar('\n'); return 0; }
template<class T> int out(const T& t){ print(t); putchar('\n'); return 0; }
template<class Head, class... Tail> int out(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); return 0; }
ll gcd(ll a, ll b){ while(b){ ll c = b; b = a % b; a = c; } return a; }
ll lcm(ll a, ll b){ if(!a || !b) return 0; return a * b / gcd(a, b); }
#define _GLIBCXX_DEBU
#define endl '\n'
#ifdef _MY_DEBUG
    #undef endl
    #define debug(x) cout<<#x<<": "<<x<<endl
    void err(){}
    template<class T> void err(const T& t){ print(t);  cout<<" ";}
    template<class Head, class... Tail> void err(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); }
#else
    #define debug(x)
    template<class... T> void err(const T&...){}
#endif
#pragma endregion

signed main(){
    ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);cout<<fixed<<setprecision(15);
    int n=in();
    if(n==1){cout<<0<<endl;return 0;}
    vec a(n+1);
    rep2(i,1,n)a[i]=i;
    vec p(n+1,1);
    p[1]=1;
    vector<vec> div(n+1);
    vec primes;
    rep2(i,2,n){
        if(p[i]){
            primes.pb(i);
            for(int j=i*2;j<=n;j+=i)p[j]=0;
        }
    }
    vec min_prime(n+1);
    vec cnt(n+1);
    rep2(i,2,n){
        if(p[i]){
            for(int j=i;j<=n;j+=i){
                if(!min_prime[j]){
                    min_prime[j]=1;
                    cnt[i]++;
                }
                a[j]/=i;
                a[j]*=i-1;
            }
        }
    }
    vec rui(n+1);
    rep2(i,2,n)rui[i]=rui[i-1]+cnt[i];
    ll ans=0;
    ans+=n*(n-1)/2;
    rep2(i,2,n) ans+=a[i];
    rep2(i,2,n){
        ans+=(ll)cnt[i]*max(0,rui[i-1]-rui[n/i]);
    }
    ans-=(n-1)*2;
    ll C=0;
    rep2(i,(n+2)/2,n){
        if(p[i])ans-=(n-2)*3,C++;
    }
    ans+=(C*(C-1))/2*3;
    cout<<ans<<endl;
}

#include <iostream>
#include <set>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <random>
#include <chrono>
#include <queue>
#include <unordered_map>
#include <unordered_set>

using namespace std;

mt19937 twister(chrono::steady_clock().now().time_since_epoch().count());
//mt19937 twister(8);

const int mod = 1e9 + 7;
const int maxn = 1e7 + 88;
const int inf = 1e9 + 88;
const int logn = 22;
const int maxa = 3e6 + 88;
const char sgl[5] = {'a', 'e', 'i', 'o', 'u'};
const char sep = 'a' - 1;

int readint()
{
    int cur;
    scanf("%d", &cur);
    return cur;
}

//int sum(int a, int b)
//{
//    return (1ll*a + 1ll*b + mod)%mod;
//}

int umn(int a, int b)
{
    return (1ll*a*b)%mod;
}

void maxi(int &a, int b)
{
    a = max(a, b);
}

void mini(int &a, int b)
{
    a = min(a, b);
}

int rnd(int l, int r)
{
    return abs((int)twister())%(r - l + 1) + l;
}

int n;
long long bad;
int p[maxn], pr[maxn], phi[maxn], sum[maxn], cnt[maxn];

void calc()
{
    int i, j;
    for (i = 2; i <= n; i++)
        phi[i] = i;
    for (i = 2; i <= n; i++)
        if (!p[i])
            for (j = i; j <= n; j += i)
            {
                cnt[j]++;
                if (!p[j])
                    p[j] = i;
                phi[j] /= i;
                phi[j] *= (i - 1);
            }
    for (i = 2; i <= n; i++)
        sum[i] = sum[i - 1] + (2*i <= n && p[i] == i ? 1 : 0);
    long long cur = 1;
    for (i = 2; i <= n; i++)
        if (i*2 > n && p[i] == i)
            cur++;
    bad += (cur)*(cur - 1)/2;
    bad += (cur)*(n - cur);
}

long long find1()
{
    long long res = 0;
    for (int i = 2; i <= n; i++)
        res += i - phi[i] - 1;
    return res;
}

long long find2()
{
    long long res = 0;
    int i, j;
    for (i = 2; i <= n; i++)
        if (p[i] != i)
            res += phi[i] - (sum[i] - cnt[i] + 1);
    res /= 2;
    for (i = 2; i <= n; i++)
        pr[p[i]]++;
    for (i = 2; i <= n; i++)
        pr[i] += pr[i - 1];
    long long cur = 0;
    for (i = 2; 2*i <= n; i++)
        if (p[i] == i)
        {
            res += pr[n/i];
            for (j = i; j <= n; j += i)
                if (p[j] <= n/i)
                    res--;
        }
    for (i = 2; 2*i <= n; i++)
        if (p[i] == i)
            cur += sum[n/i] - (n/i >= i ? 1 : 0);
    cur /= 2;
    return res - cur;
}

void solve()
{
    n = readint();
    calc();
    long long cnt1 = find1();
    long long cnt2 = find2();
    long long cnt3 = 1ll*n*(n - 1)/2 - cnt1 - cnt2 - bad;
    long long ans = cnt1 + cnt2*2 + cnt3*3;
    printf("%I64d", ans);
}

int main()
{
//    freopen("output.txt", "w", stdout);
//    freopen("war.in", "r", stdin);
//    freopen("war.out", "w", stdout);
    solve();
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 1e+7 + 10;

bool isnotp[maxn];short int u[maxn];
ll p[664539],pn;
ll cnt[664539],sum[664539];
ll n,ans;

void pre()
{
	int i,j;

	for(i=2;i<=n;i++)
	{
		if(!isnotp[i])
		{
			p[pn]=i;
			u[i]=cnt[pn++]=1;
		}
		for(j=0;j<pn && i*p[j]<=n;j++)
		{
			isnotp[i*p[j]]=true;
			u[i*p[j]]=-u[i];
			cnt[j]++;
			if(!(i%p[j]))
			{
				u[i*p[j]]=0;
				break;
			}
		}
	}cerr<<pn;

	sum[0]=cnt[0];
	for(i=1;i<pn;i++) sum[i]=sum[i-1]+cnt[i];
}

void solve()
{
	ll i,j,pos,tsum;

	ans=0;

	for(i=0;i<pn;i++)
	{
		ans+=cnt[i]*(cnt[i]-1);
		for(j=i+1;p[j]*p[i]<=n;j++) ans+=cnt[i]*cnt[j]*2;
	}//cerr<<ans<<endl;

	for(pos=0;p[pos]<=n/2;pos++);j=--pos;
	for(i=1;p[i]<=n/2;i++)
	{
		for(;p[j]*p[i]>n;j--);
		ans+=cnt[i]*(sum[pos]-sum[max(j,i)])*3;
	}

	for(i=2;i<=n;i++) if(u[i])
	{
		ans-=u[i]*(n/i)*(n/i-1)/2;
	}

	cout<<ans<<endl;
}

int main()
{
//	freopen("2368.in","r",stdin);
//	freopen("2368.out","w",stdout);

	cin>>n;
	pre();
	solve();

	return 0;
}

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int,int> pii;

const int maxn=10000003;

int phi[maxn],pr[maxn],c[maxn],mnp[maxn],sz,npr[maxn],n,a[maxn];
ll ans,sum;

ll get(int l,int r){
	if(l>r)return 0;
	return a[r]-a[l-1];
}

int main(){
	scanf("%d",&n);
	phi[1]=1;
	for(int i=2;i<=n;++i){
		if(!npr[i]){
			pr[++sz]=i;
			c[i]=i;
			phi[i]=i-1;
		}
		for(int j=1;j<=sz&&1ll*pr[j]*i<=n;++j){
			npr[i*pr[j]]=true;
			mnp[i*pr[j]]=pr[j];
			c[i*pr[j]]=pr[j];
			if(i%pr[j]==0){
				phi[i*pr[j]]=phi[i]*pr[j];
				break;
			}
			phi[i*pr[j]]=phi[i]*phi[pr[j]];
		}
	}
	ans=1ll*(n-2)*(n-1)/2;
	for(int i=2;i<=n;++i)sum+=phi[i]-1,a[c[i]]++;
	ans+=sum;
	for(int i=1;i<=n;++i)a[i]+=a[i-1];
	for(int i=1;i<=sz;++i){
		ll x=get(max(pr[i]+1,n/pr[i]+1),max(pr[i]+1,n/2+1)),y=a[pr[i]]-a[pr[i]-1];
		ll z=get(max(pr[i]+1,n/2+1),n);
		ans+=y*x;
		ans-=2*y*z;
	}
	printf("%lld\n",ans);
	return 0;
}

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <set>
#include <queue>
#define maxn 10000005
#define ll long long
using namespace std;
int mst[maxn], phi[maxn];
bool bpr[maxn];
int cnt[maxn];
int prs[maxn], prcnt = 0;
ll c(ll a){return a * (a - 1) / 2;}
int main()
{
	int n;
	scanf("%d", &n);
	for(int i = 1; i <= n; i++)
		bpr[i] = 1, mst[i] = i, phi[i] = i;
	//prs[prcnt++] = 1;
	for(int i = 2; i <= n; i++)
	{
		if(!bpr[i]) continue;
		prs[prcnt++] = i;
		for(int j = 2; j * i <= n; j++)
			bpr[i * j] = 0;
		for(int j = 1; j * i <= n; j++)
		{
			if(i < mst[j * i]) mst[j * i] = i;
			phi[j * i] /= i, phi[j * i] *= (i - 1);
		}
	}
	for(int i = 1; i <= n; i++)
		cnt[mst[i]]++;
	ll tot1 = 0, tot2 = 0, tot3 = 0;
	for(int i = 2; i <= n; i++)
		tot1 += (i - 1 - phi[i]);
	for(int i = 0; i < prcnt; i++)
		for(int j = i; prs[j] * prs[i] <= n && j < prcnt; j++)
		{
			if(i != j) tot2 += cnt[prs[i]] * (ll)cnt[prs[j]];
			else tot2 += c(cnt[prs[i]]);
		}
	int ns = 0;
	for(int i = 0; i < prcnt; i++)
		if(prs[i] * 2 > n) ns++;
	ns++;
	tot3 = (ll)(n - ns) * (ll)(n - ns - 1) / 2;
	ll ans = tot1 + 2 * (tot2 - tot1) + 3 * (tot3 - tot2);
//	cout<<tot1<<" "<<tot2<<" "<<tot3<<endl;
	printf("%I64d\n", ans);
	return 0;
}

#include<bits/stdc++.h>
#define For(i,l,r) for(int i = (l),i##end = (r);i <= i##end;i++)
#define Fordown(i,r,l) for(int i = (r),i##end = (l);i >= i##end;i--)
#define debug(x) cout << #x << " = " << x << endl

using namespace std;

typedef long long ll;

template <typename T> inline bool chkmin(T &x,T y) { return y < x ? x = y,1 : 0; }
template <typename T> inline bool chkmax(T &x,T y) { return x < y ? x = y,1 : 0; }

const int INF = 0x3f3f3f3f;
const int N = 1e7 + 10;

int phi[N],prime[N],Min[N],sum[N];
int pcnt = 0;
bitset <N> vis;

inline int read() {
	int x = 0,flag = 1;
	char ch = getchar();
	while(!isdigit(ch) && ch != '-') ch = getchar();
	if(ch == '-') flag = -1,ch = getchar();
	while(isdigit(ch)) x = (x << 3) + (x << 1) + (ch - '0'),ch = getchar();
	return x * flag;
}

inline void init(int n) {
	phi[1] = 1;
	For(i,2,n) {
		if(!vis[i]) prime[++pcnt] = i,phi[i] = i - 1,sum[Min[i] = i]++;
		for(int j = 1;j <= pcnt && i * prime[j] <= n;j++) {
			vis[i * prime[j]] = true;
			phi[i * prime[j]] = phi[i] * (prime[j] - 1);
			sum[Min[i * prime[j]] = min(Min[i],prime[j])]++;
			if(i % prime[j] == 0) {
				phi[i * prime[j]] = phi[i] * prime[j];
				break;
			}
		}
	}
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("CF871D.in","r",stdin);
	freopen("CF871D.out","w",stdout);
#endif

	int n = read();ll cnt = 1;
	init(n);
	ll ans0 = 0,ans1 = 0,ans2 = 0,ans3 = 0;

	For(i,n / 2 + 1,n) cnt += !vis[i];
	ans0 = 1ll * cnt * (n - 1) - 1ll * cnt * (cnt - 1) / 2,cnt = 0;

	For(i,2,n) cnt += phi[i];
	ans1 = 1ll * n * (n - 1) / 2 - cnt,cnt = 0;

	Fordown(i,n,1) sum[i] += sum[i + 1];
	cnt += (n - 1);
	For(i,1,pcnt) cnt += sum[n / prime[i] + 1];
	For(i,1,n) sum[i] = sum[i + 1] + !vis[i];
	For(i,1,pcnt) cnt -= sum[max(n / prime[i] + 1,prime[i])];
	ans2 = 1ll * n * (n - 1) / 2 - ans1 - cnt;

	ans3 = 1ll * n * (n - 1) / 2 - ans0 - ans1 - ans2;

	printf("%lld\n",ans1 + 2 * ans2 + 3 * ans3);
	return 0;
}

#include<deque>
#include<queue>
#include<vector>
#include<algorithm>
#include<iostream>
#include<set>
#include<cmath>
#include<tuple>
#include<string>
#include<chrono>
#include<functional>
#include<iterator>
#include<random>
#include<unordered_set>
#include<unordered_map>
#include<array>
#include<map>
#include<iomanip>
using namespace std;
typedef long long int llint;
typedef long double lldo;
#define mp make_pair
#define mt make_tuple
#define pub push_back
#define puf push_front
#define pob pop_back
#define pof pop_front
#define fir first
#define sec second
#define res resize
#define ins insert
#define era erase
#define dme cout<<-1<<endl;return 0
//ios::sync_with_stdio(false);
//<< setprecision(5)
const int mod=1000000007;
const llint big=1e18+100;
const long double pai=3.141592653589793238462643383279502884197;
const long double ena=2.71828182845904523536;
const long double eps=1e-7;
template <class T,class U>void mineq(T& a,U b){if(a>b){a=b;}}
template <class T,class U>void maxeq(T& a,U b){if(a<b){a=b;}}
llint gcd(llint a,llint b){if(a%b==0){return b;}else return gcd(b,a%b);}
llint lcm(llint a,llint b){return a/gcd(a,b)*b;}
//隣に線を張る
vector<vector<int>>yaku;
void init(int n){
	int i,j;
	yaku.res(n+1);
	for(i=2;i<=n/2;i++){
		if(yaku[i].size()>0){continue;}
		for(j=i;j<=n;j+=i){
			yaku[j].pub(i);
		}
	}

}
int hou(int n,int ter){
	//gcd!=1の数
	llint ret=0;
	for(llint bit=1;bit<(1LL<<(llint)yaku[ter].size());bit++){
		llint gen=1;
		llint kazu=0;
		for(int j=0;j<yaku[ter].size();j++){
			if((bit&(1LL<<j))==0){continue;}
			gen*=yaku[ter][j];
			kazu++;
		}
		if(kazu%2==1){ret+=n/gen;}
		else{ret-=n/gen;}
	}
	return ret;
}
int main(void){
	int n,K,i,j;
	cin>>n;
	init(n);
	int muri=0;
	vector<int>imos(n+1);
	for(i=2;i<=n;i++){
		if(yaku[i].empty()){muri++;continue;}
		imos[yaku[i][0]]++;
	}
	for(i=2;i<n;i++){imos[i+1]+=imos[i];}
	llint ans=0;
	for(i=2;i<=n;i++){
		if(yaku[i].empty()){continue;}
		int one,two,thr=0;
		one=hou(n,i);
		two=imos[n/yaku[i][0]];
		thr=n-muri;
		ans+=one;
		ans+=2*(two-one);
		ans+=3*(thr-two);
		ans-=4;

	}
	cout<<ans/2<<endl;
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=10000005;
typedef long long ll;
int miu[N],flag[N],b[N],tot,Cnt2[N],Cnt[N],n,Min[N];
void init(){
	miu[1]=1;
	for (int i=2;i<N;i++){
		if (!flag[i]){
			miu[i]=-1;
			Min[i]=i;
			b[++tot]=i;
		}
		for (int j=1;j<=tot;j++){
			int k=b[j]*i;
			if (k>=N)break;
			flag[k]=1;
			if (i%b[j]==0){
				miu[k]=0;
				Min[k]=Min[i];
				break;
			}
			miu[k]=-miu[i];
			Min[k]=min(Min[i],b[j]);
		}
	}
}
signed main(){
	scanf("%d",&n);
	init();
	int cnt=1;
	for (int i=max(2,n/2+1);i<=n;i++)
		if (!flag[i])cnt++;
	ll ans=(ll)n*cnt*2-(ll)cnt*cnt;ans=-2*ans;
	ans+=(ll)n*n-n;ans+=2*cnt;ans--;
	for (int i=1;i<=n;i++)ans+=(ll)miu[i]*(n/i)*(n/i);
	for (int i=2;i<=n;i++)
		if (i*2<=n||flag[i])Cnt[Min[i]]++;
	cout<<ans<<endl;
	for (int i=n;i;i--)Cnt2[i]=Cnt2[i+1]+Cnt[i];
	for (int i=n;i;i--){
		ans+=(ll)Cnt[i]*Cnt2[n/i+1];
		if ((ll)i*i>n)ans-=Cnt[i]*Cnt[i];
		//Cnt2[i]=Cnt[i]+Cnt2[i+1];
	//	cout<<i<<' '<<ans<<endl;
	}
	cout<<ans<<endl;
	ans/=2;
	printf("%lld\n",ans);
}

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e7+10,M=1e6+100;;
int n,v[N],p[M],w,mu[N],sum[M];
int cnt[M],pos,tr[N],to[M];
inline long long get1(int n)
{
	long long ans=0;
	for (int l=1,r;l<=n;l=r+1)
	{
		r=n/(n/l);
		ans+=1ll*(mu[r]-mu[l-1])*(n/l)*(n/l);
	}
	ans=(ans-1)/2;
	return ans;
}
inline long long get3(int n)
{
	long long ans=0;
	for (int i=1,j=pos;i<=pos;i++)
	{
		while (p[j]>n/p[i] && j>=1) j--;
		ans+=1ll*(sum[i]-sum[i-1])*(sum[pos]-sum[j]);
	}
	for (int i=1;i<=pos;i++) if (p[i]>n/p[i]) ans-=1ll*(sum[i]-sum[i-1])*(sum[i]-sum[i-1]);
	ans/=2;
	return ans;
}
inline int get0(int n)
{
	int ans=0;
	for (int i=1,j=w;i<=w;i++)
	{
		while (p[j]>n/p[i] && j>=1) j--;
		if (i>pos) ans+=1ll*(sum[i]-sum[i-1])*(sum[w]-sum[j]);
		else ans+=1ll*(sum[i]-sum[i-1])*(sum[w]-sum[max(pos,j)]);
	}
	for (int i=pos+1;i<=w;i++) if (p[i]>n/p[i]) ans-=1ll*(sum[i]-sum[i-1])*(sum[i]-sum[i-1]);
	ans/=2;
	return ans;
}
signed main()
{
	scanf("%lld",&n);
	mu[1]=1;v[1]=1;
	for (int i=2;i<=n;i++)
	{
		if (!v[i])
		{
			v[i]=p[++w]=i;
			tr[i]=w;
			sum[w]++;
			mu[i]=-1;
		}
		for (int j=1;j<=w;j++)
		{
			if (p[j]>v[i] || p[j]>n/i) break;
			sum[j]++;
			v[p[j]*i]=p[j];
			if (i%p[j]==0) mu[i*p[j]]=0;
			else mu[i*p[j]]=-mu[i];
		}
	}
	for (int i=1;i<=n;i++) mu[i]+=mu[i-1];
	for (int i=1;i<=w;i++) if (p[i]+p[i]<=n) pos=i;
	for (int i=1;i<=w;i++) sum[i]+=sum[i-1];
	long long one,zero,two,three;
	one=1ll*n*(n-1)/2-get1(n);three=get3(n);zero=get0(n);
	two=1ll*(n-2)*(n-1)/2-one-zero-three;
	printf("%lld %lld %lld %lld\n",one,two,three,zero);
	printf("%lld\n",one+two*2+three*3);
}

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

#define pii pair<int,int>
#define pll pair<ll,ll>
#define PB push_back
#define MP make_pair
#define N 10000001

int leastPrime[N], d[N], r[N], s[N];
ll c[N];

int GetCount(int i, int j, int x){
  int ans = s[j] - s[i];
  while(x > 1){
    int k = leastPrime[x];
    if(i < k && k <= j)
      ans -= d[k];
    while(x % k == 0)
      x /= k;
  }
  return ans;
}

int main(){
  int n;
  ll ans = 0;

  cin >> n;

  for(int i = 1; i <= n; ++i)
    c[i] = 1;

  for(int i = 1; i <= n; ++i){
    for(int j = i + i; j <= n; j += i){
      c[i] += c[j];
    }
  }

  for(int i = 1; i <= n; ++i)
    c[i] = c[i] * (c[i] - 1) / 2;

  for(int i = n; i > 0; --i){
    for(int j = i + i; j <= n; j += i){
      c[i] -= c[j];
    }
  }

  ans = 1ll * n * (n - 1) / 2 - c[1];

  for(int i = 2; i <= n; ++i){
    for(int j = i; j <= n; j += i){
      if(leastPrime[j] == 0){
        leastPrime[j] = i;
        ++d[i];
      }
    }
    s[i] = s[i - 1] + d[i];
  }

  for(int i = 1, j = 1; i <= n; ++i){
    for( ; i * j <= n; ++j);
    for( ; i * j > n; --j);
    r[i] = j;
  }

  for(int x = 2, k = n / 2; x <= n; ++x){
    int i = leastPrime[x], j = r[i];
    if(i <= j){
      ans += 2ll * GetCount(i, j, x);
      if(j <= k)
        ans += 3ll * GetCount(j, k, x);
    }
    else{
      if(i <= k)
        ans += 3ll * GetCount(i, k, x);
    }
  }

  cout << ans << '\n';

  return 0;
}

#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <utility>

#undef min
#undef max

using namespace std;

void SolveA()
{
    //ifstream cin("../input.txt");
    size_t q;
    cin >> q;
    for( size_t i = 0; i < q; ++i )
    {
        size_t n;
        cin >> n;
        size_t res = 0;
        if( (n % 2) )
        {
            if( n < 9 )
            {
                cout << "-1\n";
                continue;
            }
            n -= 9;
            ++res;
        }

        if( n % 4 )
        {
            if( n < 6 )
            {
                cout << "-1\n";
                continue;
            }
            n -= 6;
            ++res;
        }

        res += (n/4);
        cout << res << "\n";
    }

    //cout.flush();
}

void SolveC()
{
    //ifstream cin("../input.txt");
    size_t n;
    cin >> n;
    vector<int> x(n), y(n), newX(n), newY(n);
    for( size_t i = 0; i < n; ++i )
    {
        cin >> x[i] >> y[i];
    }

    vector<size_t> ind(n);

    for( size_t i = 0; i < n; ++i )
        ind[i] = i;
    make_heap( ind.begin(), ind.end(), [&x] ( size_t i1, size_t i2 ) -> bool { return x[i1] < x[i2]; } );
    sort_heap( ind.begin(), ind.end(), [&x] ( size_t i1, size_t i2 ) -> bool { return x[i1] < x[i2]; } );
    newX[ind[0]] = 0;
    for( size_t i = 1; i < n; ++i )
        newX[ind[i]] = newX[ind[i-1]] + (( x[ind[i]] == x[ind[i-1]] ) ? 0 : 1);

    for( size_t i = 0; i < n; ++i )
        ind[i] = i;
    make_heap( ind.begin(), ind.end(), [&y] ( size_t i1, size_t i2 ) -> bool { return y[i1] < y[i2]; } );
    sort_heap( ind.begin(), ind.end(), [&y] ( size_t i1, size_t i2 ) -> bool { return y[i1] < y[i2]; } );
    newY[ind[0]] = 0;
    for( size_t i = 1; i < n; ++i )
        newY[ind[i]] = newY[ind[i-1]] + (( y[ind[i]] == y[ind[i-1]] ) ? 0 : 1);

    vector<size_t> xCnt(n, 0), xStart(n, 0), ix(n);
    for( size_t i = 0; i < n; ++i )
        ++xCnt[newX[i]];
    for( size_t i = 1; i < n; ++i )
        xStart[i] = xStart[i-1] + xCnt[i-1];
    xCnt.assign(n, 0);
    for( size_t i = 0; i < n; ++i )
    {
        ix[xStart[newX[i]] + xCnt[newX[i]]] = i;
        ++xCnt[newX[i]];
    }

    vector<size_t> yCnt(n, 0), yStart(n, 0), iy(n);
    for( size_t i = 0; i < n; ++i )
        ++yCnt[newY[i]];
    for( size_t i = 1; i < n; ++i )
        yStart[i] = yStart[i-1] + yCnt[i-1];
    yCnt.assign(n, 0);
    for( size_t i = 0; i < n; ++i )
    {
        iy[yStart[newY[i]] + yCnt[newY[i]]] = i;
        ++yCnt[newY[i]];
    }

    long long res = 1;
    const long long mod = 1000000007;
    vector<int> q;
    vector<int> xmarked(n, 0), ymarked(n, 0), pmarked(n, 0);
    for( size_t i = 0; i < n; ++i )
    {
        if( !pmarked[i] )
        {
            q.clear();
            size_t distinctCoords = 0;
            pmarked[i] = 1;
            q.push_back(i);
            for( size_t j = 0; j < q.size(); ++j )
            {
                size_t ic = q[j];
                int xc = newX[ic];
                int yc = newY[ic];

                if( !xmarked[xc] )
                {
                    xmarked[xc] = 1;
                    ++distinctCoords;

                    for( size_t k = 0; k < xCnt[xc]; ++k )
                    {
                        size_t iNeib = ix[xStart[xc] + k];
                        if( !pmarked[iNeib] )
                        {
                            q.push_back(iNeib);
                            pmarked[iNeib] = 1;
                        }
                    }
                }

                if( !ymarked[yc] )
                {
                    ymarked[yc] = 1;
                    ++distinctCoords;

                    for( size_t k = 0; k < yCnt[yc]; ++k )
                    {
                        size_t iNeib = iy[yStart[yc] + k];
                        if( !pmarked[iNeib] )
                        {
                            q.push_back(iNeib);
                            pmarked[iNeib] = 1;
                        }
                    }
                }
            }

            long long curMult = 1;
            for( size_t j = 0; j < distinctCoords; ++j )
                curMult = (curMult * 2) % mod;
            if( distinctCoords == q.size() + 1 )
                curMult = (curMult + mod - 1) % mod;

            res = (res * curMult) % mod;
        }
    }
    cout << res;
    //cout.flush();
}

bool IsPermutation( const vector<int>& v, vector<int>& mark )
{
    bool res = true;
    for( size_t i = 0; i < v.size(); ++i )
    {
        if( v[i] >= v.size())
        {
            res = false;
            break;
        }
        if(mark[v[i]])
            res = false;
        mark[v[i]] = 1;
    }

    for( size_t i = 0; i < v.size(); ++i )
        mark[i] = 0;

    return res;
}

void SolveB()
{
    size_t n;
    cin >> n;
    vector<int> p0vs(n), vsb0(n);
    for( size_t i = 0; i < n; ++i )
    {
        cout << "? 0 " << i << "\n";
        cout.flush();
        cin >> p0vs[i];
        cout << "? " << i << " 0\n";
        cout.flush();
        cin >> vsb0[i];
    }

    vector<int> p(n), b(n), ans(n), mark(n, 0);
    size_t cnt = 0;
    for( size_t i = 0; i < n; ++i)
    {
        p[0] = i;
        for( size_t j = 0; j < n; ++j )
        {
            b[j] = p[0] ^ p0vs[j];
            p[j] = b[0] ^ vsb0[j];
        }

        bool ok = IsPermutation(p, mark) && IsPermutation(b, mark);
        if(ok)
        {
            for( size_t j = 0; j < n; ++j )
                ok = ok && (p[b[j]] == j);
        }
        if( ok )
        {
            ++cnt;
            for(size_t j = 0; j < n; ++j)
                ans[j] = p[j];
        }
    }
    cout << "!\n" << cnt << "\n";
    for(size_t i = 0; i < n; ++i)
        cout << ans[i] << " ";
    cout.flush();
}

size_t RangeSum( size_t i1, size_t i2, const vector<size_t>& v )
{
    return v[i2] - v[i1-1];
}

void SolveD()
{
    size_t n;
    cin >> n;
    vector<size_t> minDiv(n+1, 0);
    for( size_t i = 2; i * i <= n; ++i )
    {
        if( minDiv[i] )
            continue;
        size_t cur = 2*i;
        while( cur <= n )
        {
            if( minDiv[cur] == 0)
                minDiv[cur] = i;
            cur += i;
        }
    }

    vector<size_t> countPrimes(n+1);
    for( size_t i = 2; i <= n; ++i )
    {
        countPrimes[i] = countPrimes[i-1];
        if( minDiv[i] == 0 )
            ++countPrimes[i];
    }

    vector<size_t> cnt(n+1, 0);
    for( size_t i = 2; i <= n; ++i )
        if( minDiv[i] == 0 )
            ++cnt[i];
        else
            ++cnt[minDiv[i]];

    for( size_t i = 2; i <= n; ++i )
        cnt[i] += cnt[i-1];

    size_t numbits[128];
    for( size_t i = 0; i < 128; ++i )
    {
        int x = i;
        numbits[i] = 0;
        for( int j = 0; j < 7; ++j )
            if( x & (1 << j) )
                ++numbits[i];
    }

    vector<size_t> divs;
    unsigned long long ans = 0;
    for( size_t i = 2; i <= n; ++i )
    {
        size_t cur = i;
        divs.clear();
        while( cur != 1 )
        {
            size_t d = minDiv[cur];
            if(d == 0)
                d = cur;
            if( divs.empty() || d != divs.back() )
                divs.push_back(d);
            cur = cur / d;
        }

        long long n1 = 0;

        int nd = divs.size();
        for( int j = 1; j < (1 << nd); ++j )
        {
            size_t x = 1;
            for(int k = 0; k < nd; ++k)
                if( j & (1 << k) )
                    x *= divs[k];
            if( numbits[j] % 2 )
                n1 += (n / x);
            else
                n1 -= (n / x);
        }

        if( 2*i > n && minDiv[i] == 0 )
            continue;

        --n1;
        size_t md = divs[0]; // minimal divizor

        size_t n0 = RangeSum(1+(n/2), n, countPrimes );
        if( minDiv[i] != 0 || 2*i <= n )
            ++n0;

        size_t n3 = 0;
        if( md > 2 && 2 * md <= n && (n/md) + 1 <= n/2)
        {
            n3 = RangeSum((n/md) + 1, n/2, cnt);
            if( md > (n/md) )
                n3 -= RangeSum( md, md, cnt );
        }

        size_t n2 = (n-1) - n0 - n1 - n3;

        ans += n1 + 2*n2 + 3*n3;
    }

    cout << ans / 2;
}

int main(int argc, char **argv)
{
    SolveD();
    return 0;
}

#include<bits/stdc++.h>

#define rd(x) x=read()

#define N 10000005

using namespace std;

int n;
int pri[N],phi[N],p[N];
long long f[N],g[N];int tot;

inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();if(ch==-1)return 0;}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

inline void write(int x)
{
    if(x<0){putchar('-');x=-x;}
    if(x>=10)write(x/10);
    putchar(x%10+'0');
}

int main()
{
	rd(n),phi[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(!p[i]){p[i]=pri[++tot]=i;phi[i]=i-1;}
        for(int j=1;j<=tot;j++)
        {
            if(i*pri[j]>n)break;p[i*pri[j]]=pri[j];
            if(i%pri[j]==0){phi[i*pri[j]]=phi[i]*pri[j];break;}
            else phi[i*pri[j]]=phi[i]*(pri[j]-1);
        }
    }
    int cntt=0,cnt=0;
    long long ans1=0,ans2=0,ans3=0;
    for(int i=2;i<=n;i++)f[p[i]]++;
	for(int i=2;i<=n;i++)g[i]=g[i-1]+f[i];
	for(int i=1;i<=tot;i++)if(pri[i]*2>n)cnt++;
    for(int i=2;i<=n;i++)if(1ll*p[i]*p[i]<=n)cntt++;
    for(int i=2;i<=n;i++)ans1+=i-phi[i]-1,ans2+=1ll*f[i]*g[n/i];
    ans2=(ans2-cntt)/2-ans1,ans3=(n-cnt-1)*(n-cnt-2)/2-ans1-ans2;
    printf("%lld\n",ans1+ans2*2+ans3*3);

    return 0;
}

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef vector<PII> VPII;
typedef pair<LL, LL> PLL;
typedef pair<int, LL> PIL;
typedef pair<LL, int> PLI;
typedef double DB;

#define pb push_back
#define mset(a, b) memset(a, b, sizeof a)
#define all(x) (x).begin(), (x).end()
#define bit(x) (1 << (x))
#define bitl(x) (1LL << (x))
#define sqr(x) ((x) * (x))
#define sz(x) ((int)(x.size()))
#define cnti(x) (__builtin_popcount(x))
#define cntl(x) (__builtin_popcountll(x))
#define clzi(x) (__builtin_clz(x))
#define clzl(x) (__builtin_clzll(x))
#define ctzi(x) (__builtin_ctz(x))
#define ctzl(x) (__builtin_ctzll(x))

#define X first
#define Y second

#define Error(x) cout << #x << " = " << x << endl

template <typename T, typename U>
inline void chkmax(T& x, U y) {
	if (x < y) x = y;
}

template <typename T, typename U>
inline void chkmin(T& x, U y) {
	if (y < x) x = y;
}

const int MAXN = 1e7 + 10;

int p[MAXN], phi[MAXN], cnt[MAXN], prm[MAXN], prn;

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif
	int n; scanf("%d", &n);
	long long ans = 0;
	for (int i = 2; i <= n; i++) {
		if (!p[i]) {
			p[i] = i;
			phi[i] = i-1;
			prm[prn++] = i;
		}
		int k = min(n / i, p[i]);
		for (int j = 0; j < prn && prm[j] <= k; j++) {
			p[prm[j] * i] = p[i];
			phi[prm[j] * i] = phi[i] * (prm[j] - (prm[j] < p[i]));
		}
		ans -= 2 * (i - 1 - phi[i]);
	}
	for (int i = 2; i <= n; i++) cnt[p[i]]++;
	for (int i = 2; i <= n; i++) cnt[i] += cnt[i-1];
	int tot = n - 1;
	for (int i = 2; i <= n; i++) if (p[i] * 2 > n) tot--;
	for (int i = 2; i <= n; i++) {
		if (p[i] * 2 > n) continue;
		ans += 3 * (tot - 1) - (cnt[n / p[i]] - (1LL * p[i] * p[i] <= n));
	}
	cout << ans / 2 << endl;
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 1e+7 + 10;

bool isnotp[maxn];ll u[maxn];
ll p[664539],pn;
ll cnt[664539],sum[664539];
ll n,ans;

void pre()
{
	int i,j;

	for(i=2;i<=n;i++)
	{
		if(!isnotp[i])
		{
			p[pn]=i;
			u[i]=cnt[pn++]=1;
		}
		for(j=0;j<pn && i*p[j]<=n;j++)
		{
			isnotp[i*p[j]]=true;
			u[i*p[j]]=-u[i];
			cnt[j]++;
			if(!(i%p[j]))
			{
				u[i*p[j]]=0;
				break;
			}
		}
	}//cerr<<pn;

	sum[0]=cnt[0];
	for(i=1;i<pn;i++) sum[i]=sum[i-1]+cnt[i];
}

void solve()
{
	ll i,j,pos,tsum;

	ans=0;

	for(i=0;i<pn;i++)
	{
		ans+=cnt[i]*(cnt[i]-1);
		for(j=i+1;j<pn && p[j]*p[i]<=n;j++) ans+=cnt[i]*cnt[j]*2;
	}//cerr<<ans<<endl;

	for(pos=0;p[pos]<=n/2;pos++);j=--pos;
	for(i=1;i<pn && p[i]<=n/2;i++)
	{
		for(;j>=0 && p[j]*p[i]>n;j--);
		ans+=cnt[i]*(sum[pos]-sum[max(j,i)])*3;
	}

	for(i=2;i<=n;i++) if(u[i])
	{
		ans-=u[i]*(n/i)*(n/i-1)/2;
	}

	cout<<ans<<endl;
}

int main()
{
//	freopen("2368.in","r",stdin);
//	freopen("2368.out","w",stdout);

	cin>>n;
	pre();
	solve();

	return 0;
}

#include<cstdio>
#include<algorithm>
using namespace std;
#define N 10000070
int pr[N],ch[N],phi[N],s[N],su1[N],n,ct;
int prime(int n)
{
	for(int i=2;i<=n;i++)
	{
		if(!ch[i])pr[++ct]=i,phi[i]=i-1,s[i]=i;
		for(int j=1;1ll*i*pr[j]<=n&&j<=ct;j++)
		{
			ch[i*pr[j]]=1,phi[i*pr[j]]=phi[i]*(pr[j]-1);
			s[i*pr[j]]=pr[j];
			if(i%pr[j]==0)
			{
				phi[i*pr[j]]=phi[i]*pr[j];
				break;
			}
		}
	}
}
int main()
{
	scanf("%d",&n);prime(n);
	long long su=n-1,as=0,sp=0;
	for(int i=1;i<=ct;i++)if(pr[i]>n/2)su--;
	su=su*(su-1)/2;
	for(int i=2;i<=n;i++)sp+=phi[i];
	as+=1ll*n*(n-1)/2-sp;
	as+=(su-as)*2;
	for(int i=2;i<=n;i++)su1[s[i]]++;
	for(int i=2;i<=n;i++)su1[i]+=su1[i-1];
	for(int i=1;i<=ct;i++)
	if(1ll*pr[i]*pr[i]<=n)
	{
		int l=max(n/pr[i],pr[i])+1,r=n/2;
		if(l>r)continue;
		as+=(su1[r]-su1[l])*(su1[pr[i]]-su1[pr[i]-1]);
	}
	printf("%lld\n",as);
}

#pragma region Macros
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define rep2(i,a,b) for(ll i=a;i<=b;++i)
#define rep(i,n) for(ll i=0;i<n;i++)
#define rep3(i,a,b) for(ll i=a;i>=b;i--)
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pq priority_queue
#define pb push_back
#define eb emplace_back
#define vec vector<int>
#define vecll vector<ll>
#define vecpii vector<pii>
#define vecpll vector<pll>
#define vec2(a,b) vector<vec>(a,vec(b))
#define vec2ll(a,b) vector<vecll>(a,vecll(b))
#define vec3(a,b,c) vector<vector<vec>>(a,vec2(b,c))
#define vec3ll(a,b,c) vector<vector<vecll>>(a,vec2ll(b,c))
#define fi first
#define se second
#define all(c) begin(c),end(c)
#define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define lb(c,x) distance(c.begin(),lower_bound(all(c),(x)))
#define ub(c,x) distance(c.begin(),upper_bound(all(c),(x)))
using namespace std;
int in() {int x;cin>>x;return x;}
ll lin() {ll x;cin>>x;return x;}
string stin() {string s;cin>>s;return s;}
template<class T> inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T> inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
vec iota(int n){vec a(n);iota(all(a),0);return a;}
void print(){putchar(' ');}
void print(bool a){cout<<a;}
void print(int a){cout<<a;}
void print(long long a){cout<<a;}
void print(char a){cout<<a;}
void print(string &a){cout<<a;}
void print(double a){cout<<a;}
template<class T> void print(const vector<T>&);
template<class T, size_t size> void print(const array<T, size>&);
template<class T, class L> void print(const pair<T, L>& p);
template<class T, size_t size> void print(const T (&)[size]);
template<class T> void print(const vector<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout<<" "; print(*i); } cout<<endl;}
template<class T> void print(const deque<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout<<" "; print(*i); } }
template<class T, size_t size> void print(const array<T, size>& a){ print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout<<" "; print(*i); } }
template<class T, class L> void print(const pair<T, L>& p){ cout<<'(';print(p.first); cout<<","; print(p.second);cout<<')'; }
template<class T, size_t size> void print(const T (&a)[size]){ print(a[0]); for(auto i = a; ++i != end(a); ){ cout<<" "; print(*i); } }
template<class T> void print(const T& a){ cout << a; }
int out(){ putchar('\n'); return 0; }
template<class T> int out(const T& t){ print(t); putchar('\n'); return 0; }
template<class Head, class... Tail> int out(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); return 0; }
ll gcd(ll a, ll b){ while(b){ ll c = b; b = a % b; a = c; } return a; }
ll lcm(ll a, ll b){ if(!a || !b) return 0; return a * b / gcd(a, b); }
#define _GLIBCXX_DEBU
#define endl '\n'
#ifdef _MY_DEBUG
    #undef endl
    #define debug(x) cout<<#x<<": "<<x<<endl
    void err(){}
    template<class T> void err(const T& t){ print(t);  cout<<" ";}
    template<class Head, class... Tail> void err(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); }
#else
    #define debug(x)
    template<class... T> void err(const T&...){}
#endif
#pragma endregion

signed main(){
    ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);cout<<fixed<<setprecision(15);
    int n=in();
    vec a(n+1);
    rep2(i,1,n)a[i]=i;
    vec p(n+1,1);
    p[1]=1;
    vector<vec> div(n+1);
    rep2(i,2,n){
        if(p[i]){
            for(int j=i*2;j<=n;j+=i)p[j]=0;
        }
    }
    rep2(i,2,n){
        if(p[i]){
            for(int j=i;j<=n;j+=i){
                if(div[j].empty() or div[j].front()!=2)div[j].pb(i);
                a[j]/=i;
                a[j]*=i-1;
            }
        }
    }
    // a <- totient func
    int res=0;
    ll ans=0;
    // int C=0;
    // int d[n+1][n+1]={};
    // rep2(i,1,n)rep2(j,1,n)d[i][j]=(gcd(i,j)>1 ? 1:1000);
    // rep2(k,1,n)rep2(i,1,n)rep2(j,1,n)chmin(d[i][j],d[i][k]+d[k][j]);
    // rep2(i,1,n)rep2(j,i+1,n)if(d[i][j]<1000)C+=d[i][j];
    // rep2(i,1,n){
    //     rep2(j,1,n)cout<<d[i][j]<<" ";cout<<endl;
    // }
    // cout<<C<<endl;
    rep2(i,1,n){
        if(p[i])res++;
        else{
            if(i%2==0 and p[i/2]){
                ll tmp=0;
                tmp+=(a[i]-res+1);
                tmp+=i-1-res;
                ans+=tmp;
                ans++;
                ans+=tmp;
                ans+=i-1-res;
                res--;
            }
            else{
                ans+=a[i]-res+i-1-res;
                if(i&1){
                    ans+=a[i]/2-res;
                    ll R=1;
                    if(div[i].size()==2){
                        ans-=(i/div[i][0]/2)*(i/div[i][1]/2);
                    }
                }
            }
        }
    }
    cout<<ans<<endl;
}

#include <bits/stdc++.h>
using namespace std;
const int N = 10000005;
using ll = long long;
int n,phi[N],cnt[N],pr[N],ptr,d[N];
bool npr[N];
int main ()
{
    ios::sync_with_stdio(false);
    cin >> n;
    phi[1] = 1;
    for (int i = 2;i <= n;i++)
    {
        if (!npr[i]) pr[++ptr] = i,phi[i] = i - 1,d[i] = i;
        for (int j = 1;j <= ptr && i * pr[j] <= n;j++)
        {
            npr[i * pr[j]] = 1;d[i * pr[j]] = pr[j];
            if (i % pr[j]) phi[i * pr[j]] = phi[i] * (pr[j] - 1);
            else {phi[i * pr[j]] = phi[i] * pr[j];break;}
        }
        ++cnt[d[i]];
    }
    for (int i = 2;i <= n;i++) cnt[i] += cnt[i - 1];
    //1不会和任何点连边，故代码中将1忽略
    ll psum = accumulate(phi + 1,phi + n + 1,0) - n;
    ll ans = ((n - 1ll) * (n - 2) / 2 - psum) + psum * 2;
    for (int i = 1;i <= ptr;i++)
    {
        ll cc = cnt[pr[i]] - cnt[pr[i] - 1];
        ans += cc * (cnt[max(pr[i],n / 2)] - cnt[max(pr[i] + 1,n / pr[i] + 1) - 1]);
        ans -= 2 * cc * (cnt[n] - cnt[max(pr[i] + 1,n / 2 + 1) - 1]);
    }
    cout << ans << endl;
    return 0;
}
// 不互质的数对的d为1，对于互质数对(A,B)，设它们的最小质因数分别为a,b
// 方案有:A -> ab -> B (ab <= n)
// ab>=n时不妨设a<b，则A -> 2a -> 2b -> B
// (2b <= n,B不珂能等于2b，不然b=2,a无合法取值，A不珂能等于2a，不然a=2,第一步已经珂以走通)
// 否则走不通

/*
ЗАПУСКАЕМ
░ГУСЯ░▄▀▀▀▄░РАБОТЯГУ░░
▄███▀░◐░░░▌░░░░░░░
░░░░▌░░░░░▐░░░░░░░
░░░░▐░░░░░▐░░░░░░░
░░░░▌░░░░░▐▄▄░░░░░
░░░░▌░░░░▄▀▒▒▀▀▀▀▄
░░░▐░░░░▐▒▒▒▒▒▒▒▒▀▀▄
░░░▐░░░░▐▄▒▒▒▒▒▒▒▒▒▒▀▄
░░░░▀▄░░░░▀▄▒▒▒▒▒▒▒▒▒▒▀▄
░░░░░░▀▄▄▄▄▄█▄▄▄▄▄▄▄▄▄▄▄▀▄
░░░░░░░░░░░▌▌░▌▌░░░░░
░░░░░░░░░░░▌▌░▌▌░░░░░
░░░░░░░░░▄▄▌▌▄▌▌░░░░░
 */
#include <iostream>
#include <complex>
#include <vector>
#include <string>
#include <algorithm>
#include <cstdio>
#include <numeric>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <list>
#include <cmath>
#include <bitset>
#include <cassert>
#include <queue>
#include <stack>
#include <deque>

using namespace std;
template<typename T1, typename T2>inline void chkmin(T1 &x, T2 y) { if (x > y) x = y; }
template<typename T1, typename T2>inline void chkmax(T1 &x, T2 y) { if (x < y) x = y; }
template<typename T, typename U> inline ostream &operator<< (ostream &_out, const pair<T, U> &_p) { _out << _p.first << ' ' << _p.second; return _out; }
template<typename T, typename U> inline istream &operator>> (istream &_in, pair<T, U> &_p) { _in >> _p.first >> _p.second; return _in; }
template<typename T> inline ostream &operator<< (ostream &_out, const vector<T> &_v) { if (_v.empty()) { return _out; } _out << _v.front(); for (auto _it = ++_v.begin(); _it != _v.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T> inline istream &operator>> (istream &_in, vector<T> &_v) { for (auto &_i : _v) { _in >> _i; } return _in; }
template<typename T> inline ostream &operator<< (ostream &_out, const set<T> &_s) { if (_s.empty()) { return _out; } _out << *_s.begin(); for (auto _it = ++_s.begin(); _it != _s.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T> inline ostream &operator<< (ostream &_out, const multiset<T> &_s) { if (_s.empty()) { return _out; } _out << *_s.begin(); for (auto _it = ++_s.begin(); _it != _s.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T> inline ostream &operator<< (ostream &_out, const unordered_set<T> &_s) { if (_s.empty()) { return _out; } _out << *_s.begin(); for (auto _it = ++_s.begin(); _it != _s.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T> inline ostream &operator<< (ostream &_out, const unordered_multiset<T> &_s) { if (_s.empty()) { return _out; } _out << *_s.begin(); for (auto _it = ++_s.begin(); _it != _s.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T, typename U> inline ostream &operator<< (ostream &_out, const map<T, U> &_m) { if (_m.empty()) { return _out; } _out << '(' << _m.begin()->first << ": " << _m.begin()->second << ')'; for (auto _it = ++_m.begin(); _it != _m.end(); ++_it) { _out << ", (" << _it->first << ": " << _it->second << ')'; } return _out; }
template<typename T, typename U> inline ostream &operator<< (ostream &_out, const unordered_map<T, U> &_m) { if (_m.empty()) { return _out; } _out << '(' << _m.begin()->first << ": " << _m.begin()->second << ')'; for (auto _it = ++_m.begin(); _it != _m.end(); ++_it) { _out << ", (" << _it->first << ": " << _it->second << ')'; } return _out; }
#define sz(c) (int)(c).size()
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define left left228
#define right right228
#define next next228
#define rank rank228
#define prev prev228
#define y1 y1228
#define read(FILENAME) freopen((FILENAME + ".in").c_str(), "r", stdin)
#define write(FILENAME) freopen((FILENAME + ".out").c_str(), "w", stdout)
#define files(FILENAME) read(FILENAME), write(FILENAME)
#define pb push_back
#define x first
#define y second
const string FILENAME = "input";
const int MAXN = 10000001;

int n;
int prime[MAXN];
char bad[MAXN];
int phi[MAXN];
int cntprimedivs[MAXN];
int minprime[MAXN];
int cntbad = 0;

long long getone() {
    long long ans = 0;
    for (int i = 2; i <= n; i++) {
        if (!bad[i]) {
            ans += i - 1 - phi[i];
        }
    }
    return ans;
}

long long gettwo() {
    long long ans = 0;
    int cntprime = 1;
    for (int i = 2; i <= n; i++) {
        if (prime[i] != i) {
            ans += phi[i];
            ans -= cntprime;
            ans += cntprimedivs[i];
        } else {
            cntprime++;
        }
    }
    for (int i = 1; i <= n; i++) {
        if (!bad[i]) {
            minprime[prime[i]]++;
        }
    }
    for (int i = 1; i <= n; i++) {
        minprime[i] += minprime[i - 1];
    }
    for (int i = 2; i <= n; i++) {
        if (prime[i] != i || bad[i]) {
            continue;
        }
        ans += minprime[n / i];
        for (int j = i; j <= n; j += i) {
            if (prime[j] <= n / i) {
                ans--;
            }
        }
    }
    for (int i = 2; i <= n; i++) {
        int a = prime[i];
        int b = i / a;
        if (b != 1 && prime[b] == b && a != b) {
            ans--;
        }
    }
    return ans;
}

int main(){
	ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
//    read(FILENAME);
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        phi[i] = i;
    }
    for (int i = 2; i <= n; i++) {
        if (prime[i]) {
            continue;
        }
        for (int j = i; j <= n; j += i) {
            if (!prime[j]) {
                prime[j] = i;
            }
            phi[j] /= i;
            phi[j] *= i - 1;
        }
    }
    for (int i = 1; i <= n; i++) {
        if (i == 1 || (prime[i] == i && i * 2 > n)) {
            bad[i] = true;
            cntbad++;
        }
    }
    for (int i = 2; i <= n; i++) {
        if (prime[i] == i) {
            cntprimedivs[i] = 1;
        } else if (prime[i / prime[i]] == prime[i]) {
            cntprimedivs[i] = cntprimedivs[i / prime[i]];
        } else {
            cntprimedivs[i] = cntprimedivs[i / prime[i]] + 1;
        }
    }
    long long cnt1 = getone();
    long long cnt2 = gettwo();
    long long cnt3 = 1LL * (n - cntbad) * (n - cntbad - 1) / 2 - cnt1 - cnt2;
    cout << cnt1 * 1 + cnt2 * 2 + cnt3 * 3 << '\n';
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e7;
const int inf = 0x3f3f3f3f;
int not_prime[maxn+10], prime[maxn];
int phi[maxn], mu[maxn];
int low[maxn];
ll sum[maxn];
void get_euler(int n){
	memset(not_prime, 0, sizeof not_prime);
	memset(sum, 0, sizeof sum);
	not_prime[1] = true;
	phi[1] = 1;
	mu[1] = 1;
	for(int i = 2; i <= n; i++){
		if(!not_prime[i]){
			prime[++prime[0]] = i;
			low[i] = prime[0];
			phi[i] = i-1;
			mu[i] = -1;
		}
		for(int j = 1; j <= prime[0] && prime[j] <= n / i; j++){
			not_prime[i*prime[j]] = true;
			low[i * prime[j]] = j;
			if(i % prime[j] == 0){
				phi[i * prime[j]] = phi[i] * prime[j];
				mu[i * prime[j]] = 0;
				break;
			}
			else{
				phi[i * prime[j]] = phi[i] * (prime[j] - 1);
				mu[i * prime[j]] = -mu[i];
			}
		}
		++sum[low[i]];
	}
}
int main(){
	int n;	cin>>n;
	ll tot = n * (n - 1) / 2;
	ll a1, a2, a3, a4, tmp = 0;
//	for(int i = 1; i <= n; i++){
//		cout<<i<<" "<<mu[i]<<" "<<phi[i]<<endl;
//	}
	get_euler(n);
	for(int i = 2; i <= n ; i++){
		tmp += phi[i];
	}
	a1 = tot - tmp;
	tmp = a4 = 0;
	for(int i = 1; i <= prime[0]; i++)
		if(2 * prime[i] > n) tmp++;
	a4 = tmp * (n - tmp - 1) + tmp * (tmp - 1) / 2;
	a2 = 0;
	for(int i = 2; i <= prime[0]; i++)
		sum[i] += sum[i-1];
	for (int i = 1, j = prime[0]; i <= prime[0]; ++i)    {
        for ( ; j && prime[i] * prime[j] > n; --j);
        a2 += sum[j] * (sum[i] - sum[i-1]);
    }
	for(int i = 2; i <= n; i++)
		a2 += mu[i] * ((ll)(n/i) * (n/i) - (!not_prime[i] && (ll)i * i > n));
	a2 >>= 1;
	a3 = (ll)(n-1)*(n-2)/2 - a1 - a2 - a4;
	//cout<<a1<<" "<<a2<<" "<<a3<<" " <<a4<<endl;
	ll ans = a1 + 2 * a2 + 3 * a3;
	cout<<ans<<endl;
}

#include<cstdio>
#include<cstring>
#include<iostream>
#include<stdlib.h>
#include<ctime>
#include<string>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<bitset>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define LL long long
#define FOR(i,a,b) for (int i=a;i<=b;++i)
#define FORD(i,a,b) for (int i=a;i>=b;--i)
using namespace std;
typedef pair<int,int> pa;
typedef long double ld;
void getint(LL &v){
    char ch,fu=0;
    for(ch='*'; (ch<'0'||ch>'9')&&ch!='-'; ch=getchar());
    if(ch=='-') fu=1, ch=getchar();
    for(v=0; ch>='0'&&ch<='9'; ch=getchar()) v=v*10+ch-'0';
    if(fu) v=-v;
}
bool u[10000010];
LL c0,c1,Q[10000010],c2,c3,tot,f[10000010],ans,good,bad,s[10000010];
int t,n,ts,q[10000010],phi[10000010],tmp[10000010],cnt[10000010],p[10000010],pr,l,r;
void getp(){
	phi[1]=1;
	q[1]=n+1;
	FOR(i,2,n){
		if (!u[i]){p[++pr]=i;q[i]=i;phi[i]=i-1;}
		FOR(j,1,pr){
			if (i*p[j]>n) break;
			u[i*p[j]]=1;
			q[i*p[j]]=p[j];
			if (i%p[j]==0){phi[i*p[j]]=phi[i]*p[j];break;}
			else phi[i*p[j]]=phi[i]*phi[p[j]];
		}
	}
}
int main(){
	cin>>n;
	tot=(LL)n*(n+1)/2;
	getp();
	c0=n;
	FOR(i,1,n)
		if (i==1 || i*2>n && !u[i]) ++bad;
	good=n-bad;
	tot-=good*bad+bad*(bad-1)/2;
	tot-=c0;
	FOR(i,2,n) c1+=i-1-phi[i];
	tot-=c1;

	//c2 q[i]*q[j]<=n && gcd(i,j)==1
	FOR(i,2,n) s[i]=s[i-1]+(!u[i]);
	//prime
	FOR(i,2,n) ++Q[q[i]];
	FOR(i,2,n) Q[i]+=Q[i-1];
	//valq_presum
	FOR(i,2,n)
		if (!u[i]){
			c2+=Q[n/i];
			for (int j=i;j<=n;j+=i)
				if (q[i]*q[j]<=n) --c2;
		}
	//prime<->all
	FORD(i,n/2,1){
		LL s=0;
		for (int j=i;j<=n;j+=i)
			if (u[j]) ++s;
		f[i]=s*(s-1)/2;
		for (int j=i+i;j<=n;j+=i)
			f[i]-=f[j];
	}
	c2+=f[1];
	//!prime<->!prime
	FOR(i,2,n) if (!u[i]) c2-=s[min(i-1,n/i)];
	//prime<->prime

	tot-=c2;
	c3=tot;
	cout<<c1+c2*2+c3*3<<endl;
	return 0;
}

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int i,j;
int sp[10000005],nump[10000005],phi[10000005],cnt;
long long n,prime[10000005],pfxprime[10000005],temp,temp2,ans0,ans1,ans2,ans3;
bool isp[10000005];
int main(){
	scanf("%lld",&n);
	memset(isp,true,sizeof(isp));
	sp[1]=1;
	nump[1]=0;
	isp[1]=false;
	cnt=0;
	for(i=2;i<=n;i++){
		if (isp[i]){
			cnt++;
			prime[cnt]=i;
			sp[i]=i;
			nump[i]=1;
		}
		for(j=1;j<=cnt;j++){
			if (prime[j]*((long long)i)<=n){
				isp[prime[j]*i]=false;
				sp[prime[j]*i]=prime[j];
				if (sp[i]!=prime[j]) nump[prime[j]*i]=nump[i]+1;
				else nump[prime[j]*i]=nump[i];
			}
			else break;
			if ((i % prime[j])==0) break;
		}
	}
	pfxprime[1]=0;
	for(i=2;i<=n;i++){
		if (isp[i]) pfxprime[i]=pfxprime[i-1]+1;
		else pfxprime[i]=pfxprime[i-1];
	}
	phi[1]=1;
	for(i=2;i<=n;i++){
		if (sp[i]!=sp[i/sp[i]]) phi[i]=phi[i/sp[i]]*(sp[i]-1);
		else phi[i]=phi[i/sp[i]]*sp[i];
	}
	temp=pfxprime[n]-pfxprime[n/2]+1;
	ans0=temp*(n-temp)+temp*(temp-1)/2;
	ans1=0;
	for(i=2;i<=n;i++){
		ans1+=i-1-phi[i];
	}
	ans2=0;
	for(i=2;i<=n;i++){
		if (!isp[i]){
			ans2+=phi[i]-pfxprime[i]-1+nump[i];
			//if (sp[i]*(long long)i<=n) ans2--;
			ans2+=pfxprime[n/sp[i]];
			temp=i;
			while(sp[temp]*(long long)i<=n){
				if (temp==1) break;
				ans2--;
				temp2=sp[temp];
				while(sp[temp]==temp2) temp=temp/sp[temp];
			}
		}
	}
	temp=0;
	for(i=1;i<=cnt;i++){
		temp+=pfxprime[n/prime[i]];
	}
	temp+=pfxprime[(int)(sqrt(n))];
	ans2-=temp/2;
	ans3=n*(n-1)/2-ans0-ans1-ans2;
	printf("%lld\n",ans1+ans2*2+ans3*3);
	/*printf("%d %d %d %d\n",ans0,ans1,ans2,ans3);
	for(i=1;i<=100;i++){
		//printf("%d %d\n",i,nump[i]);
	}*/
	return 0;
}

#include <iostream>
#include <vector>

using namespace std;

typedef long long ll;

const int MAX_N = 1e7 + 5;

ll pairc (ll n) {
  return (n * (n - 1)) / 2;
}

int factor [MAX_N];
int sieve [MAX_N];
int cspf [MAX_N];
int mobius [MAX_N];
int nxtp [MAX_N];

int main () {
  ll n;
  cin >> n;

  vector<ll> primes;
  for (ll i = 2; i <= n; i++) {
    if (!sieve[i]) {
      nxtp[i] = i;
      primes.push_back(i);
      for (ll j = i; j <= n; j += i) {
        factor[j] = i;
        if (!sieve[j]) {
          sieve[j] = 1;
          cspf[i]++;
        }
      }
    }
  }

  for (ll i = 2; i <= n; i++) {
    if (factor[i] == i) {
      mobius[i] = 1;
    } else if (factor[i / factor[i]] == factor[i]) {
      mobius[i] = 0;
    } else {
      mobius[i] = -mobius[i / factor[i]];
    }
  }

  for (ll i = n - 1; i >= 0; i--) {
    cspf[i] += cspf[i + 1];
    if (nxtp[i] == 0) nxtp[i] = nxtp[i + 1];
  }

  ll isol = 0;
  for (ll i = 2; i <= n; i++) {
    if (factor[i] != i || 2 * i <= n) {
      isol++;
    }
  }
  ll ans = isol * (isol - 1);

  // cerr << " " << isol << endl;
  // cerr << ans << endl;

  // calculate # of "big pairs"
  ll bigp = 0;
  for (ll p : primes) {
    if (2 * p <= n) {
      ll s = n / p + 1; // smallest s.t. s * p > n
      ll curc = cspf[s];
      if (s <= p) {
        // subtract p itself and its multiples
        curc -= n / p;
      }

      if (nxtp[s] != 0 && 2 * nxtp[s] <= n) {
        bigp += curc;
      }
    }
  }
  bigp /= 2;
  ans += bigp;

  //  cerr << bigp << endl;

  // calculate # of "small pairs"
  ll smallp = 0;
  for (ll i = 2; i <= n; i++) {
    smallp += (ll) mobius[i] * pairc(n / i);
  }

  // cerr << smallp << endl;
  ans -= smallp;

  cout << ans << endl;
}

#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define sf scanf
#define pf printf
#define pb push_back
#define mp make_pair
#define IN freopen("transposition-115.txt","r",stdin)
#define OUT freopen("dichromatic.out","w",stdout)
#define FOR(i,a,b) for(i=a ; i<=b ; i++)
#define DBG pf("Hi\n")
#define INF 1000000000000000000LL
#define i64 long long int
#define eps (1e-8)
#define xx first
#define yy second
#define sq(x)  ((x)*(x))

using namespace __gnu_pbds;
using namespace std ;

#define maxn 10000005
#define mod 1000000007LL

typedef pair<i64,i64> pii ;
typedef  long long int T ;

bool isPrime[maxn] ;
int divCount[maxn] , phi[maxn] , firstPrime[maxn] , primeCnt[maxn] , firstPrimeCnt[maxn] ;
vector <int> prm ;

int main()
{
    int n = 10000000 ;

    memset(isPrime,1,sizeof(isPrime)) ;
    isPrime[1] = 0 ;
    for(int i=2 ; i<=n ; i++)
    {
        if(isPrime[i]) for(int j=i+i ; j<=n ; j+=i) isPrime[j] = 0 ;
    }

    for(int i=2 ; i<=n ; i++) if( isPrime[i] ) prm.pb(i) ;

    for(int i=2 ; i<=n ; i++) phi[i] = i ;

    for(int i=(int)prm.size() - 1 ; i >= 0 ; i-- )
    {
        int p = prm[i] ;
        for(int j=p ; j<=n ; j+=p)
        {
            phi[j] /=p ;
            phi[j] *= (p-1) ;
            divCount[j]++ ; firstPrime[j] = p ;
        }
    }

    i64 ans = 0LL ;

    for(int i=2 ; i<=n ; i++) primeCnt[i] = primeCnt[i-1] + isPrime[i] ;

    scanf("%d",&n) ;

    for(int i=2 ; i<=n ; i++)
    {
        if( !isPrime[i] )
        {
            int comp = (i-2) - primeCnt[i-1] , compWithEdge = (i-1) - phi[i] - divCount[i] ;
            ans += compWithEdge*1 ;
            ans += ( comp - compWithEdge )*2LL ;
        }
    }

 //   printf("Composite Answer : %lld\n",ans) ;

    for(int i=2 ; i<=n ; i++ )
    {
        if( !isPrime[i] ) firstPrimeCnt[ firstPrime[i] ]++ ;
    }

    for(int i=0 ; i<prm.size() && prm[i]*2 <=n  ; i++)
    {
        int p = prm[i] ;

        ans += primeCnt[ min(p-1 , n/p ) ]*2 ;

        ans += (primeCnt[p-1] - primeCnt[ min(p-1 , n/p ) ] )*3 ;

        int r1 = primeCnt[ min(p-1 , n/p ) ]*2 , r2 = (primeCnt[p-1] - primeCnt[ min(p-1 , n/p ) ] )*3 ;

//        printf("%d : %d\n", p , r1+r2 ) ;

        int dis1 = 0 , dis2 = 0 , dis3 = 0 ;

        for(int j=0 ; prm[j]*prm[i] <= n ; j++ )
        {
            if(j==i) continue ;
            dis2 += firstPrimeCnt[ prm[j] ] ;
        }
        for( int j=p+p ; j<=n ; j+=p)
        {
            if( firstPrime[j] != p ) dis2-- ;
            dis1++ ;
        }

        dis3 = ( n-1  - primeCnt[n]) - dis1 - dis2 ;

        ans += dis1*1 + dis2*2 + dis3*3 ;

  //      printf("%d: %d %d %d\n",p,dis1,dis2,dis3) ;
    }

    printf("%d\n",ans) ;

    return 0 ;
}

#include <bits/stdc++.h>
#pragma GCC optimize ("O2")
#pragma GCC optimize ("unroll-loops")
//#pragma GCC optimize("no-stack-protector,fast-math")

using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef pair<ll, ll> pll;
#define debug(x) cerr<<#x<<'='<<(x)<<endl;
#define debugp(x) cerr<<#x<<"= {"<<(x.first)<<", "<<(x.second)<<"}"<<endl;
#define debug2(x, y) cerr<<"{"<<#x<<", "<<#y<<"} = {"<<(x)<<", "<<(y)<<"}"<<endl;
#define debugv(v) cerr<<#v<<" : ";for (auto x:v) cerr<<x<<' ';cerr<<endl;
#define all(x) x.begin(), x.end()
#define pb push_back
#define kill(x) return cout<<x<<'\n', 0;

const ld eps=1e-7;
const int inf=1000000010;
const ll INF=10000000000000010LL;
const int mod = 1000000007;
const int MAXN = 10000010, LOG=20;

ll n, m, k, u, v, x, y, t, c1, c2, c3, ans;
int sieve[MAXN];
int phi[MAXN];
int ps[MAXN];

int main(){
	ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	sieve[1]=phi[1]=1;
	for (int i=2; i<MAXN; i++) if (!sieve[i]) for (int j=i; j<MAXN; j+=i) if (!sieve[j]) sieve[j]=i;
	for (int i=2; i<MAXN; i++){
		int p=sieve[i], tmp=i/p;
		if (tmp%p) phi[i]=(p-1)*phi[tmp];
		else phi[i]=p*phi[tmp];
	}
	cin>>n;
	for (int i=2; i<=n; i++){
		c1+=i-phi[i]-1;
		if (sieve[i]==i && 2*i>n) t++;
	}
	t=n-t-1;
	c3=t*(t-1)/2;

	for (int i=2; i<=n; i++) ps[sieve[i]]++;
	for (int i=2; i<=n; i++) ps[i]+=ps[i-1];
	for (int i=2; i<=n; i++) c2+=ps[n/sieve[i]];
	for (int i=2; i<=n; i++) if (sieve[i]*sieve[i]<=n) c2--;
	c2/=2;
	//debug(c2)
	c2-=c1;
	c3-=c1+c2;
	//debug2(c1, c2)
	//debug(c3)
	cout<<c1+2*c2+3*c3<<'\n';

	return 0;
}

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<ll> vi;

const int maxn = 1e7+100;

ll cri[maxn];
vi pri;
int n,m;

int main(){
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> n;
  for(int i = 0; i < maxn; ++i) cri[i] = 1;
  cri[0] = cri[1] = 0;
  for(ll i = 2; i < maxn; ++i){
    if(cri[i]){
      pri.push_back(i);
      ll j = i*i;
      while(j < maxn){
        cri[j] = 0;
        j += i;
      }
    }
  }
  m = upper_bound(pri.begin(),pri.end(),n)-pri.begin();
  for(int i = 0; i <= n; ++i) cri[i] = 1;
  vi cnt(m,0),acc(m+1,0);
  for(int i = 0; i < m; ++i){
    for(int j = pri[i]; j <= n; j += pri[i]){
      if(cri[j]){
        cri[j] = 0;
        ++cnt[i];
      }
    }
    acc[i+1] = acc[i]+cnt[i];
  }
  ll sol = 0;
  for(int i = 0; i < m; ++i){
    sol += (cnt[i]*(cnt[i]-1))/2 + cnt[i]*(n/pri[i]-cnt[i]);
  }
  for(int i = 0; 2*pri[i] <= n; ++i){
    ll k = upper_bound(pri.begin(),pri.end(),n/pri[i])-pri.begin();
    k = min(k,ll(i));
//     cerr << sol << ' ' << i << ' ' << cnt[i] << ' ' << k << ' ' << acc[k] << '\n';
    sol += 2*cnt[i]*(acc[k]-(n/pri[i]-cnt[i]));
    sol += 3*cnt[i]*(acc[i]-acc[k]);
  }
  cout << sol << '\n';
}

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
// #define int long long
typedef long long ll;
#define fi first
#define se second
#define pii pair<int,int>
#define endl '\n'
#define fr(i, a, b) for(int i = a; i <= b; i++)
#define sz(s) (int)s.size()
#define y1 fdfbvfds
typedef long double f80;
#define all(x) x.begin(), x.end()
typedef long double f80;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
ll rand(ll l,ll r){
    uniform_int_distribution<ll> uid(l, r);
    return uid(rng);
}

const int mod = 1e9 + 7;
int pwr(int a,int b) {
    int ans = 1;
    while(b) {
        if(b & 1) {
            ans = (ans * 1LL * a) % mod;
        }
        a = (a * 1LL * a) % mod;
        b >>= 1;
    }
    return ans;
}

const int N = 1e7 + 5;
vector<int> pf[N];
bool pr[N];
int phi[N], lol[N];

vector<int> g[1005];
int dist[1005];

int brute(int n) {
    fr(i, 1, n) {
        g[i].clear();
    }
    fr(i, 2, n) {
        fr(j, i + 1, n) {
            if(__gcd(i, j) > 1) {
                g[i].pb(j);
                g[j].pb(i);
            }
        }
    }
    ll ans = 0;
    ll one = 0, two = 0, three = 0, zero = 0;
    fr(i, 1, n) {
        fr(j, 1, n) {
            dist[j] = 1e9;
        }
        dist[i] = 0;
        queue<int> q;
        q.push(i);
        while(!q.empty()) {
            int u = q.front();
            q.pop();
            for(int v : g[u]) {
                if(dist[v] > dist[u] + 1) {
                    dist[v] = dist[u] + 1;
                    q.push(v);
                }
            }
        }
        fr(j, i + 1, n) {
            if(dist[j] != 1e9) {
                ans += dist[j];
                if(dist[j] == 1) one++;
                if(dist[j] == 2) two++;
                if(dist[j] == 3) three++;
            }
            else {
                zero++;
            }
        }
    }
    return ans;
}

signed main()
{
    ios_base::sync_with_stdio(0);
    int n;
    cin >> n;
    iota(phi + 1, phi + n + 1, 1);
    pr[1] = 1;
    fr(i, 2, n) {
        if(!pr[i]) {
            for(int j = i; j <= n; j += i) {
                pf[j].pb(i);
                pr[j] = 1;
                phi[j] = (i - 1) * (phi[j] / i);
            }
            pr[i] = 0;
        }
    }
    fr(i, 2, n)
        lol[i - 1] = pf[i][0];
    sort(lol + 1, lol + n);
    reverse(lol + 1, lol + n);
    int pt = 1;
    ll one = 0, two = 0;
    fr(i, 2, n) {
        if(!pr[i] && i <= n / 2) {
            for(int j = i; j <= n; j += i) {
                if(pf[j][0] * i <= n) two--;
            }
            while(pt < n && lol[pt] * i > n) pt++;
            two += n - pt;
        }
    }
    int cp = 1;
    fr(i, 2, n) {
        if(pr[i]){
            two += phi[i] - cp + sz(pf[i]);
        }
        one += i - 1 - phi[i];
        if(!pr[i]) cp++;
    }
    ll c = 1;
    fr(i, n / 2 + 1, n) {
        if(!pr[i]) {
            c++;
        }
    }
    ll zero = c * (n - 1) - (c * (c - 1)) / 2;
    fr(i, 1, n) {
        if(sz(pf[i]) == 2 && pf[i][0] * pf[i][1] == i) {
            two--;
        }
    }
    ll three = (n * 1LL * (n - 1)) / 2 - zero - one - two;
    cout << three * 3 + two * 2 + one * 1;

    return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 1e+7 + 10;

bool isnotp[maxn];short int u[maxn];
ll p[664539],pn;
ll cnt[664539],sum[664539];
ll n,ans;

void pre()
{
	int i,j;

	for(i=2;i<=n;i++)
	{
		if(!isnotp[i])
		{
			p[pn]=i;
			u[i]=cnt[pn++]=1;
		}
		for(j=0;j<pn && i*p[j]<=n;j++)
		{
			isnotp[i*p[j]]=true;
			u[i*p[j]]=-u[i];
			cnt[j]++;
			if(!(i%p[j]))
			{
				u[i*p[j]]=0;
				break;
			}
		}
	}cerr<<pn;

	sum[0]=cnt[0];
	for(i=1;i<pn;i++) sum[i]=sum[i-1]+cnt[i];
}

void solve()
{
	ll i,j,pos,tsum;

	ans=0;

	for(i=0;i<pn;i++)
	{
		ans+=cnt[i]*(cnt[i]-1);
		for(j=i+1;p[j]*p[i]<=n;j++) ans+=cnt[i]*cnt[j]*2;
	}//cerr<<ans<<endl;

	for(pos=0;p[pos]<=n/2;pos++);j=--pos;
	for(i=1;p[i]<=n/2;i++)
	{
		for(;p[j]*p[i]>n;j--);
		ans+=cnt[i]*(sum[pos]-sum[max(j,i)])*3;
	}

	for(i=2;i<=n;i++) if(u[i])
	{
		ans-=u[i]*(n/i)*(n/i-1)/2;
	}

	cout<<ans<<endl;
}

int main()
{
//	freopen("2368.in","r",stdin);
//	freopen("2368.out","w",stdout);

	cin>>n;
	pre();
	solve();

	return 0;
}

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 10000010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
	int x=0,f=1;char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return x*f;
}
int n,prime[N],phi[N],p[N],v[N],cnt;
ll ans;
bool flag[N],f[N];
signed main()
{
#ifndef ONLINE_JUDGE
	freopen("d.in","r",stdin);
	freopen("d.out","w",stdout);
#endif
	n=read();if (n==4) {cout<<1;return 0;}
	flag[1]=1;phi[1]=1;
	for (int i=2;i<=n;i++)
	{
		if (!flag[i]) prime[++cnt]=i,phi[i]=i-1,p[i]=i,v[i]=-1;
		for (int j=1;j<=cnt&&prime[j]*i<=n;j++)
		{
			flag[prime[j]*i]=1;
			p[prime[j]*i]=prime[j];
			if (i%prime[j]==0) {phi[prime[j]*i]=phi[i]*prime[j];break;}
			phi[prime[j]*i]=phi[i]*(prime[j]-1);
		}
	}
	ll tot=0;
	for (int i=2;i<=n;i++) tot+=phi[i],v[p[i]]++;
	ans+=1ll*n*(n-1)/2-tot; //dis=1
	int u=1;for (int i=1;i<=cnt;i++) if (prime[i]>n/2+1) u++;
	tot-=1ll*u*(n-1);tot+=1ll*u*(u-1)/2; //dis=0 tot=dis2+dis3
	ans+=tot*3;
	/*for (int i=2;i<=n;i++)
		for (int j=2;j<i;j++)
		{
		if (gcd(i,j)==1&&1ll*p[i]*p[j]<=n) ans--,cout<<i<<' '<<j<<endl;}
	cout<<ans;return 0;*/
	for (int i=1;i<=cnt;i++)
	if (prime[i]<=n/2)
	{
		for (int j=1;j<i;j++)
		if (prime[i]*prime[j]<=n) ans--;
		else break;
		for (int j=1;j<=cnt;j++)
		if (prime[j]<=n/prime[i]) ans-=v[prime[j]];
		else break;
		for (int j=prime[i]*2;j<=n;j+=prime[i])
		if (p[j]<=n/prime[i]) ans++;
	}
	else break;
	u=0;
	for (int i=2;i<=n;i++)
	if (flag[i])
	{
		ans-=i-2;
		ans+=i-1-phi[i];
		ans+=u;
		int v=i;while (v>1) ans-=!f[p[v]],f[p[v]]=1,v/=p[v];
		v=i;while (v>1) f[p[v]]=0,v/=p[v];
	}
	else u++;
	cout<<ans;
	return 0;
	//NOTICE LONG LONG!!!!!
}
//dis=0 gcd=1 ����֮һ��1��>n/2������
//dis=1 gcd>1
//dis=2 gcd=1 ������С�����ӵĳ˻�<=n �Ҳ�Ϊ1
//��������Ϊ���������С������֮��һ��<=n
//ö�ٽϴ���� ��С��Ӧ�Ǻ��������以��
//���б���С���� ������������ ���������ʵ� �����������Ҳ����ʵ�
//��������Ϊ���� ��
//��һ��������һ��Ϊ���� ���ж��ٸ�������С������<x �Ҳ������������� ��
//dis=3 gcd=1 (gcd=1)-(dis=0)-(dis=2)

#include <stdio.h>
#include <vector>
using namespace std;
typedef long long int ll;
#define PB push_back
constexpr int kN = int(1E7 + 10);
vector<ll> prime;
int l[kN], mu[kN], s[kN];
ll n;
void pre() {
	mu[1] = 1;
	for (int i = 2; i <= n; i++) {
		if (l[i] == 0) {
			mu[i] = -1;
			prime.PB(l[i] = i);
		}
		for (int j : prime) {
			if (i * j > n) break;
			l[i * j] = min(l[i], j);
			if (i % j == 0) {
				mu[i * j] = 0;
				break;
			}
			else mu[i * j] = -mu[i];
		}
	}
	for (int i = 2; i <= n; i++) s[l[i]]++;
	for (int i = 3; i <= n; i++) s[i] += s[i - 1];
	return ;
}

int main() {
	ll ans = 0, one = 0, two = 0, three = 0, zero = 0, cnt = 1;
	scanf("%lld", &n);
	pre();
	for (ll i : prime) if ((i << 1) > n) cnt++;
	zero = (((n - 1) + (n - cnt)) * cnt) >> 1;

	for (int k = 1; k <= n; k++) one += mu[k] * (n / k) * (n / k);
	one = n * (n - 1) / 2 - (one >> 1);

	for (ll i : prime) if (i * i < n) continue;
	else if ((i << 1) > n) break;
	else three += s[i - 1] - s[n / i];

	two = n * (n - 1) / 2 - zero - one - three;

//	printf("zero = %lld\n", zero);
//	printf("one = %lld\n", one);
//	printf("two = %lld\n", two);
//	printf("three = %lld\n", three);

	ans = one + two * 2 + three * 3;
	printf("%lld\n", ans);
}

#include <iostream>
#include <vector>

using namespace std;

typedef long long ll;

const int MAX_N = 1e7 + 5;

ll pairc (ll n) {
  return (n * (n - 1)) / 2;
}

int factor [MAX_N];
int sieve [MAX_N];
int cspf [MAX_N];
int mobius [MAX_N];
int nxtp [MAX_N];

int main () {
  ll n;
  cin >> n;

  vector<int> primes;
  for (int i = 2; i <= n; i++) {
    if (!sieve[i]) {
      nxtp[i] = i;
      primes.push_back(i);
      for (int j = i; j <= n; j += i) {
        factor[j] = i;
        if (!sieve[j]) {
          sieve[j] = 1;
          cspf[i]++;
        }
      }
    }
  }

  for (int i = 2; i <= n; i++) {
    if (factor[i] == i) {
      mobius[i] = 1;
    } else if (factor[i / factor[i]] == factor[i]) {
      mobius[i] = 0;
    } else {
      mobius[i] = -mobius[i / factor[i]];
    }
  }

  for (int i = n - 1; i >= 0; i--) {
    cspf[i] += cspf[i + 1];
    if (nxtp[i] == 0) nxtp[i] = nxtp[i + 1];
  }

  ll isol = 0;
  for (int i = 2; i <= n; i++) {
    if (factor[i] != i || 2 * i <= n) {
      isol++;
    }
  }
  ll ans = isol * (isol - 1);

  // cerr << " " << isol << endl;
  // cerr << ans << endl;

  // calculate # of "big pairs"
  ll bigp = 0;
  for (int p : primes) {
    if (2 * p <= n) {
      ll s = n / p + 1; // smallest s.t. s * p > n
      ll curc = cspf[s];
      if (s <= p) {
        // subtract p itself and its multiples
        curc -= n / p;
      }

      if (nxtp[s] != 0 && 2 * nxtp[s] <= n) {
        bigp += curc;
      }
    }
  }
  bigp /= 2;
  ans += bigp;

  //  cerr << bigp << endl;

  // calculate # of "small pairs"
  ll smallp = 0;
  for (int i = 2; i <= n; i++) {
    smallp += mobius[i] * pairc(n / i);
  }

  // cerr << smallp << endl;
  ans -= smallp;

  cout << ans << endl;
}

#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define F0R(i, a) for (int i=0; i<(a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)

#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

const int MOD = 1000000007;

template<int SZ> struct Sieve {
    int num[SZ+1], sq[SZ+1], lst[SZ+1];
    Sieve() {
        F0R(i,SZ+1) num[i] = lst[i] = sq[i] = 0;
        for (int i = 2; i*i <= SZ; ++i) if (!num[i])
            for (int j = i; j <= SZ; j += i) {
                num[j] ++;
                int j1 = j/i;
                if (!lst[j]) lst[j] = i;
                while (j1 % i == 0) j1 /= i, sq[j] = 1, num[j] ++;
            }
    }
};

Sieve<10000000> S;
ll co[4], cum[10000001];
ll n,z;

void gen0() {
	// distance 0: one is a prime > n/2, or 1
	FOR(i,1,n+1) if (i == 1 || (2*i > n && S.num[i] == 1)) z++;
	co[0] = n*(n-1)/2-(n-z)*(n-z-1)/2;
}

int mob(int x) {
    if (S.sq[x]) return 0;
    if (S.num[x] % 2 == 0) return 1;
    return -1;
}

void gen1() { // gcd > 1
    FOR(i,1,n+1) co[1] += mob(i)*(n/i)*(n/i);
    co[1] = n*n-co[1]-(n-1);
    co[1] /= 2;
}

ll get(int lo, int hi) {
    if (lo > hi) return 0;
    return cum[hi]-cum[lo-1];
}

void gen2() { // gcd = 1, lowest primes multiplied <= n
    FOR(i,2,n+1) cum[S.lst[i]] ++;
    FOR(i,1,n+1) cum[i] += cum[i-1];
    FOR(i,2,n+1) if (S.num[i] == 1) {
        co[2] += get(i,i)*get(i+1,n/i);
        co[2] += get(i,i)*(get(i,i)-1)/2;
    }
    co[2] -= co[1];
}

int main() {
	ios_base::sync_with_stdio(0);cin.tie(0);
    cin >> n;

    gen0();
    gen1();
    gen2();

    co[3] = n*(n-1)/2-co[0]-co[1]-co[2];
    //cout << co[0] << " " << co[1] << " " << co[2] << " " << co[3] << "\n";
    cout << co[1]+2*co[2]+3*co[3];
}

// read!
// ll vs. int!

//by yjz
#include<bits/stdc++.h>
using namespace std;
#define FF first
#define SS second
#define PB push_back
#define MP make_pair
#define bged(v) (v).begin(),(v).end()
#define foreach(it,s) for(__typeof((s).begin()) it=(s).begin();it!=(s).end();it++)
typedef long long ll;
const int Imx=2147483647;
const ll Lbig=2e18;
const int mod=1e9+7;
//My i/o stream
struct fastio
{
	char s[100000];
	int it,len;
	fastio(){it=len=0;}
	inline char get()
	{
		if(it<len)return s[it++];it=0;
		len=fread(s,1,100000,stdin);
		if(len==0)return EOF;else return s[it++];
	}
	bool notend()
	{
		char c=get();
		while(c==' '||c=='\n')c=get();
		if(it>0)it--;
		return c!=EOF;
	}
}_buff;
#define geti(x) x=getnum()
#define getii(x,y) geti(x),geti(y)
#define getiii(x,y,z) getii(x,y),geti(z)
#define puti(x) putnum(x),putchar(' ')
#define putii(x,y) puti(x),puti(y)
#define putiii(x,y,z) putii(x,y),puti(z)
#define putsi(x) putnum(x),putchar('\n')
#define putsii(x,y) puti(x),putsi(y)
#define putsiii(x,y,z) putii(x,y),putsi(z)
inline ll getnum()
{
	ll r=0;bool ng=0;char c;c=_buff.get();
	while(c!='-'&&(c<'0'||c>'9'))c=_buff.get();
	if(c=='-')ng=1,c=_buff.get();
	while(c>='0'&&c<='9')r=r*10+c-'0',c=_buff.get();
	return ng?-r:r;
}
template<class T> inline void putnum(T x)
{
	if(x<0)putchar('-'),x=-x;
	register short a[20]={},sz=0;
	while(x)a[sz++]=x%10,x/=10;
	if(sz==0)putchar('0');
	for(int i=sz-1;i>=0;i--)putchar('0'+a[i]);
}
inline char getreal(){char c=_buff.get();while(c==' '||c=='\n')c=_buff.get();return c;}
int p[1000111],pn,mnp[10000111],phi[10000111],mu[10000111];
bool np[10000111];
int pre[1000111];
ll solve(int d,int n,int lim)
{
	if(n==1)return 0;
//	cerr<<"solve:"<<d<<" "<<n<<" "<<lim<<endl;
	ll ret=0,all=0,tret=0;
	for(int i=2;i<=n;i++)
	{
		int cmnp=min(mnp[d],mnp[i]);
		if(1ll*cmnp*mnp[d]<=lim)tret+=2;
		else if(cmnp*2<=lim&&mnp[d]*2<=lim)tret+=3;

		if(1ll*cmnp*cmnp<=lim)ret-=2;
		else if(cmnp*2<=lim)ret-=3;
		if(cmnp*2<=lim)all++;
		pre[cmnp]++;
	}
	for(int i=1;i<=n;i++)pre[i]+=pre[i-1];
	for(int i=1;i<=n;i++)
	{
		if(np[i])continue;
		ll cur=pre[i]-pre[i-1];
//		cerr<<i<<":"<<cur<<endl;
		if(cur==0)continue;
		ret+=cur*pre[min(n,lim/i)]*2;
		if(i*2<=lim)ret+=cur*(all-pre[min(n,lim/i)])*3;
	}
	for(int i=1;i<=n;i++)pre[i]=0;
//	cerr<<"ret="<<ret/2<<endl;
	return ret/2+tret;
}

int main()
{
	mu[1]=1;mnp[1]=23333333;
	for(int i=2;i<=10000005;i++)
	{
		if(!np[i])p[pn++]=i,mnp[i]=i,phi[i]=i-1,mu[i]=-1;
		for(int j=0;j<pn&&1ll*i*p[j]<=10000005;j++)
		{
			np[i*p[j]]=1;
			mnp[i*p[j]]=p[j];
			if(i%p[j]==0)
			{
				phi[i*p[j]]=phi[i]*p[j];
				mu[i*p[j]]=0;
				break;
			}
			else phi[i*p[j]]=phi[i]*(p[j]-1),mu[i*p[j]]=-mu[i];
		}
	}
/*	cerr<<clock()<<endl;
	for(int i=1;i<=20;i++)cerr<<mnp[i]<<" ";cerr<<endl;
	for(int i=1;i<=20;i++)cerr<<phi[i]<<" ";cerr<<endl;
	for(int i=1;i<=20;i++)cerr<<mu[i]<<" ";cerr<<endl;
	*/
	int n;
	cin>>n;
//	n=10000000;
	ll ans=0;
	for(int i=2;i<=n;i++)ans+=(i-1)-phi[i];
//	cerr<<"ans="<<ans<<endl;
	for(int i=1;i<=n;i++)
	{
		if(!mu[i])continue;
		ans+=mu[i]*solve(i,n/i,n);
	}
	cout<<ans<<endl;
	return 0;
}

#include "bits/stdc++.h"
#define MAXN 100009
#define INF 1000000007
#define mp(x,y) make_pair(x,y)
#define all(v) v.begin(),v.end()
#define pb(x) push_back(x)
#define wr cout<<"----------------"<<endl;
#define ppb() pop_back()
#define tr(ii,c) for(__typeof((c).begin()) ii=(c).begin();ii!=(c).end();ii++)
#define ff first
#define ss second
#define my_little_dodge 46
#define debug(x)  cerr<< #x <<" = "<< x<<endl;
using namespace std;

typedef long long ll;
typedef pair<int,int> PII;
template<class T>bool umin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
template<class T>bool umax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
const int N=1e7+9;
int lp[N],phi[N],n;
ll par[N];
vector<int>pr;
ll path[4];
int main(){
	freopen("file.in","r",stdin);
	phi[1]=1;
    for(int i=2;i<N;i++){
        if(!lp[i])
			lp[i]=i,phi[i]=i-1,pr.push_back(i);
        else{
            if(lp[i]==lp[i/lp[i]])
                phi[i]=phi[i/lp[i]]*lp[i];
            else
                phi[i]=phi[i/lp[i]]*(lp[i]-1);
        }
        for(int j=0;j<(int)pr.size() and pr[j]<=lp[i] and i*pr[j]<N;j++)
            lp[i*pr[j]]=pr[j];
    }
	scanf("%d",&n);
	for(int i=2;i<=n;i++)
		path[1]+=i-1-phi[i];
	for(int i=2;i<=n;i++)
		par[lp[i]]++;
	for(int i=2;i<=n;i++)
		par[i]+=par[i-1];
	for(int i=2;i<=n;i++){
		path[2]+=par[n/lp[i]];
		if(lp[i]*1LL*lp[i]<=n)
			path[2]--;
	}assert(path[2]%2==0);path[2]/=2;
	path[2]-=path[1];
	for(int i=2;i<=n;i++)
		if(lp[i]*2<=n)
			path[3]+=par[n/2]-1;
	assert(path[3]%2==0);path[3]/=2;
	path[3]-=path[2]+path[1];
	//~ cout<<path[1]<<" "<<path[2]<<" "<<path[3]<<endl;
	ll ans=0;
	for(int i=1;i<=3;i++)
		ans+=path[i]*1LL*i;
	printf("%lld\n",ans);
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=10000007;
int phi[N],p[N],mi[N],c[N],v[N],tot,n;
long long ans;
int rd()
{
    char c=getchar();int s=0,f=1;
    while(c>'9'||c<'0'){if(c=='-')f=-f;c=getchar();}
    while(c>='0'&&c<='9') s=(s<<1)+(s<<3)+(c^48),c=getchar();
    return s*f;
}
void prepare()
{
    phi[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(!v[i]){p[++tot]=i,mi[i]=i,phi[i]=i-1;}
        for(int j=1;j<=tot;j++)
        {
            if(p[j]*i>n) break;v[i*p[j]]=1;mi[i*p[j]]=p[j];
            if(i%p[j]==0){phi[i*p[j]]=phi[i]*p[j];break;}
            else phi[i*p[j]]=phi[i]*(p[j]-1);
        }
        phi[i]+=phi[i-1];
    }
    for(int i=1;i<=n;i++) c[mi[i]]++;
    for(int i=1;i<=n;i++) c[i]+=c[i-1];
}
int get(int l,int r)
{
    if(r<l) return 0;
    return c[r]-c[l-1];
}
int main()
{
    n=rd();prepare();
    ans=(n-1)*(n-2)/2+phi[n]-n;
    for(int i=1;i<=tot;i++)
    {
        int cnt=c[p[i]]-c[p[i]-1];
        ans+=get(max(p[i]+1,n/p[i]+1),max(p[i]+1,n/2+1)-1)*cnt;
        ans-=2*get(max(p[i]+1,(n>>1)+1),n)*cnt;
    }
    printf("%lld\n",ans);
    return 0;
}

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

const int MN = 10000010;

vector<int> pr;
int pchk[MN];

void sieve() {
    for(int i = 2; i < MN; i++) {
        if(!pchk[i]) {
            pr.push_back(i);
            pchk[i] = i;
        }
        for(int j = 0; j < pr.size() && i * pr[j] < MN; j++) {
            pchk[ i * pr[j] ] = pr[j];
            if(i % pr[j] == 0) break;
        }
    }
}

int N;
ll dp[MN], ans;
int C[MN];

int main() {
    sieve();

    cin >> N;
    //N = 1e7;

    for(int i = N; i >= 1; i--) {
        dp[i] = 1LL * (N / i) * (N / i);
        for(int j = 2; i * j <= N; j++) {
            dp[i] -= dp[i * j];
        }
    }

    ans += (1LL * N * (N - 1) / 2) - dp[1] / 2;
    ans += dp[1] / 2 * 3;

    int cnt = 0;
    for(int i = 0; i < pr.size(); i++) {
        if(pr[i] > N) break;
        if(pr[i] > N / 2) cnt++;
    }

    ans -= 3LL * (N - 2) * cnt + 3LL * cnt * (cnt - 1) / 2;
    ans -= 3 * (N - 1);

    for(int i = 2; i <= N; i++) {
        if(pchk[i]) C[ pchk[i] ]++;
    }

    ll x = 0;
    for(int i = 0; i < pr.size(); i++) {
        for(int j = i; j < pr.size(); j++) {
            if(1LL * pr[i] * pr[j] > N) break;

            if(i == j) x += 1LL * C[ pr[i] ] * (C[ pr[i] ] - 1) / 2;
            else x += 1LL * C[ pr[i] ] * C[ pr[j] ];
        }
    }

    ans -= x - (1LL * N * (N - 1) / 2 - dp[1] / 2);
    printf("%lld", ans);
}

#include<bits/stdc++.h>
using namespace std;
const int N=10000005;
const int MOD=(int)1e9+7;
int add(int x,int y){x+=y; return x>=MOD ? x-MOD : x;}
int sub(int x,int y){x-=y; return x<0 ? x+MOD : x;}
int mul(int x,int y){return 1ll*x*y%MOD;}
int prime[N],bl[N],tot=0,phi[N],f[N],g[N];
void init(int n)
{
    for(int i=1;i<=n;i++) bl[i]=1;
    bl[1]=0; phi[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(bl[i]) prime[++tot]=i,phi[i]=i-1,f[i]++;
        for(int j=1;j<=tot;j++)
        {
            if(i*prime[j]>n) break;
            bl[i*prime[j]]=0;
            f[prime[j]]++;
            if(i%prime[j]==0)
            {
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
            //cout<<prime[j]<<"PPP\n";
            phi[i*prime[j]]=phi[i]*phi[prime[j]];
        }
    }
    //for(int i=1;i<=n;i++) cout<<f[i]<<endl;
    for(int i=2;i<=n;i++) g[i]=add(g[i-1],f[i]);
}

int inv2=(MOD+1)/2;
int ans1=0,ans2=0,ans3=0,rest=0,n;
void solve()
{
    for(int i=2;i<=n;i++) ans1=add(ans1,i-1-phi[i]);
    for(int i=1;i<=tot;i++)
    {
        int L=max(n/prime[i]+1,prime[i]+1);
        int R=n/2;
        if(L<=R) ans3=add(ans3,mul(f[prime[i]],sub(g[R],g[L-1])));
        R=n; L=max(n/2+1,L);
        //cout<<prime[i]<<" "<<L<<" "<<R<<endl;
        rest=add(rest,mul(f[prime[i]],sub(g[R],g[L-1])));
    }
    int sum=mul(mul(n-1,n-2),inv2);
    ans2=sub(sum,add(rest,add(ans1,ans3)));
    //cout<<ans1<<" "<<ans2<<" "<<ans3<<" "<<rest<<endl;
    printf("%d\n",add(add(mul(ans2,2),mul(ans3,3)),ans1));
}

int main()
{
    scanf("%d",&n);
    init(n);
    solve();
}