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 <bits/stdc++.h>
using namespace std;
// flow from KACTL
typedef long long LL;
struct Flow{
	int n;
	vector<vector<int> > graph; //list of id's
	vector<int> st, en, back; //back = back edge id
	vector<LL> f, c;
	vector<int> par;
	Flow(int n): n(n), graph(n), par(n){}
	void add_edge(int u, int v, int cap){
		int id1 = st.size();
		int id2 = id1 + 1;
		st.push_back(u); st.push_back(v);
		en.push_back(v); en.push_back(u);
		back.push_back(id2); back.push_back(id1);
		f.push_back(0); f.push_back(0);
		c.push_back(cap); c.push_back(0);
		graph[u].push_back(id1);
		graph[v].push_back(id2);
	}

	void add(int id1, int v){
		f[id1] += v;
		c[id1] -= v;
		f[back[id1]] -= v;
		c[back[id1]] += v;
	}

	LL maxflow(int s, int t){
		LL ans = 0;
		vector<int> bfs;
		if(s == t) return ans;
		while(1){
			for(int i = 0; i < n; i++) par[i] = -1;
			bfs.clear();
			bfs.push_back(s); par[s] = -2;
			int cur = 0;
			while(cur < bfs.size()){
				int u = bfs[cur]; cur++;
				for(int i = 0; i < graph[u].size(); i++){
					int id = graph[u][i];
					if(c[id] == 0) continue;
					if(par[en[id]] != -1) continue;
					par[en[id]] = id;
					bfs.push_back(en[id]);
				}
			}
			if(par[t] == -1) break;
			LL send = 4e18;
			int curv = t;
			while(par[curv] != -2){
				send = min(send, c[par[curv]]);
				curv = st[par[curv]];
			}
			curv = t;
			while(par[curv] != -2){
				add(par[curv], send);
				curv = st[par[curv]];
			}
			ans += send;
		}
		return ans;
	}
};
int main(){
	int n;
	cin >> n;
	int z[n];
	map<int,int> f;
	for(int i = 0; i < n; i++){
		cin >> z[i];
		f[z[i]]++;
		f[z[i]+1]++;
	}
	vector<int> r;
	vector<int> odd, even;
	for(map<int,int>::iterator it = f.begin(); it != f.end(); it++){
		if(it->second == 1){
			r.push_back(it->first);
			if(it->first % 2){
				odd.push_back(it->first);
			} else {
				even.push_back(it->first);
			}
		}
	}
	Flow s(300);
	for(int i = 0; i < 100; i++){
		s.add_edge(200,i,1);
		s.add_edge(i+100,201,1);
	}
	for(int i = 0; i < odd.size(); i++){
		for(int j = 0; j < even.size(); j++){
			int a = odd[i];
			int b = even[j];
			//cout << a << " " << b << endl;
			int p = abs(a-b);
			int ok = 1;
			if(p <= 1) ok = 0;
			for(int c = 2; c*c <= p; c++){
				if(p % c == 0){
					ok = 0;
					break;
				}
			}
			if(ok){
				s.add_edge(i,j+100,1);
			}
		}
	}
	int flow = (int)s.maxflow(200,201);
	int o1 = (int)odd.size() - flow;
	int e1 = (int)even.size() - flow;
	int ans = flow;
	ans += (o1/2)*2;
	ans += (e1/2)*2;
	o1 %= 2;
	e1 %= 2;
	if(o1 >= 1){
		ans += 3;
	}
	cout << ans << endl;
}