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;
inline char gc() {
  static char buf[100000], *p1 = buf, *p2 = buf;
  return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
             ? EOF
             : *p1++;
}
inline long long read() {
  long long x = 0;
  char ch = getchar();
  bool positive = 1;
  for (; !isdigit(ch); ch = getchar())
    if (ch == '-') positive = 0;
  for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
  return positive ? x : -x;
}
inline void write(long long a) {
  if (a < 0) {
    a = -a;
    putchar('-');
  }
  if (a >= 10) write(a / 10);
  putchar('0' + a % 10);
}
inline void writeln(long long a) {
  write(a);
  puts("");
}
inline void wri(long long a) {
  write(a);
  putchar(' ');
}
inline unsigned long long rnd() {
  return ((unsigned long long)rand() << 30 ^ rand()) << 4 | rand() % 4;
}
const int N = 205, M = 20005, inf = 1e9, P = M;
int di[M], nxt[M], ed[M];
int son[N], nedge, cur[N], deep[N];
inline void aedge(int a, int b, int c) {
  nxt[++nedge] = son[a];
  son[a] = nedge;
  ed[nedge] = b;
  di[nedge] = c;
}
inline void insert(int a, int b, int c) {
  aedge(a, b, c);
  aedge(b, a, 0);
}
inline bool bfs(int s, int t) {
  for (int i = 0; i < N; i++) deep[i] = inf;
  for (int i = 0; i < N; i++) cur[i] = son[i];
  deep[s] = 0;
  queue<int> q;
  q.push(s);
  while (!q.empty()) {
    int now = q.front();
    q.pop();
    for (int tmp = son[now]; tmp; tmp = nxt[tmp])
      if (deep[ed[tmp]] >= inf && di[tmp]) {
        deep[ed[tmp]] = deep[now] + 1, q.push(ed[tmp]);
      }
  }
  return deep[t] < inf;
}
int dfs(int now, int t, int limit) {
  if (!limit || now == t) return limit;
  int flow = 0, f;
  for (int tmp = cur[now]; tmp; tmp = nxt[tmp]) {
    cur[now] = tmp;
    if (deep[ed[tmp]] == deep[now] + 1 &&
        (f = dfs(ed[tmp], t, min(limit, di[tmp])))) {
      flow += f;
      limit -= f;
      di[tmp] -= f;
      di[((tmp - 1) ^ 1) + 1] += f;
      if (!limit) break;
    }
  }
  return flow;
}
inline int dinic(int s, int t) {
  int ans = 0;
  while (bfs(s, t)) ans += dfs(s, t, inf);
  return ans;
}
bool vis[N], heshu[P];
int a[N];
vector<int> v[N];
void GG() {
  puts("Impossible");
  exit(0);
}
int main() {
  for (int i = (int)(2); i <= (int)(P - 1); i++)
    if (!heshu[i]) {
      for (int j = i + i; j < P; j += i) heshu[j] = 1;
    }
  int n = read(), s = n + 1, t = n + 2;
  if (n & 1) GG();
  for (int i = (int)(1); i <= (int)(n); i++) a[i] = read();
  for (int i = (int)(1); i <= (int)(n); i++) {
    if (a[i] % 2 == 1) {
      insert(s, i, 2);
      for (int j = (int)(1); j <= (int)(n); j++)
        if (!heshu[a[i] + a[j]]) {
          insert(i, j, 1);
        }
    } else
      insert(i, t, 2);
  }
  if (dinic(s, t) != n) GG();
  for (int i = (int)(1); i <= (int)(n); i++)
    if (a[i] & 1)
      for (int j = son[i]; j; j = nxt[j])
        if (ed[j] != s && di[j] == 0) {
          v[i].push_back(ed[j]);
          v[ed[j]].push_back(i);
        }
  vector<vector<int> > an;
  for (int i = (int)(1); i <= (int)(n); i++)
    if (!vis[i]) {
      vector<int> zs;
      for (int j = i; !vis[j]; j = vis[v[j][0]] ? v[j][1] : v[j][0]) {
        vis[j] = 1;
        zs.push_back(j);
      }
      an.push_back(zs);
    }
  writeln(an.size());
  for (auto i : an) {
    wri(i.size());
    for (auto j : i) wri(j);
    puts("");
  }
}