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;
int src, sink, nums[205], n, cnt;
bool sieve[2 * 10005];
int flow[205][205], cap[205][205];
int p[205];
bool vis[205];
int last[205];
struct E {
  int from, to, prev, cap, flow;
};
E Edges[40404];
queue<int> Q;
vector<vector<int> > ANS;
void input() {
  int i, j;
  scanf("%d", &n);
  for (i = 1; i <= n; i++) scanf("%d", &nums[i]);
}
void Sieve() {
  int i, j;
  for (i = 2; i <= 2 * 10000; i++) sieve[i] = true;
  for (i = 2; i < 141; i++) {
    if (sieve[i]) {
      for (j = i * i; j <= 20000; j += i) sieve[j] = false;
    }
  }
}
void addEdge(int u, int v, int cap) {
  Edges[cnt].from = u;
  Edges[cnt].to = v;
  Edges[cnt].prev = last[u];
  Edges[cnt].cap = cap;
  Edges[cnt].flow = 0;
  last[u] = cnt;
  cnt++;
  Edges[cnt].from = v;
  Edges[cnt].to = u;
  Edges[cnt].prev = last[v];
  Edges[cnt].cap = 0;
  Edges[cnt].flow = 0;
  last[v] = cnt;
  cnt++;
}
void build() {
  int i, j;
  src = 0;
  sink = n + 1;
  memset(last, -1, sizeof(last));
  cnt = 0;
  for (i = 1; i <= n; i++) {
    if (nums[i] % 2)
      addEdge(src, i, 2);
    else
      addEdge(i, sink, 2);
  }
  for (i = 1; i <= n; i++) {
    if (nums[i] % 2 == 0) continue;
    for (j = 1; j <= n; j++) {
      if (nums[j] % 2 == 0 && sieve[nums[i] + nums[j]]) addEdge(i, j, 1);
    }
  }
}
bool BFS() {
  int u, v, i, e;
  while (!Q.empty()) Q.pop();
  memset(vis, false, sizeof(vis));
  memset(p, -1, sizeof(p));
  Q.push(src);
  vis[src] = true;
  while (!Q.empty()) {
    u = Q.front();
    Q.pop();
    for (e = last[u]; e != -1; e = Edges[e].prev) {
      v = Edges[e].to;
      if (!vis[v] && Edges[e].cap - Edges[e].flow > 0) {
        vis[v] = true;
        Q.push(v);
        p[v] = e;
      }
    }
  }
  return vis[sink];
}
int Max_Flow() {
  int u, v, inc, mx = 0;
  while (BFS()) {
    inc = (1 << 28);
    for (v = sink; p[v] != -1; v = Edges[p[v]].from) {
      inc = min(inc, Edges[p[v]].cap - Edges[p[v]].flow);
    }
    for (v = sink; p[v] != -1; v = Edges[p[v]].from) {
      Edges[p[v]].flow += inc;
      Edges[p[v] ^ 1].flow -= inc;
    }
    mx += inc;
  }
  return mx;
}
int main() {
  int i, j, ret, e, u;
  input();
  Sieve();
  build();
  ret = Max_Flow();
  if (ret != n)
    printf("Impossible\n");
  else {
    memset(vis, 0, sizeof(vis));
    ANS.clear();
    vector<int> tmp;
    bool first;
    vector<int> N;
    for (i = 1; i <= n; i++) {
      if (nums[i] % 2 && !vis[i]) {
        tmp.clear();
        first = true;
        u = i;
        while (1) {
          N.clear();
          for (e = last[u]; e != -1; e = Edges[e].prev) {
            if (Edges[e].to == src || Edges[e].to == sink) continue;
            if (nums[u] % 2 == 1 && Edges[e].cap - Edges[e].flow == 0) {
              N.push_back(Edges[e].to);
            } else if (nums[u] % 2 == 0 && Edges[e].cap - Edges[e].flow == 1) {
              N.push_back(Edges[e].to);
            }
          }
          if (first) {
            vis[u] = vis[N[0]] = vis[N[1]] = true;
            tmp.push_back(N[0]);
            tmp.push_back(u);
            tmp.push_back(N[1]);
            u = N[1];
            first = false;
            continue;
          } else {
            if (vis[N[0]] && vis[N[1]]) {
              ANS.push_back(tmp);
              break;
            } else {
              if (!vis[N[0]])
                u = N[0];
              else
                u = N[1];
              tmp.push_back(u);
              vis[u] = true;
            }
          }
        }
      }
    }
    printf("%d\n", ANS.size());
    for (i = 0; i < ANS.size(); i++) {
      printf("%d", ANS[i].size());
      for (j = 0; j < ANS[i].size(); j++) printf(" %d", ANS[i][j]);
      printf("\n");
    }
  }
  return 0;
}