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;
const int MAXN = 300;
vector<vector<pair<long long, long long>>> g(MAXN), f(MAXN);
vector<long long> d(MAXN), ind(MAXN), used(MAXN);
long long n, m;
long long solve2(long long v, long long flow, long long p, long long ptr) {
  used[v] = true;
  if (v == n - 1) {
    f[p][ptr].second += flow;
    for (int i = 0; i < f[v].size(); i++) {
      if (f[v][i].first == p) {
        f[v][i].second -= flow;
      }
    }
    return flow;
  }
  for (int i = ind[v]; i < f[v].size(); i++) {
    long long to = f[v][i].first;
    long long flow_to = g[v][i].second - f[v][i].second;
    long long geg = 0;
    if (flow_to > 0 && !used[to] && d[to] == d[v] + 1) {
      geg = solve2(to, min(flow_to, flow), v, i);
    }
    if (geg > 0) {
      if (p != -1) {
        f[p][ptr].second += geg;
        for (int j = 0; j < f[v].size(); j++) {
          if (f[v][j].first == p) {
            f[v][j].second -= geg;
          }
        }
      }
      return geg;
    }
    ind[v]++;
  }
  return 0;
}
bool solve1() {
  queue<long long> q;
  q.push(0);
  d[0] = 0;
  used.assign(n, false);
  used[0] = true;
  while (!q.empty()) {
    long long v = q.front();
    q.pop();
    for (int i = 0; i < f[v].size(); i++) {
      long long to = f[v][i].first;
      long long bound = g[v][i].second;
      long long ost = bound - f[v][i].second;
      if (ost > 0 && !used[to]) {
        used[to] = true;
        d[to] = d[v] + 1;
        q.push(to);
      }
    }
  }
  bool ans = false;
  ind.assign(n, 0);
  used.assign(n, false);
  while (solve2(0, 1e10, -1, -1)) {
    ans = true;
    used.assign(n, false);
  }
  return ans;
}
bool is_prime(long long p) {
  for (long long i = 2; i * i <= p; i++) {
    if (p % i == 0) {
      return false;
    }
  }
  return true;
}
long long next(long long cur, long long p) {
  for (int i = 0; i < f[cur].size(); i++) {
    long long kek = f[cur][i].first;
    if (kek != p && f[cur][i].second != 0 && kek != 0 && kek != n - 1) {
      return kek;
    }
  }
}
int main() {
  cin >> n;
  vector<long long> a(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (i != j) {
        long long p = a[i] + a[j];
        if (is_prime(p) && a[i] % 2 == 0) {
          g[i + 1].push_back({j + 1, 1});
          g[j + 1].push_back({i + 1, 0});
          f[i + 1].push_back({j + 1, 0});
          f[j + 1].push_back({i + 1, 0});
        }
      }
    }
  }
  n++;
  for (int i = 1; i < n; i++) {
    if (a[i - 1] % 2 == 0) {
      g[0].push_back({i, 2});
      g[i].push_back({0, 2});
      f[0].push_back({i, 0});
      f[i].push_back({0, 0});
    }
  }
  n++;
  for (int i = 1; i < n - 1; i++) {
    if (a[i - 1] % 2 == 1) {
      g[n - 1].push_back({i, 2});
      g[i].push_back({n - 1, 2});
      f[n - 1].push_back({i, 0});
      f[i].push_back({n - 1, 0});
    }
  }
  while (true) {
    if (!solve1()) {
      break;
    }
  }
  long long ans = 0;
  for (int i = 0; i < f[0].size(); i++) {
    ans += f[0][i].second;
  }
  if (ans < (n - 2) || n % 2 == 1) {
    cout << "Impossible";
  } else {
    vector<vector<long long>> puk;
    vector<bool> usd(n, false);
    for (int i = 1; i < n - 1; i++) {
      if (!usd[i]) {
        vector<long long> path;
        long long cur = i;
        long long p = -1;
        path.push_back(cur);
        while (next(cur, p) != i) {
          long long pp = cur;
          cur = next(cur, p);
          p = pp;
          path.push_back(cur);
        }
        for (int j = 0; j < path.size(); j++) {
          usd[path[j]] = true;
        }
        puk.push_back(path);
      }
    }
    cout << puk.size() << endl;
    for (int i = 0; i < puk.size(); i++) {
      cout << puk[i].size() << ' ';
      for (int j = 0; j < puk[i].size(); j++) {
        cout << puk[i][j] << ' ';
      }
      cout << endl;
    }
  }
}
