#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

bool notPrime[100001];

int n;
int data[100000], loc[100000];

int main(void)
{
	for(int i = 2; i < 100000; i++)
	{
		if(notPrime[i] == false)
		{
			for(int j = i * 2; j < 100000; j += i)
				notPrime[j] = true;
		}
	}

	scanf("%d", &n);
	for(int i = 0; i < n; i++)
	{
		scanf("%d", data + i);
		data[i]--;
		loc[data[i]] = i;
	}

	vector <pair<int, int>> ans;
	for(int i = 0; i < n; i++)
	{
		int curLoc = loc[i];
		int gap = curLoc - i + 1;
		while(gap > 1 && notPrime[gap])
		{
			ans.push_back(make_pair(i + gap - 1, i + gap));
			int &u = data[i + gap - 2], &v = data[i + gap - 1];
			swap(loc[u], loc[v]);
			swap(u, v);
			gap--;
		}

		if(gap > 1)
		{
			ans.push_back(make_pair(i + 1, i + gap));
			int &u = data[i], &v = data[i + gap - 1];
			swap(loc[u], loc[v]);
			swap(u, v);
		}
	}

	printf("%d\n", (int)ans.size());
	for(auto v: ans) printf("%d %d\n", v.first, v.second);

	return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

bool notPrime[100001];

int n;
int data[100000], loc[100000];

int main(void)
{
	for(int i = 2; i < 100000; i++)
	{
		if(notPrime[i] == false)
		{
			for(int j = i * 2; j < 100000; j += i)
				notPrime[j] = true;
		}
	}

	scanf("%d", &n);
	for(int i = 0; i < n; i++)
	{
		scanf("%d", data + i);
		data[i]--;
		loc[data[i]] = i;
	}

	vector <pair<int, int>> ans;
	for(int i = 0; i < n; i++)
	{
		int curLoc = loc[i];
		int gap = curLoc - i + 1;
		while(gap > 1 && notPrime[gap])
		{
			ans.push_back(make_pair(i + gap - 1, i + gap));
			int &u = data[i + gap - 2], &v = data[i + gap - 1];
			swap(loc[u], loc[v]);
			swap(u, v);
			gap--;
		}

		if(gap > 1)
		{
			ans.push_back(make_pair(i + 1, i + gap));
			int &u = data[i], &v = data[i + gap - 1];
			swap(loc[u], loc[v]);
			swap(u, v);
		}
	}

	printf("%d\n", (int)ans.size() + 10 * n);
	for(auto v: ans) printf("%d %d\n", v.first, v.second);
	for(int i = 0; i < 5 * n; i++) printf("1 2\n2 1\n");

	return 0;
}


#define GOD
#include <bits/stdc++.h>
#define forn(i,a,b) for(int i=(a);i<=(b);++i)
#define ford(i,a,b) for(int i=(a);i>=(b);--i)
typedef long long   LL;
using namespace std;

const int maxn = 100010;

ostringstream out;

int D(int p, int q)
{
	return q-p+1;
}

void doSwaps(int p, int q, bool* pr, int &cnt)
{
	int d = D(p,q);
	if (!pr[d])
	{
		out << p << ' ' << q << endl;
		cnt++;
	}
	else if (d%2 == 0)
	{
		int j = p+1;
		while (!(!pr[D(p,j)] && !pr[D(j+1,q)]))
			j++;
		out << p << ' ' << j << endl;
		out << j+1 << ' ' << q << endl;
		out << j << ' ' << j+1 << endl;
		out << p << ' ' << j << endl;
		out << j+1 << ' ' << q << endl;
		cnt += 5;
	}
	else
	{
		int j = p+1;
		while (!(!pr[D(p,j)] && !pr[D(j,q)]))
			j++;
		out << p << ' ' << j << endl;
		out << j << ' ' << q << endl;
		out << p << ' ' << j << endl;
		cnt += 3;
	}
}

int main()
{
	int n, cnt = 0, a[maxn], p[maxn];
	cin >> n;
	bool pr[maxn] = {0};
	forn(i, 1, n)
	{
		cin >> a[i];
		p[a[i]] = i;
	}
	forn(i, 2, sqrt(n))
	{
		if (pr[i] == 0)
			for (int j = i*i; j <= n; j += i)
				pr[j] = 1;
	}
	forn(i, 1, n)
		if (i != a[i])
		{
			doSwaps(i, p[i], pr, cnt);
			swap(a[i], a[p[i]]);
			swap(p[a[i]], p[a[p[i]]]);
		}
	cout << cnt << endl << out.str();
	return 0;
}


#define GOD
#include <bits/stdc++.h>
#define forn(i,a,b) for(int i=(a);i<=(b);++i)
#define ford(i,a,b) for(int i=(a);i>=(b);--i)
typedef long long   LL;
using namespace std;

const int maxn = 100010;

ostringstream out;

int D(int p, int q)
{
	return q-p+1;
}

void doSwaps(int p, int q, bool* pr, int &cnt)
{
	int d = D(p,q);
	if (!pr[d])
	{
		out << p << ' ' << q << endl;
		cnt++;
	}
	else if (d%2 == 0)
	{
		int j = p+1;
		while (!(!pr[D(p,j)] && !pr[D(j+1,q)]))
			j++;
		out << p << ' ' << j << endl;
		out << j+1 << ' ' << q << endl;
		out << j << ' ' << j+1 << endl;
		out << p << ' ' << j << endl;
		out << j+1 << ' ' << q << endl;
		cnt += 5;
	}
	else
	{
		int j = p+1;
		while (!(!pr[D(p,j)] && !pr[D(j,q)]))
			j++;
		out << p << ' ' << j << endl;
		out << j << ' ' << q << endl;
		out << p << ' ' << j << endl;
		cnt += 3;
	}
}

int main()
{
	int n, cnt = 0, a[maxn], p[maxn];
	cin >> n;
	bool pr[maxn] = {0};
	forn(i, 1, n)
	{
		cin >> a[i];
		p[a[i]] = i;
	}
	forn(i, 2, n)
	{
		if (pr[i] == 0)
		for (int j = i*i; j <= n; j += i)
			pr[j] = 1;
	}
	forn(i, 1, n)
		if (i != p[i])
		{
			doSwaps(i, p[i], pr, cnt);
			swap(a[i], a[p[i]]);
			swap(p[i], p[p[i]]);
		}
	cout << cnt << endl << out.str();
	return 0;
}


#define GOD
#include <bits/stdc++.h>
#define forn(i,a,b) for(int i=(a);i<=(b);++i)
#define ford(i,a,b) for(int i=(a);i>=(b);--i)
typedef long long   LL;
using namespace std;

const int maxn = 100010;

ostringstream out;

int D(int p, int q)
{
	return q-p+1;
}

void doSwaps(int p, int q, bool* pr, int &cnt)
{
	int d = D(p,q);
	if (!pr[d])
	{
		out << p << ' ' << q << endl;
		cnt++;
	}
	else if (d%2 == 0)
	{
		int j = p+1;
		while (!(!pr[D(p,j)] && !pr[D(j+1,q)]))
			j++;
		out << p << ' ' << j << endl;
		out << j+1 << ' ' << q << endl;
		out << j << ' ' << j+1 << endl;
		out << p << ' ' << j << endl;
		out << j+1 << ' ' << q << endl;
		cnt += 5;
	}
	else
	{
		int j = p+1;
		while (!(!pr[D(p,j)] && !pr[D(j,q)]))
			j++;
		out << p << ' ' << j << endl;
		out << j << ' ' << q << endl;
		out << p << ' ' << j << endl;
		cnt += 3;
	}
}

int main()
{
	int n, cnt = 0, a[maxn], p[maxn];
	cin >> n;
	bool pr[maxn] = {0};
	forn(i, 1, n)
	{
		cin >> a[i];
		p[a[i]] = i;
	}
	forn(i, 2, n)
	{
		if (pr[i] == 0)
		for (int j = i*i; j <= n; j += i)
			pr[j] = 1;
	}
	forn(i, 1, n)
		if (i != a[i])
		{
			doSwaps(i, p[i], pr, cnt);
			swap(a[i], a[p[i]]);
			swap(p[a[i]], p[a[p[i]]]);
		}
	cout << cnt << endl << out.str();
	return 0;
}


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

int main(){
    ios_base::sync_with_stdio(false);

    int n;
    cin >> n;
    int a[n];
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
        a[i]--;
    }

    vector<int> pr;
    int N = n + 1;
    vector<char> used(N, 0);
    for (int i = 2; i <= n; ++i) {
        if (!used[i]) {
            pr.push_back(i);
            if (i * 1ll * i <= n) {
                for (int j = i * i; j <= N; j += i) {
                    used[j] = 1;
                }
            }
        }
    }

    int pos[n];
    for (int i = 0; i < n; ++i) {
        pos[a[i]] = i;
    }

    vector<pair<int, int> > ans;

    for (int i = 0; i < n - 1; ++i) {
        while (1) {
            int delta = pos[i] - i;
            if (delta == 0) {
                break;
            }
            int prime_num = upper_bound(pr.begin(), pr.end(), delta + 1) - pr.begin();
            --prime_num;
            int prime = pr[prime_num];

            int p1 = pos[i];
            int p2 = pos[i] - prime + 1;

            ans.push_back(make_pair(p2, p1));
            swap(pos[a[p2]], pos[a[p1]]);
            swap(a[p1], a[p2]);
        }
    }

    cout << ans.size() << "\n";
    for (pair<int, int> p : ans) {
        cout << p.first + 1 << " " << p.second + 1 << "\n";
    }
    return 0;
}


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

int main(){
    ios_base::sync_with_stdio(false);

    int n;
    cin >> n;
    int a[n];
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
        a[i]--;
    }

    vector<int> pr;
    int N = n + 1;
    vector<char> used(N, 0);
    for (int i = 2; i <= N; ++i) {
        if (!used[i]) {
            pr.push_back(i);
            if (i * 1ll * i <= N) {
                for (int j = i * i; j <= N; j += i) {
                    used[j] = 1;
                }
            }
        }
    }

    int pos[n];
    for (int i = 0; i < n; ++i) {
        pos[a[i]] = i;
    }

    vector<pair<int, int> > ans;

    for (int i = 0; i < n - 1; ++i) {
        while (1) {
            int delta = pos[i] - i;
            if (delta == 0) {
                break;
            }
            int prime_num = upper_bound(pr.begin(), pr.end(), delta + 1) - pr.begin();
            --prime_num;
            int prime = pr[prime_num];

            int p1 = pos[i];
            int p2 = pos[i] - prime + 1;

            ans.push_back(make_pair(p2, p1));
            swap(pos[a[p2]], pos[a[p1]]);
            swap(a[p1], a[p2]);
        }
    }

    cout << ans.size() << "\n";
    for (pair<int, int> p : ans) {
        cout << p.first + 1 << " " << p.second + 1 << "\n";
    }
    return 0;
}


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

int main(){
    ios_base::sync_with_stdio(false);

    int n;
    cin >> n;
    int a[n];
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
        a[i]--;
    }

    vector<int> pr;
    int N = n + 1;
    vector<char> used(N, 0);
    for (int i = 2; i <= n; ++i) {
        if (!used[i]) {
            pr.push_back(i);
            if (i * 1ll * i <= n) {
                for (int j = i * i; j <= n; j += i) {
                    used[j] = 1;
                }
            }
        }
    }

    int pos[n];
    for (int i = 0; i < n; ++i) {
        pos[a[i]] = i;
    }

    vector<pair<int, int> > ans;

    for (int i = 0; i < n - 1; ++i) {
        while (1) {
            int delta = pos[i] - i;
            if (delta == 0) {
                break;
            }
            int prime_num = upper_bound(pr.begin(), pr.end(), delta + 1) - pr.begin();
            --prime_num;
            int prime = pr[prime_num];

            int p1 = pos[i];
            int p2 = pos[i] - prime + 1;

            ans.push_back(make_pair(p2, p1));
            swap(pos[a[p2]], pos[a[p1]]);
            swap(a[p1], a[p2]);
        }
    }

    cout << ans.size() << "\n";
    for (pair<int, int> p : ans) {
        cout << p.first + 1 << " " << p.second + 1 << "\n";
    }
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cassert>
#include <ctime>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define FOR(i,a,b) for(int _b=(b),i=(a); i<_b; ++i)
#define ROF(i,b,a) for(int _a=(a),i=(b); i>_a; --i)
#define _1 first
#define _2 second
#define PB(x) push_back(x)
#define MP(x,y) make_pair(x,y)
#define MSET(m,v) memset(m,v,sizeof(m))
#define MAX_PQ(T) priority_queue <T>
#define MIN_PQ(T) priority_queue <T,vector<T>,greater<T>>
typedef long long LL; typedef long double LD; typedef unsigned int uint;
typedef pair<int,int> PII; typedef pair<LL,LL> PLL;
typedef vector<int> VI; typedef vector<LL> VL; typedef vector<PII> VP;
template<typename A, typename B> inline bool mina(A &x, B y) { return (x > y)? (x=y,1):0; }
template<typename A, typename B> inline bool maxa(A &x, B y) { return (x < y)? (x=y,1):0; }

// More templates here

#define MAXN (100005)

int N;
int A[MAXN];
int B[MAXN];

int T[MAXN];
int P[MAXN];
int pn;

PII sol[MAXN*5];
int sn;

