#include <bits/stdc++.h>   inline int mymin(int x, int y) { return x < y ? x : y; }   bool isprime[22000];   inline void init_prime() {     memset(isprime, true, sizeof(isprime));     for (int i = 2; i <= (int)sqrt(20000 * 1.0); ++i)       if (isprime[i])         for (int j = 2; i * j <= 20000; ++j) isprime[i * j] = false;   }   struct edge {     int to, c, next;   } e[22000];   int n, id[220], a[220], head[220], h[220], q[220], cnt, tot, num[55],       path[55][220];   bool f[220];   inline void print() { printf( Impossible n ); }   inline void ins(int u, int v, int c) {     e[++cnt].to = v;     e[cnt].c = c;     e[cnt].next = head[u];     head[u] = cnt;     e[++cnt].to = u;     e[cnt].c = 0;     e[cnt].next = head[v];     head[v] = cnt;   }   int dfs(int u, int in) {     if (u == n + 1 || !in) return in;     int out = 0;     for (int i = head[u]; i; i = e[i].next) {       int v = e[i].to, c = e[i].c;       if (h[v] == h[u] + 1 && c) {         int flow = dfs(v, mymin(in - out, c));         if (!flow)           h[v] = 0;         else           out += flow;         e[i].c -= flow;         e[i ^ 1].c += flow;         if (in == out) return out;       }     }     return out;   }   inline bool bfs() {     int op = 0, cl = 0;     memset(h, 0, sizeof(h));     h[q[++cl] = 0] = 1;     while (op < cl) {       int u = q[++op];       if (u == n + 1) break;       for (int i = head[u]; i; i = e[i].next) {         int v = e[i].to, c = e[i].c;         if (!h[v] && c) h[q[++cl] = v] = h[u] + 1;       }     }     return h[n + 1];   }   inline int Dinic() {     int rec = 0;     while (bfs()) rec += dfs(0, n);     return rec;   }   int dfs_path(int x) {     path[tot][++num[tot]] = x;     int y;     for (int i = head[x]; i; i = e[i].next) {       if (e[i].c) continue;       y = e[i].to;       if (f[y]) continue;       f[y] = true;       path[tot][++num[tot]] = y;       break;     }     for (int i = head[y]; i; i = e[i].next) {       if (e[i ^ 1].c) continue;       x = e[i].to;       if (f[x]) continue;       f[x] = true;       dfs_path(x);     }   }   int main() {     scanf( %d , &n);     if (n & 1) {       print();       return 0;     }     int cnt1 = 0, cnt2 = n >> 1;     for (int i = 1; i <= n; ++i) {       int x;       scanf( %d , &x);       if (x & 1) {         a[++cnt1] = x;         id[cnt1] = i;       } else {         a[++cnt2] = x;         id[cnt2] = i;       }       if (cnt1 > n >> 1 || cnt2 > n) {         print();         return 0;       }     }     init_prime();     memset(head, 0, sizeof(head));     cnt = 1;     for (int i = 1; i <= (n >> 1); ++i) {       ins(0, id[i], 2);       for (int j = (n >> 1) + 1; j <= n; ++j)         if (isprime[a[i] + a[j]]) ins(id[i], id[j], 1);     }     for (int i = (n >> 1) + 1; i <= n; ++i) ins(id[i], n + 1, 2);     int maxflow = Dinic();     if (maxflow != n) {       print();       return 0;     }     memset(f, false, sizeof(f));     f[0] = f[n + 1] = true;     tot = 0;     for (int i = 1; i <= (n >> 1); ++i)       if (!f[id[i]]) {         f[id[i]] = true;         ++tot;         num[tot] = 0;         dfs_path(id[i]);       }     printf( %d n , tot);     for (int i = 1; i <= tot; ++i) {       printf( %d , num[i]);       for (int j = 1; j <= num[i]; ++j) printf(  %d , path[i][j]);       if (i != tot) printf(  n );     }     return 0;   }