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;
const int INF = (int)1E9;
int N, S, T, FN;
int L, adj[205], dst[205], pre[205], pret[205];
struct llist {
  int id, next, c, f, w;
  llist() {}
  llist(int _id, int _next, int _c, int _w) {
    id = _id;
    next = _next;
    c = _c;
    f = 0;
    w = _w;
  }
} lists[2 * 100005];
void init() {
  L = 0;
  memset(adj, -1, sizeof(adj));
}
inline void insertList(int &a, int b, int c, int w) {
  lists[L] = llist(b, a, c, w);
  a = L++;
}
inline void insertEdge(int a, int b, int c, int w) {
  insertList(adj[a], b, c, w);
  insertList(adj[b], a, 0, -w);
}
bool spfa() {
  for (int i = (0); i < (FN); i++) dst[i] = INF;
  dst[S] = 0;
  queue<int> que;
  que.push(S);
  while (!que.empty()) {
    int x = que.front();
    que.pop();
    int t = adj[x];
    while (t != -1) {
      int y = lists[t].id, nw = dst[x] + lists[t].w;
      if (lists[t].c != lists[t].f && nw < dst[y]) {
        dst[y] = nw;
        pre[y] = x;
        pret[y] = t;
        que.push(y);
      }
      t = lists[t].next;
    }
  }
  return dst[T] != INF;
}
pair<int, int> sap() {
  int totw = 0, totf = 0;
  while (1) {
    bool augable = spfa();
    if (!augable) break;
    int minflow = INF, x = T;
    while (x != S) {
      int flow = lists[pret[x]].c - lists[pret[x]].f;
      minflow = min(minflow, flow);
      x = pre[x];
    }
    x = T;
    while (x != S) {
      lists[pret[x]].f += minflow;
      lists[pret[x] ^ 1].f = -lists[pret[x]].f;
      x = pre[x];
    }
    totf += minflow;
    totw += minflow * dst[T];
  }
  return make_pair(totf, totw);
}
int a[205], G;
bool v[205];
vector<int> g[205], aa[205];
void dfs(int x) {
  v[x] = 1;
  g[G].push_back(x);
  int sz = aa[x].size();
  for (int i = (0); i < (sz); i++) {
    int y = aa[x][i];
    if (!v[y]) {
      dfs(y);
    }
  }
}
int P, dvd[100005], prm[100005];
void sieve() {
  memset(dvd, -1, sizeof(dvd));
  P = 0;
  for (int i = 2; i < 100005; i++) {
    if (dvd[i] != -1) continue;
    prm[P++] = i;
    for (int j = 1; j < 100005; j++) {
      if (i * j >= 100005) break;
      dvd[i * j] = i;
    }
  }
}
int main() {
  cin >> N;
  int cntodd = 0;
  sieve();
  for (int i = (1); i < (N + 1); i++) {
    scanf("%d", a + i);
    if (a[i] % 2) cntodd++;
  }
  if (cntodd != N - cntodd) return puts("Impossible"), 0;
  S = 0;
  T = N + 1;
  FN = N + 2;
  init();
  for (int i = (1); i < (N + 1); i++) {
    for (int j = (1); j < (N + 1); j++) {
      if (a[j] % 2 != a[i] % 2 && dvd[a[i] + a[j]] == a[i] + a[j]) {
        if (a[i] % 2) {
          insertEdge(i, j, 1, -1);
        }
      }
    }
    if (a[i] % 2) {
      insertEdge(S, i, 2, 0);
    } else {
      insertEdge(i, T, 2, 0);
    }
  }
  pair<int, int> ret = sap();
  if (ret.first != N || ret.second != -N) {
    return puts("Impossible"), 0;
  }
  for (int x = (1); x < (N + 1); x++) {
    if (a[x] % 2) {
      int t = adj[x];
      while (t != -1) {
        int y = lists[t].id;
        if (lists[t].c == lists[t].f) {
          aa[x].push_back(y);
          aa[y].push_back(x);
        }
        t = lists[t].next;
      }
    }
  }
  for (int x = (1); x < (N + 1); x++) {
    if (!v[x] && a[x] % 2) {
      dfs(x);
      G++;
    }
  }
  cout << G << endl;
  for (int i = (0); i < (G); i++) {
    int sz = g[i].size();
    printf("%d", sz);
    for (int j = (0); j < (sz); j++) printf(" %d", g[i][j]);
    puts("");
  }
  return 0;
}