int main()
{
	P[0] = 2;
	pn = 1;
	for(int i = 3; i < MAXN; i += 2)
	{
		int p = 1;
		for(int j = 0; j < pn && P[j]*P[j] <= i; ++j)
		{
			if(i % P[j] == 0)
			{
				p = 0;
				break;
			}
		}
		if(p) P[pn++] = i;
	}

	{
		int j = 0;
		FOR(i,2,MAXN)
		{
			if(j+1 < pn && P[j+1] == i) ++j;
			T[i] = P[j];
		}
	}

	cin >> N;
	FOR(i,1,N+1)
	{
		int a;
		scanf("%d", &a);
		A[i] = a;
		B[a] = i;
	}

	FOR(i,1,N+1) while(A[i] != i)
	{
		int d = T[B[i] - i + 1];
		int b = B[i];
		int a = b - d + 1;

		sol[sn++] = PII(a, b);
		swap(A[a], A[b]);
		B[A[a]] = a;
		B[A[b]] = b;
	}

	printf("%d\n", sn);
	FOR(i,0,sn) printf("%d %d\n", sol[i]._1, sol[i]._2);

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define TR(i,v) 		for(__typeof((v).begin())i=(v).begin();i!=(v).end();++i)
#define DEBUG(x) 		cout << #x << " = "; cout << x << endl;
#define SIZE(p) 		(int)(p).size()
#define MP(a, b)		make_pair((a), (b))
#define ALL(p)			(p).begin(), (p).end()
#define rep(i, n)		for(int (i)=0; (i)<(int)(n); ++(i))
#define REP(i, a, n)	for(int (i)=(a); (i)<(int)(n); ++(i))
#define FOR(i, a, b)   	for(int (i)=(int)(a); (i)<=(int)(b); ++(i))
#define FORD(i, b, a)  	for(int (i)=(int)(b); (i)>=(int)(a); --(i))
typedef long long LL;
typedef pair<int, int> pii;
int A[100005], idx[100005];
vector<pii> res;
inline void Swap(int l, int r) {
	swap(idx[A[l]], idx[A[r]]), swap(A[l], A[r]);
	res.push_back(MP(min(l,r),max(l,r)));
}
int main(int argc, char const *argv[])
{
	#ifndef ONLINE_JUDGE
    freopen("C.in", "r", stdin);
    freopen("out", "w", stdout);
    #endif
	// ios::sync_with_stdio(false);    cin.tie(0);
	int h = 100003;
	static int prime[100005];
	static bool bad[100005];
	FOR(i, 2, h)
	for(LL j=(LL)i*i; j<=h; j+=i) bad[j]=1;
	int k=0;
	FOR(i, 2, h) if(!bad[i])
		prime[k++]=i;
	static vector<int> G[100005] ;
	rep(i, k)
		REP(j, i, k) {
			int x=prime[i]+prime[j];
			if(x>h)	break;
			if(G[x].empty()) {
				G[x].push_back(prime[i]),G[x].push_back(prime[j]);
			}
		}
	int n;	cin>>n;
	rep(i, n)	cin>>A[i], --A[i], idx[A[i]]=i;
	rep(i, n) {
		if(idx[i]==i)	continue;
		int p=abs(idx[i]-i)+1;
		int L=min(idx[i],i), R=max(i,idx[i]);
		// printf("L=%d R=%d\n", L, R);
		if(!bad[p]) {
			Swap(idx[i],i);
		}else {
			++p;
			if(p&1) {
				if(idx[i]>i) {
					Swap(idx[i], idx[i]-1);
					--p;
					// DEBUG(p);
					--R;
					// DEBUG(L);
					// DEBUG(R);
					// DEBUG(G[p][0]);
					// DEBUG(G[p][1]);
					Swap(R, R-G[p][0]+1);
					Swap(R-G[p][0]+1, L);
				}else {
					Swap(L, L+1);
					--p;
					++L;
					Swap(L, L+G[p][0]-1);
					Swap(L+G[p][0]-1, R);
				}
			}else {
				if(idx[i]>i) {
					Swap(R, R-G[p][0]+1);
					Swap(R-G[p][0]+1, L);
				}else {
					Swap(L, L+G[p][0]-1);
					Swap(L+G[p][0]-1, R);
				}
			}
		}
		// rep(i, n)
			// printf("%d ", A[i]);	puts("");
	}
	printf("%d\n", SIZE(res));
	rep(i,SIZE(res))
		printf("%d %d\n", res[i].first+1, res[i].second+1);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define TR(i,v) 		for(__typeof((v).begin())i=(v).begin();i!=(v).end();++i)
#define DEBUG(x) 		cout << #x << " = "; cout << x << endl;
#define SIZE(p) 		(int)(p).size()
#define MP(a, b)		make_pair((a), (b))
#define ALL(p)			(p).begin(), (p).end()
#define rep(i, n)		for(int (i)=0; (i)<(int)(n); ++(i))
#define REP(i, a, n)	for(int (i)=(a); (i)<(int)(n); ++(i))
#define FOR(i, a, b)   	for(int (i)=(int)(a); (i)<=(int)(b); ++(i))
#define FORD(i, b, a)  	for(int (i)=(int)(b); (i)>=(int)(a); --(i))
typedef long long LL;
typedef pair<int, int> pii;

int main(int argc, char const *argv[])
{
	#ifndef ONLINE_JUDGE
    freopen("C.in", "r", stdin);
    freopen("out", "w", stdout);
    #endif
	// ios::sync_with_stdio(false);    cin.tie(0);
	int h = 100003;
	static int prime[100005];
	static bool bad[100005];
	FOR(i, 2, h)
	for(LL j=(LL)i*i; j<=h; j+=i) bad[j]=1;
	int k=0;
	FOR(i, 2, h) if(!bad[i])
		prime[k++]=i;
	static vector<int> G[100005] ;
	rep(i, k)
		REP(j, i, k) {
			int x=prime[i]+prime[j];
			if(x>h)	continue;
			if(G[x].empty()) {
				// DEBUG(x);
				G[x].push_back(prime[i]),G[x].push_back(prime[j]);
			}
		}
	static int A[100005], idx[100005];
	int n;	cin>>n;
	rep(i, n)	cin>>A[i], --A[i], idx[A[i]]=i;
	// DEBUG(n);
	vector<pii> res;
	rep(i, n) {
		// DEBUG(i);
		// DEBUG(idx[i]);
		if(idx[i]==i)	continue;
		int p = abs(idx[i]-i)+1;
		if(!bad[p]) {
			int L=idx[i], R=i;
			// puts("!");
			res.push_back(pii(i, idx[i]));
			int tmp = idx[i];
			idx[i] = i, idx[A[i]] = tmp;
			swap(A[L], A[R]);
		}else {
			// puts("@");
			++p;
			int L=min(i , idx[i]), R=max(i, idx[i]);
			// DEBUG(L);
			// DEBUG(R);
			// DEBUG(SIZE(G[p]));
			// DEBUG(G[p][0]);
			// DEBUG(G[p][1]);
			while(G[p].empty())		;
			res.push_back(pii(L, L+G[p][0]-1));
			idx[A[L]] = L+G[p][0]-1, idx[A[L+G[p][0]-1]] = L;
			swap(A[L], A[L+G[p][0]-1]);
			res.push_back(pii(L+G[p][0]-1, R));
			idx[A[L+G[p][0]-1]] = R, idx[A[R]] = L+G[p][0]-1;
			swap(A[L+G[p][0]-1], A[R]);
		}
		// fflush(stdout);
	}
	printf("%d\n", SIZE(res));
	// fflush(stdout);
	// return 0;
	rep(i, SIZE(res)) {
		int L = min(res[i].first, res[i].second);
		int R = max(res[i].first, res[i].second);
		printf("%d %d\n", L+1, R+1);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define TR(i,v) 		for(__typeof((v).begin())i=(v).begin();i!=(v).end();++i)
#define DEBUG(x) 		cout << #x << " = "; cout << x << endl;
#define SIZE(p) 		(int)(p).size()
#define MP(a, b)		make_pair((a), (b))
#define ALL(p)			(p).begin(), (p).end()
#define rep(i, n)		for(int (i)=0; (i)<(int)(n); ++(i))
#define REP(i, a, n)	for(int (i)=(a); (i)<(int)(n); ++(i))
#define FOR(i, a, b)   	for(int (i)=(int)(a); (i)<=(int)(b); ++(i))
#define FORD(i, b, a)  	for(int (i)=(int)(b); (i)>=(int)(a); --(i))
typedef long long LL;
typedef pair<int, int> pii;

int main(int argc, char const *argv[])
{
	#ifndef ONLINE_JUDGE
    freopen("C.in", "r", stdin);
    freopen("out", "w", stdout);
    #endif
	// ios::sync_with_stdio(false);    cin.tie(0);
	int h = 100000;
	static int prime[100005];
	static bool bad[100005];
	FOR(i, 2, h)
	for(LL j=(LL)i*i; j<=h; j+=i) bad[j]=1;
	int k=0;
	FOR(i, 2, h) if(!bad[i])
		prime[k++]=i;
	static vector<int> G[100005] ;
	rep(i, k)
		REP(j, i, k) {
			int x=prime[i]+prime[j];
			if(x>h)	continue;
			if(G[x].empty()) {
				// DEBUG(x);
				G[x].push_back(prime[i]),G[x].push_back(prime[j]);
			}
		}
	static int A[100005], idx[100005];
	int n;	cin>>n;
	rep(i, n)	cin>>A[i], --A[i], idx[A[i]]=i;
	// DEBUG(n);
	vector<pii> res;
	rep(i, n) {
		// DEBUG(i);
		// DEBUG(idx[i]);
		if(idx[i]==i)	continue;
		int p = abs(idx[i]-i)+1;
		if(!bad[p]) {
			int L=idx[i], R=i;
			// puts("!");
			res.push_back(pii(i, idx[i]));
			int tmp = idx[i];
			idx[i] = i, idx[A[i]] = tmp;
			swap(A[L], A[R]);
		}else {
			// puts("@");
			++p;
			int L=min(i , idx[i]), R=max(i, idx[i]);
			// DEBUG(L);
			// DEBUG(R);
			// DEBUG(SIZE(G[p]));
			// DEBUG(G[p][0]);
			// DEBUG(G[p][1]);
			res.push_back(pii(L, L+G[p][0]-1));
			idx[A[L]] = L+G[p][0]-1, idx[A[L+G[p][0]-1]] = L;
			swap(A[L], A[L+G[p][0]-1]);
			res.push_back(pii(L+G[p][0]-1, R));
			idx[A[L+G[p][0]-1]] = R, idx[A[R]] = L+G[p][0]-1;
			swap(A[L+G[p][0]-1], A[R]);
		}
		// fflush(stdout);
	}
	printf("%d\n", SIZE(res));
	// fflush(stdout);
	// return 0;
	rep(i, SIZE(res)) {
		int L = min(res[i].first, res[i].second);
		int R = max(res[i].first, res[i].second);
		printf("%d %d\n", L+1, R+1);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define TR(i,v) 		for(__typeof((v).begin())i=(v).begin();i!=(v).end();++i)
#define DEBUG(x) 		cout << #x << " = "; cout << x << endl;
#define SIZE(p) 		(int)(p).size()
#define MP(a, b)		make_pair((a), (b))
#define ALL(p)			(p).begin(), (p).end()
#define rep(i, n)		for(int (i)=0; (i)<(int)(n); ++(i))
#define REP(i, a, n)	for(int (i)=(a); (i)<(int)(n); ++(i))
#define FOR(i, a, b)   	for(int (i)=(int)(a); (i)<=(int)(b); ++(i))
#define FORD(i, b, a)  	for(int (i)=(int)(b); (i)>=(int)(a); --(i))
typedef long long LL;
typedef pair<int, int> pii;

int main(int argc, char const *argv[])
{
	#ifndef ONLINE_JUDGE
    freopen("C.in", "r", stdin);
    freopen("out", "w", stdout);
    #endif
	// ios::sync_with_stdio(false);    cin.tie(0);
	int h = 100003;
	static int prime[100005];
	static bool bad[100005];
	FOR(i, 2, h)
	for(LL j=(LL)i*i; j<=h; j+=i) bad[j]=1;
	int k=0;
	FOR(i, 2, h) if(!bad[i])
		prime[k++]=i;
	static vector<int> G[100005] ;
	rep(i, k)
		REP(j, i, k) {
			int x=prime[i]+prime[j];
			if(x>h)	continue;
			if(G[x].empty()) {
				// DEBUG(x);
				G[x].push_back(prime[i]),G[x].push_back(prime[j]);
			}
		}
	// FOR(p, 2, h) {
	// 	printf("p=%d %d\n",p,SIZE(G[p]));
	// 	// if(G[p].empty())

	// }
	static int A[100005], idx[100005];
	int n;	cin>>n;
	rep(i, n)	cin>>A[i], --A[i], idx[A[i]]=i;
	// DEBUG(n);
	vector<pii> res;
	rep(i, n) {
		// DEBUG(i);
		// DEBUG(idx[i]);
		if(idx[i]==i)	continue;
		int p = abs(idx[i]-i)+1;
		if(!bad[p]) {
			int L=idx[i], R=i;
			// puts("!");
			res.push_back(pii(i, idx[i]));
			int tmp = idx[i];
			idx[i] = i, idx[A[i]] = tmp;
			swap(A[L], A[R]);
		}else {
			// puts("@");
			++p;
			int L=min(i , idx[i]), R=max(i, idx[i]);
			// DEBUG(p);
			if(!bad[p]) {
				res.push_back(pii(L, L+1));
				idx[A[L]]=L+1, idx[A[L+1]]=L;
				swap(A[L],A[L+1]);
				res.push_back(pii(L+1, R));
				idx[A[L+1]]=R, idx[A[R]]=L+1;
				swap(A[L+1], A[R]);
				continue;
			}
			// DEBUG(L);
			// DEBUG(R);
			// DEBUG(SIZE(G[p]));
			// DEBUG(G[p][0]);
			// DEBUG(G[p][1]);
			while(G[p].empty());
			res.push_back(pii(L, L+G[p][0]-1));
			idx[A[L]] = L+G[p][0]-1, idx[A[L+G[p][0]-1]] = L;
			swap(A[L], A[L+G[p][0]-1]);
			res.push_back(pii(L+G[p][0]-1, R));
			idx[A[L+G[p][0]-1]] = R, idx[A[R]] = L+G[p][0]-1;
			swap(A[L+G[p][0]-1], A[R]);
		}
		// fflush(stdout);
	}
	printf("%d\n", SIZE(res));
	// fflush(stdout);
	// return 0;
	rep(i, SIZE(res)) {
		int L = min(res[i].first, res[i].second);
		int R = max(res[i].first, res[i].second);
		printf("%d %d\n", L+1, R+1);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define TR(i,v) 		for(__typeof((v).begin())i=(v).begin();i!=(v).end();++i)
#define DEBUG(x) 		cout << #x << " = "; cout << x << endl;
#define SIZE(p) 		(int)(p).size()
#define MP(a, b)		make_pair((a), (b))
#define ALL(p)			(p).begin(), (p).end()
#define rep(i, n)		for(int (i)=0; (i)<(int)(n); ++(i))
#define REP(i, a, n)	for(int (i)=(a); (i)<(int)(n); ++(i))
#define FOR(i, a, b)   	for(int (i)=(int)(a); (i)<=(int)(b); ++(i))
#define FORD(i, b, a)  	for(int (i)=(int)(b); (i)>=(int)(a); --(i))
typedef long long LL;
typedef pair<int, int> pii;

int main(int argc, char const *argv[])
{
	#ifndef ONLINE_JUDGE
    freopen("C.in", "r", stdin);
    freopen("out", "w", stdout);
    #endif
	// ios::sync_with_stdio(false);    cin.tie(0);
	int h = 100003;
	static int prime[100005];
	static bool bad[100005];
	FOR(i, 2, h)
	for(LL j=(LL)i*i; j<=h; j+=i) bad[j]=1;
	int k=0;
	FOR(i, 2, h) if(!bad[i])
		prime[k++]=i;
	static vector<int> G[100005] ;
	rep(i, k)
		REP(j, i, k) {
			int x=prime[i]+prime[j];
			if(x>h)	continue;
			if(G[x].empty()) {
				// DEBUG(x);
				G[x].push_back(prime[i]),G[x].push_back(prime[j]);
			}
		}
	// FOR(p, 2, h) {
	// 	printf("p=%d %d\n",p,SIZE(G[p]));
	// 	// if(G[p].empty())

	// }
	static int A[100005], idx[100005];
	int n;	cin>>n;
	rep(i, n)	cin>>A[i], --A[i], idx[A[i]]=i;
	// DEBUG(n);
	vector<pii> res;
	rep(i, n) {
		// DEBUG(i);
		// DEBUG(idx[i]);
		if(idx[i]==i)	continue;
		int p = abs(idx[i]-i)+1;
		if(!bad[p]) {
			int L=idx[i], R=i;
			// puts("!");
			res.push_back(pii(i, idx[i]));
			int tmp = idx[i];
			idx[i] = i, idx[A[i]] = tmp;
			swap(A[L], A[R]);
		}else {
			// puts("@");
			++p;
			int L=min(i , idx[i]), R=max(i, idx[i]);
			// DEBUG(p);
			if(G[p].empty())
				assert(bad[p]);
			if(!bad[p]) {
				res.push_back(pii(L, L+1));
				idx[A[L]]=L+1, idx[A[L+1]]=L;
				swap(A[L],A[L+1]);
				res.push_back(pii(L+1, R));
				idx[A[L+1]]=R, idx[A[R]]=L+1;
				swap(A[L+1], A[R]);
				continue;
			}
			// DEBUG(L);
			// DEBUG(R);
			// DEBUG(SIZE(G[p]));
			// DEBUG(G[p][0]);
			// DEBUG(G[p][1]);
			while(G[p].empty());
			res.push_back(pii(L, L+G[p][0]-1));
			idx[A[L]] = L+G[p][0]-1, idx[A[L+G[p][0]-1]] = L;
			swap(A[L], A[L+G[p][0]-1]);
			res.push_back(pii(L+G[p][0]-1, R));
			idx[A[L+G[p][0]-1]] = R, idx[A[R]] = L+G[p][0]-1;
			swap(A[L+G[p][0]-1], A[R]);
		}
		// fflush(stdout);
	}
	printf("%d\n", SIZE(res));
	// fflush(stdout);
	// return 0;
	rep(i, SIZE(res)) {
		int L = min(res[i].first, res[i].second);
		int R = max(res[i].first, res[i].second);
		printf("%d %d\n", L+1, R+1);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define TR(i,v) 		for(__typeof((v).begin())i=(v).begin();i!=(v).end();++i)
#define DEBUG(x) 		cout << #x << " = "; cout << x << endl;
#define SIZE(p) 		(int)(p).size()
#define MP(a, b)		make_pair((a), (b))
#define ALL(p)			(p).begin(), (p).end()
#define rep(i, n)		for(int (i)=0; (i)<(int)(n); ++(i))
#define REP(i, a, n)	for(int (i)=(a); (i)<(int)(n); ++(i))
#define FOR(i, a, b)   	for(int (i)=(int)(a); (i)<=(int)(b); ++(i))
#define FORD(i, b, a)  	for(int (i)=(int)(b); (i)>=(int)(a); --(i))
typedef long long LL;
typedef pair<int, int> pii;

int main(int argc, char const *argv[])
{
	#ifndef ONLINE_JUDGE
    freopen("C.in", "r", stdin);
    freopen("out", "w", stdout);
    #endif
	// ios::sync_with_stdio(false);    cin.tie(0);
	int h = 100003;
	static int prime[100005];
	static bool bad[100005];
	FOR(i, 2, h)
	for(LL j=(LL)i*i; j<=h; j+=i) bad[j]=1;
	int k=0;
	FOR(i, 2, h) if(!bad[i])
		prime[k++]=i;
	static vector<int> G[100005] ;
	rep(i, k)
		REP(j, i, k) {
			int x=prime[i]+prime[j];
			if(x>h)	continue;
			if(G[x].empty()) {
				// DEBUG(x);
				G[x].push_back(prime[i]),G[x].push_back(prime[j]);
			}
		}
	static int A[100005], idx[100005];
	int n;	cin>>n;
	rep(i, n)	cin>>A[i], --A[i], idx[A[i]]=i;
	// DEBUG(n);
	vector<pii> res;
	rep(i, n) {
		// DEBUG(i);
		// DEBUG(idx[i]);
		if(idx[i]==i)	continue;
		int p = abs(idx[i]-i)+1;
		if(!bad[p]) {
			int L=idx[i], R=i;
			// puts("!");
			res.push_back(pii(i, idx[i]));
			int tmp = idx[i];
			idx[i] = i, idx[A[i]] = tmp;
			swap(A[L], A[R]);
		}else {
			// puts("@");
			++p;
			int L=min(i , idx[i]), R=max(i, idx[i]);
			// DEBUG(L);
			// DEBUG(R);
			// DEBUG(SIZE(G[p]));
			// DEBUG(G[p][0]);
			// DEBUG(G[p][1]);
			res.push_back(pii(L, L+G[p][0]-1));
			idx[A[L]] = L+G[p][0]-1, idx[A[L+G[p][0]-1]] = L;
			swap(A[L], A[L+G[p][0]-1]);
			res.push_back(pii(L+G[p][0]-1, R));
			idx[A[L+G[p][0]-1]] = R, idx[A[R]] = L+G[p][0]-1;
			swap(A[L+G[p][0]-1], A[R]);
		}
		// fflush(stdout);
	}
	printf("%d\n", SIZE(res));
	// fflush(stdout);
	// return 0;
	rep(i, SIZE(res)) {
		int L = min(res[i].first, res[i].second);
		int R = max(res[i].first, res[i].second);
		printf("%d %d\n", L+1, R+1);
	}
	return 0;
}


#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <algorithm>
#include <iterator>
#include <utility>
#include <iomanip>
#include <cmath>
#include <climits>
#include <stdio.h>
#include <string.h>

using namespace std;

vector<int>  prime;
bool is_prime[100000+1];

int sieve(int n) {
  int p = 0;
  for (int i = 0; i <= n; i++) is_prime[i] = true;
  is_prime[0] = is_prime[1] = false;

  for (int i = 2; i <= n; i++) {
    if (is_prime[i]) {
      p++;
      prime.push_back(i);
      for (int j = 2*i; j <= n; j+=i) is_prime[j] = false;
    }
  }

  return p;
}

void solve() {
  int n;
  cin >> n;

  std::vector<int > vv ;
  std::map<int, int > mm;
  vv.push_back(0);
  for (int i = 0; i < n; i++) {
    int a;
    cin >> a;
    vv.push_back(a);
    mm[a] = i+1;
  }

  sieve(100000);

  std::vector<pair<int, int> > ret;

  for (int i = 1; i <= n; i++) {
    // for (int j = 1; j <= n; j++) {
    //   cerr << j << " " << mm[j] << endl;
    // }
    // cerr << endl;

    int diff = mm[i] - i;
    if (diff < 0) std::cerr << "should not reach here!" << std::endl;
    if (diff == 0) continue;

    // diff+1 が素数
    if (is_prime[diff+1]) {
      int tmp = vv[i];
      swap(vv[mm[i]], vv[i]);
      mm[tmp] = mm[i]; // mm[i] = i;

      ret.push_back(make_pair(i, mm[i]));
    } else {
      // diff が偶数 = diff+2 が2素数の和
      // diff が奇数 = diff+3 が3素数の和 = diff が2素数の和
      int diff_ =
	((diff == 3) || (diff % 2 == 0)) ?
	diff + 2  :
	diff;

      auto it = lower_bound( prime.begin(), prime.end(), diff_ ); // 最初に見つかった diff_ "以上"の要素の位置
      if (it == prime.end()) {
	std::cerr << "should not reach here! 2" << std::endl;
      }
      for (auto iter = it-1; it >= prime.begin(); --it) {
	auto val = *iter;
	if (is_prime[diff_-val]) {
	  if ((diff == 3) || (diff % 2 == 0)) {
	    int tmp = i + val - 1;
	    ret.push_back(make_pair(tmp, mm[i]));
	    ret.push_back(make_pair(i,   tmp));

	    swap(vv[tmp], vv[mm[i]]);
	    mm[vv[mm[i]]] = mm[i];
	    swap(vv[i],   vv[tmp]);
	    mm[vv[tmp]] = tmp;
	  } else {
	    int tmp1 = i + 2 + val - 1;
	    int tmp2 = i + 2;
	    ret.push_back(make_pair(tmp1, mm[i]));
	    ret.push_back(make_pair(tmp2, tmp1));
	    ret.push_back(make_pair(i,    tmp2));

	    swap(vv[tmp1], vv[mm[i]]);
	    mm[vv[mm[i]]] = mm[i];
	    swap(vv[tmp2], vv[tmp1]);
	    mm[vv[tmp1]] = tmp1;
	    swap(vv[i],    vv[tmp2]);
	    mm[vv[tmp2]] = tmp2;
	  }
	  break;
	}
      }
    }
  }

  std::cout << ret.size() << std::endl;
  for (auto x : ret) {
    std::cout << x.first << " " << x.second << std::endl;
  }
}

int main(int argc, char *argv[])
{
  solve();
  return 0;
}


#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <algorithm>
#include <iterator>
#include <utility>
#include <iomanip>
#include <cmath>
#include <climits>
#include <stdio.h>
#include <string.h>

using namespace std;

// n 以下の素数の数を返す (ついでに全ての素数の一覧も作成)
// 計算量は O(n log log n)  (= 約 O(n))
//
// なお, 素数定理より, だいたい x/log(x) (logは自然対数) くらいの数になるはず.
// log(x)は 10000 で 10 くらい. 1000000(1M) で 16 くらい
vector<int>  prime; // n 番目の素数を格納
bool is_prime[100000+1];     // i が素数かどうかを示す

int sieve(int n) {
  int p = 0;
  for (int i = 0; i <= n; i++) is_prime[i] = true;
  is_prime[0] = is_prime[1] = false;

  for (int i = 2; i <= n; i++) {
    if (is_prime[i]) {
      p++;
      prime.push_back(i);
      for (int j = 2*i; j <= n; j+=i) is_prime[j] = false;
    }
  }

  return p;
}

void solve() {
  int n;
  cin >> n;

  std::vector<int > vv ;
  std::map<int, int > mm;
  vv.push_back(0);
  for (int i = 0; i < n; i++) {
    int a;
    cin >> a;
    vv.push_back(a);
    mm[a] = i+1;
  }

  sieve(100000);

  std::vector<pair<int, int> > ret;

  for (int i = 1; i <= n; i++) {
    // for (int j = 1; j <= n; j++) {
    //   cerr << j << " " << mm[j] << endl;
    // }
    // cerr << endl;

    int diff = mm[i] - i;
    if (diff < 0) std::cerr << "should not reach here!" << std::endl;
    if (diff == 0) continue;

    // diff+1 が素数
    if (is_prime[diff+1]) {
      int tmp = vv[i];
      swap(vv[mm[i]], vv[i]);
      mm[tmp] = mm[i]; // mm[i] = i;

      ret.push_back(make_pair(i, mm[i]));
    } else {
      // diff が偶数 = diff+2 が2素数の和
      // diff が奇数 = diff+3 が3素数の和 = diff が2素数の和
      int diff_ =
	((diff == 3) || (diff % 2 == 0)) ?
	diff + 2  :
	diff;

      auto it = lower_bound( prime.begin(), prime.end(), diff_ ); // 最初に見つかった diff_ "以上"の要素の位置
      if (it == prime.end()) {
	std::cerr << "should not reach here! 2" << std::endl;
      }
      for (auto iter = it-1; it >= prime.begin(); --it) {
	auto val = *iter;
	if (is_prime[diff_-val]) {
	  if ((diff == 3) || (diff % 2 == 0)) {
	    int tmp = i + val - 1;
	    ret.push_back(make_pair(tmp, mm[i]));
	    ret.push_back(make_pair(i,   tmp));

	    swap(vv[tmp], vv[mm[i]]);
	    mm[vv[mm[i]]] = mm[i];
	    swap(vv[i],   vv[tmp]);
	    mm[vv[tmp]] = tmp;
	  } else {
	    int tmp1 = i + val - 1;
	    int tmp2 = i + 2;
	    ret.push_back(make_pair(tmp1, mm[i]));
	    ret.push_back(make_pair(tmp2, tmp1));
	    ret.push_back(make_pair(i,    tmp2));

	    swap(vv[tmp1], vv[mm[i]]);
	    mm[vv[mm[i]]] = mm[i];
	    swap(vv[tmp2], vv[tmp1]);
	    mm[vv[tmp1]] = tmp1;
	    swap(vv[i],    vv[tmp2]);
	    mm[vv[tmp2]] = tmp2;
	  }
	  break;
	}
      }
    }
  }

  std::cout << ret.size() << std::endl;
  for (auto x : ret) {
    std::cout << x.first << " " << x.second << std::endl;
  }
}

int main(int argc, char *argv[])
{
  solve();
  return 0;
}


#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <algorithm>
#include <iterator>
#include <utility>
#include <iomanip>
#include <cmath>
#include <climits>
#include <stdio.h>
#include <string.h>

using namespace std;

vector<int>  prime;
bool is_prime[100000+1];

int sieve(int n) {
  int p = 0;
  for (int i = 0; i <= n; i++) is_prime[i] = true;
  is_prime[0] = is_prime[1] = false;

  for (int i = 2; i <= n; i++) {
    if (is_prime[i]) {
      p++;
      prime.push_back(i);
      for (int j = 2*i; j <= n; j+=i) is_prime[j] = false;
    }
  }

  return p;
}

void solve() {
  int n;
  cin >> n;

  std::vector<int > vv ;
  std::map<int, int > mm;
  vv.push_back(0);
  for (int i = 0; i < n; i++) {
    int a;
    cin >> a;
    vv.push_back(a);
    mm[a] = i+1;
  }

  sieve(100000);

  std::vector<pair<int, int> > ret;

  for (int i = 1; i <= n; i++) {
    // for (int j = 1; j <= n; j++) {
    //   cerr << j << " " << mm[j] << endl;
    // }
    // cerr << endl;

    int diff = mm[i] - i;
    if (diff < 0) std::cerr << "should not reach here!" << std::endl;
    if (diff == 0) continue;

    // diff+1 が素数
    if (is_prime[diff+1]) {
      int tmp = vv[i];
      swap(vv[mm[i]], vv[i]);
      mm[tmp] = mm[i]; // mm[i] = i;

      ret.push_back(make_pair(i, mm[i]));
    } else {
      // diff が偶数 = diff+2 が2素数の和
      // diff が奇数 = diff+3 が3素数の和 = diff が2素数の和   <= 間違い!!! 3だと偶奇が変わらない. 2なら変わるので diff+1 が2素数の和を目指す方がいい
      int diff_ =
	((diff == 3) || (diff % 2 == 0)) ?
	diff + 2  :
	diff + 1;

      // cerr << "diff: " << diff_ << endl;

      auto it = lower_bound( prime.begin(), prime.end(), diff_ ); // 最初に見つかった diff_ "以上"の要素の位置
      for (auto iter = prime.begin(); iter < it; ++iter) {
	auto val = *iter;
	// cerr << "val: " << val << " " << diff_-val << endl;
	if (is_prime[diff_-val]) {
	  if ((diff == 3) || (diff % 2 == 0)) {
	    int tmp = i + val - 1;
	    ret.push_back(make_pair(tmp, mm[i]));
	    ret.push_back(make_pair(i,   tmp));

	    swap(vv[tmp], vv[mm[i]]);
	    mm[vv[mm[i]]] = mm[i];
	    swap(vv[i],   vv[tmp]);
	    mm[vv[tmp]] = tmp;
	  } else {
	    int tmp1 = i + 1 + val - 1;
	    int tmp2 = i + 1;
	    ret.push_back(make_pair(tmp1, mm[i]));
	    ret.push_back(make_pair(tmp2, tmp1));
	    ret.push_back(make_pair(i,    tmp2));

	    swap(vv[tmp1], vv[mm[i]]);
	    mm[vv[mm[i]]] = mm[i];
	    swap(vv[tmp2], vv[tmp1]);
	    mm[vv[tmp1]] = tmp1;
	    swap(vv[i],    vv[tmp2]);
	    mm[vv[tmp2]] = tmp2;
	  }
	  break;
	}
      }
    }
  }

  std::cout << ret.size() << std::endl;
  for (auto x : ret) {
    std::cout << x.first << " " << x.second << std::endl;
  }
}

int main(int argc, char *argv[])
{
  solve();
  return 0;
}


#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <string>
#include <cstring>
#include <cassert>
#include <cmath>

using namespace std;

bool isprime(int n) {
	if (n < 2)
		return false;
	int sq = sqrt(n);
	for (int i = 2; i <= sq; i++)
		if (n % i == 0)
			return false;
	return true;
}

int search(const vector<int>& p, int value) {
	int low = 0, high = p.size();
	while (low < high) {
		int middle = low + (high - low + 1) / 2;
		if (p[middle] > value)
			high = middle - 1;
		else
			low = middle;
	}
	return p[low];
}

int main() {
	ios_base::sync_with_stdio(false);

	vector<int> prime_list;
	for (int i = 2; i <= 100000; i++)
		if (isprime(i))
			prime_list.push_back(i - 1);
	int N;
	cin >> N;
	vector<int> a(N), pos(N);
	for (int i = 0; i < N; i++) {
		cin >> a[i];
		a[i]--;
		pos[a[i]] = i;
	}
	vector<pair<int, int>> answer;
	for (int i = 0; i < N; i++) {
		while (pos[i] - i > 0) {
			int p = search(prime_list, pos[i] - i);
			int x = a[pos[i]], y = a[pos[i] - p];
			answer.push_back(make_pair(pos[i] - p + 1, pos[i] + 1));
			swap(a[pos[i]], a[pos[i] - p]);
			swap(pos[x], pos[y]);
		}
	}
	assert((int)answer.size() <= 5 * N);
	cout << answer.size() << endl;
	for (auto p : answer)
		cout << p.first << ' ' << p.second << endl;
	return 0;
}


#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <string>
#include <cstring>
#include <cassert>
#include <cmath>

using namespace std;

bool isprime(int n) {
	if (n < 2)
		return false;
	int sq = sqrt(n);
	for (int i = 2; i <= sq; i++)
		if (n % i == 0)
			return false;
	return true;
}

int search(const vector<int>& p, int value) {
	int low = 0, high = p.size() - 1;
	while (low < high) {
		int middle = low + (high - low + 1) / 2;
		if (p[middle] <= value)
			low = middle;
		else
			high = middle - 1;
	}
	return p[low];
}

int main() {
	ios_base::sync_with_stdio(false);

	vector<int> prime_list;
	for (int i = 2; i <= 100000; i++)
		if (isprime(i))
			prime_list.push_back(i - 1);

	int N;
	cin >> N;
	vector<int> a(N), pos(N);
	for (int i = 0; i < N; i++) {
		cin >> a[i];
		a[i]--;
		pos[a[i]] = i;
	}
	vector<pair<int, int>> answer;
	for (int i = 0; i < N; i++) {
		while (pos[i] - i > 0) {
			int p = search(prime_list, pos[i] - i);
			int x = a[pos[i]], y = a[pos[i] - p];
			answer.push_back(make_pair(pos[i] - p + 1, pos[i] + 1));
			assert((int)answer.size() <= 5 * N);
			swap(a[pos[i]], a[pos[i] - p]);
			swap(pos[x], pos[y]);
		}
	}
	cout << answer.size() << endl;
	for (auto p : answer)
		cout << p.first << ' ' << p.second << endl;
	return 0;
}


#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <string>
#include <cstring>
#include <cassert>
#include <cmath>

using namespace std;

bool isprime(int n) {
	if (n < 2)
		return false;
	int sq = sqrt(n);
	for (int i = 2; i <= sq; i++)
		if (n % i == 0)
			return false;
	return true;
}

int search(const vector<int>& p, int value) {
	int low = 0, high = p.size();
	while (low < high) {
		int middle = low + (high - low + 1) / 2;
		if (p[middle] <= value)
			low = middle;
		else
			high = middle - 1;
	}
	return p[low];
}

int main() {
	ios_base::sync_with_stdio(false);

	vector<int> prime_list;
	for (int i = 2; i <= 100000; i++)
		if (isprime(i))
			prime_list.push_back(i - 1);
	int N;
	cin >> N;
	vector<int> a(N), pos(N);
	for (int i = 0; i < N; i++) {
		cin >> a[i];
		a[i]--;
		pos[a[i]] = i;
	}
	vector<pair<int, int>> answer;
	for (int i = 0; i < N; i++) {
		while (pos[i] - i > 0) {
			int p = search(prime_list, pos[i] - i);
			int x = a[pos[i]], y = a[pos[i] - p];
			answer.push_back(make_pair(pos[i] - p + 1, pos[i] + 1));
			assert((int)answer.size() <= 5 * N);
			swap(a[pos[i]], a[pos[i] - p]);
			swap(pos[x], pos[y]);
		}
	}
	assert((int)answer.size() <= 5 * N);
	cout << answer.size() << endl;
	for (auto p : answer)
		cout << p.first << ' ' << p.second << endl;
	return 0;
}


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

bool fun(int p) {
    if (p == 1 || p == 2 || p == 3)
        return true;
    if (p % 2 == 0)
        return false;
    int sq = sqrt(p);
    for (int i = 3; i <= sq; i++)
        if (p % i == 0)
            return false;
    return true;
}
int main() {
    int n;
    cin >> n;
    int ar[n + 10], ar1[n + 10];
    bool prime[n + 10];
    for (int i = 1; i <= n; i++)
        prime[i] = fun(i);
    for (int i = 1, z = n; i <= n; i++, z--)
        cin >> ar[i], ar1[ar[i]] = i;

    vector<pair<int, int> > v;
    for (int wanted = n; wanted >= 1; wanted--) {
        int place = ar1[wanted];
        if (place == wanted)
            continue;
        while (place != wanted) {
            int count = wanted - place+1;
            for (int I = count; I >= 1; I--)
                if (prime[I]) {
                    count = I;
                    break;
                }
            count= place +  count-1;
            ar1[ar[place]] = count;
            ar1[ar[count]] = place;

            swap(ar[place], ar[count]);
            v.push_back(make_pair(place, count));
            place = count;

        }
    }

    cout << v.size() << endl;
    for (int i = 0; i < (int) v.size(); i++)
        cout << v[i].first << " " << v[i].second << endl;
    return 0;
}
;


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

bool fun(int p) {
    if (p == 1 || p == 2 || p == 3)
        return true;
    if (p % 2 == 0)
        return false;
    int sq = sqrt(p);
    for (int i = 3; i <= sq; i++)
        if (p % i == 0)
            return false;
    return true;
}
int main() {
    int n;
    cin >> n;
    int ar[n + 10], ar1[n + 10];
    bool prime[n + 10];
    for (int i = 1; i <= n; i++)
        prime[i] = fun(i);
    for (int i = 1,z=n; i <= n; i++,z--)
        cin>> ar[i], ar1[ar[i]] = i;

    vector <pair<int,int> > v;
    for (int wanted = n; wanted >= 1; wanted--) {
        int place = ar1[wanted];
        if (place == wanted)
            continue;
        while (place != wanted) {
            if (prime[wanted - place + 1]) {

                ar1[ar[place]] = wanted;
                ar1[ar[wanted]] = place;

                swap(ar[place], ar[wanted]);
                v.push_back(make_pair(place , wanted ));
                place = wanted;
            } else {
                v.push_back(make_pair(place , place + 1 ));
                ar1[ar[place]] = place + 1;
                ar1[ar[place + 1]] = place;
                swap(ar[place], ar[place + 1]);
                place++;
            }
        }
    }

    cout<<v.size()<<endl;
    for(int i=0;i<(int)v.size();i++)
        cout<<v[i].first<<" "<<v[i].second<<endl;
    return 0;
}
;


// Enjoy your stay.

#include <bits/stdc++.h>

#define EPS 1e-9
#define INF 1070000000LL
#define MOD 1000000007LL
#define fir first
#define foreach(it,X) for(auto it=(X).begin();it!=(X).end();it++)
#define ite iterator
#define mp make_pair
#define mt make_tuple
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<(n);i++)
#define pb push_back
#define sec second
#define sz(x) ((int)(x).size())

using namespace std;

typedef istringstream iss;
typedef long long ll;
typedef pair<ll,ll> pi;
typedef stringstream sst;
typedef vector<ll> vi;

int n,a[100010],pos[100010];
bool isp[100010];
int choice[100010];
vector<pi> ans;

void Swap(int pos1,int pos2){
	ans.pb(mp(pos1,pos2));
	swap(a[pos1], a[pos2]);
	swap(pos[a[pos1]], pos[a[pos2]]);
}

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

	cin>>n;
	rep2(i,2,n+1){
		isp[i] = 1;
		for(int j=2;j*j<=i;j++)if(i%j == 0)isp[i] = 0;
	}
	for(int i = 4; i <= n+1; i+=2){
		rep(j,i)if(isp[j] && isp[i - j]){
			choice[i] = j; break;
		}
	}
	rep2(i,1,n+1){
		cin>>a[i];
		pos[a[i]] = i;
	}
	rep2(i,1,n+1){
		int dif = i - pos[i];
		if(dif == 0){
		}
		else if(dif > 0){
			if(dif%2 == 1){
				Swap(pos[i], pos[i]+1);
				dif--;
			}
			if(dif > 0){
				int d1 = choice[dif + 2] - 1;
				int d2 = dif+2 - d1 - 1;
				Swap(pos[i], pos[i]+d1);
				Swap(pos[i], pos[i]+d2);
			}
		}
		else{
			dif *= -1;
			if(dif%2 == 1){
				Swap(pos[i], pos[i]-1);
				dif--;
			}
			if(dif > 0){
				int d1 = choice[dif + 2] - 1;
				int d2 = dif - d1;
				Swap(pos[i], pos[i]-d1);
				Swap(pos[i], pos[i]-d2);
			}
		}
	}
	cout<<sz(ans)<<endl;
	rep(i,sz(ans))cout<<ans[i].fir<<" "<<ans[i].sec<<endl;
}


// Enjoy your stay.

#include <bits/stdc++.h>

#define EPS 1e-9
#define INF 1070000000LL
#define MOD 1000000007LL
#define fir first
#define foreach(it,X) for(auto it=(X).begin();it!=(X).end();it++)
#define ite iterator
#define mp make_pair
#define mt make_tuple
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<(n);i++)
#define pb push_back
#define sec second
#define sz(x) ((int)(x).size())

using namespace std;

typedef istringstream iss;
typedef long long ll;
typedef pair<ll,ll> pi;
typedef stringstream sst;
typedef vector<ll> vi;

int n,a[100010],pos[100010];
bool isp[100010];
int choice[100010];
vector<pi> ans;

void Swap(int pos1,int pos2){
	if(pos1 > pos2) swap(pos1, pos2);
	ans.pb(mp(pos1,pos2));
	swap(a[pos1], a[pos2]);
	swap(pos[a[pos1]], pos[a[pos2]]);
}

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

	cin>>n;
	rep2(i,2,n+1){
		isp[i] = 1;
		for(int j=2;j*j<=i;j++)if(i%j == 0)isp[i] = 0;
	}
	for(int i = 4; i <= n+1; i+=2){
		rep(j,i)if(isp[j] && isp[i - j]){
			choice[i] = j; break;
		}
	}
	rep2(i,1,n+1){
		cin>>a[i];
		pos[a[i]] = i;
	}
	rep2(i,1,n+1){
		int dif = i - pos[i];
		if(dif == 0){
		}
		else if(dif > 0){
			if(dif%2 == 1){
				Swap(pos[i], pos[i]+1);
				dif--;
			}
			if(dif > 0){
				int d1 = choice[dif + 2] - 1;
				int d2 = dif+2 - d1 - 1;
				Swap(pos[i], pos[i]+d1);
				Swap(pos[i], pos[i]+d2);
			}
		}
		else{
			dif *= -1;
			if(dif%2 == 1){
				Swap(pos[i], pos[i]-1);
				dif--;
			}
			if(dif > 0){
				int d1 = choice[dif + 2] - 1;
				int d2 = dif - d1;
				Swap(pos[i], pos[i]-d1);
				Swap(pos[i], pos[i]-d2);
			}
		}
	}
	cout<<sz(ans)<<endl;
	rep(i,sz(ans))cout<<ans[i].fir<<" "<<ans[i].sec<<endl;
}


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

bool pr[100005];
int go[100005];

int n;
int a[100005], v[100005], p[100005];

vector< pair<int, int> > sol;

inline void change(int i, int j) {
    swap(v[i], v[j]);
    swap(p[v[i]], p[v[j]]);
}

int main() {

    for (int i = 2; i <= 100000; ++i)
        if (!pr[i])
            for (int j = i + i; j <= 100000; j += i)
                pr[j] = true;
    for (int i = 2; i <= 100000; ++i)
        if (pr[i] == false)
            go[i] = i;
        else
            go[i] = go[i - 1];

    cin >> n;
    for (int i = 1; i <= n; ++i)
        cin >> a[i], v[i] = a[i], p[v[i]] = i;

    sort(a + 1, a + 1 + n);

    for (int i = 1; i <= n; ++i) {
        int pos = p[a[i]];
        while (pos > i) {
            int dif = go[pos - i + 1], ppos;
            ppos = pos - dif + 1;
            change(ppos, pos);
            sol.push_back(make_pair(ppos, pos));
            pos = ppos;
        }
    }

    cout << sol.size() << '\n';
    for (auto i : sol)
        cout << i.first << ' ' << i.second << '\n';
}


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

bool pr[100005];
int go[100005];

int n;
int a[100005], v[100005], p[100005];

vector< pair<int, int> > sol;

inline void change(int i, int j) {
    swap(v[i], v[j]);
    swap(p[i], p[j]);
}

int main() {

    for (int i = 2; i <= 100000; ++i)
        if (!pr[i])
            for (int j = i + i; j <= 100000; j += i)
                pr[j] = true;
    for (int i = 2; i <= 100000; ++i)
        if (pr[i] == false)
            go[i] = i;
        else
            go[i] = go[i - 1];

    cin >> n;
    for (int i = 1; i <= n; ++i)
        cin >> a[i], v[i] = a[i], p[v[i]] = i;

    sort(a + 1, a + 1 + n);

    for (int i = 1; i <= n; ++i) {
        int pos = p[a[i]];
        while (pos > i) {
            int val = go[pos - i + 1], ppos;
            ppos = pos - val + 1;
            change(ppos, pos);
            sol.push_back(make_pair(ppos, pos));
            pos = ppos;
        }
    }

    cout << sol.size() << '\n';
    for (auto i : sol)
        cout << i.first << ' ' << i.second << '\n';
}


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

bool pr[100005];
int go[100005];

int n;
int a[100005], v[100005], p[100005];

vector< pair<int, int> > sol;

inline void change(int i, int j) {
    swap(v[i], v[j]);
    swap(p[i], p[j]);
}

int main() {

    for (int i = 2; i <= 100000; ++i)
        if (!pr[i])
            for (int j = i + i; j <= 100000; j += i)
                pr[j] = true;
    for (int i = 2; i <= 100000; ++i)
        if (pr[i] == false)
            go[i] = i;
        else
            go[i] = go[i - 1];

    cin >> n;
    for (int i = 1; i <= n; ++i)
        cin >> a[i], v[i] = a[i], p[v[i]] = i;

    sort(a + 1, a + 1 + n);

    for (int i = 1; i <= n; ++i) {
        int pos = p[a[i]];
        while (pos > i) {
            int dif = go[pos - i + 1], ppos;
            ppos = pos - dif + 1;
            change(ppos, pos);
            sol.push_back(make_pair(ppos, pos));
            pos = ppos;
        }
    }

    cout << sol.size() << '\n';
    for (auto i : sol)
        cout << i.first << ' ' << i.second << '\n';
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
bool p[N];
int n, a[N], sorted[N], fmove[N], pos[N];
vector <int> pr;
vector <pair <int, int> > ans;

void mswap(int i, int j) {
    ans.push_back(make_pair(i, j));
    pos[a[i]] = j;
    pos[a[j]] = i;
    swap(a[i], a[j]);
}

int main() {
    //freopen("out.txt", "w", stdout);
    p[1] = true;
    for (int i = 2; i * i < N; ++i)
        if (!p[i])
            for (int j = i * i; j < N; j += i)
                p[j] = true;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
        --a[i];
        pos[a[i]] = i;
    }

    for (int i = 2; i <= n + 1; ++i)
        if (!p[i]) pr.push_back(i);

    for (int l = 2; l <= n + 1; ++l) {
        if (!p[l])
        {
            fmove[l] = l;
            continue;
        }

        if (l % 2 == 0)
            continue;
        for (int i = 0; i < pr.size() && pr[i] < l; ++i)
            if (!p[l - pr[i] + 1]) {
                fmove[l] = pr[i];
                break;
            }
    }

    for (int i = 0; i < n; ++i)
        if (i != a[i]) {
            int len = pos[i] - i + 1;
            if (fmove[len] == len) {
                mswap(i, pos[i]);
                continue;
            }
            if (len % 2 == 0) {
                mswap(pos[i] - 1, pos[i]);
                --len;
            }

            if (fmove[len] == len)
                mswap(i, pos[i]);
            else {
                int to = pos[i] - fmove[len] - 1;
                mswap(to, pos[i]);
                mswap(i, to);
            }
        }
    cout << ans.size() << endl;
    for (int i = 0; i < ans.size(); ++i)
        printf("%d %d\n", ans[i].first + 1, ans[i].second + 1);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cassert>
using namespace std;
const int N = 1e5 + 10;
bool p[N];
int n, a[N], sorted[N], fmove[N], pos[N];
vector <int> pr;
vector <pair <int, int> > ans;

void mswap(int i, int j) {
    ans.push_back(make_pair(i, j));
    pos[a[i]] = j;
    pos[a[j]] = i;
    swap(a[i], a[j]);
}

int main() {
    //freopen("out.txt", "w", stdout);
    p[1] = true;
    for (int i = 2; i * i < N; ++i)
        if (!p[i])
            for (int j = i * i; j < N; j += i)
                p[j] = true;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
        --a[i];
        pos[a[i]] = i;
    }

    for (int i = 2; i <= n + 1; ++i)
        if (!p[i]) pr.push_back(i);

    for (int l = 2; l <= n + 1; ++l) {
        if (!p[l])
        {
            fmove[l] = l;
            continue;
        }

        if (l % 2 == 0)
            continue;
        for (int i = 0; i < pr.size() && pr[i] < l; ++i)
            if (!p[l - pr[i] + 1]) {
                fmove[l] = pr[i];
                break;
            }
        assert(fmove[l] != 0);
    }

    for (int i = 0; i < n; ++i)
        if (i != a[i]) {
            int len = pos[i] - i + 1;
            if (fmove[len] == len) {
                mswap(i, pos[i]);
                continue;
            }

            if (len % 2 == 0) {
                mswap(pos[i] - 1, pos[i]);
                --len;
            }

            if (fmove[len] == len)
                mswap(i, pos[i]);
            else {
                int to = pos[i] - fmove[len] + 1;
                mswap(to, pos[i]);
                mswap(i, to);
            }
        }

    cout << ans.size() << endl;
    for (int i = 0; i < ans.size(); ++i)
        printf("%d %d\n", ans[i].first + 1, ans[i].second + 1);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
bool p[N];
int n, a[N], sorted[N], fmove[N], pos[N];
vector <int> pr;
vector <pair <int, int> > ans;

void mswap(int i, int j) {
    ans.push_back(make_pair(i, j));
    pos[a[i]] = j;
    pos[a[j]] = i;
    swap(a[i], a[j]);
}

int main() {
    p[1] = true;
    for (int i = 2; i * i < N; ++i)
        if (!p[i])
            for (int j = i * i; j < N; j += i)
                p[j] = true;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
        --a[i];
        pos[a[i]] = i;
    }

    for (int i = 2; i <= n + 1; ++i)
        if (!p[i]) pr.push_back(i);

    for (int l = 2; l <= n + 1; ++l) {
        if (!p[l])
        {
            fmove[l] = l;
            continue;
        }

        if (l % 2 == 0)
            continue;
        for (int i = 0; i < pr.size() && pr[i] < l; ++i)
            if (!p[l - pr[i] + 1]) {
                fmove[l] = pr[i];
                break;
            }
    }

    for (int i = 0; i < n; ++i)
        if (i != a[i]) {
            int len = pos[i] - i + 1;
            if (len % 2 == 1) {
                mswap(pos[i] - 1, pos[i]);
                --len;
            }

            if (fmove[len] == len)
                mswap(i, pos[i]);
            else {
                int to = pos[i] - fmove[len] - 1;
                mswap(to, pos[i]);
                mswap(i, to);
            }
        }
    cout << ans.size() << endl;
    for (int i = 0; i < ans.size(); ++i)
        printf("%d %d\n", ans[i].first + 1, ans[i].second + 1);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int MAX = 100005;
bool p[MAX];
vector<pair<int, int> > ans;
int a[MAX];

void sieve()
{
    memset(p, true, sizeof(p));
	p[0]=p[1]=false;
	for(int i = 2; i*i<=MAX;i++)
        if(p[i])
            for(int j=i*i; j<MAX;j+=i)
				p[j]=false;
}

void swaP(int x, int y)
{
	if (x > y)
		swap(x, y);
	for (int i=y;i>=x;i--)
		if (p[i-x+1])
		{
			swap(a[x], a[i]);
			ans.push_back(make_pair(x, i));
			break;
		}
}

int main()
{
	sieve();

	int n;
	cin>>n;

	for(int i=1;i<=n;i++)
		cin>>a[i];

	for(int i=1;i<=n;i++)
		while (a[i] != i)
			swaP(i,a[i]);

	cout<<ans.size()<<endl;
	for(int i=0; i<ans.size();i++)
		cout<<ans[i].first<<" "<<ans[i].second<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int MAX = 100005;
bool p[MAX];
vector<pair<int, int> > ans;
int a[MAX];

void sieve()
{
    memset(p, true, sizeof(p));
    p[0]=p[1]=false;
    for(int i = 2; i*i<=MAX;i++)
        if(p[i])
            for(int j=i*i; j<MAX;j+=i)
                p[j]=false;
}

void swaP(int x, int y)
{
    if(x==y)
        return;
    if (x>y)
        swap(x, y);
    for(int i=y;i>x;i--)
        if (p[i-x+1])
        {
            swap(a[x],a[i]);
            ans.push_back(make_pair(x, i));
            swaP(i,y);
            return;
        }
}

int main()
{
    sieve();

    int n;
    cin>>n;

    for(int i=1;i<=n;i++)
        cin>>a[i];

    for(int i=1;i<=n;i++)
        while(a[i] != i)
            swaP(i,a[i]); // i, pos

    cout<<ans.size()<<endl;
    for(int i=0; i<ans.size();i++)
        cout<<ans[i].first<<" "<<ans[i].second<<endl;
    return 0;
}


#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <float.h>

using namespace std;

#define REP(i, from, to) for (int i = (from); i < (to); ++i)
#define FOR(i, n) REP(i, 0, (n))
#define ALL(x) x.begin(), x.end()
#define SIZE(x) (int)x.size()
#define PB push_back
#define MP make_pair

typedef long long i64;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef vector<VS> VVS;
typedef pair<int, int> PII;

int main() {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    ios_base::sync_with_stdio(false);

    int n;
    cin >> n;

    VI x(n);
    VI p(n);
    FOR (i, n) {
        cin >> x[i];
        --x[i];
        p[x[i]] = i;
    }

    int const MAX_SUM = 100001;
    VI primes;
    REP (k, 2, MAX_SUM + 1) {
        bool isPrime = true;
        for (int j = 2; j * j <= k; ++j) {
            if (k % j == 0) {
                isPrime = false;
                break;
            }
        }

        if (isPrime) {
            primes.PB(k);
        }
    }

    vector<PII> repr(2 * MAX_SUM);
    FOR (i, SIZE(primes)) FOR (j, SIZE(primes)) {
        repr[primes[i] + primes[j]] = MP(primes[i], primes[j]);
        repr[primes[i]] = MP(primes[i], 0);
    }

    vector<PII> res;
    FOR (i, n) {
        int pos = p[i];
        int target = i;

        if (pos == target) continue;
        if (pos > target)
            swap(pos, target);

        int diff = abs(target - pos) + 1;

        if (diff % 2 == 0 || repr[diff].first != 0)  {
            int const a = repr[diff].first;
            int const b = repr[diff].second;

            if (b == 0) {
                res.PB(MP(pos, target));
                swap(p[x[pos]], p[x[target]]);
                swap(x[pos], x[target]);
            } else {
                res.PB(MP(pos, pos + a - 1));
                res.PB(MP(pos + a - 1, target));

                if (p[i] < target) {
                    swap(p[x[pos]], p[x[pos + a - 1]]);
                    swap(x[pos], x[pos + a - 1]);
                    swap(p[x[pos + a - 1]], p[x[target]]);
                    swap(x[pos + a - 1], x[target]);
                } else {
                    swap(p[x[pos + a - 1]], p[x[target]]);
                    swap(x[pos + a - 1], x[target]);
                    swap(p[x[pos]], p[x[pos + a - 1]]);
                    swap(x[pos], x[pos + a - 1]);
                }
            }
        } else {
            res.PB(MP(pos, pos + 3 - 1));

            diff -= 3;
            int const a = repr[diff].first;
            int const b = repr[diff].second;

            if (b == 0) {
                res.PB(MP(pos, target));
                swap(p[x[pos]], p[x[target]]);
                swap(x[pos], x[target]);
            } else {
                res.PB(MP(pos, pos + a - 1));
                res.PB(MP(pos + a - 1, target));

                if (p[i] < target) {
                    swap(p[x[pos]], p[x[pos + a - 1]]);
                    swap(x[pos], x[pos + a - 1]);
                    swap(p[x[pos + a - 1]], p[x[target]]);
                    swap(x[pos + a - 1], x[target]);
                } else {
                    swap(p[x[pos + a - 1]], p[x[target]]);
                    swap(x[pos + a - 1], x[target]);
                    swap(p[x[pos]], p[x[pos + a - 1]]);
                    swap(x[pos], x[pos + a - 1]);
                }
            }
        }
    }

    VI orig(n);
    FOR (i, n) orig[i] = i;

    if (orig != p) {
        cout << "FAILED!\n";
        throw 10;
    }

    cout << SIZE(res) << endl;
    FOR (i, SIZE(res)) {
        cout << res[i].first + 1 << " " << res[i].second + 1 << "\n";
    }

    return 0;
}


#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <float.h>

using namespace std;

#define REP(i, from, to) for (int i = (from); i < (to); ++i)
#define FOR(i, n) REP(i, 0, (n))
#define ALL(x) x.begin(), x.end()
#define SIZE(x) (int)x.size()
#define PB push_back
#define MP make_pair

typedef long long i64;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef vector<VS> VVS;
typedef pair<int, int> PII;

int main() {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    ios_base::sync_with_stdio(false);

    int n;
    cin >> n;

    VI x(n);
    VI p(n);
    FOR (i, n) {
        cin >> x[i];
        --x[i];
        p[x[i]] = i;
    }

    int const MAX_SUM = 100001;
    VI primes;
    REP (k, 2, 2 * n + 1) {
        bool isPrime = true;
        for (int j = 2; j * j <= k; ++j) {
            if (k % j == 0) {
                isPrime = false;
                break;
            }
        }

        if (isPrime) {
            primes.PB(k);
        }
    }

    vector<PII> res;
    FOR (i, n) {
        int const pos1 = p[i];
        int const pos2 = i;

        int p1 = min(pos1, pos2);
        int const p2 = max(pos1, pos2);

        VI positions;
        positions.PB(p1);
        while (p1 != p2) {
            int const diff = p2 - p1 + 1;
            auto it = lower_bound(ALL(primes), diff);
            if (it == primes.end() || *it > diff)
                --it;
            int const usedPrime = *it;
            p1 += usedPrime - 1;
            positions.PB(p1);
        }

        if (pos1 > pos2) reverse(ALL(positions));

        FOR (j, SIZE(positions) - 1) {
            int const p1 = positions[j];
            int const p2 = positions[j + 1];

            swap(x[p1], x[p2]);
            p[x[p1]] = p1;
            p[x[p2]] = p2;

            res.PB(MP(min(p1, p2), max(p1, p2)));
        }
    }

    VI orig(n);
    FOR (i, n) orig[i] = i;

    if (orig != x) {
        cout << "FAILED!\n";
        throw 10;
    }

    cout << SIZE(res) << endl;
    FOR (i, SIZE(res)) {
        cout << res[i].first + 1 << " " << res[i].second + 1 << "\n";
    }

    return 0;
}


#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <float.h>

using namespace std;

#define REP(i, from, to) for (int i = (from); i < (to); ++i)
#define FOR(i, n) REP(i, 0, (n))
#define ALL(x) x.begin(), x.end()
#define SIZE(x) (int)x.size()
#define PB push_back
#define MP make_pair

typedef long long i64;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef vector<VS> VVS;
typedef pair<int, int> PII;

int main() {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    ios_base::sync_with_stdio(false);

    int n;
    cin >> n;

    VI a(n);
    VI p(n);
    FOR (i, n) {
        cin >> a[i];
        --a[i];
        p[a[i]] = i;
    }

    int const MAX_SUM = 100001;
    VI primes;
    REP (k, 2, MAX_SUM + 1) {
        bool isPrime = true;
        for (int j = 2; j * j <= k; ++j) {
            if (k % j == 0) {
                isPrime = false;
                break;
            }
        }

        if (isPrime) {
            primes.PB(k);
        }
    }

    vector<PII> repr(2 * MAX_SUM);
    FOR (i, SIZE(primes)) FOR (j, SIZE(primes)) {
        repr[primes[i] + primes[j]] = MP(primes[i], primes[j]);
        repr[primes[i]] = MP(primes[i], 0);
    }

    vector<PII> res;
    FOR (i, n) {
        int pos = p[i];
        int target = i;

        if (pos == target) continue;
        if (pos > target)
            swap(pos, target);

        int diff = abs(target - pos) + 1;

        if (diff % 2 == 0 || repr[diff].first != 0)  {
            int const a = repr[diff].first;
            int const b = repr[diff].second;

            if (b == 0) {
                res.PB(MP(pos, target));
                swap(p[pos], p[target]);
            } else {
                res.PB(MP(pos, pos + a - 1));
                res.PB(MP(pos + a - 1, target));

                swap(p[pos], p[pos + a - 1]);
                swap(p[pos + a - 1], p[target]);
            }
        } else {
            res.PB(MP(pos, pos + 3 - 1));

            diff -= 3;
            int const a = repr[diff].first;
            int const b = repr[diff].second;

            if (b == 0) {
                res.PB(MP(pos, target));
                swap(p[pos], p[target]);
            } else {
                res.PB(MP(pos, pos + a - 1));
                res.PB(MP(pos + a - 1, target));

                swap(p[pos], p[pos + a - 1]);
                swap(p[pos + a - 1], p[target]);
            }
        }
    }

    cout << SIZE(res) << endl;
    FOR (i, SIZE(res)) {
        cout << res[i].first + 1 << " " << res[i].second + 1 << "\n";
    }

    return 0;
}


#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <float.h>

using namespace std;

#define REP(i, from, to) for (int i = (from); i < (to); ++i)
#define FOR(i, n) REP(i, 0, (n))
#define ALL(x) x.begin(), x.end()
#define SIZE(x) (int)x.size()
#define PB push_back
#define MP make_pair

typedef long long i64;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef vector<VS> VVS;
typedef pair<int, int> PII;

int main() {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    ios_base::sync_with_stdio(false);

    int n;
    cin >> n;

    VI x(n);
    VI p(n);
    FOR (i, n) {
        cin >> x[i];
        --x[i];
        p[x[i]] = i;
    }

    int const MAX_SUM = 100001;
    VI primes;
    REP (k, 2, 2 * n + 1) {
        bool isPrime = true;
        for (int j = 2; j * j <= k; ++j) {
            if (k % j == 0) {
                isPrime = false;
                break;
            }
        }

        if (isPrime) {
            primes.PB(k);
        }
    }

    vector<PII> res;
    FOR (i, n) {
        int const pos1 = p[i];
        int const pos2 = i;

        int p1 = min(pos1, pos2);
        int const p2 = max(pos1, pos2);

        VI positions;
        positions.PB(p1);
        while (p1 != p2) {
            int const diff = p2 - p1 + 1;
            auto it = lower_bound(ALL(primes), diff);
            if (it == primes.end() || *it > diff)
                --it;
            int const usedPrime = *it;
            p1 += usedPrime - 1;
            positions.PB(p1);
        }

        if (pos1 > pos2) reverse(ALL(positions));

        FOR (j, SIZE(positions) - 1) {
            int const p1 = positions[j];
            int const p2 = positions[j + 1];

            swap(x[p1], x[p2]);
            p[x[p1]] = p1;
            p[x[p2]] = p2;

            res.PB(MP(p1, p2));
        }
    }

    VI orig(n);
    FOR (i, n) orig[i] = i;

    if (orig != x) {
        cout << "FAILED!\n";
        throw 10;
    }

    cout << SIZE(res) << endl;
    FOR (i, SIZE(res)) {
        cout << res[i].first + 1 << " " << res[i].second + 1 << "\n";
    }

    return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <map>
#include <vector>
#include <utility>
using namespace std;
const int MAXN = 100000;
const int maxn = MAXN + 10;
typedef pair<int,int> PII;
int a[maxn];
int pos[maxn];
int p[maxn],c;
bool vis[maxn];
int x[maxn];
vector<PII>ans;
int main()
{
    ios::sync_with_stdio(false);
    int n,i,j;
    vis[0]=1;
    for(i=2;i*i<MAXN;++i){
        if(!vis[i]){
            for(j=i*i;j<MAXN;j+=i){
                vis[j]=true;
            }
        }
    }
    for(i=2;i<maxn;++i){
        x[i]=x[i-1];
        if(!vis[i]){
            //p[c++]=i;
            x[i]=i;
        }
    }
    cin>>n;
    for(i=0;i<n;++i){
        cin>>a[i];
        --a[i];
        pos[a[i]]=i;
    }
    for(i=0;i<n;++i){
        while(pos[i]!=i){
            int k,d;
            if(pos[i]>i){
                d=pos[i]-i+1;
                d=x[d];
                k=pos[i]-d+1;
            }else{
                d=i-pos[i]+1;
                d=x[d];
                k=pos[i]+d-1;
            }
            int t=pos[i];
            ans.push_back(PII(pos[i]+1,k+1));
            swap(pos[i],pos[a[k]]);
            swap(a[t],a[k]);
           // cout<<i<<" "<<pos[i]<<" "<<k<<" "<<d<<endl;
        }
    }
    cout<<ans.size()<<endl;
    for(auto it:ans){
        int x=it.first;
        int y=it.second;
        if(x>y){
            swap(x,y);
        }
        cout<<x<<" "<<y<<endl;
    }
    return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <map>
#include <vector>
#include <utility>
using namespace std;
const int MAXN = 100000;
const int maxn = MAXN + 10;
typedef pair<int,int> PII;
int a[maxn];
int pos[maxn];
int p[maxn],c;
bool vis[maxn];
int x[maxn];
vector<PII>ans;
int main()
{
    ios::sync_with_stdio(false);
    int n,i,j;
    vis[0]=1;
    for(i=2;i*i<MAXN;++i){
        if(!vis[i]){
            for(j=i*i;j<MAXN;j+=i){
                vis[j]=true;
            }
        }
    }
    for(i=2;i<maxn;++i){
        x[i]=x[i-1];
        if(!vis[i]){
            //p[c++]=i;
            x[i]=i;
        }
    }
    cin>>n;
    for(i=0;i<n;++i){
        cin>>a[i];
        --a[i];
        pos[a[i]]=i;
    }
    for(i=0;i<n;++i){
        while(pos[i]!=i){
            int k,d;
            if(pos[i]>i){
                d=pos[i]-i+1;
                d=x[d];
                k=pos[i]-d+1;
            }else{
                d=i-pos[i]+1;
                d=x[d];
                k=pos[i]+d-1;
            }
            int t=pos[i];
            ans.push_back(PII(pos[i]+1,k+1));
            swap(pos[i],pos[a[k]]);
            swap(a[t],a[k]);
           // cout<<i<<" "<<pos[i]<<" "<<k<<" "<<d<<endl;
        }
    }
    cout<<ans.size()<<endl;
    for(auto it:ans){
        cout<<it.first<<" "<<it.second<<endl;
    }
    return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <map>
#include <vector>
#include <utility>
using namespace std;
const int MAXN = 100000;
const int maxn = MAXN + 10;
typedef pair<int,int> PII;
int a[maxn];
int pos[maxn];
int p[maxn],c;
bool vis[maxn];
int x[maxn];
vector<PII>ans;
int main()
{
    ios::sync_with_stdio(false);
    int n,i,j;
    vis[0]=1;
    for(i=2;i*i<=MAXN;++i){
        if(!vis[i]){
            for(j=i*i;j<=MAXN;j+=i){
                vis[j]=true;
            }
        }
    }
    for(i=2;i<maxn;++i){
        x[i]=x[i-1];
        if(!vis[i]){
            //p[c++]=i;
            x[i]=i;
        }
    }
    cin>>n;
    for(i=0;i<n;++i){
        cin>>a[i];
        --a[i];
        pos[a[i]]=i;
    }
    for(i=n-1;i>=0;--i){
        while(pos[i]!=i){
            int k,d;

            d=i-pos[i]+1;
            d=x[d];
            k=pos[i]+d-1;

            int t=pos[i];
            ans.push_back(PII(pos[i]+1,k+1));
            swap(pos[i],pos[a[k]]);
            swap(a[t],a[k]);
           // cout<<i<<" "<<pos[i]<<" "<<k<<" "<<d<<endl;
        }
    }
    cout<<ans.size()<<endl;
    for(auto it:ans){
        int x=it.first;
        int y=it.second;
        if(x>y){
            swap(x,y);
        }
        cout<<x<<" "<<y<<endl;
    }
    return 0;
}


#include <bits/stdc++.h>
#define fr(i,a,b) for(int i = (a); i < (b); ++i)
#define rep(i,n) fr(i,0,n)
#define cl(a,b) memset((a), (b), sizeof(a))
#define all(c) (c).begin(), (c).end()
#define _ << ", " <<
#define db(x) cerr << #x " == " << x << endl

using namespace std;

typedef pair<int,int> ii;
typedef vector<int> vi;
typedef long long ll;
const int inf = 0x3f3f3f3f;

ll sieve_size;
bitset<100010> bs;

vi primes;

void sieve(ll upperbound) {
  sieve_size = upperbound + 1;
  bs.set();
  bs[0] = bs[1] = 0;
  for (ll i = 2; i <= sieve_size; i++) if (bs[i]) {
    for (ll j = i * i; j <= sieve_size; j += i) bs[j] = 0;
    primes.push_back(i);
  }
}

ii pares[100010];

int main() {
  //ios_base::sync_with_stdio(false);

  sieve(100010);

  rep(i, (int)primes.size()) {
    pares[primes[i]] = ii(primes[i],-1);
    fr(j,i, (int)primes.size()) {
      if (primes[i] + primes[j] < 100010) {
        pares[primes[i] + primes[j]] = ii(primes[i], primes[j]);
      }
    }
  }

  int n;
  scanf("%d", &n);
  vector<ii> v(n);
  vi pos(n);
  vi ind(n);
  rep(i,n) {
    scanf("%d", &v[i].first);
    v[i].second = i;
    ind[i] = v[i].second;
    pos[v[i].second] = i;
  }

  sort(all(v));

  vector<ii> ops;
  rep(i, n) {

    int j = i;
    int id = pos[v[i].second];
    if (id == i) continue;
    //db(i _ id);
    int diff = abs(i - id) + 1;
    ii par;
    if (diff % 2 == 0) {
      if (diff == 2) {
        ops.push_back({id, i});
        swap(pos[ind[i]], pos[ind[id]]);
        swap(ind[i], ind[id]);
        continue;
      }
      par = pares[diff];

    } else {
      if (diff == 3) {
        ops.push_back({id, i});
        swap(pos[ind[i]], pos[ind[id]]);
        swap(ind[i], ind[id]);
        continue;
      } else {
        par = pares[diff - 1];
      }
    }

    if (id < i) {

      int x = id, y = id + par.first - 1;
      ops.push_back( {x, y} );
      swap(pos[ind[x]], pos[ind[y]]);
      swap(ind[x], ind[y]);

      x = id + par.first - 1, y = id + par.first;
      swap(pos[ind[x]], pos[ind[y]]);
      swap(ind[x], ind[y]);

      x = id + par.first - 1, y = i;
      ops.push_back( {x, y} );
      swap(pos[ind[x]], pos[ind[y]]);
      swap(ind[x], ind[y]);

    } else {
      int x = id, y = id - par.first + 1;
      ops.push_back( {x, y} );
      swap(pos[ind[x]], pos[ind[y]]);
      swap(ind[x], ind[y]);

      x = id - par.first + 1, y = id - par.first;
      swap(pos[ind[x]], pos[ind[y]]);
      swap(ind[x], ind[y]);

      x = id - par.first, y = i;
      swap(pos[ind[x]], pos[ind[y]]);
      swap(ind[x], ind[y]);
    }
    i = j;

  }

  printf("%d\n", (int) ops.size());

  for ( auto x : ops ) {
    if (x.first > x.second) swap(x.first, x.second);
    printf("%d %d\n", x.first + 1, x.second + 1);
  }

  return 0;
}


#include <bits/stdc++.h>
#define fr(i,a,b) for(int i = (a); i < (b); ++i)
#define rep(i,n) fr(i,0,n)
#define cl(a,b) memset((a), (b), sizeof(a))
#define all(c) (c).begin(), (c).end()
#define _ << ", " <<
#define db(x) cerr << #x " == " << x << endl

using namespace std;

typedef pair<int,int> ii;
typedef vector<int> vi;
typedef long long ll;
const int inf = 0x3f3f3f3f;

ll sieve_size;
bitset<100010> bs;

vi primes;

void sieve(ll upperbound) {
  sieve_size = upperbound + 1;
  bs.set();
  bs[0] = bs[1] = 0;
  for (ll i = 2; i <= sieve_size; i++) if (bs[i]) {
    for (ll j = i * i; j <= sieve_size; j += i) bs[j] = 0;
    primes.push_back(i);
  }
}

ii pares[100010];

int main() {
  //ios_base::sync_with_stdio(false);

  sieve(100010);

  rep(i, (int)primes.size()) {
    pares[primes[i]] = ii(primes[i],-1);
    fr(j,i, (int)primes.size()) {
      if (primes[i] + primes[j] < 100010) {
        pares[primes[i] + primes[j]] = ii(primes[i], primes[j]);
      }
    }
  }

  int n;
  scanf("%d", &n);
  vector<ii> v(n);
  vi pos(n);
  vi ind(n);
  rep(i,n) {
    scanf("%d", &v[i].first);
    v[i].second = i;
    ind[i] = v[i].second;
    pos[v[i].second] = i;
  }

  sort(all(v));

  vector<ii> ops;
  rep(i, n) {

    int j = i;
    int id = pos[v[i].second];
    if (id == i) continue;
    //db(i _ id);
    int diff = abs(i - id) + 1;
    ii par;
    if (diff % 2 == 0) {
      if (diff == 2) {
        ops.push_back({id, i});
        swap(pos[ind[i]], pos[ind[id]]);
        swap(ind[i], ind[id]);
        continue;
      }
      par = pares[diff];

    } else {
      if (diff == 3) {
        ops.push_back({id, i});
        swap(pos[ind[i]], pos[ind[id]]);
        swap(ind[i], ind[id]);
        continue;
      } else {
        par = pares[diff - 1];
      }
    }

    if (id < i) {

      int x = id, y = id + par.first - 1;
      ops.push_back( {x, y} );
      swap(pos[ind[x]], pos[ind[y]]);
      swap(ind[x], ind[y]);

      x = id + par.first - 1, y = id + par.first;
      ops.push_back( {x, y} );
      swap(pos[ind[x]], pos[ind[y]]);
      swap(ind[x], ind[y]);

      x = id + par.first - 1, y = i;
      ops.push_back( {x, y} );
      swap(pos[ind[x]], pos[ind[y]]);
      swap(ind[x], ind[y]);

    } else {
      int x = id, y = id - par.first + 1;
      ops.push_back( {x, y} );
      swap(pos[ind[x]], pos[ind[y]]);
      swap(ind[x], ind[y]);

      x = id - par.first + 1, y = id - par.first;
      ops.push_back( {x, y} );
      swap(pos[ind[x]], pos[ind[y]]);
      swap(ind[x], ind[y]);

      x = id - par.first, y = i;
      ops.push_back( {x, y} );
      swap(pos[ind[x]], pos[ind[y]]);
      swap(ind[x], ind[y]);
    }
    i = j;

  }

  printf("%d\n", (int) ops.size());

  for ( auto x : ops ) {
    if (x.first > x.second) swap(x.first, x.second);
    printf("%d %d\n", x.first + 1, x.second + 1);
  }

  return 0;
}


#include <bits/stdc++.h>
#define fr(i,a,b) for(int i = (a); i < (b); ++i)
#define rep(i,n) fr(i,0,n)
#define cl(a,b) memset((a), (b), sizeof(a))
#define all(c) (c).begin(), (c).end()
#define _ << ", " <<
#define db(x) cerr << #x " == " << x << endl

using namespace std;

typedef pair<int,int> ii;
typedef vector<int> vi;
typedef long long ll;
const int inf = 0x3f3f3f3f;

ll sieve_size;
bitset<100010> bs;

vi primes;
vi pos, ind;

void sieve(ll upperbound) {
  sieve_size = upperbound + 1;
  bs.set();
  bs[0] = bs[1] = 0;
  for (ll i = 2; i <= sieve_size; i++) if (bs[i]) {
    for (ll j = i * i; j <= sieve_size; j += i) bs[j] = 0;
    primes.push_back(i);
  }
}

void doswap(int x, int y) {
  swap(pos[ind[x]], pos[ind[y]]);
  swap(ind[x], ind[y]);
}

int main() {
  //ios_base::sync_with_stdio(false);

  sieve(100010);

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

  vector<ii> A(n);
  pos = vi(n);
  ind = vi(n);

  rep(i,n) {
    scanf("%d", &A[i].first);
    A[i].second = i;
    pos[A[i].second] = i;
    ind[i] = i;
  }

  sort(all(A));

  vector<ii> ops;

  rep(i, n) {
    int curr = pos[A[i].second];
    int goal = i;
    while (curr != goal) {
      int diff = abs(curr - goal) + 1;
      int ind = upper_bound(all(primes), diff) - primes.begin();
      --ind;
      int next = curr - primes[ind] + 1;
      ops.push_back( {next, curr} );
      doswap(next, curr);
      curr = next;
    }
  }

  printf("%d\n", (int) ops.size());

  for (auto x : ops) {
    if (x.first > x.second) swap(x.first, x.second);
    printf("%d %d\n", x.first + 1, x.second + 1);
  }

  return 0;
}


#include <bits/stdc++.h>
#define fr(i,a,b) for(int i = (a); i < (b); ++i)
#define rep(i,n) fr(i,0,n)
#define cl(a,b) memset((a), (b), sizeof(a))
#define all(c) (c).begin(), (c).end()
#define _ << ", " <<
#define db(x) cerr << #x " == " << x << endl

using namespace std;

typedef pair<int,int> ii;
typedef vector<int> vi;
typedef long long ll;
const int inf = 0x3f3f3f3f;

ll sieve_size;
bitset<100010> bs;

vi primes;
vi pos, ind;

void sieve(ll upperbound) {
  sieve_size = upperbound + 1;
  bs.set();
  bs[0] = bs[1] = 0;
  for (ll i = 2; i <= sieve_size; i++) if (bs[i]) {
    for (ll j = i * i; j <= sieve_size; j += i) bs[j] = 0;
    primes.push_back(i);
  }
}

void doswap(int x, int y) {
  swap(pos[ind[x]], pos[ind[y]]);
  swap(ind[x], ind[y]);
}

int main() {
  //ios_base::sync_with_stdio(false);

  sieve(100010);

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

  vector<ii> A(n);
  pos = vi(n);
  ind = vi(n);

  rep(i,n) {
    scanf("%d", &A[i].first);
    A[i].second = i;
    pos[A[i].second] = i;
    ind[i] = i;
  }

  sort(all(A));

  vector<ii> ops;

  rep(i, n) {
    int curr = pos[A[i].second];
    int goal = i;
    while (curr != goal) {
      int diff = abs(curr - goal) + 1;
      int ind = upper_bound(all(primes), diff) - primes.begin();
      --ind;
      int next = (curr > goal ? curr - primes[ind] + 1 : curr + primes[ind] - 1);
      ops.push_back( {next, curr} );
      doswap(next, curr);
      curr = next;
    }
  }

  printf("%d\n", (int) ops.size());

  for (auto x : ops) {
    if (x.first > x.second) swap(x.first, x.second);
    printf("%d %d\n", x.first + 1, x.second + 1);
  }

  return 0;
}


#include <iostream>
#include <vector>

using namespace std;

typedef pair<int, int> P;

const int N = 1e5 + 10;
int np[N], near[N], a[N], pos[N];

vector<P> ans;

inline void sw(int i, int j){
	ans.push_back(make_pair(i, j));
	swap(pos[a[i]], pos[a[j]]);
	swap(a[i], a[j]);
}

int main(){
	ios::sync_with_stdio(0);

	for (int i = 2; i*i < N; ++i){
		if (!np[i]) for (int j = i * 2; j < N; j += i) np[j] = 1;
	}

	int tmp = 1;
	for (int i = 1; i < N - 1; ++i){
		if (!np[i + 1]) tmp = i;
		near[i] = tmp;
	}

	int n;
	cin >> n;
	for (int i = 0; i < n; ++i){
		cin >> a[i];
		pos[--a[i]] = i;
	}

	for (int i = 0; i < n; ++i){
		while (near[pos[i] - i]) sw(pos[i] - near[pos[i] - i], pos[i]);
	}

	cout << ans.size() << '\n';
	for(auto p : ans){
		cout << p.first + 1 << ' ' << p.second + 1 << '\n';
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <numeric>
#include <cctype>
#include <tuple>
#include <iterator>
#include <bitset>
#include <random>
#include <assert.h>
#include <unordered_map>

#ifdef _MSC_VER
#include <agents.h>
#endif

#define FOR(i, a, b) for(int i = (a); i < (int)(b); ++i)
#define rep(i, n) FOR(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define REV(v) v.rbegin(), v.rend()
#define MEMSET(v, s) memset(v, s, sizeof(v))
#define X first
#define Y second
#define MP make_pair
#define umap unordered_map

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> P;

const int N = 1e5 + 10;
int np[N];
int near[N];
int a[N], pos[N];

vector<P> ans;

inline void sw(int i, int j){
	ans.push_back(MP(i, j));
	swap(pos[a[i]], pos[a[j]]);
	swap(a[i], a[j]);
}

int main(){
	ios::sync_with_stdio(0);

	vector<int> prime;
	for (int i = 2; i*i < N; ++i){
		if (!np[i]) for (int j = i * 2; j < N; j += i) np[j] = 1;
	}

	int tmp = 1;
	FOR(i, 1, N - 1){
		if (!np[i + 1]) tmp = i;
		near[i] = tmp;
	}

	int n;
	cin >> n;
	rep(i, n){
		cin >> a[i];
		pos[--a[i]] = i;
	}

	rep(i, n){
		int dist = pos[i] - i;
		if (dist < 0){
			sw(pos[i], pos[i] + near[dist]);
			for (int j = 72; j >= 1; --j){
				if (np[j + 1]) continue;
				if (abs(pos[i] - i) >= j) sw(pos[i], pos[i] + j);
			}
		}
		if (dist > 0){
			sw(pos[i] - near[dist], pos[i]);
			for (int j = 72; j >= 1; --j){
				if (np[j + 1]) continue;
				if (abs(pos[i] - i) >= j) sw(pos[i] - j, pos[i]);
			}
		}
	}

	cout << ans.size() << '\n';
	rep(i, ans.size()){
		cout << ans[i].first+1 << ' ' << ans[i].second+1 << '\n';
	}

	return 0;
}


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

int main() {

    vector<int> primes = {2, 3, 5, 7};
    for (int i = 11; i < 100000; i += 2) {
        bool is_prime = true;
        for (int j = 0; primes[j]*primes[j] <= i; j++) {
            if (i % primes[j] == 0) {
                is_prime = true;
                break;
            }
        }
        if (is_prime) {
            primes.push_back(i);
        }
    }

    for (size_t i = 0; i < primes.size(); i++) {
        primes[i]--;
    }

    vector<vector<int>> steps(100001);
    for (int i = 1; i <= 100000; i++) {
        int left = i;
        while (left > 0) {
            vector<int>::iterator steps_it = lower_bound(primes.begin(), primes.end(), left);
            int index = steps_it - primes.begin();
            if (index == primes.size()) {
                index--;
            }
            if (primes[index] > left) {
                index--;
            }
            left -= primes[index];
            steps[i].push_back(primes[index]);
        }
    }

    int n;
    cin >> n;
    vector<int> a(n+1);
    vector<int> current_position(n+1);
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        current_position[a[i]] = i;
    }

    vector<pair<int,int>> sequence;
    for (int i = 1; i <= n; i++) {
        int cp = current_position[i];
        int dst = current_position[i] - i;
        for (int j = 0; j < steps[dst].size(); j++) {
            int step = steps[dst][j];
            swap(a[cp], a[cp-step]);
            swap(current_position[a[cp]], current_position[a[cp-step]]);
            sequence.push_back(make_pair(cp-step, cp));
            cp -= step;
        }
    }
    cout << sequence.size() << endl;
    for (int i = 0; i < sequence.size(); i++) {
        cout << sequence[i].first << " " << sequence[i].second << endl;
    }

    return 0;
}


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

int main() {

    vector<int> primes = {2, 3, 5, 7};
    for (int i = 11; i < 100000; i += 2) {
        bool is_prime = true;
        for (int j = 0; primes[j]*primes[j] <= i; j++) {
            if (i % primes[j] == 0) {
                is_prime = false;
                break;
            }
        }
        if (is_prime) {
            primes.push_back(i);
        }
    }

    for (size_t i = 0; i < primes.size(); i++) {
        primes[i]--;
    }

    vector<vector<int>> steps(100001);
    for (int i = 1; i <= 100000; i++) {
        int left = i;
        while (left > 0) {
            vector<int>::iterator steps_it = lower_bound(primes.begin(), primes.end(), left);
            int index = steps_it - primes.begin();
            if (index == primes.size()) {
                index--;
            }
            if (primes[index] > left) {
                index--;
            }
            left -= primes[index];
            steps[i].push_back(primes[index]);
        }
    }

    int n;
    cin >> n;
    vector<int> a(n+1);
    vector<int> current_position(n+1);
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        current_position[a[i]] = i;
    }

    vector<pair<int,int>> sequence;
    for (int i = 1; i <= n; i++) {
        int cp = current_position[i];
        int dst = current_position[i] - i;
        for (int j = 0; j < steps[dst].size(); j++) {
            int step = steps[dst][j];
            swap(a[cp], a[cp-step]);
            swap(current_position[a[cp]], current_position[a[cp-step]]);
            sequence.push_back(make_pair(cp-step, cp));
            cp -= step;
        }
    }
    cout << sequence.size() << endl;
    for (int i = 0; i < sequence.size(); i++) {
        cout << sequence[i].first << " " << sequence[i].second << endl;
    }

    return 0;
}


#include <algorithm>
#include <functional>

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

#include <map>
#include <set>
#include <queue>

#include <vector>
#include <string>
#include <sstream>
#include <iostream>

#include <cassert>

using namespace std;

#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 mp make_pair
#define pb push_back
#define sz(s) (int)((s).size())
#define eps 10e-7

typedef long long ll;
typedef pair<int, int> pint;
const int N = 100010;

int a[N], pom[N], id[N];
set<int> G[N];
vector<int> primes;
int n;

void gen_primes() {
  FOR(i, 2, N)
    pom[i] = 1;
  FOR(i, 2, N)
    if(pom[i])
      for(ll j = ((ll) i) * i; j < N; j += i)
        pom[j] = 0;

  FOR(i, 2, N)
    if(pom[i])
      primes.pb(i);
}

int main() {
  scanf("%d", &n);
  REP(i, n) {
    scanf("%d", &a[i + 1]);
    id[a[i + 1]] = i + 1;
  }

  gen_primes();
  FOR(i, 1, n + 1)
    for(int p : primes) {
      if(i + p - 1 < 1) continue;
      if(i + p - 1  > n) break;
      G[i].insert(i + p - 1);
      G[i + p - 1].insert(i);
    }

  vector<pint> rj;
  //int ok = 0;
  //while(ok != n) {
 // ok = n;
  FOR(i, 1, n + 1) {
    if(id[i] == i) {continue;}
    int d = id[i];
    if(G[i].find(d) != G[i].end()) {
      swap(a[i], a[d]);
      swap(id[i], id[d]);
      rj.pb(mp(min(i, d), max(i, d)));
    } else {
      vector<int> inter(50);
      auto it = set_intersection(G[i].begin(), G[i].end(), G[d].begin(), G[d].end(), inter.begin());
      if(it == inter.begin())  {
   //     ok--;
        continue;
      }
      swap(a[i], a[d]);
      swap(id[i], id[d]);
      rj.pb(mp(min(i, inter[0]), max(i, inter[0])));
      rj.pb(mp(min(inter[0], d), max(inter[0], d)));
      rj.pb(mp(min(i, inter[0]), max(i, inter[0])));
   // }
  }
  }

  printf("%d\n", rj.size());
  for(pint par  : rj) {
    printf("%d %d\n", par.first, par.second);
  }

  return 0;
}


#include <algorithm>
#include <functional>

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

#include <map>
#include <set>
#include <queue>

#include <vector>
#include <string>
#include <sstream>
#include <iostream>

#include <cassert>

using namespace std;

#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 mp make_pair
#define pb push_back
#define sz(s) (int)((s).size())
#define eps 10e-7

typedef long long ll;
typedef pair<int, int> pint;
const int N = 100010;

int a[N], pom[N], id[N];
vector<int> primes;
int n;

void gen_primes() {
  FOR(i, 2, N)
    pom[i] = 1;
  FOR(i, 2, N)
    if(pom[i])
      for(ll j = ((ll) i) * i; j < N; j += i)
        pom[j] = 0;

  FOR(i, 2, N)
    if(pom[i])
      primes.pb(i);
}

int main() {
  scanf("%d", &n);
  REP(i, n) {
    scanf("%d", &a[i + 1]);
    id[a[i + 1]] = i + 1;
  }

  gen_primes();

  vector<pint> rj;
  FOR(i, 1, n + 1) {
    while(id[i] != i) {
      auto it  = lower_bound(primes.begin(), primes.end(), id[i] - i + 1);
      if(*it != id[i] - i + 1) --it;
      int cur_id = id[i] + 1 - *it;
      int val2 = a[cur_id];
      rj.pb(mp(cur_id, id[i]));
      swap(id[val2], id[i]);
      swap(a[id[i]], a[id[val2]]);
    }
  }

  printf("%d\n", rj.size());
  for(pint par  : rj) {
    printf("%d %d\n", par.first, par.second);
  }

  return 1;
}


#include <algorithm>
#include <functional>

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

#include <map>
#include <set>
#include <queue>

#include <vector>
#include <string>
#include <sstream>
#include <iostream>

#include <cassert>

using namespace std;

#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 mp make_pair
#define pb push_back
#define sz(s) (int)((s).size())
#define eps 10e-7

typedef long long ll;
typedef pair<int, int> pint;
const int N = 100010;

int a[N], pom[N], id[N];
set<int> G[N];
vector<int> primes;
int n;

void gen_primes() {
  FOR(i, 2, N)
    pom[i] = 1;
  FOR(i, 2, N)
    if(pom[i])
      for(ll j = ((ll) i) * i; j < N; j += i)
        pom[j] = 0;

  FOR(i, 2, N)
    if(pom[i])
      primes.pb(i);
}

int main() {
  scanf("%d", &n);
  REP(i, n) {
    scanf("%d", &a[i + 1]);
    id[a[i + 1]] = i + 1;
  }

  gen_primes();
  FOR(i, 1, n + 1)
    for(int p : primes) {
      if(i + p > n) break;
      G[i].insert(i + p);
      G[i + p].insert(i);
    }

  vector<pint> rj;
  FOR(i, 1, n + 1) {
    if(id[i] == i) continue;
    int d = id[i];
    if(G[i].find(d) != G[i].end()) {
      swap(a[i], a[d]);
      swap(id[i], id[d]);
      rj.pb(mp(min(i, d), max(i, d)));
    } else {
      vector<int> inter;
      set_intersection(G[i].begin(), G[i].end(), G[d].begin(), G[d].end(), inter.begin());
      swap(a[i], a[d]);
      swap(id[i], id[d]);
      rj.pb(mp(min(i, inter[0]), max(i, inter[0])));
      rj.pb(mp(min(inter[0], d), max(inter[0], d)));
      rj.pb(mp(min(i, inter[0]), max(i, inter[0])));
    }
  }

  printf("%d\n", rj.size());
  for(pint par  : rj) {
    printf("%d %d\n", par.first, par.second);
  }

  return 0;
}


#include <algorithm>
#include <functional>

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

#include <map>
#include <set>
#include <queue>

#include <vector>
#include <string>
#include <sstream>
#include <iostream>

#include <cassert>

using namespace std;

#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 mp make_pair
#define pb push_back
#define sz(s) (int)((s).size())
#define eps 10e-7

typedef long long ll;
typedef pair<int, int> pint;
const int N = 100010;

int a[N], pom[N], id[N];
set<int> G[N];
vector<int> primes;
int n;

void gen_primes() {
  FOR(i, 2, N)
    pom[i] = 1;
  FOR(i, 2, N)
    if(pom[i])
      for(ll j = ((ll) i) * i; j < N; j += i)
        pom[j] = 0;

  FOR(i, 2, N)
    if(pom[i])
      primes.pb(i);
}

int main() {
  scanf("%d", &n);
  REP(i, n) {
    scanf("%d", &a[i + 1]);
    id[a[i + 1]] = i + 1;
  }

  gen_primes();
  FOR(i, 1, n + 1)
    for(int p : primes) {
      if(i + p - 1 < 1) continue;
      if(i + p - 1  > n) break;
      G[i].insert(i + p - 1);
      G[i + p - 1].insert(i);
    }

  vector<pint> rj;
  FOR(i, 1, n + 1) {
    while(id[i] != i) {
      int dis = id[i] - i + 1;
      auto it = lower_bound(primes.begin(), primes.end(), abs(dis));
      int next_id = *it;
      swap(a[next_id], i);
      swap(id[a[next_id]], id[i]);
      rj.pb(mp(i, next_id));
    }
  }

  FOR(i, 1, n + 1)
    printf("%d ", a[i]);
  printf("\n");

  printf("%d\n", rj.size());
  for(pint par  : rj) {
    printf("%d %d\n", par.first, par.second);
  }

  return 1;
}


#include <algorithm>
#include <functional>

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

#include <map>
#include <set>
#include <queue>

#include <vector>
#include <string>
#include <sstream>
#include <iostream>

#include <cassert>

using namespace std;

#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 mp make_pair
#define pb push_back
#define sz(s) (int)((s).size())
#define eps 10e-7

typedef long long ll;
typedef pair<int, int> pint;
const int N = 100010;

int a[N], pom[N], id[N];
set<int> G[N];
vector<int> primes;
int n;

void gen_primes() {
  FOR(i, 2, N)
    pom[i] = 1;
  FOR(i, 2, N)
    if(pom[i])
      for(ll j = ((ll) i) * i; j < N; j += i)
        pom[j] = 0;

  FOR(i, 2, N)
    if(pom[i])
      primes.pb(i);
}

int main() {
  scanf("%d", &n);
  REP(i, n) {
    scanf("%d", &a[i + 1]);
    id[a[i + 1]] = i + 1;
  }

  gen_primes();
  FOR(i, 1, n + 1)
    for(int p : primes) {
      if(i + p - 1 < 1) continue;
      if(i + p - 1  > n) break;
      G[i].insert(i + p - 1);
      G[i + p - 1].insert(i);
    }

  vector<pint> rj;
  FOR(i, 1, n + 1) {
    if(id[i] == i) continue;
    int d = id[i];
    if(G[i].find(d) != G[i].end()) {
      swap(a[i], a[d]);
      swap(id[i], id[d]);
      rj.pb(mp(min(i, d), max(i, d)));
    } else {
      vector<int> inter(50);
      auto it = set_intersection(G[i].begin(), G[i].end(), G[d].begin(), G[d].end(), inter.begin());
      assert(it != inter.begin());
      swap(a[i], a[d]);
      swap(id[i], id[d]);
      rj.pb(mp(min(i, inter[0]), max(i, inter[0])));
      rj.pb(mp(min(inter[0], d), max(inter[0], d)));
      rj.pb(mp(min(i, inter[0]), max(i, inter[0])));
    }
  }

  printf("%d\n", rj.size());
  for(pint par  : rj) {
    printf("%d %d\n", par.first, par.second);
  }

  return 0;
}


#include <algorithm>
#include <functional>

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

#include <map>
#include <set>
#include <queue>

#include <vector>
#include <string>
#include <sstream> #include <iostream>
#include <cassert>

using namespace std;

#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 mp make_pair
#define pb push_back
#define sz(s) (int)((s).size())
#define eps 10e-7

typedef long long ll;
typedef pair<int, int> pint;
const int N = 100010;

int a[N], pom[N], id[N];
vector<int> primes;
int n;

void gen_primes() {
  FOR(i, 2, N)
    pom[i] = 1;
  FOR(i, 2, N)
    if(pom[i])
      for(ll j = ((ll) i) * i; j < N; j += i)
        pom[j] = 0;

  FOR(i, 2, N)
    if(pom[i])
      primes.pb(i);
}

int main() {
  scanf("%d", &n);
  REP(i, n) {
    scanf("%d", &a[i + 1]);
    id[a[i + 1]] = i + 1;
  }

  gen_primes();

  vector<pint> rj;
  FOR(i, 1, n + 1) {
    while(id[i] != i) {
      auto it  = lower_bound(primes.begin(), primes.end(), id[i] - i + 1);
      if(*it != id[i] - i + 1) --it;
      int cur_id = id[i] + 1 - *it;
      int val2 = a[cur_id];
      rj.pb(mp(cur_id, id[i]));
      swap(id[val2], id[i]);
      swap(a[id[i]], a[id[val2]]);
    }
  }

  printf("%d\n", rj.size());
  for(pint par  : rj) {
    printf("%d %d\n", par.first, par.second);
  }

  return 0;
}


#include <algorithm>
#include <functional>

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

#include <map>
#include <set>
#include <queue>

#include <vector>
#include <string>
#include <sstream>
#include <iostream>

#include <cassert>

using namespace std;

#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 mp make_pair
#define pb push_back
#define sz(s) (int)((s).size())
#define eps 10e-7

typedef long long ll;
typedef pair<int, int> pint;
const int N = 100010;

int a[N], pom[N], id[N];
vector<int> primes;
int n;

void gen_primes() {
  FOR(i, 2, N)
    pom[i] = 1;
  FOR(i, 2, N)
    if(pom[i])
      for(ll j = ((ll) i) * i; j < N; j += i)
        pom[j] = 0;

  FOR(i, 2, N)
    if(pom[i])
      primes.pb(i);
}

int main() {
  scanf("%d", &n);
  REP(i, n) {
    scanf("%d", &a[i + 1]);
    id[a[i + 1]] = i + 1;
  }

  gen_primes();

  vector<pint> rj;
  FOR(i, 1, n + 1) {
    while(id[i] != i) {
      int dis = id[i] - i + 1;
      auto it = lower_bound(primes.begin(), primes.end(), abs(dis));
      int next_id = *it;
      swap(a[next_id], i);
      swap(id[a[next_id]], id[i]);
      rj.pb(mp(i, next_id));
    }
  }

  FOR(i, 1, n + 1)
    printf("%d ", a[i]);
  printf("\n");

  printf("%d\n", rj.size());
  for(pint par  : rj) {
    printf("%d %d\n", par.first, par.second);
  }

  return 1;
}


#include<bits/stdc++.h>
using namespace std;
 int main(){
    int n,k;
    cin>>n>>k;
    vector <int>  arr(n) , vis(n , 0);
    list <int > q,q1;
    for(int i=0 ; i<n ;i++ ) cin>>arr[i];

    // for(int i=0 ;i < n ; i++)  cout<<vis[i]<<" ";

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

            // q1 = q;
            // while(!q1.empty()){
            //    cout<<q1.front()<<" " , q1.pop_front();
            // }
            // cout<<endl;

            if(vis[arr[i]] == 0) {

                vis[arr[i]] = 1;

                if(q.size() == k)
                {
                    int front  =  q.front();
                    q.pop_front();

                    if(find(q.begin() , q.end() , front) == q.end())
                    {
                        vis[front] = 0;
                    }
                    q.push_back(arr[i]);
                }

                else{
                    q.push_back(arr[i]);
                }
            }
        }

    cout<<q.size()<<endl;
    while(!q.empty()){
        cout<<q.back()<<" " , q.pop_back();
    }
    }


// https://codeforces.com/contest/1234

#include<bits/stdc++.h>
using namespace std;
 int main(){
    long long int n,k;
    cin>>n>>k;
    vector <long long int>  arr(n);
    list <long long int > q,q1;
    for(int i=0 ; i<n ;i++ ) cin>>arr[i];
        long long int front;
        for(int i=0;i<n;i++){

            if(find(q.begin() , q.end() , arr[i]) == q.end())
            {
                if(q.size() == k)
                {
                    front  =  q.front();
                    q.pop_front();
                    q.push_back(arr[i]);
                }

                else{
                    q.push_back(arr[i]);
                }
            }
        }
    cout<<q.size()<<endl;
    while(!q.empty()){
        cout<<q.back()<<" " , q.pop_back();
    }
        }