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 i, j, n, m;
int p[1000];
int noprime[20010];
int q[20010], t;
struct Graph {
  int n, et, ind[5011], e[61000], last[61000];
  bool checked[5011];
  vector<vector<int>> blocks;
  int nowcolor;
  inline void adde(int a, int b) {
    last[++et] = ind[a];
    e[et] = b;
    ind[a] = et;
  }
  inline void init(int nn) {
    n = nn, et = 1;
    memset(ind, 0, sizeof(int) * (n + 1));
  }
  void dfs(int a) {
    checked[a] = true;
    int i;
    blocks[nowcolor].push_back(a);
    for (i = ind[a]; i; i = last[i])
      if (!checked[e[i]]) {
        dfs(e[i]);
      }
  }
  void colorit() {
    int i;
    for (i = 1; i <= n; i++)
      if (!checked[i]) {
        blocks.push_back({});
        dfs(i);
        nowcolor++;
      }
  }
};
struct FlowGraph : public Graph {
  int S, T;
  long long int cap[61000], f[61000];
  inline void adde(int a, int b, long long int c) {
    Graph::adde(a, b);
    f[et] = 0, cap[et] = c;
  }
  inline void addee(int a, int b, long long int c) {
    adde(a, b, c), adde(b, a, c);
  }
  inline void init(int nn, int s, int t) {
    Graph::init(nn);
    S = s, T = t;
  }
};
struct ResiGraph : public FlowGraph {
  int ek[61000];
  bool checked[5011];
  void adde(int a, int b, long long int c, int k) {
    FlowGraph::adde(a, b, c);
    ek[et] = k;
  }
  long long int dfs(int a, long long int flow) {
    if (flow == 0) {
      return 0;
    }
    if (a == T) return flow;
    long long int ans = 0, now;
    for (int i = ind[a]; i; i = last[i])
      if (!checked[e[i]] && cap[i] - f[i]) {
        now = dfs(e[i], std::min(flow, cap[i] - f[i]));
        ans += now, f[i] += now, flow -= now;
      }
    if (flow) checked[a] = true;
    return ans;
  }
  long long int blocking_flow() {
    long long int upper_bound = 0;
    memset(checked, 0, sizeof(bool) * (n + 1));
    for (int i = ind[S]; i; i = last[i]) {
      upper_bound += cap[i];
    }
    return dfs(S, upper_bound);
  }
};
struct DinicGraph : public FlowGraph {
  ResiGraph resi;
  int que[5011], nowqt, qt, checked[5011];
  long long int cf() {
    resi.init(n, S, T);
    memset(checked, 0, sizeof(int) * (n + 1));
    qt = nowqt = 1;
    que[1] = S;
    checked[S] = 1;
    for (int i = 1, j = 0, nowlv = 2; i <= qt; i++) {
      if (i > nowqt) {
        nowlv++, nowqt = qt;
        if (checked[T]) {
          break;
        }
      }
      for (j = ind[que[i]]; j; j = last[j])
        if ((!checked[e[j]] || checked[e[j]] == nowlv) && f[j] < cap[j]) {
          if ((j & 1) && f[j ^ 1]) {
            resi.adde(que[i], e[j], f[j ^ 1], j);
            if (!checked[e[j]]) {
              que[++qt] = e[j];
              checked[e[j]] = nowlv;
            }
          } else if (!(j & 1)) {
            resi.adde(que[i], e[j], cap[j] - f[j], j);
            if (!checked[e[j]]) {
              que[++qt] = e[j];
              checked[e[j]] = nowlv;
            }
          }
        }
    }
    long long int incr = resi.blocking_flow();
    if (incr == 0) {
      return 0;
    }
    for (int i = 1, j, k; i <= n; i++) {
      for (j = resi.ind[i]; j; j = resi.last[j])
        if (resi.f[j]) {
          k = resi.ek[j];
          if (f[k ^ 1]) {
            f[k ^ 1] -= resi.f[j];
          } else {
            f[k] += resi.f[j];
          }
        }
    }
    return incr;
  }
  long long int maxflow() {
    long long int ans = 0, now = cf();
    while (now) {
      ans += now;
      now = cf();
    }
    return ans;
  }
} G;
void prepare() {
  int i, j;
  for (i = 2; i < 20010; i++) {
    if (!noprime[i]) {
      q[++t] = i;
      noprime[i] = i;
    }
    for (j = 1; j <= t; j++) {
      if (double(q[j]) * i + 1e-9 < 20010) {
        noprime[q[j] * i] = q[j];
      } else {
        break;
      }
      if (i % q[j] == 0) break;
    }
  }
}
Graph gg;
int main() {
  prepare();
  scanf("%d", &n);
  for (i = 1; i <= n; i++) {
    scanf("%d", &p[i]);
  }
  if (n & 1) {
    printf("Impossible\n");
    return 0;
  }
  int S = n + 1, T = n + 2;
  G.init(T, S, T);
  for (i = 1; i <= n; i++)
    if (p[i] & 1) {
      G.addee(S, i, 2);
      for (j = 1; j <= n; j++) {
        if (noprime[p[i] + p[j]] == p[i] + p[j]) {
          G.addee(i, j, 1);
        }
      }
    } else {
      G.addee(i, T, 2);
    }
  int ans = G.maxflow();
  if (ans != n) {
    printf("Impossible\n");
    return 0;
  }
  gg.init(n);
  for (i = 1; i <= n; i++) {
    for (j = G.ind[i]; j; j = G.last[j])
      if (!(j & 1) && G.f[j] && G.e[j] <= n) {
        gg.adde(i, G.e[j]);
        gg.adde(G.e[j], i);
      }
  }
  gg.colorit();
  printf("%d\n", gg.nowcolor);
  for (i = 0; i < gg.nowcolor; i++) {
    printf("%d", (int)gg.blocks[i].size());
    for (auto jj : gg.blocks[i]) {
      printf(" %d", jj);
    }
    printf("\n");
  }
  return 0;
}