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 <vector>
#include <queue>
#include <algorithm>
#include <set>
#include <bitset>
using namespace std;
int N;
int x;
set<int> S;
vector<int> G[205];
int L[205];
int R[205];
vector<int> Me,Mo;
bitset<205> U;
bool prime(int nr)
{
    for(int i=2;i*i<=nr;i++)if(nr%i==0)return 0;
    return 1;
}
bool pairup(int nod)
{
    if(U[nod])return 0;
    U[nod]=1;
    for(auto it:G[nod])
    {
        if(!R[it])
        {
            L[nod]=it;
            R[it]=nod;
            return 1;
        }
    }
    for(auto it:G[nod])
    {
        if(pairup(R[it]))
        {
            L[nod]=it;
            R[it]=nod;
            return 1;
        }
    }
    return 0;
}
int main()
{
    cin>>N;
    for(int i=1;i<=N;i++)
    {
        cin>>x;
        if(S.find(x)!=S.end())
        {
            S.erase(x);
        }
        else
        {
            S.insert(x);
        }
        S.insert(x+1);
    }
    for(auto it:S)
        if(it%2==0)
            Me.push_back(it);
        else
            Mo.push_back(it);
    for(int i=0;i<Me.size();i++)
    {
        for(int j=0;j<Mo.size();j++)
        {
            if(prime(abs(Mo[j]-Me[i])))
                G[i].push_back(j);
        }
    }
    bool ok=1;
    int k=0;
    while(ok)
    {
        ok=0;
        U.reset();
        for(int i=0;i<Me.size();i++)
        {
            if(!L[i]&&pairup(i))
            {
                k++;
                ok=1;
            }
        }
    }
    int rez=k+(((int)Me.size()-k)/2)*2+(((int)Mo.size()-k)/2)*2+(((int)Me.size()-k)%2)*3;
    cout<<rez;
    return 0;
}