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>
void setmax(T &a, T b) {
  if (b > a) a = b;
}
template <class T>
void setmin(T &a, T b) {
  if (b < a) a = b;
}
template <class T>
T gcd(T a, T b) {
  return b == 0 ? a : gcd(b, a % b);
}
const int INFI = 1 << 30;
template <size_t N, size_t E, class T>
class Dinic {
  struct Edge {
    int y;
    T w;
    Edge *next, *oppo;
  } edges[E * 2];
  Edge *g[N], *ce[N];
  int e_cnt, n, src, dst;
  int d[N], q[N];
  bool build() {
    memset(d, 0, sizeof(d));
    d[q[1] = src] = 1;
    for (int ss = 0, tt = 1; ss < tt;) {
      int x = q[++ss];
      for (Edge *e = ce[x] = g[x]; e; e = e->next)
        if (e->w > 0 && d[e->y] == 0) d[q[++tt] = e->y] = d[x] + 1;
    }
    return d[dst] > 0;
  }
  T find(int x, T rest) {
    if (x == dst) return rest;
    T ans = 0;
    for (Edge *&e = ce[x]; e; e = e->next)
      if (e->w > 0 && d[e->y] > d[x]) {
        T cur = find(e->y, min(e->w, rest));
        e->w -= cur;
        e->oppo->w += cur;
        ans += cur;
        rest -= cur;
        if (rest == 0) break;
      }
    return ans;
  }

 public:
  Dinic() { init(); }
  int s() { return src; }
  int t() { return dst; }
  void init() {
    memset(g, 0, sizeof(g));
    e_cnt = 0;
    n = 2, src = 1, dst = 2;
  }
  int newNode() { return ++n; }
  void addEdge(int x, int y, T w1, T w2) {
    Edge *e1 = &edges[e_cnt++], *e2 = &edges[e_cnt++];
    e1->y = y, e1->w = w1, e1->oppo = e2, e1->next = g[x], g[x] = e1;
    e2->y = x, e2->w = w2, e2->oppo = e1, e2->next = g[y], g[y] = e2;
  }
  T compute() {
    T ans = 0;
    while (build()) ans += find(src, INFI);
    return ans;
  }
  T getFlow(int x, int y) {
    for (Edge *e = g[x]; e; e = e->next)
      if (e->y == y) return e->oppo->w;
    return 0;
  }
};
const int MAXN = 222;
const int MAXE = MAXN + MAXN * MAXN;
Dinic<MAXN, MAXE, int> dinic;
int n, a[MAXN], ai[MAXN];
bool isPrime(int x) {
  for (int y = 2; y * y <= x; ++y)
    if (x % y == 0) return false;
  return true;
}
int main() {
  cin >> n;
  for (int i = int(1); i <= int(n); ++i) cin >> a[i];
  dinic.init();
  for (int i = int(1); i <= int(n); ++i) ai[i] = dinic.newNode();
  for (int i = int(1); i <= int(n); ++i)
    if (a[i] % 2 == 0) dinic.addEdge(dinic.s(), ai[i], 2, 0);
  for (int i = int(1); i <= int(n); ++i)
    if (a[i] % 2 == 1) dinic.addEdge(ai[i], dinic.t(), 2, 0);
  for (int i = int(1); i <= int(n); ++i)
    if (a[i] % 2 == 0)
      for (int j = int(1); j <= int(n); ++j)
        if (a[j] % 2 == 1)
          if (isPrime(a[i] + a[j])) dinic.addEdge(ai[i], ai[j], 1, 0);
  int flow = dinic.compute();
  if (flow != n)
    cout << "Impossible" << endl;
  else {
    vector<vector<int> > ans;
    static bool vis[MAXN];
    memset(vis, false, sizeof(vis));
    for (int cur = int(1); cur <= int(n); ++cur)
      if (!vis[cur]) {
        int i = cur, la = 0;
        vector<int> lst;
        do {
          vis[i] = true;
          lst.push_back(i);
          for (int j = int(1); j <= int(n); ++j)
            if (j != la) {
              int x = i, y = j;
              if (a[y] % 2 == 0) swap(x, y);
              if (dinic.getFlow(ai[x], ai[y]) > 0) {
                la = i;
                i = j;
                break;
              }
            }
        } while (i != cur);
        ans.push_back(lst);
      }
    cout << ans.size() << endl;
    for (int i = int(0); i <= int((ans.size()) - 1); ++i) {
      cout << ans[i].size();
      for (int j = int(0); j <= int((ans[i].size()) - 1); ++j)
        cout << " " << ans[i][j];
      cout << endl;
    }
  }
  return 0;
}