Problem: Fox Ciel is participating in a party in Prime Kingdom. There are n foxes there (include Fox Ciel). The i-th fox is ai years old.

They will have dinner around some round tables. You want to distribute foxes such that:

  1. Each fox is sitting at some table. 
  2. Each table has at least 3 foxes sitting around it. 
  3. The sum of ages of any two adjacent foxes around each table should be a prime number. 



If k foxes f1, f2, ..., fk are sitting around table in clockwise order, then for 1 ≤ i ≤ k - 1: fi and fi + 1 are adjacent, and f1 and fk are also adjacent.

If it is possible to distribute the foxes in the desired manner, find out a way to do that.

Input

The first line contains single integer n (3 ≤ n ≤ 200): the number of foxes in this party. 

The second line contains n integers ai (2 ≤ ai ≤ 104).

Output

If it is impossible to do this, output "Impossible".

Otherwise, in the first line output an integer m (<image>): the number of tables.

Then output m lines, each line should start with an integer k -=– the number of foxes around that table, and then k numbers — indices of fox sitting around that table in clockwise order.

If there are several possible arrangements, output any of them.

Examples

Input

4
3 4 8 9


Output

1
4 1 2 4 3


Input

5
2 2 2 2 2


Output

Impossible


Input

12
2 3 4 5 6 7 8 9 10 11 12 13


Output

1
12 1 2 3 6 5 12 9 8 7 10 11 4


Input

24
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25


Output

3
6 1 2 3 6 5 4
10 7 8 9 12 15 14 13 16 11 10
8 17 18 23 22 19 20 21 24

Note

In example 1, they can sit around one table, their ages are: 3-8-9-4, adjacent sums are: 11, 17, 13 and 7, all those integers are primes.

In example 2, it is not possible: the sum of 2+2 = 4 is not a prime number.

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
struct line {
  int s, t;
  int f;
  int next;
} a[100001];
int head[1001];
int edge;
inline void add(int s, int t, int f) {
  a[edge].next = head[s];
  head[s] = edge;
  a[edge].s = s;
  a[edge].t = t;
  a[edge].f = f;
}
int p;
inline bool pd(int x) {
  if (x == 1) return false;
  int i;
  bool flag = true;
  for (i = 2; i <= sqrt(x); i++) {
    if (x % i == 0) {
      flag = false;
      break;
    }
  }
  return flag;
}
queue<int> Q;
int pt[100001];
inline bool bfs(int st, int tt) {
  memset(pt, -1, sizeof(pt));
  while (!Q.empty()) Q.pop();
  Q.push(st);
  pt[st] = 0;
  int i;
  while (!Q.empty()) {
    int d = Q.front();
    Q.pop();
    for (i = head[d]; i != 0; i = a[i].next) {
      int t = a[i].t;
      if (a[i].f > 0 && pt[t] == -1) {
        Q.push(t);
        pt[t] = pt[d] + 1;
      }
    }
  }
  if (pt[tt] >= 0) return true;
  return false;
}
inline int dfs(int d, int tt, int s) {
  if (d == tt) return s;
  int tx = s;
  int i;
  for (i = head[d]; i != 0; i = a[i].next) {
    int t = a[i].t;
    if (pt[t] == pt[d] + 1 && a[i].f > 0) {
      int xx = dfs(t, tt, min(s, a[i].f));
      a[i].f -= xx;
      if (i % 2 == 0)
        a[i - 1].f += xx;
      else
        a[i + 1].f += xx;
      s -= xx;
    }
  }
  return tx - s;
}
inline int dinic(int st, int tt) {
  int s = 0;
  while (bfs(st, tt)) s += dfs(st, tt, 2100000000);
  return s;
}
int xt[10001];
int s1[10001], s2[10001];
int v[10001];
int belong[10001];
int sx[10001];
int loc[1001][1001];
inline void dfsx(int d, int x) {
  v[d] = true;
  belong[d] = x;
  sx[x]++;
  loc[x][sx[x]] = d;
  int i;
  for (i = head[d]; i != 0; i = a[i].next) {
    int t = a[i].t;
    if (v[t]) continue;
    if (xt[d] % 2 == 1) {
      if (a[i].f == 0 && t != 0) dfsx(t, x);
    } else {
      if (a[i].f == 1 && t != p) dfsx(t, x);
    }
  }
}
int main() {
  int n;
  scanf("%d", &n);
  int i, j, k;
  int p1 = 0, p2 = 0;
  p = n + 1;
  int lf = 0, ri = 0;
  for (i = 1; i <= n; i++) {
    scanf("%d", &xt[i]);
    if (xt[i] % 2 == 1) {
      p1++;
      s1[p1] = i;
      edge++;
      add(0, i, 2);
      edge++;
      add(i, 0, 0);
      lf += 2;
    } else {
      p2++;
      s2[p2] = i;
      edge++;
      add(i, p, 2);
      edge++;
      add(p, i, 0);
      ri += 2;
    }
  }
  for (i = 1; i <= p1; i++) {
    for (j = 1; j <= p2; j++) {
      int s = xt[s1[i]] + xt[s2[j]];
      if (pd(s)) {
        edge++;
        add(s1[i], s2[j], 1);
        edge++;
        add(s2[j], s1[i], 0);
      }
    }
  }
  if (lf != ri) {
    printf("Impossible\n");
    return 0;
  }
  int all = dinic(0, p);
  if (all != ri) {
    printf("Impossible\n");
    return 0;
  }
  int sum = 0;
  for (i = 1; i <= n; i++) {
    if (!v[i]) {
      sum++;
      v[i] = false;
      dfsx(i, sum);
    }
  }
  printf("%d\n", sum);
  for (i = 1; i <= sum; i++) {
    printf("%d", sx[i]);
    for (j = 1; j <= sx[i]; j++) printf(" %d", loc[i][j]);
    printf("\n");
  }
  return 0;
}