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.
#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline void read(T& x) {
  int f;
  char c;
  for (f = 1, c = getchar(); c < '0' || c > '9'; c = getchar())
    if (c == '-') f = -f;
  for (x = 0; c <= '9' && c >= '0'; c = getchar()) x = x * 10 + (c & 15);
  x *= f;
}
template <typename T>
inline void write(T x) {
  static char q[64];
  int cnt = 0;
  if (!x) putchar('0');
  if (x < 0) putchar('-'), x = -x;
  while (x) q[cnt++] = x % 10 + '0', x /= 10;
  while (cnt--) putchar(q[cnt]);
}
const int maxn = 205, maxm = 100005;
struct Edge {
  int v, w, nt;
  Edge(int v = 0, int w = 0, int nt = 0) : v(v), w(w), nt(nt) {}
} e[maxm];
int num = 1, hd[maxn];
void qaq(int u, int v, int w) {
  e[++num] = Edge(v, w, hd[u]);
  hd[u] = num;
}
void qwq(int u, int v, int w) {
  qaq(u, v, w);
  qaq(v, u, 0);
}
int S, T, dis[maxn], q[maxn];
int bfs(void) {
  int fro = 0, bac = 0;
  memset(dis, 0, sizeof dis);
  dis[q[bac++] = S] = 1;
  while (fro < bac) {
    int u = q[fro++];
    for (int i = hd[u]; i; i = e[i].nt) {
      int v = e[i].v, w = e[i].w;
      if (!dis[v] && w) {
        dis[q[bac++] = v] = dis[u] + 1;
      }
    }
  }
  return dis[T];
}
int cur[maxn];
int dfs(int u, int ep) {
  if (u == T) return ep;
  int re = 0;
  for (int& i = cur[u]; i; i = e[i].nt) {
    int v = e[i].v, w = e[i].w;
    if (dis[v] == dis[u] + 1 && w) {
      int tmp = dfs(v, min(ep, w));
      e[i].w -= tmp, e[i ^ 1].w += tmp;
      ep -= tmp, re += tmp;
      if (!ep) break;
    }
  }
  return re;
}
int solve(void) {
  int re = 0;
  while (bfs()) {
    memcpy(cur, hd, sizeof hd);
    re += dfs(S, 0x3f3f3f3f);
  }
  return re;
}
int vis[20005], pri[20005];
int st[maxn], tp, snt[maxn][2], cnt[maxn], fin[maxn], edge[maxn][maxn], a[maxn];
void xox(int no, int la) {
  if (fin[no]) return;
  fin[st[tp++] = no] = true;
  if (snt[no][0] == la)
    xox(snt[no][1], no);
  else
    xox(snt[no][0], no);
}
int main() {
  for (int i = 2, tot = 0; i <= 20000; ++i) {
    if (!vis[i]) pri[++tot] = i;
    for (int j = 1; j <= tot; ++j) {
      int t = i * pri[j];
      if (t > 20000) break;
      vis[t] = true;
      if (i % pri[j] == 0) break;
    }
  }
  int n;
  read(n);
  S = n + 1, T = S + 1;
  for (int i = 1; i <= n; ++i) {
    read(a[i]);
    int o = a[i] & 1;
    if (o)
      qwq(S, i, 2);
    else
      qwq(i, T, 2);
    for (int j = 1; j < i; ++j) {
      if (!vis[a[i] + a[j]]) {
        if (o)
          qwq(i, j, 1);
        else
          qwq(j, i, 1);
        edge[i][j] = num;
      }
    }
  }
  if (solve() < n)
    puts("Impossible");
  else {
    for (int i = 1; i <= n; ++i) {
      for (int j = 1; j < i; ++j) {
        if (e[edge[i][j]].w) {
          snt[i][cnt[i]++] = j;
          snt[j][cnt[j]++] = i;
        }
      }
    }
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
      if (!fin[i]) {
        tp = 0;
        xox(i, 0);
        ++ans;
      }
    }
    write(ans), putchar('\n');
    memset(fin, 0, sizeof fin);
    for (int i = 1; i <= n; ++i) {
      if (!fin[i]) {
        tp = 0;
        xox(i, 0);
        write(tp), putchar(' ');
        for (int j = 0; j < tp; ++j) write(st[j]), putchar(" \n"[j == tp - 1]);
      }
    }
  }
  return 0;
}
