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;
bool is_prime(int n) {
  if (n == 1) return false;
  if (n == 2) return true;
  for (int x = 2; x * x <= n; ++x) {
    if ((n % x) == 0) return false;
  }
  return true;
}
struct edge {
  int b;
  int cap, f;
  int rev_id;
};
vector<edge> E[208];
int vis[208], depth[208];
bool bfs_aug(int s, int t, const int& iter) {
  queue<int> Q;
  Q.push(s);
  vis[s] = iter;
  depth[s] = 0;
  int i, j, numE;
  while (!Q.empty()) {
    i = Q.front();
    Q.pop();
    if (i == t) return true;
    numE = E[i].size();
    for (int x = 0; x < (numE); ++x)
      if (j = E[i][x].b, vis[j] < iter && E[i][x].cap > E[i][x].f)
        vis[j] = iter, depth[j] = depth[i] + 1, Q.push(j);
  }
  return false;
}
int dfs_aug(int i, int t, int res) {
  if (i == t) return res;
  int numE = E[i].size();
  int sum = 0, v = 0;
  for (int x = 0; x < (numE); ++x) {
    int j = E[i][x].b, r = E[i][x].rev_id;
    int c = min(E[i][x].cap - E[i][x].f, res);
    if (c > 0 && depth[j] == depth[i] + 1 && (v = dfs_aug(j, t, c)) > 0)
      E[i][x].f += v, E[j][r].f -= v, res -= v, sum += v;
  }
  assert(res >= 0);
  return sum;
}
int dinics(int s, int t) {
  int ans = 0;
  memset(vis, 0, sizeof(vis));
  for (int phase = 1; bfs_aug(s, t, phase) > 0; ++phase)
    ans += dfs_aug(s, t, 1000000000);
  return ans;
}
void clear_flow() {
  for (int i = 0; i < (208); ++i)
    for (int x = 0; x < ((int)E[i].size()); ++x) E[i][x].f = 0;
}
void add_edge(int a, int b, int c) {
  edge x = {b, c, 0, (int)E[b].size()};
  edge y = {a, 0, 0, (int)E[a].size()};
  E[a].push_back(x);
  E[b].push_back(y);
}
int A[208];
vector<int> D[208];
bool z[208];
void solve(int i, vector<int>& ret) {
  while (!z[i]) {
    z[i] = true;
    ret.push_back(i);
    assert(D[i].size() == 2);
    if (z[D[i][0]] && z[D[i][1]]) return;
    if (z[D[i][0]])
      i = D[i][1];
    else
      i = D[i][0];
  }
}
int main() {
  int N;
  scanf("%d", &N);
  for (int i = 0; i < (N); ++i) scanf("%d", &A[i]);
  for (int i = 0; i < (N); ++i) {
    if (A[i] % 2)
      add_edge((208 - 1), i, 2);
    else
      add_edge(i, (208 - 2), 2);
  }
  for (int i = 0; i < (N); ++i) {
    if ((A[i] % 2) == 0) continue;
    for (int j = 0; j < (N); ++j) {
      if (is_prime(A[i] + A[j])) {
        add_edge(i, j, 1);
      }
    }
  }
  int ans = dinics((208 - 1), (208 - 2));
  if (ans < N)
    printf("Impossible\n");
  else {
    assert(ans == N);
    for (int i = 0; i < (N); ++i) {
      if ((A[i] % 2) == 0) continue;
      int numE = E[i].size();
      for (int x = 0; x < (numE); ++x) {
        if (E[i][x].f > 0 && E[i][x].b != (208 - 1) && E[i][x].b != (208 - 2)) {
          int j = E[i][x].b;
          D[i].push_back(j);
          D[j].push_back(i);
        }
      }
    }
    vector<vector<int> > ans;
    vector<int> tmp;
    for (int i = 0; i < (N); ++i) {
      if (z[i]) continue;
      tmp.clear();
      solve(i, tmp);
      ans.push_back(tmp);
    }
    int Z = ans.size();
    printf("%d\n", Z);
    for (int i = 0; i < (Z); ++i) {
      int X = ans[i].size();
      printf("%d", X);
      for (int j = 0; j < (X); ++j) printf(" %d", ans[i][j] + 1);
      printf("\n");
    }
  }
}