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.
#include <bits/stdc++.h>
using namespace std;
int n;
int a[1 << 20];
const int N = 100500;
const int M = 256;
const long long INF = 1LL << 50;
bool prime[N];
const int MAXN = 505;
int nodes, src, dst;
int dist[MAXN], q[MAXN], work[MAXN];
struct edge {
  int to, rev;
  long long f, cap;
};
vector<edge> g[MAXN];
void add_edge(int s, int t, long long cap) {
  g[s].push_back((edge){t, ((int)(g[t]).size()), 0, cap});
  g[t].push_back((edge){s, ((int)(g[s]).size()) - 1, 0, 0});
}
bool dinic_bfs() {
  fill(dist, dist + nodes, -1);
  dist[src] = 0;
  int qt = 0;
  q[qt++] = src;
  for (int qh = 0; qh < qt; qh++) {
    int u = q[qh];
    for (int i = 0, ThxDem = ((int)(g[u]).size()); i < ThxDem; ++i) {
      edge &e = g[u][i];
      int v = g[u][i].to;
      if (dist[v] < 0 && e.f < e.cap) dist[v] = dist[u] + 1, q[qt++] = v;
    }
  }
  return dist[dst] >= 0;
}
long long dinic_dfs(int u, long long f) {
  if (u == dst) return f;
  for (int &i = work[u]; i < ((int)(g[u]).size()); i++) {
    edge &e = g[u][i];
    if (e.cap <= e.f) continue;
    int v = e.to;
    if (dist[v] == dist[u] + 1) {
      long long df = dinic_dfs(v, min(f, e.cap - e.f));
      if (df > 0) {
        e.f += df;
        g[v][e.rev].f -= df;
        return df;
      }
    }
  }
  return 0;
}
long long max_flow(int _src, int _dst) {
  src = _src;
  dst = _dst;
  long long result = 0;
  while (dinic_bfs()) {
    fill(work, work + nodes, 0);
    while (long long delta = dinic_dfs(src, INF)) result += delta;
  }
  return result;
}
bool w[MAXN][MAXN];
bool vis[MAXN];
vector<int> ans[MAXN];
int pos;
void doit(int x) {
  if (vis[x]) return;
  ans[pos].push_back(x + 1);
  vis[x] = 1;
  for (int i = 0, ThxDem = MAXN; i < ThxDem; ++i)
    if (w[x][i]) doit(i);
}
int main() {
  for (int i = 2, ThxDem = N; i < ThxDem; ++i) {
    if (prime[i]) continue;
    for (int j = i + i; j < N; j += i) prime[j] = 1;
  }
  cin >> n;
  nodes = n;
  for (int i = 0, ThxDem = n; i < ThxDem; ++i) cin >> a[i];
  for (int i = 0, ThxDem = n; i < ThxDem; ++i)
    for (int j = 0, ThxDem = n; j < ThxDem; ++j)
      if (a[i] & 1 && prime[a[i] + a[j]] == 0) add_edge(i, j, 1);
  for (int i = 0, ThxDem = n; i < ThxDem; ++i)
    if (a[i] & 1)
      add_edge(nodes, i, 2);
    else
      add_edge(i, nodes + 1, 2);
  nodes += 2;
  long long f = max_flow(nodes - 2, nodes - 1);
  if (f == 0 && f != n) {
    cout << "Impossible\n";
  } else {
    int x = 0;
    for (int i = 0, ThxDem = n; i < ThxDem; ++i)
      if (a[i] & 1) {
        for (auto e : g[i]) {
          if (e.to < n && e.f) {
            x = i;
            w[i][e.to] = 1;
            w[e.to][i] = 1;
          }
        }
      }
    long long dd = 0, nn = 0;
    for (auto e : g[n])
      if (e.f && !vis[e.to]) {
        if (e.f == 1) dd = 1;
        doit(e.to);
        dd |= ((int)(ans[pos]).size()) % 2;
        for (int i = 0, ThxDem = ((int)(ans[pos]).size()); i < ThxDem; ++i)
          dd |= prime[a[ans[pos][i] - 1] +
                      a[(ans[pos][(i + 1) % ((int)(ans[pos]).size())] - 1)]];
        nn += ((int)(ans[pos]).size());
        pos++;
      }
    if (dd || nn != n) {
      cout << "Impossible\n";
      return 0;
    }
    cout << pos << "\n";
    for (int i = 0, ThxDem = pos; i < ThxDem; ++i) {
      cout << ((int)(ans[i]).size());
      for (int x : ans[i]) cout << " " << x;
      cout << "\n";
    }
  }
}
