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;
long long power(long long x, long long y, long long mod) {
  if (y < 0) return power(power(x, mod - 2, mod), -y, mod);
  long long res = 1;
  for (; y; y >>= 1, x = x * x % mod)
    if (y & 1) res = res * x % mod;
  return res;
}
const int ne = 300010, inf = 1 << 30;
const int MAX = 30000;
const int nn = 1100;
int mg[nn][nn], a[nn], v[MAX + 10];
int N, cnt;
vector<int> res[nn];
struct MAXFLOW {
  int S, T, es, flow, n;
  int g[ne], other[ne], next[ne], va[ne], vh[ne], di[ne], dis[ne], his[ne],
      pre[ne], v[ne];
  void insert(int x, int y, int z) {
    other[++es] = y;
    next[es] = g[x];
    g[x] = es;
    va[es] = z;
    other[++es] = x;
    next[es] = g[y];
    g[y] = es;
    va[es] = 0;
  }
  void init(int _S, int _T, int _n) {
    es = 1;
    flow = 0;
    S = _S;
    T = _T;
    n = _n;
    for (int i = 0; i <= _n + 10; ++i) g[i] = vh[i] = v[i] = dis[i] = 0;
  }
  void sap() {
    int aug = inf;
    for (int i = 0; i <= n; ++i) di[i] = g[i];
    vh[0] = n;
    int i = S;
    while (dis[S] < n) {
      his[i] = aug;
      int flag = 0;
      for (int p = di[i]; p; p = next[p]) {
        int j = other[p];
        if (va[p] > 0 && dis[i] == dis[j] + 1) {
          flag = 1;
          di[i] = p;
          pre[j] = p;
          aug = min(aug, va[p]);
          i = j;
          if (i == T) {
            flow += aug;
            while (i != S) {
              va[pre[i]] -= aug;
              va[pre[i] ^ 1] += aug;
              i = other[pre[i] ^ 1];
            }
            aug = inf;
          }
          break;
        }
      }
      if (flag) continue;
      int min = n - 1, j1;
      for (int p = g[i]; p; p = next[p])
        if (va[p] > 0 && dis[other[p]] < min) min = dis[other[p]], j1 = p;
      if (--vh[dis[i]] == 0) break;
      dis[i] = min + 1;
      ++vh[dis[i]];
      di[i] = j1;
      if (i != S) {
        i = other[pre[i] ^ 1];
        aug = his[i];
      }
    }
  }
  void bfs(int s) {
    queue<int> Q;
    Q.push(s);
    v[s] = 1;
    while (Q.size()) {
      int x = Q.front();
      Q.pop();
      for (int p = g[x]; p; p = next[p]) {
        int j = other[p];
        if (va[p] <= 0 || v[j]) continue;
        v[j] = 1;
        Q.push(j);
      }
    }
  }
  void work() {
    for (int i = 1; i <= N; ++i)
      if (a[i] % 2 == 1) {
        for (int p = g[i]; p; p = next[p]) {
          int j = other[p];
          if (va[p] == 0) {
            mg[i][j] = mg[j][i] = 1;
          }
        }
      }
  }
} T;
void init() {
  v[1] = 1;
  for (int i = 2; i <= MAX; ++i) {
    if (v[i]) continue;
    for (int j = i; j <= MAX / i; ++j) v[i * j] = 1;
  }
}
void dfs(int x, vector<int> &a) {
  if (v[x]) return;
  v[x] = 1;
  a.push_back(x);
  for (int i = 1; i <= N; ++i)
    if (mg[x][i]) {
      mg[x][i] = mg[i][x] = 0;
      dfs(i, a);
      return;
    }
}
int main() {
  init();
  scanf("%d", &N);
  T.init(0, N + 1, N + 2);
  for (int i = 1; i <= N; ++i) {
    scanf("%d", &a[i]);
  }
  int n0 = 0, n1 = 0;
  for (int i = 1; i <= N; ++i) {
    if (a[i] % 2 == 0) {
      n0++;
      T.insert(i, N + 1, 2);
    } else {
      n1++;
      T.insert(0, i, 2);
    }
    for (int j = 1; j <= N; ++j) {
      if (!v[a[i] + a[j]]) {
        if (a[i] % 2 == 1) T.insert(i, j, 1);
      }
    }
  }
  T.sap();
  if (n0 != n1 || T.flow != 2 * n0) {
    return puts("Impossible"), 0;
  }
  T.work();
  memset(v, 0, sizeof(v));
  int cnt = 0;
  for (int i = 1; i <= N; ++i) {
    dfs(i, res[cnt]);
    if (res[cnt].size()) cnt++;
  }
  printf("%d\n", cnt);
  for (int i = 0; i < cnt; ++i) {
    printf("%d", res[i].size());
    for (int j = 0; j < res[i].size(); ++j) {
      printf(" %d", res[i][j]);
    }
    puts("");
  }
}