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 <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <cassert>
#include <queue>
#include <ctime>
#include <string>
#include <cstring>
#include <random>
#define mp make_pair
#define pb push_back
#define NAME ""
#define y1 y1_423
#define list lista

using namespace std;

typedef long long ll;
typedef long double ld;

template<typename T>
ostream& operator << (ostream& cout, const vector<T> &a) {
	if ((int)a.size() == 0) {
		return (cout << "()");
	}
	cout << "(" << a[0];
	for (int i = 1; i < (int)a.size(); i++) {
		cout << "; " << a[i];
	}
	return (cout << ")");
}

template<typename T>
ostream& operator << (ostream& cout, const set<T> &a) {
	if ((int)a.size() == 0) {
		return (cout << "{}");
	}
	auto it = a.begin();
	cout << "{" << *it;
	++it;
	for (; it != a.end(); ++it) {
		cout << "; " << *it;
	}
	return (cout << "}");
}

template<typename T>
ostream& operator << (ostream& cout, const multiset<T> &a) {
	if ((int)a.size() == 0) {
		return (cout << "{}");
	}
	auto it = a.begin();
	cout << "{" << *it;
	++it;
	for (; it != a.end(); ++it) {
		cout << "; " << *it;
	}
	return (cout << "}");
}

template<typename T1, typename T2>
ostream& operator << (ostream& cout, const pair<T1, T2> &a) {
	return cout << "(" << a.first << "; " << a.second << ")";
}

random_device gen;
mt19937 rnd(gen());

const int nmax = 1000 * 1000 * 10 + 10;
const int inf = 2000 * 1000 * 1000;
const ll infl = 1000ll * 1000ll * 1000ll * 1000ll * 1000ll * 1000ll;
const int mod = 1000 * 1000 * 1000 + 7;
const ld pi = acos(-1.0);

bool used[nmax], u[nmax];
int p[300];
int b[nmax];
vector<int> a, go[300];

bool ok(int v) {
	if (u[v]) return false;
	u[v] = true;
	for (int u : go[v]) {
		if (p[u] == -1) {
			p[u] = v;
			return true;
		}
	}
	for (int u : go[v]) {
		if (ok(u)) {
			p[u] = v;
			return true;
		}
	}
	return false;
}

int main() {
	//freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
	//freopen(NAME".in", "r", stdin);freopen(NAME".out", "w", stdout);
	for (int i = 2; i < nmax; i++) {
		used[i] = 1;
	}
	for (ll i = 2; i * i < nmax; i++) {
		if (!used[i]) continue;
		for (ll j = i * i; j < nmax; j += i) {
			used[j] = 0;
		}
	}
	used[0] = used[1] = used[2] = 0;
	int n;
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		int x;
		scanf("%d", &x);
		b[x] ^= 1;
		b[x + 1] ^= 1;
	}
	for (int i = 0; i < nmax; i++) {
		if (b[i] == 1) {
			a.pb(i);
		}
	}
	n = a.size();
	assert(n < 300);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			if (i == j) continue;
			if (used[abs(a[i] - a[j])]) {
				go[i].pb(j);
			}
		}
	}
	int cnt0 = 0, cnt1 = 0;
	for (int i = 0; i < n; i++) {
		if (a[i] % 2 == 0) {
			cnt0++;
		} else {
			cnt1++;
		}
	}
	for (int j = 0; j < n; j++) {
		p[j] = -1;
	}
	int answer = 0;
	for (int i = 0; i < n; i++) {
		if (a[i] % 2 == 0) continue;
		for (int j = 0; j < n; j++) {
			u[j] = 0;
		}
		if (ok(i)) answer++;
	}
	cout << answer + ((cnt0 - answer) / 2 + (cnt1 - answer) / 2) * 2 + ((cnt1 - answer) % 2) * 3 << endl;
	return 0;
}