Problem p03642 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#define maxn 1005
#define maxm 10000005
#define Rint register int
#define INF 0x3f3f3f3f
using namespace std;
typedef long long lxl;

template <typename T> inline void read(T &x) {
  x = 0;
  T f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (x << 1) + (x << 3) + ch - '0';
    ch = getchar();
  }
  x *= f;
}

int prime[maxm], cnt;
bool flag[maxm];

inline void sieve() {
  for (int i = 2; i < maxm; ++i) {
    if (!flag[i])
      prime[++cnt] = i;
    for (int j = 1; j <= cnt && i * prime[j] < maxm; ++j) {
      flag[i * prime[j]] = true;
      if (!(i % prime[j]))
        break;
    }
  }
  flag[1] = flag[2] = true;
}

struct edge {
  int u, v, next;
  edge(int u, int v, int next) : u(u), v(v), next(next) {}
  edge() {}
} e[maxn << 1];

int head[maxn], k;

inline void add(int u, int v) {
  e[k] = edge(u, v, head[u]);
  head[u] = k++;
}

int n;
int a[maxn], f[maxm], L[maxn], R[maxn];
int match[maxn];
bool vis[maxn];

inline int findpath(int u) {
  for (int i = head[u]; ~i; i = e[i].next) {
    int v = e[i].v;
    if (!vis[v]) {
      vis[v] = true;
      if (!match[v] || findpath(match[v])) {
        match[v] = u;
        return true;
      }
    }
  }
  return false;
}

inline int Hungary() {
  int res = 0;
  for (int i = 1; i <= L[0]; ++i) {
    memset(vis, 0, sizeof(vis));
    res += findpath(i);
  }
  return res;
}

int main() {
  sieve();
  read(n);
  int up = 0;
  for (int i = 1; i <= n; ++i) {
    read(a[i]);
    ++f[a[i]];
    up = max(up, a[i]);
  }
  for (int i = 1; i <= up + 1; ++i)
    if (f[i] != f[i - 1]) {
      if (i & 1)
        L[++L[0]] = i;
      else
        R[++R[0]] = i;
    }
  memset(head, -1, sizeof(head));
  for (int i = 1; i <= L[0]; ++i)
    for (int j = 1; j <= R[0]; ++j)
      if (!flag[abs(L[i] - R[j])])
        add(i, j);
  int maxmatch = Hungary();
  int ans = maxmatch;
  ans += (L[0] - maxmatch) / 2 * 2 + (R[0] - maxmatch) / 2 * 2;
  ans += ((L[0] - maxmatch) & 1) * 3;
  printf("%d\n", ans);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#define maxn 10005
#define maxm 10000005
#define Rint register int
#define INF 0x3f3f3f3f
using namespace std;
typedef long long lxl;

template <typename T> inline void read(T &x) {
  x = 0;
  T f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (x << 1) + (x << 3) + ch - '0';
    ch = getchar();
  }
  x *= f;
}

int prime[maxm], cnt;
bool flag[maxm];

inline void sieve() {
  for (int i = 2; i < maxm; ++i) {
    if (!flag[i])
      prime[++cnt] = i;
    for (int j = 1; j <= cnt && i * prime[j] < maxm; ++j) {
      flag[i * prime[j]] = true;
      if (!(i % prime[j]))
        break;
    }
  }
  flag[1] = flag[2] = true;
}

struct edge {
  int u, v, next;
  edge(int u, int v, int next) : u(u), v(v), next(next) {}
  edge() {}
} e[maxn << 1];

int head[maxn], k;

inline void add(int u, int v) {
  e[k] = edge(u, v, head[u]);
  head[u] = k++;
}

int n;
int a[maxn], f[maxm], L[maxn], R[maxn];
int match[maxn];
bool vis[maxn];

inline int findpath(int u) {
  for (int i = head[u]; ~i; i = e[i].next) {
    int v = e[i].v;
    if (!vis[v]) {
      vis[v] = true;
      if (!match[v] || findpath(match[v])) {
        match[v] = u;
        return true;
      }
    }
  }
  return false;
}

inline int Hungary() {
  int res = 0;
  for (int i = 1; i <= L[0]; ++i) {
    memset(vis, 0, sizeof(vis));
    res += findpath(i);
  }
  return res;
}

int main() {
  sieve();
  read(n);
  int up = 0;
  for (int i = 1; i <= n; ++i) {
    read(a[i]);
    ++f[a[i]];
    up = max(up, a[i]);
  }
  for (int i = 1; i <= up + 1; ++i)
    if (f[i] != f[i - 1]) {
      if (i & 1)
        L[++L[0]] = i;
      else
        R[++R[0]] = i;
    }
  memset(head, -1, sizeof(head));
  for (int i = 1; i <= L[0]; ++i)
    for (int j = 1; j <= R[0]; ++j)
      if (!flag[abs(L[i] - R[j])])
        add(i, j);
  int maxmatch = Hungary();
  int ans = maxmatch;
  ans += (L[0] - maxmatch) / 2 * 2 + (R[0] - maxmatch) / 2 * 2;
  ans += ((L[0] - maxmatch) & 1) * 3;
  printf("%d\n", ans);
  return 0;
}