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>
const double EPS = 1e-4;
const long long int MOD = 1000000007ll;
const long long int HASHMOD[2] = {1000000009ll, 1100000009ll};
const double PI = 3.14159265359;
int INF = 2147483645;
long long int INFINF = 9223372036854775807;
template <class T>
T Max2(T a, T b) {
  return a < b ? b : a;
}
template <class T>
T Min2(T a, T b) {
  return a < b ? a : b;
}
template <class T>
T Max3(T a, T b, T c) {
  return Max2(Max2(a, b), c);
}
template <class T>
T Min3(T a, T b, T c) {
  return Min2(Min2(a, b), c);
}
template <class T>
T Max4(T a, T b, T c, T d) {
  return Max2(Max2(a, b), Max2(c, d));
}
template <class T>
T Min4(T a, T b, T c, T d) {
  return Min2(Min2(a, b), Min2(c, d));
}
using namespace std;
long long int bit_count(long long int _x) {
  long long int _ret = 0;
  while (_x) {
    if (_x % 2 == 1) _ret++;
    _x /= 2;
  }
  return _ret;
}
long long int bit(long long int _mask, long long int _i) {
  return (_mask & (1 << _i)) == 0 ? 0 : 1;
}
long long int powermod(long long int _a, long long int _b, long long int _m) {
  long long int _r = 1;
  while (_b) {
    if (_b % 2 == 1) _r = (_r * _a) % _m;
    _b /= 2;
    _a = (_a * _a) % _m;
  }
  return _r;
}
class MaximumFlow {
  int s, f;

 public:
  struct edge {
    int u, v;
    long long int capacity, flow;
    edge() { u = v = capacity = flow = 0; }
    edge(int u_, int v_, long long int capacity_, long long int flow_)
        : u(u_), v(v_), capacity(capacity_), flow(flow_) {}
  };
  vector<edge> edges;
  vector<vector<int> > graph;
  vector<int> ptr, level;
  queue<int> q;
  int n;
  MaximumFlow() {}
  MaximumFlow(int number) {
    n = number;
    graph.resize(n);
    ptr.assign(n, 0);
    level.resize(n);
  }
  void addEdge(int u, int v, long long int capacity) {
    int sz = (int)(edges.size());
    edges.push_back(edge(u, v, capacity, 0));
    edges.push_back(edge(v, u, 0, 0));
    graph[u].push_back(sz);
    graph[v].push_back(sz + 1);
  }
  void updateLevels() {
    level.assign(n, -1);
    q.push(s);
    level[s] = 0;
    while (!q.empty()) {
      int topq = q.front();
      q.pop();
      for (int index = 0; index < graph[topq].size(); ++index) {
        int i = graph[topq][index];
        int to = edges[i].v;
        if (edges[i].capacity - edges[i].flow == 0) continue;
        if (level[to] == -1) {
          level[to] = level[topq] + 1;
          q.push(to);
        }
      }
    }
  }
  long long int pushFlow(int v, long long int flow) {
    if (v == f || flow == 0) return flow;
    for (; ptr[v] < graph[v].size(); ++ptr[v]) {
      int index = graph[v][ptr[v]];
      int to = edges[index].v;
      if (level[v] + 1 == level[to]) {
        int pushed =
            pushFlow(to, min(flow, edges[index].capacity - edges[index].flow));
        if (pushed > 0) {
          edges[index].flow += pushed;
          edges[index ^ 1].flow -= pushed;
          return pushed;
        }
      }
    }
    return 0;
  }
  long long int dinicFlow(int start, int finish) {
    s = start, f = finish;
    long long int result = 0;
    while (true) {
      updateLevels();
      if (level[f] == -1) break;
      while (true) {
        long long int pushed = pushFlow(start, INF);
        if (pushed == 0) break;
        result += pushed;
      }
      ptr.assign(n, 0);
    }
    return result;
  }
};
int n;
int a[210];
bool isp[20010];
vector<int> G[210];
vector<vector<int> > ans;
bool vis[210];
vector<int> temp;
void dfs(int u) {
  vis[u] = true;
  temp.push_back(u);
  for (int v : G[u])
    if (!vis[v]) dfs(v);
}
int main() {
  srand(time(NULL));
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
  for (int i = 2; i <= 20000; i++) isp[i] = true;
  for (int i = 2; i <= 20000; i++)
    if (isp[i])
      for (int j = i + i; j <= 20000; j += i) isp[j] = false;
  MaximumFlow mf(n + 4);
  for (int i = 1; i <= n; i++)
    if (a[i] % 2 == 1) mf.addEdge(n + 1, i, 2);
  for (int i = 1; i <= n; i++)
    if (a[i] % 2 == 0) mf.addEdge(i, n + 2, 2);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
      if (a[i] % 2 == 1 && a[j] % 2 == 0 && isp[a[i] + a[j]])
        mf.addEdge(i, j, 1);
  int flow = mf.dinicFlow(n + 1, n + 2);
  if (flow != n) {
    printf("Impossible");
    return 0;
  } else {
    for (int i = 1; i <= n; i++)
      for (int j = 0; j < mf.graph[i].size(); j++) {
        int idx = mf.graph[i][j];
        if (mf.edges[idx].flow == 1 && mf.edges[idx].v <= n)
          G[i].push_back(mf.edges[idx].v), G[mf.edges[idx].v].push_back(i);
      }
  }
  for (int i = 1; i <= n; i++)
    if (!vis[i]) {
      temp.clear();
      dfs(i);
      ans.push_back(temp);
    }
  printf("%d\n", ans.size());
  for (auto t : ans) {
    printf("%d ", t.size());
    for (int t1 : t) printf("%d ", t1);
    printf("\n");
  }
  return 0;
}