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 edge {
  int f, t, cap, fl;
  edge(int _f = 0, int _t = 0, int _cap = 0) {
    f = _f;
    t = _t;
    cap = _cap;
    fl = 0;
  }
  int rc() { return cap - fl; }
};
int N, F, T;
vector<edge> E;
vector<int> fo[210];
void add_edge(int f, int t, int cap) {
  E.push_back(edge(f, t, cap));
  E.push_back(edge(t, f, 0));
  fo[f].push_back(((int)(E).size()) - 2);
  fo[t].push_back(((int)(E).size()) - 1);
}
int lev[210], Q[210], QL, QR;
bool bfs() {
  memset(lev, -1, N * sizeof(int));
  QL = QR = 0;
  lev[F] = 1;
  Q[QR++] = F;
  while (QL < QR) {
    int V = Q[QL++];
    for (int i = 0; i < ((int)(fo[V]).size()); ++i)
      if (E[fo[V][i]].rc()) {
        int to = E[fo[V][i]].t;
        if (lev[to] == -1) {
          lev[to] = lev[V] + 1;
          Q[QR++] = to;
        }
      }
  }
  return lev[T] != -1;
}
int pos[210];
int dfs(int vr, int htp = 1000000000) {
  if (htp == 0 || vr == T) return htp;
  for (; pos[vr] < ((int)(fo[vr]).size()); ++pos[vr]) {
    edge& e = E[fo[vr][pos[vr]]];
    if (lev[e.f] + 1 == lev[e.t] && e.cap > e.fl) {
      int pushed = dfs(e.t, min(htp, e.rc()));
      if (pushed) {
        e.fl += pushed;
        E[fo[vr][pos[vr]] ^ 1].fl -= pushed;
        return pushed;
      }
    }
  }
  return 0;
}
int max_flow() {
  int FLOW = 0, how;
  while (bfs()) {
    memset(pos, 0, N * sizeof(int));
    while (how = dfs(F)) FLOW += how;
  }
  return FLOW;
}
void say_no() {
  puts("Impossible");
  exit(0);
}
bool is_pr[20010];
int n, a[210];
vector<int> L, R;
vector<int> go[210];
bool ban[210];
vector<vector<int> > cyc;
void cycle(int vr) {
  ban[vr] = true;
  cyc.back().push_back(vr);
  for (int i = 0; i < ((int)(go[vr]).size()); ++i)
    if (!ban[go[vr][i]]) cycle(go[vr][i]);
}
int main() {
  fill(is_pr, is_pr + 20010, true);
  for (int i = 2; i < 20010; ++i)
    if (is_pr[i])
      for (int j = i + i; j < 20010; j += i) is_pr[j] = false;
  scanf("%d", &n);
  for (int i = 0; i < n; ++i) {
    scanf("%d", &a[i]);
    if (a[i] & 1)
      L.push_back(i);
    else
      R.push_back(i);
  }
  if (L.empty() || R.empty()) say_no();
  N = n + 2, F = N - 2, T = N - 1;
  for (int i = 0; i < ((int)(L).size()); ++i)
    for (int j = 0; j < ((int)(R).size()); ++j)
      if (is_pr[a[L[i]] + a[R[j]]]) add_edge(L[i], R[j], 1);
  for (int i = 0; i < ((int)(L).size()); ++i) add_edge(F, L[i], 2);
  for (int j = 0; j < ((int)(R).size()); ++j) add_edge(R[j], T, 2);
  if (max_flow() != 2 * max(((int)(L).size()), ((int)(R).size()))) say_no();
  for (int i = 0; i < ((int)(E).size()); ++i)
    if (E[i].fl > 0 && E[i].f != F && E[i].t != T)
      go[E[i].f].push_back(E[i].t), go[E[i].t].push_back(E[i].f);
  for (int i = 0; i < n; ++i)
    if (!ban[i]) cyc.push_back(vector<int>()), cycle(i);
  printf("%d\n", ((int)(cyc).size()));
  for (int i = 0; i < ((int)(cyc).size()); ++i) {
    printf("%d", ((int)(cyc[i]).size()));
    for (int j = 0; j < ((int)(cyc[i]).size()); ++j)
      printf(" %d", cyc[i][j] + 1);
    puts("");
  }
  return 0;
}