#include <bits/stdc++.h>
using namespace std;
class dinic_flow {
 public:
  struct edge {
    int to, rev, cap;
    edge(int to = 0, int rev = 0, int cap = 0) : to(to), rev(rev), cap(cap) {}
  };
  vector<vector<edge> > g;
  vector<vector<edge>::iterator> nowi;
  vector<int> dist;
  int nodes, src, dst;
  queue<int> q;
  void init(int _nodes) {
    nodes = _nodes;
    g.resize(_nodes);
    nowi.resize(_nodes);
    for (int i = 0; i < _nodes; i++) g[i].clear();
    dist.resize(_nodes);
  }
  void add_Edge(int _from, int _to, int _cap) {
    g[_from].push_back(edge(_to, g[_to].size(), _cap));
    g[_to].push_back(edge(_from, g[_from].size() - 1, 0));
  }
  bool dinic_bfs() {
    fill(dist.begin(), dist.end(), -1);
    dist[src] = 0;
    q.push(src);
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      for (int i = 0; i < g[u].size(); i++) {
        edge e = g[u][i];
        if (e.cap) {
          int v = e.to;
          if (dist[v] < 0) dist[v] = dist[u] + 1, q.push(v);
        }
      }
    }
    return dist[dst] >= 0;
  }
  int dinic_dfs(int u, int f) {
    if (u == dst) return f;
    int ret = 0;
    for (vector<edge>::iterator &it = nowi[u]; it != g[u].end(); it++)
      if (it->cap) {
        int v = it->to;
        if (dist[v] == dist[u] + 1) {
          int tmp = dinic_dfs(v, min(f, it->cap));
          it->cap -= tmp, f -= tmp, ret += tmp, g[v][it->rev].cap += tmp;
          if (!f) return ret;
        }
      }
    return ret;
  }
  int maxFlow(int _src, int _dst) {
    src = _src, dst = _dst;
    int flow = 0;
    while (dinic_bfs()) {
      for (int i = 0; i < nodes; i++) nowi[i] = g[i].begin();
      flow += dinic_dfs(_src, 1e9);
    }
    return flow;
  }
} D;
bool p[20202];
void prepare() {
  for (int i = 2; i < 20202; i++)
    if (!p[i])
      for (int j = 2 * i; j < 20202; j += i) p[j] = 1;
}
bool vis[222];
vector<int> adj[222], v[222], e, o;
int n, a[222], ans;
void dfs(int x) {
  vis[x] = 1;
  v[ans].push_back(x);
  for (int i = 0; i < adj[x].size(); i++) {
    int y = adj[x][i];
    if (!vis[y]) dfs(y);
  }
}
int main() {
  prepare();
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) scanf("%d", a + i);
  if (n & 1) {
    puts("Impossible");
    return 0;
  }
  for (int i = 1; i <= n; i++) {
    if (a[i] & 1)
      o.push_back(i);
    else
      e.push_back(i);
  }
  D.init(n + 4);
  int S = 0, T = n + 1;
  for (int i = 0; i < e.size(); i++) D.add_Edge(S, e[i], 2);
  for (int i = 0; i < o.size(); i++) D.add_Edge(o[i], T, 2);
  for (int i = 0; i < e.size(); i++) {
    int x = e[i];
    for (int j = 0; j < o.size(); j++) {
      int y = o[j];
      if (!p[a[x] + a[y]]) D.add_Edge(x, y, 1);
    }
  }
  int f = D.maxFlow(S, T);
  if (f != n) {
    puts("Impossible");
    return 0;
  }
  for (int i = 0; i < e.size(); i++) {
    int x = e[i];
    for (int j = 0; j < D.g[x].size(); j++) {
      int y = D.g[x][j].to, z = D.g[x][j].cap;
      if (y == S) continue;
      if (z == 0) {
        adj[x].push_back(y);
        adj[y].push_back(x);
      }
    }
  }
  for (int i = 1; i <= n; i++)
    if (!vis[i]) ans++, dfs(i);
  printf("%d\n", ans);
  for (int i = 1; i <= ans; i++) {
    int sz = v[i].size();
    printf("%d", sz);
    for (int j = 0; j < sz; j++) printf(" %d", v[i][j]);
    puts("");
  }
}
