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;
const int inf = ~0U >> 1;
const long long INF = ~0ULL >> 1;
template <class T>
inline void read(T &n) {
  char c;
  for (c = getchar(); !(c >= '0' && c <= '9'); c = getchar())
    ;
  n = c - '0';
  for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) n = n * 10 + c - '0';
}
int Pow(int base, int n, int mo) {
  if (n == 0) return 1;
  if (n == 1) return base % mo;
  int tmp = Pow(base, n >> 1, mo);
  tmp = (long long)tmp * tmp % mo;
  if (n & 1) tmp = (long long)tmp * base % mo;
  return tmp;
}
struct MinCostMaxFlow {
  struct edge {
    int f, C, y;
    edge(int _y, int c) : y(_y), C(c) { f = 0; }
  };
  vector<vector<edge> > E;
  vector<vector<int> > op;
  int ans, aug, S, T;
  vector<pair<int, int> > pre;
  vector<int> vis, gap, dis, _aug, cur;
  queue<int> Q;
  void Aug() {
    ans += aug;
    for (int i = T; i != S; i = pre[i].first)
      E[pre[i].first][pre[i].second].f += aug,
          E[i][op[pre[i].first][pre[i].second]].f -= aug;
  }
  int SAP() {
    ans = 0;
    for (int i = (1); i <= (T); ++i)
      gap[i] = 0, dis[i] = T, _aug[i] = 0, cur[i] = 0;
    dis[T] = 0;
    Q.push(T);
    while (Q.size()) {
      int u = Q.front();
      Q.pop();
      for (int i = cur[u]; i < E[u].size(); ++i)
        if (!E[u][i].C && dis[u] + 1 < dis[E[u][i].y]) {
          dis[E[u][i].y] = dis[u] + 1;
          Q.push(E[u][i].y);
        }
    }
    for (int i = (1); i <= (T); ++i) gap[dis[i]]++;
    int u = S;
    aug = inf;
    while (dis[S] < T) {
      _aug[u] = aug;
      bool flag = 1;
      for (int i = cur[u]; i < E[u].size(); ++i) {
        int v = E[u][i].y;
        if (dis[v] + 1 == dis[u] && E[u][i].C - E[u][i].f > 0LL) {
          cur[u] = i;
          if (E[u][i].C - E[u][i].f < aug) aug = E[u][i].C - E[u][i].f;
          flag = 0, pre[v] = make_pair(u, i), u = v;
          if (u == T) Aug(), u = S, aug = inf;
          break;
        }
      }
      if (!flag) continue;
      if ((--gap[dis[u]]) == 0) return ans;
      dis[u] = T;
      for (int i = 0; i < E[u].size(); ++i) {
        int v = E[u][i].y;
        if (dis[v] + 1 < dis[u] && E[u][i].C - E[u][i].f > 0)
          dis[u] = dis[v] + 1, cur[u] = i;
      }
      gap[dis[u]]++;
      if (u != S) u = pre[u].first, aug = _aug[u];
    }
    return ans;
  }
  void add(int x, int y, int c) {
    E[x].push_back(edge(y, c));
    E[y].push_back(edge(x, 0));
    op[x].push_back(E[y].size() - 1);
    op[y].push_back(E[x].size() - 1);
  }
  int MaxFlow() { return SAP(); }
  void init(int N, int _S, int _T) {
    S = _S, T = _T;
    pre.resize(N), vis.resize(N), gap.resize(N), dis.resize(N), _aug.resize(N),
        cur.resize(N), E.resize(N), op.resize(N);
    for (int i = (0); i <= (N - 1); ++i) E[i].clear(), op[i].clear();
  }
} flow;
int N, a[1000], G[600][600], vis[600];
vector<vector<int> > ans;
int isprime(int x) {
  for (int i = 2; i * i <= x; ++i)
    if (x % i == 0) return 0;
  return 1;
}
int main() {
  scanf("%d", &N);
  for (int i = (1); i <= (N); ++i) scanf("%d", &a[i]);
  flow.init(500, 459, 480);
  for (int i = (1); i <= (N); ++i)
    if (a[i] & 1)
      flow.add(flow.S, i, 2);
    else
      flow.add(i, flow.T, 2);
  for (int i = (1); i <= (N); ++i)
    if (a[i] & 1)
      for (int j = (1); j <= (N); ++j)
        if (a[j] % 2 == 0 && isprime(a[i] + a[j])) flow.add(i, j, 1);
  int ret = flow.SAP();
  if (ret != N)
    puts("Impossible");
  else {
    for (int i = (1); i <= (N); ++i)
      if (a[i] & 1) {
        for (int j = (0); j < (flow.E[i].size()); ++j)
          if (flow.E[i][j].y >= 1 && flow.E[i][j].y <= N && flow.E[i][j].f)
            G[i][flow.E[i][j].y] = G[flow.E[i][j].y][i] = 1;
      }
    for (int i = (1); i <= (N); ++i)
      if (!vis[i]) {
        vector<int> tmp;
        tmp.clear();
        int j;
        for (int k = (1); k <= (N); ++k)
          if (G[i][k] == 1) j = k;
        vis[i] = 1;
        tmp.push_back(i);
        for (; j;) {
          vis[j] = 1;
          tmp.push_back(j);
          int flag = 0;
          for (int k = (1); k <= (N); ++k)
            if (G[j][k] && !vis[k]) {
              flag = 1;
              j = k;
              break;
            }
          if (!flag) break;
        }
        ans.push_back(tmp);
      }
    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]);
      puts("");
    }
  }
  return 0;
}