Problem:
Score : 1200 points

Problem Statement

There are infinitely many cards, numbered 1, 2, 3, ...
Initially, Cards x_1, x_2, ..., x_N are face up, and the others are face down.

Snuke can perform the following operation repeatedly:

Select a prime p greater than or equal to 3. Then, select p consecutive cards and flip all of them.

Snuke's objective is to have all the cards face down.
Find the minimum number of operations required to achieve the objective.

Constraints

1 ≤ N ≤ 100

1 ≤ x_1 < x_2 < ... < x_N ≤ 10^7

Input

Input is given from Standard Input in the following format:

N
x_1 x_2 ... x_N

Output

Print the minimum number of operations required to achieve the objective.

Sample Input 1

2
4 5

Sample Output 1

2

Below is one way to achieve the objective in two operations:

Select p = 5 and flip Cards 1, 2, 3, 4 and 5.

Select p = 3 and flip Cards 1, 2 and 3.

Sample Input 2

9
1 2 3 4 5 6 7 8 9

Sample Output 2

3

Below is one way to achieve the objective in three operations:

Select p = 3 and flip Cards 1, 2 and 3.

Select p = 3 and flip Cards 4, 5 and 6.

Select p = 3 and flip Cards 7, 8 and 9.

Sample Input 3

2
1 10000000

Sample Output 3

4

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <ctime>
#include <set>

#define Rep(i, n) for (int i = 1; i <= n; i ++)
#define Rep0(i, n) for (int i = 0; i <= n; i ++)
#define RepG(i, x) for (int i = head[x]; i; i = edge[i].next)
#define v edge[i].to
#define mp(a, b) make_pair(a, b)
#define fi first
#define se second

using namespace std;

const int N = 210;

bool isnotprime[10000010];
int prime[10000010], cnt;
void get_prime()
{
	isnotprime[1] = true;
	for (int i = 2; i <= 10000000; i ++) {
		if (!isnotprime[i]) prime[++ cnt] = i;
		for (int j = 1; j <= cnt && i * prime[j] <= 10000000; j ++) {
			isnotprime[i * prime[j]] = true;
			if (!(i % prime[j])) break;
		}
	}
}

int vv[10000010], p[N], d0[N], d1[N], lnk[N], cd0, cd1;
bool vis[N];
bool dfs(int x)
{
	Rep(i, cd1) if (!isnotprime[abs(d0[x] - d1[i])] && !vis[i]) {
	//	printf("!%d\n", abs(d0[x] - d1[i]));
		vis[i] = true;
		if (lnk[i] == -1 || dfs(lnk[i])){ lnk[i] = x; return true;} 
	}
	return false;
}

int main()
{
	get_prime();
	
	int T = 1;
	//scanf("%d", &T);
	while (T --){
		int n;
		scanf("%d", &n);
		cd0 = cd1 = 0;
		Rep(i, n) {
			scanf("%d", &p[i]);
			if (vv[p[i]] != T + 1) vv[p[i]] = T + 1;
		}
		Rep(i, n) {
			if (vv[p[i]] != vv[p[i] - 1]) {
				if (p[i] & 1) d1[++ cd1] = p[i];
				else d0[++ cd0] = p[i];
			}
			if (vv[p[i]] != vv[p[i] + 1]) {
				if (p[i] & 1) d0[++ cd0] = p[i] + 1;
				else d1[++ cd1] = p[i] + 1;
			}
		}
	//	printf("%d %d\n", cd0, cd1);
	//	Rep(i, cd0) printf("_%d ", d0[i]); printf("\n");
	//	Rep(i, cd1) printf("_%d ", d1[i]); printf("\n");
		
		int ans = 0;
		memset(lnk, -1, sizeof(lnk));
		Rep(i, cd0) {
			memset(vis, false, sizeof(vis));
			if (dfs(i)) ans ++;
		}
		ans += ((cd0 - ans) / 2) * 2 + ((cd1 - ans) / 2) * 2;
		if ((cd0 - ans) & 1) ans += 3;
		printf("%d\n", ans);
	}
	
	return 0;
}
/*
3
2
2 3
3
1 2 4
5
101 102 103 104 105
*/