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;
long limit = 100000;
bool IsPrimes[100000];
void atkin() {
  long vsqrt = sqrt(limit);
  for (int i = 0; i < limit; ++i) IsPrimes[i] = false;
  for (long x = 1; x <= vsqrt; x++)
    for (long y = 1; y <= vsqrt; y++) {
      long x2 = x * x;
      long y2 = y * y;
      long n = 4 * x2 + y2;
      if (n <= limit && (n % 12 == 1 || n % 12 == 5)) IsPrimes[n] ^= true;
      n -= x2;
      if (n <= limit && n % 12 == 7) IsPrimes[n] ^= true;
      n -= 2 * y2;
      if (x > y && n <= limit && n % 12 == 11) IsPrimes[n] ^= true;
    }
  for (long n = 5; n <= vsqrt; n += 2)
    if (IsPrimes[n]) {
      long s = n * n;
      for (long k = s; k <= limit; k += s) IsPrimes[k] = false;
    }
  IsPrimes[2] = true;
  IsPrimes[3] = true;
}
bool input_age_data(vector<pair<int, int> >& ages) {
  int n = 0;
  cin >> n;
  if (n % 2) return false;
  ages.resize(n);
  int odd = 0;
  int even = n / 2;
  for (int i = 0; i < n; ++i) {
    int data;
    cin >> data;
    pair<int, int> age(data, i);
    if (data % 2) {
      if (odd >= (n / 2)) return false;
      ages[odd] = age;
      ++odd;
    } else {
      if (even >= n) return false;
      ages[even] = age;
      ++even;
    }
  }
  return true;
}
bool create_2sidegraph(vector<pair<int, int> >& ages,
                       vector<vector<int> >& fgraph) {
  fgraph.resize(ages.size());
  int evenstart = fgraph.size() / 2;
  for (int odd = 0; odd < evenstart; ++odd)
    for (int even = evenstart; even < fgraph.size(); ++even) {
      if (IsPrimes[ages[odd].first + ages[even].first] == true) {
        fgraph[odd].push_back(even);
        fgraph[even].push_back(odd);
      }
    }
  for (int i = 0; i < fgraph.size(); ++i) {
    if (fgraph[i].size() < 2) return false;
  }
  return true;
}
bool select_connections(vector<vector<int> >& fgraph,
                        vector<vector<int> >& wgraph, int numcycle) {
  bool isok = true;
  for (int i = 0; i < fgraph.size(); ++i) {
    int localindex = i;
    if (wgraph[localindex].size() < 2) {
      isok = false;
      vector<int>::iterator it;
      int remoteindex;
      int pos = numcycle;
      do {
        remoteindex = fgraph[i][pos % fgraph[i].size()];
        it = find(wgraph[localindex].begin(), wgraph[localindex].end(),
                  remoteindex);
        pos++;
      } while (it != wgraph[localindex].end());
      wgraph[localindex].push_back(remoteindex);
      wgraph[remoteindex].push_back(localindex);
    } else {
      while (wgraph[localindex].size() > 2) {
        isok = false;
        int remoteindex = wgraph[localindex][0];
        vector<int>::iterator it = find(wgraph[remoteindex].begin(),
                                        wgraph[remoteindex].end(), localindex);
        if (it != wgraph[remoteindex].end()) {
          wgraph[remoteindex].erase(it);
          wgraph[localindex].erase(wgraph[localindex].begin());
        }
      }
    }
  }
  return isok;
}
vector<vector<int> > get_cycles(vector<vector<int> >& wgraph) {
  vector<vector<int> > indexes;
  vector<int> vis(wgraph.size(), 0);
  for (int i = 0; i < wgraph.size(); ++i) {
    if (vis[i]) continue;
    vector<int> cycle_ids;
    int from = wgraph[i][0];
    int start = -1;
    int act = i;
    while (start != i) {
      cycle_ids.push_back(act);
      vis[act] = 1;
      if (wgraph[act][0] == from) {
        from = act;
        act = wgraph[act][1];
      } else {
        if (wgraph[act][1] == from) {
          from = act;
          act = wgraph[act][0];
        }
      }
      start = act;
    }
    indexes.push_back(cycle_ids);
  }
  return indexes;
}
void print_cycles(vector<vector<int> >& idxs, vector<pair<int, int> >& ages) {
  cout << idxs.size() << endl;
  for (int i = 0; i < idxs.size(); ++i) {
    cout << idxs[i].size();
    for (int c = 0; c < idxs[i].size(); ++c) {
      cout << " " << ages[idxs[i][c]].second + 1;
    }
    cout << endl;
  }
}
int div2290E(vector<pair<int, int> >& ages) {
  atkin();
  vector<vector<int> > fullgraph;
  vector<vector<int> > workgraph;
  if (create_2sidegraph(ages, fullgraph) == false) {
    cout << "Impossible" << endl;
    return 0;
  }
  workgraph.resize(fullgraph.size());
  bool isok = false;
  for (int i = 0; i < 100000 && isok == false; ++i) {
    isok = select_connections(fullgraph, workgraph, i);
  }
  if (isok) {
    vector<vector<int> > indexes = get_cycles(workgraph);
    print_cycles(indexes, ages);
  } else {
    cout << "Impossible" << endl;
  }
  return 0;
}
int main() {
  vector<pair<int, int> > ages;
  if (input_age_data(ages) == false) {
    cout << "Impossible" << endl;
    return 0;
  }
  return div2290E(ages);
}