#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <locale>
#include <iostream>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#define REP(i,n) for(int i=0;i<(int)(n);i++)
#define ALL(x) (x).begin(),(x).end()

using namespace std;

using ll = long long;
using ld = long double;

template <typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template <typename T> int len(const T &x) { return x.size(); }

template<typename T>
vector<T> table(int n, T v) { return vector<T>(n, v); }

template <class... Args>
auto table(int n, Args... args) {
  auto val = table(args...);
  return vector<decltype(val)>(n, move(val));
}

struct yes_no : numpunct<char> {
  string_type do_truename()  const { return "YES"; }
  string_type do_falsename() const { return "NO"; }
};

class BipartiteMatching {
  int size;
  vector<vector<int>> g;
  vector<int> match;
  vector<bool> used;
  bool dfs(int v) {
    used[v] = true;
    for (int u: g[v]) {
      int w = match[u];
      if (w < 0 || (!used[w] && dfs(w))) {
        match[v] = u;
        match[u] = v;
        return true;
      }
    }
    return false;
  }
public:
  BipartiteMatching(int v) : size(v), g(v), match(v), used(v) {}
  void add_edge(int u, int v) {
    g[u].push_back(v);
    g[v].push_back(u);
  }
  int maximum_matching(void) {
    int res = 0;
    fill(begin(match), end(match), -1);
    for (int v = 0; v < size; ++v) {
      if (match[v] >= 0) continue;
      fill(begin(used), end(used), 0);
      if (dfs(v)) ++res;
    }
    return res;
  }
};

const int Prime_N = 1024000 * 10;

bitset<Prime_N> is_prime;

vector<int> primes() {
  is_prime.set();
  is_prime[0] = false;
  is_prime[1] = false;
  for (int i = 2; i * i < Prime_N; ++i) {
    if (is_prime[i]) {
      for (int j = i * i; j < Prime_N; j += i) {
        is_prime[j] = false;
      }
    }
  }
  vector<int> res;
  for (int i = 2; i < Prime_N; ++i) {
    if (is_prime[i]) res.push_back(i);
  }
  return res;
}

void add(vector<int> &v, int x) {
  auto it = find(ALL(v), x);
  if (it == end(v)) v.push_back(x);
  else v.erase(it);
}

void solve(ll N, vector<ll> x) {
  primes();
  vector<int> v;
  for (ll i: x) {
    add(v, i);
    add(v, i + 1);
  }
  sort(ALL(v));

  N = v.size();
  BipartiteMatching mat(N);
  REP(i,N) REP(j,N) {
    if (v[i] % 2 == 0 && v[j] % 2 == 1) {
      int d = abs(v[i] - v[j]);
      if (d >= 3 && is_prime[d]) mat.add_edge(i, j);
    }
  }
  // for (int i: v) cout << i << " "; cout << endl;
  int maxv = mat.maximum_matching();

  int even = 0, odd = 0;
  for (int i: v) {
    if (i % 2 == 0) ++even; else ++odd;
  }
  int res = 0;
  res += maxv;
  odd -= maxv; even -= maxv;

  res += even / 2 * 2;
  res += odd / 2 * 2;
  if (even % 2) res += 3;
  cout << res << endl;
}

int main() {
  locale loc(locale(), new yes_no);
  cout << boolalpha << setprecision(12) << fixed;
  cout.imbue(loc);
	ll N;
	scanf("%lld", &N);
	vector<ll> x(N-1+1);
	for (int i = 0 ; i <= N-1 ; i++) {
	  scanf("%lld", &x[i]);
	}
	solve(N, x);
	return 0;
}


Measured memory_bytes: 7664