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;
template <class T>
struct isap {
  isap(){};
  int cnt, u, v, e, s, t, d, N[50004], now[50004], dpth[50004], vtn[50004],
      pre[50004];
  int vt[800003], ne[800003];
  T cap[800003];
  T maxflow, tflow;
  void init(int _s, int _t, int _d) {
    s = _s;
    t = _t;
    d = _d;
    cnt = 2;
    maxflow = 0;
    memset(N, 0, sizeof(N));
  };
  void link(int u, int v, T c) {
    vt[cnt] = v;
    ne[cnt] = N[u];
    cap[cnt] = c;
    now[u] = N[u] = cnt++;
  }
  void build(int u, int v, T c) {
    link(u, v, c);
    link(v, u, 0);
  }
  T run() {
    memset(dpth, 0, sizeof(dpth));
    memset(vtn, 0, sizeof(vtn));
    vtn[0] = d;
    for (u = s; dpth[s] < d;) {
      if (u == t) {
        for (v = s, tflow = (0x3f3f3f3f); v != t;
             tflow = min(cap[now[v]], tflow), v = vt[now[v]])
          ;
        for (v = s; v != t; v = vt[now[v]]) {
          cap[now[v]] -= tflow;
          cap[now[v] ^ 1] += tflow;
        }
        u = s;
        maxflow += tflow;
      } else {
        for (e = now[u]; e; e = ne[e])
          if (cap[e] > 0 && dpth[vt[e]] + 1 == dpth[u]) break;
        if (e) {
          now[u] = e;
          pre[vt[e]] = u;
          u = vt[e];
        } else {
          if (--vtn[dpth[u]] == 0) break;
          for (e = N[u], v = d; e; e = ne[e])
            if (cap[e] > 0) v = min(v, dpth[vt[e]]);
          dpth[u] = v + 1;
          ++vtn[dpth[u]];
          now[u] = N[u];
          if (u != s) u = pre[u];
        }
      }
    }
    return maxflow;
  }
};
isap<int> flow;
bool ispri(int n) {
  for (int i = 2; i * i <= n; ++i)
    if (n % i == 0) return false;
  return true;
}
int main() {
  int n, a[50004];
  bool vis[50004];
  int od, ev;
  vector<vector<int> > ans;
  vector<int> res;
  scanf("%d", &n);
  flow.init(0, n + 1, n + 2);
  od = ev = 0;
  memset(vis, 0, sizeof(vis));
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &a[i]);
    if (a[i] & 1) {
      flow.build(flow.s, i, 2);
      ++od;
    } else {
      flow.build(i, flow.t, 2);
      ++ev;
    }
  }
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= n; ++j)
      if ((a[i] & 1) && !(a[j] & 1) && ispri(a[i] + a[j])) flow.build(i, j, 1);
  if (od == ev && flow.run() == n) {
    int v, e, te, pre;
    bool end;
    for (e = flow.N[flow.s]; e; e = flow.ne[e])
      if (!vis[flow.vt[e]]) {
        v = flow.vt[e];
        res.push_back(v);
        vis[v] = true;
        pre = 0;
        end = false;
        while (!end) {
          for (te = flow.N[v]; te; te = flow.ne[te])
            if (flow.vt[te] != pre && !flow.cap[te]) {
              res.push_back(flow.vt[te]);
              pre = v;
              v = flow.vt[te];
              break;
            }
          for (te = flow.N[v]; te; te = flow.ne[te])
            if (flow.vt[te] != pre && flow.cap[te]) {
              if (flow.vt[te] == res.front()) {
                end = true;
                break;
              }
              res.push_back(flow.vt[te]);
              pre = v;
              v = flow.vt[te];
              vis[v] = true;
              break;
            }
        }
        ans.push_back(res);
        res.clear();
      }
    printf("%d\n", ans.size());
    for (int i = 0; i < ans.size(); ++i) {
      printf("%d", ans[i].size());
      for (int j = 0; j < ans[i].size(); ++j) printf(" %d", ans[i][j]);
      printf("\n");
    }
  } else
    printf("Impossible\n");
}