#include <bits/stdc++.h>   using namespace std;   const long long INF = 1e17 + 7;   const long long maxn = 5e5 + 700;   const int mod = 998244353;   const int up = 1e9;   template <typename T>   inline void read(T &a) {     char c = getchar();     T x = 0, f = 1;     while (!isdigit(c)) {       if (c ==  - ) f = -1;       c = getchar();     }     while (isdigit(c)) {       x = (x << 1) + (x << 3) + c -  0 ;       c = getchar();     }     a = f * x;   }   long long n, m, p;   int num[maxn], b[maxn];   struct Dinic {     long long cnt = 2;     struct Edge {       int e, next;       long long w;     };     int _S, _T, N;     int head[maxn], d[maxn], cur[maxn];     Edge edge[maxn];     void _inint(int s, int t, int n) {       memset(head, 0, sizeof(head));       cnt = 2;       _S = s, _T = t, N = n;     }     void addedge(int u, int v, long long w) {       edge[cnt] = Edge{v, head[u], w};       head[u] = cnt++;     }     void Add(int u, int v, long long w) {       addedge(u, v, w);       addedge(v, u, 0);     }     bool bfs() {       for (int k = 0; k <= N; k++) d[k] = 0;       queue<int> q;       q.push(_S);       d[_S] = 1;       while (!q.empty()) {         int u = q.front();         q.pop();         for (int i = head[u]; i; i = edge[i].next) {           int e = edge[i].e;           if (edge[i].w <= 0 || d[e]) continue;           d[e] = d[u] + 1;           q.push(e);         }       }       for (int k = 0; k <= N; k++) cur[k] = head[k];       return (d[_T] != 0);     }     long long dfs(int u, long long flow) {       if (u == _T) return flow;       for (int &i = cur[u]; i; i = edge[i].next) {         int e = edge[i].e;         if (d[e] != d[u] + 1 || edge[i].w <= 0) continue;         long long temp = dfs(e, min(flow, edge[i].w));         if (temp <= 0) continue;         edge[i].w -= temp;         edge[i ^ 1].w += temp;         return temp;       }       return 0;     }     long long MaxFlow() {       long long maxflow = 0, delta = 0;       while (bfs()) {         while (delta = dfs(_S, INF)) maxflow += delta;       }       return maxflow;     }     vector<int> v[maxn];     int col[maxn];     vector<vector<int>> res;     void dfs(int u, vector<int> &a) {       col[u] = 1;       a.push_back(u);       for (int e : v[u]) {         if (col[e]) continue;         dfs(e, a);       }     }     void AC() {       long long temp = MaxFlow();       if (temp == N - 1) {         for (int i = 1; i <= n; i++) {           if (!(num[i] & 1)) continue;           for (int k = head[i]; k; k = edge[k].next) {             int e = edge[k].e;             if (edge[k ^ 1].w) {               v[e].push_back(i);               v[i].push_back(e);             }           }         }         for (int i = 1; i <= n; i++) {           if (!col[i]) {             vector<int> temp;             dfs(i, temp);             res.push_back(temp);           }         }         printf( %d n , res.size());         for (auto x : res) {           printf( %d  , x.size());           for (int y : x) printf( %d  , y);           printf(  n );         }       } else         printf( Impossible n );     }   } g;   int judge(int x) {     for (int i = 2; i * i <= x; i++)       if (x % i == 0) return 0;     return 1;   }   int main() {     read(n);     g._inint(0, n + 1, n + 1);     for (int i = 1; i <= n; i++) {       read(num[i]);       if (num[i] & 1)         g.Add(0, i, 2);       else         g.Add(i, n + 1, 2);     }     for (int i = 1; i <= n; i++) {       for (int k = i + 1; k <= n; k++) {         if (judge(num[i] + num[k])) {           if (num[i] & 1)             g.Add(i, k, 1);           else             g.Add(k, i, 1);         }       }     }     g.AC();     return 0;   }