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;
long long _sieve_size;
bitset<10000010> bs;
vector<int> primes;
void sieve(long long upperbound) {
  _sieve_size = upperbound + 1;
  bs.reset();
  bs.flip();
  bs.set(0, false);
  bs.set(1, false);
  for (long long i = 2; i <= _sieve_size; ++i) {
    for (long long j = i * i; j <= _sieve_size; j += i)
      bs.set((size_t)j, false);
    primes.push_back((int)i);
  }
}
bool is_prime(long long N) {
  if (N < _sieve_size) return bs.test(N);
  for (int i = 0; i < primes.size(); ++i)
    if (N % primes[i] == 0) return false;
  return true;
}
struct FlowNetwork {
  struct edge {
    int v, nxt;
    long long cap, flo;
    edge(int _v, long long _cap, int _nxt)
        : v(_v), cap(_cap), nxt(_nxt), flo(0) {}
  };
  int n, edge_count = 0, *h;
  vector<edge> e;
  FlowNetwork(int V, int E = 0) : n(V) {
    e.reserve(2 * (E == 0 ? V : E));
    memset(h = new int[V], -1, n * sizeof(int));
  }
  void add_edge(int u, int v, long long uv_cap, long long vu_cap = 0) {
    e.push_back(edge(v, uv_cap, h[u]));
    h[u] = edge_count++;
    e.push_back(edge(u, vu_cap, h[v]));
    h[v] = edge_count++;
  }
  void cleanup() { delete[] h; }
  long long edmonds_karp(int s, int t);
};
long long FlowNetwork::edmonds_karp(int s, int t) {
  int v, p[300], q[300];
  long long f = 0, c[300];
  while (true) {
    memset(p, -1, n * sizeof(int));
    int i, u = -1, l = 0, r = 0;
    c[s] = 9000000000000000;
    p[q[r++] = s] = -2;
    while (l != r && u != t) {
      for (u = q[l++], i = h[u]; i != -1; i = e[i].nxt) {
        if (e[i].cap > e[i].flo && p[v = e[i].v] == -1) {
          p[q[r++] = v] = i;
          c[v] = min(c[u], e[i].cap - e[i].flo);
        }
      }
    }
    if (p[t] == -1) break;
    for (i = p[t]; i != -2; i = p[e[i ^ 1].v]) {
      e[i].flo += c[t];
      e[i ^ 1].flo -= c[t];
    }
    f += c[t];
  }
  return f;
}
struct Fox {
 public:
  int a = -1, id = -1;
  bool odd = false;
  vector<int> nbrs;
  Fox() {}
  Fox(int a, int id) : a(a), odd(a % 2 == 1), id(id) {}
};
void dfs(int ix, vector<Fox>& mine, vector<Fox>& other, bitset<210>& vs,
         vector<vector<int> >& table) {
  vs.set(mine[ix].id, true);
  table[table.size() - 1].push_back(mine[ix].id);
  for (int nx : mine[ix].nbrs) {
    if (vs.test(other[nx].id)) continue;
    dfs(nx, other, mine, vs, table);
  }
}
int main() {
  sieve(1e5);
  int n;
  cin >> n;
  vector<Fox> oddFoxes, evenFoxes;
  for (int i = 0; i < n; ++i) {
    int a;
    cin >> a;
    if (a % 2 == 0)
      evenFoxes.push_back(Fox(a, i + 1));
    else
      oddFoxes.push_back(Fox(a, i + 1));
  }
  int evsize = evenFoxes.size(), odsize = oddFoxes.size();
  if (evsize != odsize)
    cout << "Impossible" << endl;
  else {
    int SOURCE = 0, SINK = evsize + odsize + 1;
    FlowNetwork fn(n + 2);
    for (int i = 0; i < evsize; ++i) {
      fn.add_edge(SOURCE, i + 1, 2);
    }
    for (int i = 0; i < odsize; ++i) {
      fn.add_edge(evsize + i + 1, SINK, 2);
    }
    for (int i = 0; i < evsize; ++i) {
      for (int j = 0; j < odsize; ++j) {
        if (is_prime(evenFoxes[i].a + oddFoxes[j].a)) {
          fn.add_edge(i + 1, evsize + j + 1, 1);
        }
      }
    }
    long long flow = fn.edmonds_karp(SOURCE, SINK);
    if (flow < 2 * evsize) {
      cout << "Impossible" << endl;
    } else {
      for (int i = 0; i < fn.e.size(); ++i) {
        if (fn.e[i].cap != 1) continue;
        if (fn.e[i].flo != 1) continue;
        int ev = fn.e[i ^ 1].v - 1, od = fn.e[i].v - 1 - evsize;
        evenFoxes[ev].nbrs.push_back(od);
        oddFoxes[od].nbrs.push_back(ev);
      }
      vector<vector<int> > table;
      bitset<210> vs;
      vs.reset();
      for (int i = 0; i < evsize; ++i) {
        if (vs.test(evenFoxes[i].id)) continue;
        table.push_back(vector<int>());
        dfs(i, evenFoxes, oddFoxes, vs, table);
      }
      cout << table.size() << endl;
      for (vector<int>& t : table) {
        cout << t.size();
        for (int i = 0; i < t.size(); ++i) cout << ' ' << t[i];
        cout << endl;
      }
    }
    fn.cleanup();
  }
  return 0;
}
