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;
enum { WHITE = 0, GRAY, BLACK };
enum { UNVISITED = -1 };
const double pi = 2 * acos(0);
const double tau = 2.0 * pi;
struct edge {
  int v;
  long long c, f;
  edge(int v, long long c) : v(v), c(c), f(0) {}
};
long long edmonds_karp(vector<vector<edge>>& G, int s, int t) {
  struct resedge {
    int v;
    long long fw, bw;
    edge* e;
    resedge(int u, int v, long long c, edge* e) : v(v), fw(c), bw(0), e(e) {}
    void add(int u, int v, long long d) {
      if (v == this->v)
        fw += d;
      else
        bw += d;
      e->f = e->c - fw;
    }
    long long c(int u, int v) const { return v == this->v ? fw : bw; }
  };
  int n = G.size();
  vector<vector<pair<int, int>>> Gf(n);
  vector<resedge> Ef;
  for (int u = 0, ENDD = n - 1; u <= ENDD; u++)
    for (auto& e : G[u]) {
      int v = e.v;
      long long c = e.c;
      int idx = Ef.size();
      Ef.emplace_back(u, v, c, &e);
      Gf[u].emplace_back(v, idx);
      Gf[v].emplace_back(u, idx);
    }
  vector<pair<int, int>> parent(n);
  function<long long(int, long long)> augment = [&](int v, long long f) {
    if (v == s) return f;
    int u = parent[v].first;
    auto& e = Ef[parent[v].second];
    f = augment(u, min(f, e.c(u, v)));
    e.add(u, v, -f);
    e.add(v, u, f);
    return f;
  };
  vector<int> kew(n);
  int kewl = 0, kewr = 0;
  auto Qpush = [&](int x) { kew[kewr++] = x; };
  auto Qpop = [&]() { return kew[kewl++]; };
  auto Qclear = [&]() {
    kewl = 0;
    kewr = 0;
  };
  auto Qempty = [&]() { return kewl == kewr; };
  vector<int> mark(n, 0);
  int pass = 1;
  auto relax = [&](int u, int v, int idx) {
    mark[v] = pass;
    parent[v] = pair<int, int>(u, idx);
    Qpush(v);
  };
  long long maxflow = 0;
  for (long long f = 1; f > 0; pass++) {
    f = 0;
    Qclear();
    relax(s, s, -1);
    while (!Qempty()) {
      int u = Qpop();
      if (u == t) {
        f = augment(t, 0x3f3f3f3f3f3f3f3fLL);
        break;
      }
      for (auto& e : Gf[u]) {
        int v = e.first, idx = e.second;
        if (mark[v] < pass && Ef[idx].c(u, v) > 0) relax(u, v, idx);
      }
    }
    maxflow += f;
  }
  return maxflow;
}
bool is_prime(int x) {
  for (int i = 2, ENDD = x - 1; i <= ENDD; i++) {
    if (i * i > x) return true;
    if (x % i == 0) return false;
  }
  return true;
}
struct fox {
  int a, u, i;
  fox(int a, int u, int i) : a(a), u(u), i(i) {}
};
int idx[210];
int main() {
  vector<vector<edge>> G;
  auto vertex = [&]() {
    int ans = G.size();
    G.emplace_back();
    return ans;
  };
  int s = vertex(), t = vertex();
  int n;
  cin >> n;
  vector<fox> ev, od;
  for (int i = 1, ENDD = n; i <= ENDD; i++) {
    int a;
    cin >> a;
    int u = vertex();
    idx[u] = i;
    if (a & 1) {
      G[s].emplace_back(u, 2);
      od.emplace_back(a, u, i);
    } else {
      G[u].emplace_back(t, 2);
      ev.emplace_back(a, u, i);
    }
  }
  for (auto& o : od)
    for (auto& e : ev)
      if (is_prime(o.a + e.a)) G[o.u].emplace_back(e.u, 1);
  if (edmonds_karp(G, s, t) < n) {
    cout << "Impossible\n";
    return 0;
  }
  vector<vector<int>> B(n + 1);
  for (auto& o : od)
    for (auto& edg : G[o.u])
      if (edg.f) {
        int e_i = idx[edg.v];
        B[o.i].push_back(e_i);
        B[e_i].push_back(o.i);
      }
  vector<vector<int>> tables;
  vector<bool> visited(n + 1, false);
  function<void(int)> dfs = [&](int u) {
    tables.back().push_back(u);
    visited[u] = true;
    for (int v : B[u])
      if (!visited[v]) dfs(v);
  };
  for (int u = 1, ENDD = n; u <= ENDD; u++)
    if (!visited[u]) {
      tables.emplace_back();
      dfs(u);
    }
  cout << tables.size() << endl;
  for (auto& tab : tables) {
    cout << tab.size();
    for (int i : tab) cout << " " << i;
    cout << endl;
  }
  return 0;
}
