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: Wrong Answer)

#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <utility>
#include <bitset>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <cstring>
#include <climits>
#include <string.h>
#include <stdio.h>
#define LL long long
#define all(x) (x).begin(),(x).end()
#define pii pair<int,int>
#define piii pair<int, pii >
#define REP(i,n) for (int (i)=0;(i)<(n);(i)++)
#define vi vector<int>
#define vpi vector< pii >
#define INF 2147483647
#define big 19260817
#define pb push_back
#define mp make_pair
using namespace std;
const int Maxk=1005;
string mul(string a,string b){
	int res[Maxk];
	memset(res,0,sizeof(res));
	reverse(a.begin(),a.end());
	reverse(b.begin(),b.end());
	for (int i=0;i<a.length();i++){
		for (int j=0;j<b.length();j++){
			res[i+j]+=(a[i]-'0')*(b[j]-'0');
		}
	}
	for (int i=0;i<Maxk;i++){
		if (res[i]>=10) {
			res[i+1]+=(res[i]/10);
			res[i]%=10;
		}
	}
	string ret;
	bool flag=false;
	for (int i=Maxk-1;i>=0;i--){
		if (flag || res[i]){
			flag=true;
			ret=ret+(char)(res[i]+'0');
		}
	}
	if (ret=="") ret="0";
	return ret;
}
string add(string a,string b){
	if (a.length()<b.length()) swap(a,b);
	while (a.length()!=b.length()){
		b='0'+b;
	}
	for (int i=a.length()-1;i>=0;i--){
		a[i]+=(b[i]-'0');
		if (a[i]>'9' && i){
			a[i]-=10;
			a[i-1]++;
		}
	}
	if (a[0]>'9'){
		a[0]-=10;
		a='1'+a;
	}
	return a;
}

// cf IO: I64d
// atcoder IO: ｌｌｄ
inline int read()
{
	int x = 0, f = 1; char ch = getchar();
	while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
const int Maxn=305;
const int Maxm=1e7+5;
int cnt;
int pos[Maxn],len[Maxn];
int dp[Maxn][Maxn][2];
bool isp[Maxm];
void _init(){
	memset(isp,true,sizeof(isp));
	isp[1]=isp[0]=false;
	for (int i=2;i<Maxm;i++){
		if (isp[i]){
			for (int j=i+i;j<Maxm;j+=i){
				isp[j]=false;
			}
		}
	}
}
int cost(int len){
	if (!len) return 0;
	if (len%2==0) return 2;
	if (isp[len]) return 1;
	return 3;
}
int main(){
	_init();//cerr<<123<<endl;
	int n;
	scanf("%d",&n);
	for (int i=0;i<n;i++){
		scanf("%d",&pos[i]);
	}
	int sum=1;
	for (int i=1;i<n;i++){
		if (pos[i]==pos[i-1]+1) sum++;
		else{
			len[++cnt]=sum;
			len[++cnt]=pos[i]-pos[i-1]-1;
			sum=1;
		}
	}
	len[++cnt]=sum;
	for (int i=1;i<=cnt;i++){
		if (i%2==0)dp[i][i][0]=0;
		else dp[i][i][1]=0;
		if (i%2==0)dp[i][i][1]=cost(len[i]);
		else dp[i][i][0]=cost(len[i]);
	}
	//cout<<cnt<<endl;
	for (int Len=2;Len<=cnt;Len++){
		for (int i=1;i<=cnt;i++){
			int j=i+Len-1;
			if (j>cnt) continue;
			int totlen=0;
			for (int k=i;k<=j;k++) totlen+=len[k];
			for (int f=0;f<2;f++){
				dp[i][j][f]=1e9;
				for (int k=i+1;k<=j;k++){
					// i~k-1 k~j
					dp[i][j][f]=min(dp[i][j][f],dp[i][k-1][f]+dp[k][j][f]);
				}
			}
			//cout<<i<<' '<<j<<' '<<totlen<<' '<<cost(totlen)<<' '<<dp[i][j][0]<<' '<<dp[i][j][1]<<endl;
			if (dp[i][j][0]>dp[i][j][1]){
				dp[i][j][0]=min(dp[i][j][0],dp[i][j][1]+cost(totlen));
				
			}
			else{
				dp[i][j][1]=min(dp[i][j][1],dp[i][j][0]+cost(totlen));
			}
			
		}
	}
//	cout<<dp[1][1][1]<<' '<<dp[2][4][1]<<endl;
	printf("%d\n",dp[1][cnt][0]);
	return 0;
}