#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
#include <iostream>
#include <set>
#include <cmath>
#include <cstring>
#include <bitset>
#include <deque>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef vector<vi> vvi;

#define mp make_pair
#define pb push_back
#define bpc(a) __builtin_popcount(a)
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define clr(ar,val) memset(ar, val, sizeof(ar))
#define forn(i,n) for(int i=0;i<(n);++i)
#define X first
#define Y second
#define debug(x) { cerr<<#x<<" = "<<(x)<<endl; }

const int mod = 1e9 + 7;
const int inf = 1e9;

ll powm(ll a,ll p,ll m){ll r=1 % m;while(p){if(p&1)r=r*a%m;p>>=1;a=a*a%m;}return r;}

bool issimple(int d)
{
    for(int i = 2; i * i <= d; ++i)
        if(d % i == 0)
            return false;
    return true;
}

int g[210][210], n, f[210], s = 0, t, mf[210][201], uses[210];

vi path;

bool bfs()
{
    deque<int> q;
    q.pb(s);
    vi d(n + 2, -1);
    d[s] = 0;
    while(!q.empty())
    {
        int v = q.front();
        q.pop_front();
        forn(i, n + 2)
            if(g[v][i] > mf[v][i] && d[i] == -1)
            {
                d[i] = v;
                q.pb(i);
            }
    }
    if(d[t] != -1)
    {
        path.clear();
        int cur = t;
        while(cur != s)
        {
            path.pb(cur);
            cur = d[cur];
        }
        path.pb(s);
        reverse(all(path));
    }
    return d[t] != -1;
}

int main()
{
    scanf("%d", &n);
    t = n + 1;
    int odd = 0;
    forn(i, n)
    {
        scanf("%d", f + i + 1);
        if(f[i + 1] % 2 == 1)
            g[s][i + 1] = 2, odd++;
        else
            g[i + 1][t] = 2;
    }
    if(2 * odd != n)
    {
        puts("Impossible");
        return 0;
    }
    forn(i, n)
        forn(j, n)
            if(f[i + 1] % 2)
                g[i + 1][j + 1] = issimple(f[i + 1] + f[j + 1]);
    forn(i, n)
    {
        if(bfs())
        {
            forn(j, sz(path) - 1)
            {
                int u = path[j], v = path[j + 1];
                mf[u][v]++;
                mf[v][u]--;
            }
        }
        else
        {
            puts("Impossible");
            return 0;
        }
    }
    clr(uses, 0);
    vvi ans;
    forn(i, n)
        if(!uses[i + 1])
        {
            vi tmp;
            int c;
            for(c = i + 1; !uses[c];)
            {
                tmp.pb(c);
                uses[c] = 1;
                forn(j, n)
                    if(abs(mf[c][j + 1]) == 1 && !uses[j + 1])
                    {
                        c = j + 1;
                        break;
                    }
            }
            //if (abs(mf[c][i+1]) != 1)
            //    return 1;
            ans.pb(tmp);
        }
    forn(i, n)
    {
        bool fl = false;
        int cnt = 0;
        forn(j, n)
            /*if(mf[0][i + 1] == 2)
                fl |= mf[i + 1][j + 1] == -1;
            else
                fl |= mf[i + 1][j + 1] == 1;*/
            cnt += abs(mf[i + 1][j + 1]);
        if(fl || cnt != 2)
        {
            printf("%d\n", cnt);
            forn(j, n)
            {
                printf("%d ", f[j+1]);
                if ((j + 1) % 80 == 0)
                    printf("\n");
            }
            return 1;
        }
    }
    printf("%d\n", sz(ans));
    forn(i, sz(ans))
    {
        printf("%d", sz(ans[i]));
        forn(j, sz(ans[i]))
            printf(" %d", ans[i][j]);
        puts("");
    }
    /*forn(i, n + 2)
    {
        forn(j, n + 2)
            printf("%d ", mf[i][j]);
        puts("");
    }*/

    return 0;
}


#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
#include <iostream>
#include <set>
#include <cmath>
#include <cstring>
#include <bitset>
#include <deque>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef vector<vi> vvi;

#define mp make_pair
#define pb push_back
#define bpc(a) __builtin_popcount(a)
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define clr(ar,val) memset(ar, val, sizeof(ar))
#define forn(i,n) for(int i=0;i<(n);++i)
#define X first
#define Y second
#define debug(x) { cerr<<#x<<" = "<<(x)<<endl; }

const int mod = 1e9 + 7;
const int inf = 1e9;

ll powm(ll a,ll p,ll m){ll r=1 % m;while(p){if(p&1)r=r*a%m;p>>=1;a=a*a%m;}return r;}

bool issimple(int d)
{
    for(int i = 2; i * i <= d; ++i)
        if(d % i == 0)
            return false;
    return true;
}

int g[210][210], n, f[210], s = 0, t, mf[210][201], uses[210];

vi path;

bool bfs()
{
    deque<int> q;
    q.pb(s);
    vi d(n + 2, -1);
    d[s] = 0;
    while(!q.empty())
    {
        int v = q.front();
        q.pop_front();
        forn(i, n + 2)
            if(g[v][i] > mf[v][i] && d[i] == -1)
            {
                d[i] = v;
                q.pb(i);
            }
    }
    if(d[t] != -1)
    {
        path.clear();
        int cur = t;
        while(cur != s)
        {
            path.pb(cur);
            cur = d[cur];
        }
        path.pb(s);
        reverse(all(path));
    }
    return d[t] != -1;
}

int main()
{
    scanf("%d", &n);
    t = n + 1;
    int odd = 0;
    forn(i, n)
    {
        scanf("%d", f + i + 1);
        if(f[i + 1] % 2 == 1)
            g[s][i + 1] = 2, odd++;
        else
            g[i + 1][t] = 2;
    }
    if(2 * odd != n)
    {
        puts("Impossible");
        return 0;
    }
    forn(i, n)
        forn(j, n)
            g[i + 1][j + 1] = g[j + 1][i + 1] = issimple(f[i + 1] + f[j + 1]);
    forn(i, n)
    {
        if(bfs())
        {
            forn(j, sz(path) - 1)
            {
                int u = path[j], v = path[j + 1];
                mf[u][v]++;
                mf[v][u]--;
            }
        }
        else
        {
            puts("Impossible");
            return 0;
        }
    }
    clr(uses, 0);
    vvi ans;
    forn(i, n)
        if(!uses[i + 1])
        {
            vi tmp;
            int c;
            for(c = i + 1; !uses[c];)
            {
                tmp.pb(c);
                uses[c] = 1;
                forn(j, n)
                    if(abs(mf[c][j + 1]) == 1 && !uses[j + 1])
                    {
                        c = j + 1;
                        break;
                    }
            }
            //if (abs(mf[c][i+1]) != 1)
            //    return 1;
            ans.pb(tmp);
        }
    printf("%d\n", sz(ans));
    forn(i, sz(ans))
    {
        printf("%d", sz(ans[i]));
        forn(j, sz(ans[i]))
            printf(" %d", ans[i][j]);
        puts("");
    }
    /*forn(i, n + 2)
    {
        forn(j, n + 2)
            printf("%d ", mf[i][j]);
        puts("");
    }*/
    forn(i, n)
    {
        bool fl = false;
        forn(j, n)
            if(mf[0][i] == 2)
                fl |= mf[i + 1][j + 1] == 1;
            else
                fl |= mf[i + 1][j + 1] == -1;
        if(fl)
            return 1;
    }
    return 0;
}


#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
#include <iostream>
#include <set>
#include <cmath>
#include <cstring>
#include <bitset>
#include <deque>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef vector<vi> vvi;

#define mp make_pair
#define pb push_back
#define bpc(a) __builtin_popcount(a)
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define clr(ar,val) memset(ar, val, sizeof(ar))
#define forn(i,n) for(int i=0;i<(n);++i)
#define X first
#define Y second
#define debug(x) { cerr<<#x<<" = "<<(x)<<endl; }

const int mod = 1e9 + 7;
const int inf = 1e9;

ll powm(ll a,ll p,ll m){ll r=1 % m;while(p){if(p&1)r=r*a%m;p>>=1;a=a*a%m;}return r;}

bool issimple(int d)
{
    for(int i = 2; i * i <= d; ++i)
        if(d % i == 0)
            return false;
    return true;
}

int g[210][210], n, f[210], s = 0, t, mf[210][201], uses[210];

vi path;

bool bfs()
{
    deque<int> q;
    q.pb(s);
    vi d(n + 2, -1);
    d[s] = 0;
    while(!q.empty())
    {
        int v = q.front();
        q.pop_front();
        forn(i, n + 2)
            if(g[v][i] > mf[v][i] && d[i] == -1)
            {
                d[i] = v;
                q.pb(i);
            }
    }
    if(d[t] != -1)
    {
        path.clear();
        int cur = t;
        while(cur != s)
        {
            path.pb(cur);
            cur = d[cur];
        }
        path.pb(s);
        reverse(all(path));
    }
    return d[t] != -1;
}

int main()
{
    scanf("%d", &n);
    t = n + 1;
    int odd = 0;
    forn(i, n)
    {
        scanf("%d", f + i + 1);
        if(f[i + 1] % 2 == 1)
            g[s][i + 1] = 2, odd++;
        else
            g[i + 1][t] = 2;
    }
    if(2 * odd != n)
    {
        puts("Impossible");
        return 0;
    }
    forn(i, n)
        forn(j, n)
            if(f[i + 1] % 2)
                g[i + 1][j + 1] = issimple(f[i + 1] + f[j + 1]);
    forn(i, n)
    {
        if(bfs())
        {
            forn(j, sz(path) - 1)
            {
                int u = path[j], v = path[j + 1];
                mf[u][v]++;
                mf[v][u]--;
            }
        }
        else
        {
            puts("Impossible");
            return 0;
        }
    }
    clr(uses, 0);
    vvi ans;
    forn(i, n)
        if(!uses[i + 1])
        {
            vi tmp;
            int c;
            for(c = i + 1; !uses[c];)
            {
                tmp.pb(c);
                uses[c] = 1;
                forn(j, n)
                    if(abs(mf[c][j + 1]) == 1 && !uses[j + 1])
                    {
                        c = j + 1;
                        break;
                    }
            }
            //if (abs(mf[c][i+1]) != 1)
            //    return 1;
            ans.pb(tmp);
        }
    printf("%d\n", sz(ans));
    forn(i, sz(ans))
    {
        printf("%d", sz(ans[i]));
        forn(j, sz(ans[i]))
            printf(" %d", ans[i][j]);
        puts("");
    }
    /*forn(i, n + 2)
    {
        forn(j, n + 2)
            printf("%d ", mf[i][j]);
        puts("");
    }
    forn(i, n)
    {
        bool fl = false;
        forn(j, n)
            if(mf[0][i + 1] == 2)
                fl |= mf[i + 1][j + 1] == -1;
            else
                fl |= mf[i + 1][j + 1] == 1;
        if(fl)
            return 1;
    }*/
    return 0;
}


#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
#include <iostream>
#include <set>
#include <cmath>
#include <cstring>
#include <bitset>
#include <deque>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef vector<vi> vvi;

#define mp make_pair
#define pb push_back
#define bpc(a) __builtin_popcount(a)
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define clr(ar,val) memset(ar, val, sizeof(ar))
#define forn(i,n) for(int i=0;i<(n);++i)
#define X first
#define Y second
#define debug(x) { cerr<<#x<<" = "<<(x)<<endl; }

const int mod = 1e9 + 7;
const int inf = 1e9;

ll powm(ll a,ll p,ll m){ll r=1 % m;while(p){if(p&1)r=r*a%m;p>>=1;a=a*a%m;}return r;}

bool issimple(int d)
{
    for(int i = 2; i * i <= d; ++i)
        if(d % i == 0)
            return false;
    return true;
}

int g[210][210], n, f[210], s = 0, t, mf[210][201], uses[210];

vi path;

bool bfs()
{
    deque<int> q;
    q.pb(s);
    vi d(n + 2, -1);
    d[s] = 0;
    while(!q.empty())
    {
        int v = q.front();
        q.pop_front();
        forn(i, n + 2)
            if(g[v][i] > mf[v][i] && d[i] == -1)
            {
                d[i] = v;
                q.pb(i);
            }
    }
    if(d[t] != -1)
    {
        path.clear();
        int cur = t;
        while(cur != s)
        {
            path.pb(cur);
            cur = d[cur];
        }
        path.pb(s);
        reverse(all(path));
    }
    return d[t] != -1;
}

int main()
{
    scanf("%d", &n);
    t = n + 1;
    int odd = 0;
    forn(i, n)
    {
        scanf("%d", f + i + 1);
        if(f[i + 1] % 2 == 1)
            g[s][i + 1] = 2, odd++;
        else
            g[i + 1][t] = 2;
    }
    if(2 * odd != n)
    {
        puts("Impossible");
        return 0;
    }
    forn(i, n)
        forn(j, n)
            if(f[i + 1] % 2)
                g[i + 1][j + 1] = issimple(f[i + 1] + f[j + 1]);
    forn(i, n)
    {
        if(bfs())
        {
            forn(j, sz(path) - 1)
            {
                int u = path[j], v = path[j + 1];
                mf[u][v]++;
                mf[v][u]--;
            }
        }
        else
        {
            puts("Impossible");
            return 0;
        }
    }
    clr(uses, 0);
    vvi ans;
    forn(i, n)
        if(!uses[i + 1])
        {
            vi tmp;
            int c;
            for(c = i + 1; !uses[c];)
            {
                tmp.pb(c);
                uses[c] = 1;
                forn(j, n)
                    if(abs(mf[c][j + 1]) == 1 && !uses[j + 1])
                    {
                        c = j + 1;
                        break;
                    }
            }
            //if (abs(mf[c][i+1]) != 1)
            //    return 1;
            ans.pb(tmp);
        }
    forn(i, n)
    {
        bool fl = false;
        int cnt = 0;
        forn(j, n)
            /*if(mf[0][i + 1] == 2)
                fl |= mf[i + 1][j + 1] == -1;
            else
                fl |= mf[i + 1][j + 1] == 1;*/
            cnt += abs(mf[i + 1][j + 1]);
        if(fl || cnt != 2)
        {
            printf("%d\n", cnt);
            forn(j, n)
            {
                printf("%d ", f[j+1]);
                if (j%40==0)
                    printf("\n");
            }
            return 1;
        }
    }
    printf("%d\n", sz(ans));
    forn(i, sz(ans))
    {
        printf("%d", sz(ans[i]));
        forn(j, sz(ans[i]))
            printf(" %d", ans[i][j]);
        puts("");
    }
    /*forn(i, n + 2)
    {
        forn(j, n + 2)
            printf("%d ", mf[i][j]);
        puts("");
    }*/

    return 0;
}


#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
#include <iostream>
#include <set>
#include <cmath>
#include <cstring>
#include <bitset>
#include <deque>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef vector<vi> vvi;

#define mp make_pair
#define pb push_back
#define bpc(a) __builtin_popcount(a)
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define clr(ar,val) memset(ar, val, sizeof(ar))
#define forn(i,n) for(int i=0;i<(n);++i)
#define X first
#define Y second
#define debug(x) { cerr<<#x<<" = "<<(x)<<endl; }

const int mod = 1e9 + 7;
const int inf = 1e9;

ll powm(ll a,ll p,ll m){ll r=1 % m;while(p){if(p&1)r=r*a%m;p>>=1;a=a*a%m;}return r;}

bool issimple(int d)
{
    for(int i = 2; i * i <= d; ++i)
        if(d % i == 0)
            return false;
    return true;
}

int g[210][210], n, f[210], s = 0, t, mf[210][201], uses[210];

vi path;

bool bfs()
{
    deque<int> q;
    q.pb(s);
    vi d(n + 2, -1);
    d[s] = 0;
    while(!q.empty())
    {
        int v = q.front();
        q.pop_front();
        forn(i, n + 2)
            if(g[v][i] > mf[v][i] && d[i] == -1)
            {
                d[i] = v;
                q.pb(i);
            }
    }
    if(d[t] != -1)
    {
        path.clear();
        int cur = t;
        while(cur != s)
        {
            path.pb(cur);
            cur = d[cur];
        }
        path.pb(s);
        reverse(all(path));
    }
    return d[t] != -1;
}

int main()
{
    scanf("%d", &n);
    t = n + 1;
    int odd = 0;
    forn(i, n)
    {
        scanf("%d", f + i + 1);
        if(f[i + 1] % 2 == 1)
            g[s][i + 1] = 2, odd++;
        else
            g[i + 1][t] = 2;
    }
    if(2 * odd != n)
    {
        puts("Impossible");
        return 0;
    }
    forn(i, n)
        forn(j, n)
            g[i + 1][j + 1] = g[j + 1][i + 1] = issimple(f[i + 1] + f[j + 1]);
    forn(i, n)
    {
        if(bfs())
        {
            forn(j, sz(path) - 1)
            {
                int u = path[j], v = path[j + 1];
                mf[u][v]++;
                mf[v][u]--;
            }
        }
        else
        {
            puts("Impossible");
            return 0;
        }
    }
    clr(uses, 0);
    vvi ans;
    forn(i, n)
        if(!uses[i + 1])
        {
            vi tmp;
            int c;
            for(c = i + 1; !uses[c];)
            {
                tmp.pb(c);
                uses[c] = 1;
                forn(j, n)
                    if(abs(mf[c][j + 1]) == 1 && !uses[j + 1])
                    {
                        c = j + 1;
                        break;
                    }

            }
            if (abs(mf[c][i+1]) != 1)
                return 1;
            ans.pb(tmp);
        }
    printf("%d\n", sz(ans));
    forn(i, sz(ans))
    {
        printf("%d", sz(ans[i]));
        forn(j, sz(ans[i]))
            printf(" %d", ans[i][j]);
        puts("");
    }
    /*forn(i, n + 2)
    {
        forn(j, n + 2)
            printf("%d ", mf[i][j]);
        puts("");
    }*/
    return 0;
}


#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
#include <iostream>
#include <set>
#include <cmath>
#include <cstring>
#include <bitset>
#include <deque>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef vector<vi> vvi;

#define mp make_pair
#define pb push_back
#define bpc(a) __builtin_popcount(a)
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define clr(ar,val) memset(ar, val, sizeof(ar))
#define forn(i,n) for(int i=0;i<(n);++i)
#define X first
#define Y second
#define debug(x) { cerr<<#x<<" = "<<(x)<<endl; }

const int mod = 1e9 + 7;
const int inf = 1e9;

ll powm(ll a,ll p,ll m){ll r=1 % m;while(p){if(p&1)r=r*a%m;p>>=1;a=a*a%m;}return r;}

bool issimple(int d)
{
    for(int i = 2; i * i <= d; ++i)
        if(d % i == 0)
            return false;
    return true;
}

int g[210][210], n, f[210], s = 0, t, mf[210][201], uses[210];

vi path;

bool bfs()
{
    deque<int> q;
    q.pb(s);
    vi d(n + 2, -1);
    d[s] = 0;
    while(!q.empty())
    {
        int v = q.front();
        q.pop_front();
        forn(i, n + 2)
            if(g[v][i] > mf[v][i] && d[i] == -1)
            {
                d[i] = v;
                q.pb(i);
            }
    }
    if(d[t] != -1)
    {
        path.clear();
        int cur = t;
        while(cur != s)
        {
            path.pb(cur);
            cur = d[cur];
        }
        path.pb(s);
        reverse(all(path));
    }
    return d[t] != -1;
}

int main()
{
    scanf("%d", &n);
    t = n + 1;
    int odd = 0;
    forn(i, n)
    {
        scanf("%d", f + i + 1);
        if(f[i + 1] % 2 == 1)
            g[s][i + 1] = 2, odd++;
        else
            g[i + 1][t] = 2;
    }
    if(2 * odd != n)
    {
        puts("Impossible");
        return 0;
    }
    forn(i, n)
        forn(j, n)
            g[i + 1][j + 1] = g[j + 1][i + 1] = issimple(f[i + 1] + f[j + 1]);
    forn(i, n)
    {
        if(bfs())
        {
            forn(j, sz(path) - 1)
            {
                int u = path[j], v = path[j + 1];
                mf[u][v]++;
                mf[v][u]--;
            }
        }
        else
        {
            puts("Impossible");
            return 0;
        }
    }
    clr(uses, 0);
    vvi ans;
    forn(i, n)
        if(!uses[i + 1])
        {
            vi tmp;
            int c;
            for(c = i + 1; !uses[c];)
            {
                tmp.pb(c);
                uses[c] = 1;
                forn(j, n)
                    if(abs(mf[c][j + 1]) == 1 && !uses[j + 1])
                    {
                        c = j + 1;
                        break;
                    }
            }
            //if (abs(mf[c][i+1]) != 1)
            //    return 1;
            ans.pb(tmp);
        }
    printf("%d\n", sz(ans));
    forn(i, sz(ans))
    {
        printf("%d", sz(ans[i]));
        forn(j, sz(ans[i]))
            printf(" %d", ans[i][j]);
        puts("");
    }
    /*forn(i, n + 2)
    {
        forn(j, n + 2)
            printf("%d ", mf[i][j]);
        puts("");
    }*/
    forn(i, n)
    {
        bool fl = false;
        forn(j, n)
            if(mf[0][i] == 2)
                fl |= mf[i + 1][j + 1] == -1;
            else
                fl |= mf[i + 1][j + 1] == 1;
        if(fl)
            return 1;
    }
    return 0;
}


#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
#include <iostream>
#include <set>
#include <cmath>
#include <cstring>
#include <bitset>
#include <deque>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef vector<vi> vvi;

#define mp make_pair
#define pb push_back
#define bpc(a) __builtin_popcount(a)
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define clr(ar,val) memset(ar, val, sizeof(ar))
#define forn(i,n) for(int i=0;i<(n);++i)
#define X first
#define Y second
#define debug(x) { cerr<<#x<<" = "<<(x)<<endl; }

const int mod = 1e9 + 7;
const int inf = 1e9;

ll powm(ll a,ll p,ll m){ll r=1 % m;while(p){if(p&1)r=r*a%m;p>>=1;a=a*a%m;}return r;}

bool issimple(int d)
{
    for(int i = 2; i * i <= d; ++i)
        if(d % i == 0)
            return false;
    return true;
}

int g[210][210], n, f[210], s = 0, t, mf[210][201], uses[210];

vi path;

bool bfs()
{
    deque<int> q;
    q.pb(s);
    vi d(n + 2, -1);
    d[s] = 0;
    while(!q.empty())
    {
        int v = q.front();
        q.pop_front();
        forn(i, n + 2)
            if(g[v][i] > mf[v][i] && d[i] == -1)
            {
                d[i] = v;
                q.pb(i);
            }
    }
    if(d[t] != -1)
    {
        path.clear();
        int cur = t;
        while(cur != s)
        {
            path.pb(cur);
            cur = d[cur];
        }
        path.pb(s);
        reverse(all(path));
    }
    return d[t] != -1;
}

int main()
{
    scanf("%d", &n);
    t = n + 1;
    int odd = 0;
    forn(i, n)
    {
        scanf("%d", f + i + 1);
        if(f[i + 1] % 2 == 1)
            g[s][i + 1] = 2, odd++;
        else
            g[i + 1][t] = 2;
    }
    if(2 * odd != n)
    {
        puts("Impossible");
        return 0;
    }
    forn(i, n)
        forn(j, n)
            g[i + 1][j + 1] = g[j + 1][i + 1] = issimple(f[i + 1] + f[j + 1]);
    forn(i, n)
    {
        if(bfs())
        {
            forn(j, sz(path) - 1)
            {
                int u = path[j], v = path[j + 1];
                mf[u][v]++;
                mf[v][u]--;
            }
        }
        else
        {
            puts("Impossible");
            return 0;
        }
    }
    clr(uses, 0);
    vvi ans;
    forn(i, n)
        if(!uses[i + 1])
        {
            vi tmp;
            for(int c = i + 1; !uses[c]; )
            {
                tmp.pb(c);
                uses[c] = 1;
                forn(j, n)
                    if(abs(mf[c][j + 1]) == 1 && !uses[j + 1])
                    {
                        c = j + 1;
                        break;
                    }
            }
            if (c != i+1)
                return 1;
            ans.pb(tmp);
        }
    printf("%d\n", sz(ans));
    forn(i, sz(ans))
    {
        printf("%d", sz(ans[i]));
        forn(j, sz(ans[i]))
            printf(" %d", ans[i][j]);
        puts("");
    }
    /*forn(i, n + 2)
    {
        forn(j, n + 2)
            printf("%d ", mf[i][j]);
        puts("");
    }*/
    return 0;
}


#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
#include <iostream>
#include <set>
#include <cmath>
#include <cstring>
#include <bitset>
#include <deque>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef vector<vi> vvi;

#define mp make_pair
#define pb push_back
#define bpc(a) __builtin_popcount(a)
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define clr(ar,val) memset(ar, val, sizeof(ar))
#define forn(i,n) for(int i=0;i<(n);++i)
#define X first
#define Y second
#define debug(x) { cerr<<#x<<" = "<<(x)<<endl; }

const int mod = 1e9 + 7;
const int inf = 1e9;

ll powm(ll a,ll p,ll m){ll r=1 % m;while(p){if(p&1)r=r*a%m;p>>=1;a=a*a%m;}return r;}

bool issimple(int d)
{
    for(int i = 2; i * i <= d; ++i)
        if(d % i == 0)
            return false;
    return true;
}

int g[210][210], n, f[210], s = 0, t, mf[210][210], uses[210];

vi path;

bool bfs()
{
    deque<int> q;
    q.pb(s);
    vi d(n + 2, -1);
    d[s] = 0;
    while(!q.empty())
    {
        int v = q.front();
        q.pop_front();
        forn(i, n + 2)
            if(g[v][i] > mf[v][i] && d[i] == -1)
            {
                d[i] = v;
                q.pb(i);
            }
    }
    if(d[t] != -1)
    {
        path.clear();
        int cur = t;
        while(cur != s)
        {
            path.pb(cur);
            cur = d[cur];
        }
        path.pb(s);
        reverse(all(path));
    }
    return d[t] != -1;
}

int main()
{
    scanf("%d", &n);
    t = n + 1;
    int odd = 0;
    forn(i, n)
    {
        scanf("%d", f + i + 1);
        if(f[i + 1] % 2 == 1)
            g[s][i + 1] = 2, odd++;
        else
            g[i + 1][t] = 2;
    }
    if(2 * odd != n)
    {
        puts("Impossible");
        return 0;
    }
    forn(i, n)
        forn(j, n)
            if(f[i + 1] % 2)
                g[i + 1][j + 1] = issimple(f[i + 1] + f[j + 1]);
    forn(i, n)
    {
        if(bfs())
        {
            forn(j, sz(path) - 1)
            {
                int u = path[j], v = path[j + 1];
                mf[u][v]++;
                mf[v][u]--;
            }
        }
        else
        {
            puts("Impossible");
            return 0;
        }
    }
    clr(uses, 0);
    vvi ans;
    forn(i, n)
        if(!uses[i + 1])
        {
            vi tmp;
            int c;
            for(c = i + 1; !uses[c];)
            {
                tmp.pb(c);
                uses[c] = 1;
                forn(j, n)
                    if(abs(mf[c][j + 1]) == 1 && !uses[j + 1])
                    {
                        c = j + 1;
                        break;
                    }
            }
            //if (abs(mf[c][i+1]) != 1)
            //    return 1;
            ans.pb(tmp);
        }
    forn(i, n)
    {
        bool fl = false;
        int cnt = 0;
        forn(j, n)
            /*if(mf[0][i + 1] == 2)
                fl |= mf[i + 1][j + 1] == -1;
            else
                fl |= mf[i + 1][j + 1] == 1;*/
            cnt += abs(mf[i + 1][j + 1]);
        if(fl || cnt != 2)
        {
            /*printf("%d\n", cnt);
            forn(j, n - 100)
            {
                printf("%d ", f[j+101]);
                //if ((j + 1) % 80 == 0)
                //    printf("\n");
            }*/
            return 1;
        }
    }
    printf("%d\n", sz(ans));
    forn(i, sz(ans))
    {
        printf("%d", sz(ans[i]));
        forn(j, sz(ans[i]))
            printf(" %d", ans[i][j]);
        puts("");
    }
    /*forn(i, n + 2)
    {
        forn(j, n + 2)
            printf("%d ", mf[i][j]);
        puts("");
    }*/

    return 0;
}


#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
#include <iostream>
#include <set>
#include <cmath>
#include <cstring>
#include <bitset>
#include <deque>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef vector<vi> vvi;

#define mp make_pair
#define pb push_back
#define bpc(a) __builtin_popcount(a)
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define clr(ar,val) memset(ar, val, sizeof(ar))
#define forn(i,n) for(int i=0;i<(n);++i)
#define X first
#define Y second
#define debug(x) { cerr<<#x<<" = "<<(x)<<endl; }

const int mod = 1e9 + 7;
const int inf = 1e9;

ll powm(ll a,ll p,ll m){ll r=1 % m;while(p){if(p&1)r=r*a%m;p>>=1;a=a*a%m;}return r;}

bool issimple(int d)
{
    for(int i = 2; i * i <= d; ++i)
        if(d % i == 0)
            return false;
    return true;
}

int g[210][210], n, f[210], s = 0, t, mf[210][201], uses[210];

vi path;

bool bfs()
{
    deque<int> q;
    q.pb(s);
    vi d(n + 2, -1);
    d[s] = 0;
    while(!q.empty())
    {
        int v = q.front();
        q.pop_front();
        forn(i, n + 2)
            if(g[v][i] > mf[v][i] && d[i] == -1)
            {
                d[i] = v;
                q.pb(i);
            }
    }
    if(d[t] != -1)
    {
        path.clear();
        int cur = t;
        while(cur != s)
        {
            path.pb(cur);
            cur = d[cur];
        }
        path.pb(s);
        reverse(all(path));
    }
    return d[t] != -1;
}

int main()
{
    scanf("%d", &n);
    t = n + 1;
    int odd = 0;
    forn(i, n)
    {
        scanf("%d", f + i + 1);
        if(f[i + 1] % 2 == 1)
            g[s][i + 1] = 2, odd++;
        else
            g[i + 1][t] = 2;
    }
    if(2 * odd != n)
    {
        puts("Impossible");
        return 0;
    }
    forn(i, n)
        forn(j, n)
            g[i + 1][j + 1] = g[j + 1][i + 1] = issimple(f[i + 1] + f[j + 1]);
    forn(i, n)
    {
        if(bfs())
        {
            forn(j, sz(path) - 1)
            {
                int u = path[j], v = path[j + 1];
                mf[u][v]++;
                mf[v][u]--;
            }
        }
        else
        {
            puts("Impossible");
            return 0;
        }
    }
    clr(uses, 0);
    vvi ans;
    forn(i, n)
        if(!uses[i + 1])
        {
            vi tmp;
            int c;
            for(c = i + 1; !uses[c];)
            {
                tmp.pb(c);
                uses[c] = 1;
                forn(j, n)
                    if(abs(mf[c][j + 1]) == 1 && !uses[j + 1])
                    {
                        c = j + 1;
                        break;
                    }
            }
            //if (abs(mf[c][i+1]) != 1)
            //    return 1;
            ans.pb(tmp);
        }
    printf("%d\n", sz(ans));
    forn(i, sz(ans))
    {
        printf("%d", sz(ans[i]));
        forn(j, sz(ans[i]))
            printf(" %d", ans[i][j]);
        puts("");
    }
    /*forn(i, n + 2)
    {
        forn(j, n + 2)
            printf("%d ", mf[i][j]);
        puts("");
    }*/
    forn(i, n)
    {
        bool fl = false;
        forn(j, n)
            if(mf[0][i + 1] == 2)
                fl |= mf[i + 1][j + 1] == -1;
            else
                fl |= mf[i + 1][j + 1] == 1;
        if(fl)
            return 1;
    }
    return 0;
}


#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
#include <iostream>
#include <set>
#include <cmath>
#include <cstring>
#include <bitset>
#include <deque>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef vector<vi> vvi;

#define mp make_pair
#define pb push_back
#define bpc(a) __builtin_popcount(a)
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define clr(ar,val) memset(ar, val, sizeof(ar))
#define forn(i,n) for(int i=0;i<(n);++i)
#define X first
#define Y second
#define debug(x) { cerr<<#x<<" = "<<(x)<<endl; }

const int mod = 1e9 + 7;
const int inf = 1e9;

ll powm(ll a,ll p,ll m){ll r=1 % m;while(p){if(p&1)r=r*a%m;p>>=1;a=a*a%m;}return r;}

bool issimple(int d)
{
    for(int i = 2; i * i <= d; ++i)
        if(d % i == 0)
            return false;
    return true;
}

int g[210][210], n, f[210], s = 0, t, mf[210][201], uses[210];

vi path;

bool bfs()
{
    deque<int> q;
    q.pb(s);
    vi d(n + 2, -1);
    d[s] = 0;
    while(!q.empty())
    {
        int v = q.front();
        q.pop_front();
        forn(i, n + 2)
            if(g[v][i] > mf[v][i] && d[i] == -1)
            {
                d[i] = v;
                q.pb(i);
            }
    }
    if(d[t] != -1)
    {
        path.clear();
        int cur = t;
        while(cur != s)
        {
            path.pb(cur);
            cur = d[cur];
        }
        path.pb(s);
        reverse(all(path));
    }
    return d[t] != -1;
}

int main()
{
    scanf("%d", &n);
    t = n + 1;
    int odd = 0;
    forn(i, n)
    {
        scanf("%d", f + i + 1);
        if(f[i + 1] % 2 == 1)
            g[s][i + 1] = 2, odd++;
        else
            g[i + 1][t] = 2;
    }
    if(2 * odd != n)
    {
        puts("Impossible");
        return 0;
    }
    forn(i, n)
        forn(j, n)
            if(f[i + 1] % 2)
                g[i + 1][j + 1] = issimple(f[i + 1] + f[j + 1]);
    forn(i, n)
    {
        if(bfs())
        {
            forn(j, sz(path) - 1)
            {
                int u = path[j], v = path[j + 1];
                mf[u][v]++;
                mf[v][u]--;
            }
        }
        else
        {
            puts("Impossible");
            return 0;
        }
    }
    clr(uses, 0);
    vvi ans;
    forn(i, n)
        if(!uses[i + 1])
        {
            vi tmp;
            int c;
            for(c = i + 1; !uses[c];)
            {
                tmp.pb(c);
                uses[c] = 1;
                forn(j, n)
                    if(abs(mf[c][j + 1]) == 1 && !uses[j + 1])
                    {
                        c = j + 1;
                        break;
                    }
            }
            //if (abs(mf[c][i+1]) != 1)
            //    return 1;
            ans.pb(tmp);
        }
    printf("%d\n", sz(ans));
    forn(i, sz(ans))
    {
        printf("%d", sz(ans[i]));
        forn(j, sz(ans[i]))
            printf(" %d", ans[i][j]);
        puts("");
    }
    /*forn(i, n + 2)
    {
        forn(j, n + 2)
            printf("%d ", mf[i][j]);
        puts("");
    }*/
    forn(i, n)
    {
        bool fl = false;
        forn(j, n)
            if(mf[0][i + 1] == 2)
                fl |= mf[i + 1][j + 1] == -1;
            else
                fl |= mf[i + 1][j + 1] == 1;
        if(fl)
            return 1;
    }
    return 0;
}


#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
#include <iostream>
#include <set>
#include <cmath>
#include <cstring>
#include <bitset>
#include <deque>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef vector<vi> vvi;

#define mp make_pair
#define pb push_back
#define bpc(a) __builtin_popcount(a)
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define clr(ar,val) memset(ar, val, sizeof(ar))
#define forn(i,n) for(int i=0;i<(n);++i)
#define X first
#define Y second
#define debug(x) { cerr<<#x<<" = "<<(x)<<endl; }

const int mod = 1e9 + 7;
const int inf = 1e9;

ll powm(ll a,ll p,ll m){ll r=1 % m;while(p){if(p&1)r=r*a%m;p>>=1;a=a*a%m;}return r;}

bool issimple(int d)
{
    for(int i = 2; i * i <= d; ++i)
        if(d % i == 0)
            return false;
    return true;
}

int g[210][210], n, f[210], s = 0, t, mf[210][201], uses[210];

vi path;

bool bfs()
{
    deque<int> q;
    q.pb(s);
    vi d(n + 2, -1);
    d[s] = 0;
    while(!q.empty())
    {
        int v = q.front();
        q.pop_front();
        forn(i, n + 2)
            if(g[v][i] > mf[v][i] && d[i] == -1)
            {
                d[i] = v;
                q.pb(i);
            }
    }
    if(d[t] != -1)
    {
        path.clear();
        int cur = t;
        while(cur != s)
        {
            path.pb(cur);
            cur = d[cur];
        }
        path.pb(s);
        reverse(all(path));
    }
    return d[t] != -1;
}

int main()
{
    scanf("%d", &n);
    t = n + 1;
    int odd = 0;
    forn(i, n)
    {
        scanf("%d", f + i + 1);
        if(f[i + 1] % 2 == 1)
            g[s][i + 1] = 2, odd++;
        else
            g[i + 1][t] = 2;
    }
    if(2 * odd != n)
    {
        puts("Impossible");
        return 0;
    }
    forn(i, n)
        forn(j, n)
            g[i + 1][j + 1] = g[j + 1][i + 1] = issimple(f[i + 1] + f[j + 1]);
    forn(i, n)
    {
        if(bfs())
        {
            forn(j, sz(path) - 1)
            {
                int u = path[j], v = path[j + 1];
                mf[u][v]++;
                mf[v][u]--;
            }
        }
        else
        {
            puts("Impossible");
            return 0;
        }
    }
    clr(uses, 0);
    vvi ans;
    forn(i, n)
        if(!uses[i + 1])
        {
            vi tmp;
            int c;
            for(c = i + 1; !uses[c];)
            {
                tmp.pb(c);
                uses[c] = 1;
                forn(j, n)
                    if(abs(mf[c][j + 1]) == 1 && !uses[j + 1])
                    {
                        c = j + 1;
                        break;
                    }
            }
            //if (abs(mf[c][i+1]) != 1)
            //    return 1;
            ans.pb(tmp);
        }
    printf("%d\n", sz(ans));
    forn(i, sz(ans))
    {
        printf("%d", sz(ans[i]));
        forn(j, sz(ans[i]))
            printf(" %d", ans[i][j]);
        puts("");
    }
    /*forn(i, n + 2)
    {
        forn(j, n + 2)
            printf("%d ", mf[i][j]);
        puts("");
    }*/
    forn(i, n)
    {
        forn(j, n)

        if(abs(mf[i + 1][j + 1]) > 1)
            return 1;
    }
    return 0;
}


#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
#include <iostream>
#include <set>
#include <cmath>
#include <cstring>
#include <bitset>
#include <deque>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef vector<vi> vvi;

#define mp make_pair
#define pb push_back
#define bpc(a) __builtin_popcount(a)
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define clr(ar,val) memset(ar, val, sizeof(ar))
#define forn(i,n) for(int i=0;i<(n);++i)
#define X first
#define Y second
#define debug(x) { cerr<<#x<<" = "<<(x)<<endl; }

const int mod = 1e9 + 7;
const int inf = 1e9;

ll powm(ll a,ll p,ll m){ll r=1 % m;while(p){if(p&1)r=r*a%m;p>>=1;a=a*a%m;}return r;}

bool issimple(int d)
{
    for(int i = 2; i * i <= d; ++i)
        if(d % i == 0)
            return false;
    return true;
}

int g[210][210], n, f[210], s = 0, t, mf[210][201], uses[210];

vi path;

bool bfs()
{
    deque<int> q;
    q.pb(s);
    vi d(n + 2, -1);
    d[s] = 0;
    while(!q.empty())
    {
        int v = q.front();
        q.pop_front();
        forn(i, n + 2)
            if(g[v][i] > mf[v][i] && d[i] == -1)
            {
                d[i] = v;
                q.pb(i);
            }
    }
    if(d[t] != -1)
    {
        path.clear();
        int cur = t;
        while(cur != s)
        {
            path.pb(cur);
            cur = d[cur];
        }
        path.pb(s);
        reverse(all(path));
    }
    return d[t] != -1;
}

int main()
{
    scanf("%d", &n);
    t = n + 1;
    int odd = 0;
    forn(i, n)
    {
        scanf("%d", f + i + 1);
        if(f[i + 1] % 2 == 1)
            g[s][i + 1] = 2, odd++;
        else
            g[i + 1][t] = 2;
    }
    if(2 * odd != n)
    {
        puts("Impossible");
        return 0;
    }
    forn(i, n)
        forn(j, n)
            g[i + 1][j + 1] = g[j + 1][i + 1] = issimple(f[i + 1] + f[j + 1]);
    forn(i, n)
    {
        if(bfs())
        {
            forn(j, sz(path) - 1)
            {
                int u = path[j], v = path[j + 1];
                mf[u][v]++;
                mf[v][u]--;
            }
        }
        else
        {
            puts("Impossible");
            return 0;
        }
    }
    clr(uses, 0);
    vvi ans;
    forn(i, n)
        if(!uses[i + 1])
        {
            vi tmp;
            for(int c = i + 1; !uses[c]; )
            {
                tmp.pb(c);
                uses[c] = 1;
                forn(j, n)
                    if(abs(mf[c][j + 1]) == 1 && !uses[j + 1])
                    {
                        c = j + 1;
                        break;
                    }
            }
            ans.pb(tmp);
        }
    printf("%d\n", sz(ans));
    forn(i, sz(ans))
    {
        printf("%d", sz(ans[i]));
        forn(j, sz(ans[i]))
            printf(" %d", ans[i][j]);
        puts("");
    }
    /*forn(i, n + 2)
    {
        forn(j, n + 2)
            printf("%d ", mf[i][j]);
        puts("");
    }*/
    return 0;
}


#include <cstdio>

#ifdef WIN32
	#define LL "%lld"
#else
	#define LL "%I64d"
#endif

#ifdef Lightning
	const bool DEBUG_FLAG = 1;
#else
	const bool DEBUG_FLAG = 0;
#endif
#define DEBUG if (DEBUG_FLAG)

const int N = 210;
const int M = 50000;
const int Inf = 666666;

#define min(aa,bb) ((aa) < (bb) ? (aa) : (bb))

int GetInt()
{
	register int aa = 0, bb = 1;
	register char ch = getchar();
	while ((ch < '0' || ch > '9') && ch != '-')
		ch = getchar();
	ch == '-' ? aa = 0, bb = -1 : aa = ch - '0';
	while (ch = getchar(), ch >= '0' && ch <= '9')
		aa = (aa << 1) + (aa << 3) + ch - '0';
	return bb == 1 ? aa : -aa;
}

int n, num[N], P[20010], Lim, S, T, Odd, Deg[N];
int Ep[M], Et[M], Ef[M], Last[N], Cur[N], En = 1;
int Dis[N], Gap[N], Link[N][2], Fa[N], Siz[N], Vis[N];

void Insert(int from, int to, int flow)
{
	Et[++En] = to;
	Ef[En] = flow;
	Ep[En] = Last[from];
	Last[from] = En;
	DEBUG printf("EDGE-%d : %d---%d--->%d\n", En, from, flow, to);
	if (!(En & 1)) Insert(to, from, 0);
}

void Draw()
{
	register int i, j;
	S = n + 1;
	T = S + 1;
	for (i = 1; i <= n; i++)
	{
		if (num[i] & 1)
		{
			Odd++;
			Insert(i, T, 2);
		} else
		{
			Insert(S, i, 2);
			for (j = 1; j <= n; j++)
			{
				if (!P[num[i] + num[j]])
				{
					Insert(i, j, 1);
					Deg[i]++;
					Deg[j]++;
				}
			}
		}
	}
}

int Sap(int now, int flow)
{
	if (now == T) return flow;
	register int i, Tmp, Ret = 0;
	for (i = Cur[now]; i; i = Ep[i])
	{
		Cur[now] = i;
		if (Ef[i] > 0 && Dis[now] == Dis[Et[i]] + 1)
		{
			Tmp = Sap(Et[i], min(Ef[i], flow - Ret));
			Ret += Tmp;
			Ef[i] -= Tmp;
			Ef[i ^ 1] += Tmp;
			if (Ret == flow) return Ret;
		}
	}
	Cur[now] = Last[now];
	if (--Gap[Dis[now]] <= 0) Dis[S] = T + 1;
	++Gap[++Dis[now]];
	return Ret;
}

int MaxFlow()
{
	DEBUG puts("Sap Begin");
	register int i, Ret = 0;
	for (i = 1; i <= T; i++)
	{
		Cur[i] = Last[i];
		Dis[i] = 0;
		Gap[i] = 0;
	}
	Gap[0] = T;
	while (Dis[S] <= T)
	{
		Ret += Sap(S, Inf);
	}
	DEBUG printf("Flow : %d\n", Ret);
	return Ret;
}

int Find(int x)
{
	return Fa[x] == x ? x : Fa[x] = Find(Fa[x]);
}

void Union(int a, int b)
{
	a = Find(a);
	b = Find(b);
	if (a != b)
	{
		Fa[a] = b;
		Siz[b] += Siz[a];
	}
}

void Print(int x)
{
	Vis[x] = 1;
	printf("%d ", x);
	if (!Vis[Link[x][0]])
		Print(Link[x][0]);
	if (!Vis[Link[x][1]])
		Print(Link[x][1]);
}

int main()
{
	register int i, j, Ans = 0;
	n = GetInt();
	for (i = 1; i <= n; i++)
	{
		num[i] = GetInt();
		num[i] > Lim ? Lim = num[i] : 0;
	}
	Lim <<= 1;
	for (i = 2; i <= Lim; i++)
	{
		if (P[i]) continue;
		for (j = i * i; j <= Lim; j += i)
			P[j] = 1;
	}
	Draw();
	for (i = 1; i <= n; i++)
	{
		if (Deg[i] < 2)
		{
			DEBUG printf("Wrong at %d!\n", i);
			Odd = 0;
		}
	}
	if (Odd * 2 != n)
	{
		puts("Impossible");
		return 0;
	}
	if (MaxFlow() < n)
	{
		puts("Impossible");
	} else
	{
		DEBUG puts("Yes");
		for (i = 1; i <= n; i++)
			Fa[i] = i, Siz[i] = 1;
		for (i = 1; i <= n; i++)
		{
			for (j = Last[i]; j; j = Ep[j])
			{
				if (Et[j] < S && Ef[j & (j ^ 1)] == 0)
				{
					Link[i][Link[i][0] > 0] = Et[j];
					Union(Et[j], i);
				}
			}
		}
		for (i = 1; i <= n; i++)
			if (Find(i) == i) Ans++;
		printf("%d\n", Ans);
		for (i = 1; i <= n; i++)
		{
			if (Fa[i] == i)
			{
				printf("%d ", Siz[i]);
				Print(i);
				puts("");
			}
		}
	}
}


#include<iostream>
#include<map>
#include<queue>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
using namespace std;
vector<int>res[300];
int cas;
int pri[100000];
int a[300],p[300],q[300];
vector<int>M[300];
int n;
struct E{
    int v,w,k;
}e[40000];
int len;
vector<int>G[300];
int level[300];
int item[300];
void add(int u,int v,int w){
    G[u].push_back(len);e[len].v=v,e[len].w=w,e[len].k=len+1;len++;
    G[v].push_back(len);e[len].v=u,e[len].w=0,e[len].k=len-1;len++;
}
void init(){
    len=0;
    for(int i=0;i<300;i++) G[i].clear();
}
bool bfs(int s,int t){
    queue<int>q;
    while(!q.empty()) q.pop();
    q.push(s);
    memset(level,-1,sizeof(level));
    level[s]=0;
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=0;i<G[u].size();i++){
            int k=G[u][i],v=e[k].v;
            if(level[v]==-1&&e[k].w){
                level[v]=level[u]+1;
                q.push(v);
            }
        }
    }
    if(level[t]==-1) return 0;
    return 1;
}
int dfs(int u,int t,int f){
    if(u==t) return f;
    for(int &i=item[u];i<G[u].size();i++){
        int k1=G[u][i],v=e[k1].v,k2=e[k1].k;
        if(level[v]>level[u]&&e[k1].w){
            int flow=dfs(v,t,min(f,e[k1].w));
            if(flow){
                e[k1].w-=flow;
                e[k2].w+=flow;
                return flow;
            }
        }
    }
    return 0;
}
int dinic(int s,int t){
    int ans=0;
    while(bfs(s,t)){
        int flow;
        memset(item,0,sizeof(item));
        while((flow=dfs(s,t,inf))) ans+=flow;
    }
    return ans;
}
int vis[300];
void work(int s,int cur){
    if(vis[s]&&cur==s) return ;
    vis[cur]=1;
    res[cas].push_back(cur);
    for(int i=0;i<M[cur].size();i++){
        if(!vis[M[cur][i]]){
            work(s,M[cur][i]);
            return ;
        }
    }
}
int main(){
    pri[5]=pri[2]=pri[3]=1;
    for(int i=6;i<100000;i++){
        int flag=1;
        for(int j=2;j<sqrt(i)+1;j++){
            if(i%j==0) {
                flag=0;
                break;
            }
        }
        if(flag) pri[i]=1;
    }
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    int temp=0;
    for(int i=1;i<=n;i++){
        if(a[i]%2==0) add(i,n+1,2),temp+=2;
        else add(0,i,2);
        for(int j=i+1;j<=n;j++){
            if(pri[a[i]+a[j]]==1){
                if(a[i]%2==0) add(j,i,1);
                else  add(i,j,1);
            }
        }
    }
    int ans=dinic(0,n+1);
    if(ans!=temp) {
        printf("Impossible\n");
        return 0;
    }
    for(int u=1;u<=n;u++)
        if(a[u]%2==1){
            for(int j=0;j<G[u].size();j++){
                int k=G[u][j],v=e[k].v;
                if(e[k].w==0){
                    M[u].push_back(v);
                    M[v].push_back(u);
                }
            }
        }
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++){
        if(a[i]%2==1&&!vis[i]){
            work(i,i);
            cas++;
        }
    }
    for(int i=0;i<cas;i++){
        printf("%lu",res[i].size());
        for(int j=0;j<res[i].size();j++){
            printf(" %d",res[i][j]);
        }
        printf("\n");
    }
}


#include<iostream>
#include<map>
#include<queue>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
using namespace std;
vector<int>res[300];
int cas;
int pri[100000];
int a[300],p[300],q[300];
vector<int>M[300];
int n;
struct E{
    int v,w,k;
}e[40000];
int len;
vector<int>G[300];
int level[300];
int item[300];
void add(int u,int v,int w){
    G[u].push_back(len);e[len].v=v,e[len].w=w,e[len].k=len+1;len++;
    G[v].push_back(len);e[len].v=u,e[len].w=0,e[len].k=len-1;len++;
}
void init(){
    len=0;
    for(int i=0;i<300;i++) G[i].clear();
}
bool bfs(int s,int t){
    queue<int>q;
    while(!q.empty()) q.pop();
    q.push(s);
    memset(level,-1,sizeof(level));
    level[s]=0;
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=0;i<G[u].size();i++){
            int k=G[u][i],v=e[k].v;
            if(level[v]==-1&&e[k].w){
                level[v]=level[u]+1;
                q.push(v);
            }
        }
    }
    if(level[t]==-1) return 0;
    return 1;
}
int dfs(int u,int t,int f){
    if(u==t) return f;
    for(int &i=item[u];i<G[u].size();i++){
        int k1=G[u][i],v=e[k1].v,k2=e[k1].k;
        if(level[v]>level[u]&&e[k1].w){
            int flow=dfs(v,t,min(f,e[k1].w));
            if(flow){
                e[k1].w-=flow;
                e[k2].w+=flow;
                return flow;
            }
        }
    }
    return 0;
}
int dinic(int s,int t){
    int ans=0;
    while(bfs(s,t)){
        int flow;
        memset(item,0,sizeof(item));
        while((flow=dfs(s,t,inf))) ans+=flow;
    }
    return ans;
}
int vis[300];
void work(int s,int cur){
    if(vis[s]&&cur==s) return ;
    vis[cur]=1;
    res[cas].push_back(cur);
    for(int i=0;i<M[cur].size();i++){
        if(!vis[M[cur][i]]){
            work(s,M[cur][i]);
            return ;
        }
    }
}
int main(){
    pri[5]=pri[2]=pri[3]=1;
    for(int i=6;i<100000;i++){
        int flag=1;
        for(int j=2;j<sqrt(i)+1;j++){
            if(i%j==0) {
                flag=0;
                break;
            }
        }
        if(flag) pri[i]=1;
    }
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    int temp=0;
    for(int i=1;i<=n;i++){
        if(a[i]%2==0) add(i,n+1,2),temp+=2;
        else add(0,i,2);
        for(int j=i+1;j<=n;j++){
            if(pri[a[i]+a[j]]==1){
                if(a[i]%2==0) add(j,i,1);
                else  add(i,j,1);
            }
        }
    }
    int ans=dinic(0,n+1);
    if(ans!=temp) {
        printf("Impossible\n");
        return 0;
    }
    for(int u=1;u<=n;u++)
        if(a[u]%2==1){
            for(int j=0;j<G[u].size();j++){
                int k=G[u][j],v=e[k].v;
                if(e[k].w==0){
                    M[u].push_back(v);
                    M[v].push_back(u);
                }
            }
        }
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++){
        if(a[i]%2==1&&!vis[i]){
            work(i,i);
            cas++;
        }
    }
    for(int i=0;i<cas;i++){
        printf("%d",res[i].size());
        for(int j=0;j<res[i].size();j++){
            printf(" %d",res[i][j]);
        }
        printf("\n");
    }
}


#include<iostream>
#include<map>
#include<queue>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
using namespace std;
vector<int>res[300];
int cas;
int pri[100000];
int a[300],p[300],q[300];
vector<int>M[300];
int n;
struct E{
    int v,w,k;
}e[40000];
int len;
vector<int>G[300];
int level[300];
int item[300];
void add(int u,int v,int w){
    G[u].push_back(len);e[len].v=v,e[len].w=w,e[len].k=len+1;len++;
    G[v].push_back(len);e[len].v=u,e[len].w=0,e[len].k=len-1;len++;
}
void init(){
    len=0;
    for(int i=0;i<300;i++) G[i].clear();
}
bool bfs(int s,int t){
    queue<int>q;
    while(!q.empty()) q.pop();
    q.push(s);
    memset(level,-1,sizeof(level));
    level[s]=0;
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=0;i<G[u].size();i++){
            int k=G[u][i],v=e[k].v;
            if(level[v]==-1&&e[k].w){
                level[v]=level[u]+1;
                q.push(v);
            }
        }
    }
    if(level[t]==-1) return 0;
    return 1;
}
int dfs(int u,int t,int f){
    if(u==t) return f;
    for(int &i=item[u];i<G[u].size();i++){
        int k1=G[u][i],v=e[k1].v,k2=e[k1].k;
        if(level[v]>level[u]&&e[k1].w){
            int flow=dfs(v,t,min(f,e[k1].w));
            if(flow){
                e[k1].w-=flow;
                e[k2].w+=flow;
                return flow;
            }
        }
    }
    return 0;
}
int dinic(int s,int t){
    int ans=0;
    while(bfs(s,t)){
        int flow;
        memset(item,0,sizeof(item));
        while((flow=dfs(s,t,inf))) ans+=flow;
    }
    return ans;
}
int vis[300];
void work(int s,int cur){
    if(vis[s]&&cur==s) return ;
    vis[cur]=1;
    res[cas].push_back(cur);
    for(int i=0;i<M[cur].size();i++){
        if(!vis[M[cur][i]]){
            work(s,M[cur][i]);
            return ;
        }
    }
}
int main(){
    pri[5]=pri[2]=pri[3]=1;
    for(int i=6;i<100000;i++){
        int flag=1;
        for(int j=2;j<sqrt(i)+1;j++){
            if(i%j==0) {
                flag=0;
                break;
            }
        }
        if(flag) pri[i]=1;
    }
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    int temp=0;
    for(int i=1;i<=n;i++){
        if(a[i]%2==0) add(i,n+1,2),temp+=2;
        else add(0,i,2);
        for(int j=i+1;j<=n;j++){
            if(pri[a[i]+a[j]]==1){
                if(a[i]%2==0) add(j,i,1);
                else  add(i,j,1);
            }
        }
    }
    int ans=dinic(0,n+1);
    if(ans!=temp) {
        printf("Impossible\n");
        return 0;
    }
    for(int u=1;u<=n;u++)
        if(a[u]%2==1){
            for(int j=0;j<G[u].size();j++){
                int k=G[u][j],v=e[k].v;
                if(e[k].w==0){
                    M[u].push_back(v);
                    M[v].push_back(u);
                }
            }
        }
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++){
        if(a[i]%2==1&&!vis[i]){
            work(i,i);
            cas++;
        }
    }
    printf("%d\n",cas);
    for(int i=0;i<cas;i++){
        printf("%d",res[i].size());
        for(int j=0;j<res[i].size();j++){
            printf(" %d",res[i][j]);
        }
        printf("\n");
    }
}


#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
struct node
{
    int from;
    int to;
    int w;
    int next;
}e[1515151];
vector<int >mp[2050];
int vis[2050];
int head[2050];
int cur[2050];
int divv[2050];
int lx[2050];
int ly[2050];
int a[205];
int Is_or[165550];//0????
int n,cont,ss,tt,contx,conty;
void add(int from,int to,int w)
{
    e[cont].from=from;
    e[cont].to=to;
    e[cont].w=w;
    e[cont].next=head[from];
    head[from]=cont++;
}
void init()
{
    memset(Is_or,0,sizeof(Is_or));
    for(int j=2;j<sqrt(165540);j++)
    {
        if(Is_or[j]==0)
        for(int k=j+j;k<=165540;k+=j)
        Is_or[k]=1;
    }
}
void getmap()
{
    cont=0;
    ss=n+1;
    tt=ss+1;
    contx=0,conty=0;
    memset(head,-1,sizeof(head));
    for(int i=1;i<=n;i++)
    {
        if(a[i]%2==0)
        {
            add(ss,i,2);
            add(i,ss,0);
            lx[contx++]=i;
        }
        else
        {
            add(i,tt,2);
            add(tt,i,0);
            ly[conty++]=i;
        }
    }
    for(int i=0;i<contx;i++)
    {
        for(int j=0;j<conty;j++)
        {
            if(Is_or[a[lx[i]]+a[ly[j]]]==0)
            {
                add(lx[i],ly[j],1);
                add(ly[j],lx[i],0);
            }
        }
    }
}
int makedivv()
{
    queue<int >s;
    s.push(ss);
    memset(divv,0,sizeof(divv));
    divv[ss]=1;
    while(!s.empty())
    {
        int u=s.front();
        if(u==tt)return 1;
        s.pop();
        for(int i=head[u];i!=-1;i=e[i].next)
        {
            int v=e[i].to;
            int w=e[i].w;
            if(w&&divv[v]==0)
            {
                divv[v]=divv[u]+1;
                s.push(v);
            }
        }
    }
    return 0;
}
int Dfs(int u,int maxflow,int tt)
{
    if(u==tt)return maxflow;
    int ret=0;
    for(int &i=cur[u];i!=-1;i=e[i].next)
    {
        int v=e[i].to;
        int w=e[i].w;
        if(w&&divv[v]==divv[u]+1)
        {
            int f=Dfs(v,min(maxflow-ret,w),tt);
            e[i].w-=f;
            e[i^1].w+=f;
            ret+=f;
            if(ret==maxflow)return ret;
        }
    }
    return ret;
}
int Dinic()
{
    int ans=0;
    while(makedivv()==1)
    {
        memcpy(cur,head,sizeof(head));
        ans+=Dfs(ss,0x3f3f3f3f,tt);
    }
    return ans;
}
void Dfss(int u,int tot)
{
    mp[tot].push_back(u);
    vis[u]=1;
    for(int i=head[u];i!=-1;i=e[i].next)
    {
        int v=e[i].to;
        if(vis[v]==1)continue;
        int w=e[i].w;
        if(v!=ss&&v!=tt)
        {
            if(i%2==0&&w==0)
            {
                Dfss(v,tot);
            }
            if(i%2==1&&e[i^1].w==0)
            {
                Dfss(v,tot);
            }
        }
    }
}
int main()
{
    init();
    while(~scanf("%d",&n))
    {
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            mp[i].clear();
        }
        getmap();
        int tmp=Dinic();
        if(tmp==n)
        {
            int tot=0;
            for(int i=1;i<=n;i++)
            {
                if(vis[i]==0)
                {
                    Dfss(i,++tot);
                }
            }
            printf("%d\n",tot);
            for(int i=1;i<=tot;i++)
            {
                printf("%d",mp[i].size());
                for(int j=0;j<mp[i].size();j++)
                {
                    printf(" %d",mp[i][j]);
                }
                printf("\n");
            }
        }
        else printf("Impossible\n");
    }
}


//
//  main.cpp
//  cf510e
//
//  Created by eycia on 15/2/11.
//  Copyright (c) 2015年 eycia. All rights reserved.
//

#include <iostream>
#include <queue>
#include <cstring>
#include <sstream>
#include <iomanip>
#include <cmath>
using namespace std;

#define INF 0x7fffffff
#define ST 0
#define EN (n+1)

int n;
int a[205];

int g[205][205];
int f[205][205];
int pre[205];
bool v[205];
int flow[205];

ostringstream ans;

bool isprime(int k) {
    for (int i = 2; i <= sqrt(k); i++) {
        if (k % i == 0) {
            return false;
        }
    }
    return true;
}

int find_one() {
    memset(v, false, sizeof(v));
    queue<int> q;
    q.push(ST);
    v[ST] = true;
    flow[ST] = INF;
    flow[EN] = 0;

    while (!q.empty()) {
        int s = q.front();
        q.pop();
        for (int i = 1; i <= n+1; i++) {
            if (g[s][i] > 0 && !v[i]) {
                pre[i] = s;
                flow[i] = min(g[s][i], flow[s]);
                v[i] = true;
                q.push(i);
                if (i == EN) {
                    return flow[EN];
                }
            }
        }
    }
    return flow[EN];
}

int zdl() {
    int tot = 0;
    while (int ll = find_one()) {
        int end = EN;
        while (end != ST) {
            g[end][pre[end]] += ll;
            g[pre[end]][end] -= ll;
            f[end][pre[end]] += ll;
            f[pre[end]][end] -= ll;
            end = pre[end];
        }
        tot += ll;
    }
    return tot;
}

void dfs(int st, int now, int tot) {
    if (tot > 0 && now == st) {
        ans << tot << " " << now << " ";
        return;
    }
    for (int i = 1; i <= n; i++) {
        if (!v[i] && f[i][now] != 0) {
            if (f[now][i] > 0) {
                f[now][i]--;
                f[i][now]++;
            } else {
                f[now][i]++;
                f[i][now]--;
            }
            dfs(st, i, tot+1);
            ans << now << " ";
            return;
        }
    }
}

int main(int argc, const char * argv[]) {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        if (a[i] % 2) {
            g[ST][i] = 2;
        } else {
            g[i][EN] = 2;
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (a[i]%2 && !(a[j]%2)) {
                if (isprime(a[i] + a[j])) {
                    g[i][j] = 1;
                }
            }
        }
    }
    if (!zdl() != n) {
        cout << "Impossible" << endl;
        return 0;
    }

    memset(v, false, sizeof(v));
    int tot = 0;
    for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (!v[j] && f[j][i] != 0) {
                    if (f[j][i] > 0) {
                        f[j][i]--;
                        f[i][j]++;
                    } else {
                        f[j][i]++;
                        f[i][j]--;
                    }
                    tot++;
                    dfs(i, j, 1);
                    ans << endl;
                }
            }
    }
    cout << tot << endl;
    cout << ans.str();
}


//
//  main.cpp
//  cf510e
//
//  Created by eycia on 15/2/11.
//  Copyright (c) 2015年 eycia. All rights reserved.
//

#include <iostream>
#include <queue>
#include <cstring>
#include <sstream>
#include <iomanip>
#include <cmath>
using namespace std;

#define INF 0x7fffffff
#define ST 0
#define EN (n+1)

int n;
int a[205];

int g[205][205];
int f[205][205];
int pre[205];
bool v[205];
int flow[205];

ostringstream ans;

bool isprime(int k) {
    for (int i = 2; i <= sqrt(k); i++) {
        if (k % i == 0) {
            return false;
        }
    }
    return true;
}

int find_one() {
    memset(v, false, sizeof(v));
    queue<int> q;
    q.push(ST);
    v[ST] = true;
    flow[ST] = INF;
    flow[EN] = 0;

    while (!q.empty()) {
        int s = q.front();
        q.pop();
        for (int i = 1; i <= n+1; i++) {
            if (g[s][i] > 0 && !v[i]) {
                pre[i] = s;
                flow[i] = min(g[s][i], flow[s]);
                v[i] = true;
                q.push(i);
                if (i == EN) {
                    return flow[EN];
                }
            }
        }
    }
    return flow[EN];
}

int zdl() {
    int tot = 0;
    while (int ll = find_one()) {
        int end = EN;
        while (end != ST) {
            g[end][pre[end]] += ll;
            g[pre[end]][end] -= ll;
            f[end][pre[end]] += ll;
            f[pre[end]][end] -= ll;
            end = pre[end];
        }
        tot += ll;
    }
    return tot;
}

void dfs(int st, int now, int tot) {
    if (tot > 0 && now == st) {
        ans << tot << " " << now << " ";
        return;
    }
    for (int i = 1; i <= n; i++) {
        if (!v[i] && f[i][now] != 0) {
            if (f[now][i] > 0) {
                f[now][i]--;
                f[i][now]++;
            } else {
                f[now][i]++;
                f[i][now]--;
            }
            dfs(st, i, tot+1);
            ans << now << " ";
            return;
        }
    }
}

int main(int argc, const char * argv[]) {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        if (a[i] % 2) {
            g[ST][i] = 2;
        } else {
            g[i][EN] = 2;
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (a[i]%2 && !(a[j]%2)) {
                if (isprime(a[i] + a[j])) {
                    g[i][j] = 1;
                }
            }
        }
    }
    if (!zdl()) {
        cout << "Impossible" << endl;
        return 0;
    }

    memset(v, false, sizeof(v));
    int tot = 0;
    for (int i = 1; i <= n; i++) {
        if (!v[i]) {
            tot++;
            for (int j = 1; j <= n; j++) {
                if (!v[j] && f[j][i] != 0) {
                    if (f[j][i] > 0) {
                        f[j][i]--;
                        f[i][j]++;
                    } else {
                        f[j][i]++;
                        f[i][j]--;
                    }
                    dfs(i, j, 1);
                    ans << endl;
                }
            }
        }
    }
    cout << tot << endl;
    cout << ans.str();
}


//
//  main.cpp
//  cf510e
//
//  Created by eycia on 15/2/11.
//  Copyright (c) 2015年 eycia. All rights reserved.
//

#include <iostream>
#include <queue>
#include <cstring>
#include <sstream>
#include <iomanip>
#include <cmath>
using namespace std;

#define INF 0x7fffffff
#define ST 0
#define EN (n+1)

int n;
int a[205];

int g[205][205];
int f[205][205];
int pre[205];
bool v[205];
int flow[205];

ostringstream ans;

bool isprime(int k) {
    for (int i = 2; i <= sqrt(k); i++) {
        if (k % i == 0) {
            return false;
        }
    }
    return true;
}

int find_one() {
    memset(v, false, sizeof(v));
    queue<int> q;
    q.push(ST);
    v[ST] = true;
    flow[ST] = INF;
    flow[EN] = 0;

    while (!q.empty()) {
        int s = q.front();
        q.pop();
        for (int i = 1; i <= n+1; i++) {
            if (g[s][i] > 0 && !v[i]) {
                pre[i] = s;
                flow[i] = min(g[s][i], flow[s]);
                v[i] = true;
                q.push(i);
                if (i == EN) {
                    return flow[EN];
                }
            }
        }
    }
    return flow[EN];
}

int zdl() {
    int tot = 0;
    while (int ll = find_one()) {
        int end = EN;
        while (end != ST) {
            g[end][pre[end]] += ll;
            g[pre[end]][end] -= ll;
            f[end][pre[end]] += ll;
            f[pre[end]][end] -= ll;
            end = pre[end];
        }
        tot += ll;
    }
    return tot;
}

void dfs(int st, int now, int tot) {
    if (tot > 0 && now == st) {
        ans << tot << " " << now << " ";
        return;
    }
    for (int i = 1; i <= n; i++) {
        if (!v[i] && f[i][now] != 0) {
            if (f[now][i] > 0) {
                f[now][i]--;
                f[i][now]++;
            } else {
                f[now][i]++;
                f[i][now]--;
            }
            dfs(st, i, tot+1);
            ans << now << " ";
            return;
        }
    }
}

int main(int argc, const char * argv[]) {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        if (a[i] % 2) {
            g[ST][i] = 2;
        } else {
            g[i][EN] = 2;
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (a[i]%2 && !(a[j]%2)) {
                if (isprime(a[i] + a[j])) {
                    g[i][j] = 1;
                }
            }
        }
    }
    if (!zdl()) {
        cout << "Impossible" << endl;
        return 0;
    }

    memset(v, false, sizeof(v));
    int tot = 0;
    for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (!v[j] && f[j][i] != 0) {
                    if (f[j][i] > 0) {
                        f[j][i]--;
                        f[i][j]++;
                    } else {
                        f[j][i]++;
                        f[i][j]--;
                    }
                    tot++;
                    dfs(i, j, 1);
                    ans << endl;
                }
            }
    }
    cout << tot << endl;
    cout << ans.str();
}


//
//  main.cpp
//  cf510e
//
//  Created by eycia on 15/2/11.
//  Copyright (c) 2015年 eycia. All rights reserved.
//

#include <iostream>
#include <queue>
#include <cstring>
#include <sstream>
#include <iomanip>
#include <cmath>
using namespace std;

#define INF 0x7fffffff
#define ST 0
#define EN (n+1)

int n;
int a[205];

int g[205][205];
int f[205][205];
int pre[205];
bool v[205];
int flow[205];

ostringstream ans;

bool isprime(int k) {
    for (int i = 2; i <= sqrt(k); i++) {
        if (k % i == 0) {
            return false;
        }
    }
    return true;
}

int find_one() {
    memset(v, false, sizeof(v));
    queue<int> q;
    q.push(ST);
    v[ST] = true;
    flow[ST] = INF;
    flow[EN] = 0;

    while (!q.empty()) {
        int s = q.front();
        q.pop();
        for (int i = 1; i <= n+1; i++) {
            if (g[s][i] > 0 && !v[i]) {
                pre[i] = s;
                flow[i] = min(g[s][i], flow[s]);
                v[i] = true;
                q.push(i);
                if (i == EN) {
                    return flow[EN];
                }
            }
        }
    }
    return flow[EN];
}

int zdl() {
    int tot = 0;
    while (int ll = find_one()) {
        int end = EN;
        while (end != ST) {
            g[end][pre[end]] += ll;
            g[pre[end]][end] -= ll;
            f[end][pre[end]] += ll;
            f[pre[end]][end] -= ll;
            end = pre[end];
        }
        tot += ll;
    }
    return tot;
}

void dfs(int st, int now, int tot) {
    if (tot > 0 && now == st) {
        ans << tot << " " << now << " ";
        return;
    }
    for (int i = 1; i <= n; i++) {
        if (!v[i] && f[i][now] != 0) {
            if (f[now][i] > 0) {
                f[now][i]--;
                f[i][now]++;
            } else {
                f[now][i]++;
                f[i][now]--;
            }
            dfs(st, i, tot+1);
            ans << now << " ";
            return;
        }
    }
}

int main(int argc, const char * argv[]) {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        if (a[i] % 2) {
            g[ST][i] = 2;
        } else {
            g[i][EN] = 2;
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (a[i]%2 && !(a[j]%2)) {
                if (isprime(a[i] + a[j])) {
                    g[i][j] = 1;
                }
            }
        }
    }
    if (zdl() != n) {
        cout << "Impossible" << endl;
        return 0;
    }

    memset(v, false, sizeof(v));
    int tot = 0;
    for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (!v[j] && f[j][i] != 0) {
                    if (f[j][i] > 0) {
                        f[j][i]--;
                        f[i][j]++;
                    } else {
                        f[j][i]++;
                        f[i][j]--;
                    }
                    tot++;
                    dfs(i, j, 1);
                    ans << endl;
                }
            }
    }
    cout << tot << endl;
    cout << ans.str();
}


#include<cstdio>
#include<cstring>
#define INF 2000000000

int min(int x, int y) {return (x < y) ? x : y; }

int get_int(){
	int t = 0; char ch = getchar();
	while(ch < '0' || ch > '9') ch = getchar();
	while(ch >= '0' && ch <= '9'){
		t = t * 10 + ch - '0';
		ch = getchar();
	}
	return t;
}

struct Edge{
	int from, to, cap, flow;
	Edge(int from_ = 0, int to_ = 0, int cap_ = 0, int flow_ = 0) {from = from_; to = to_; cap = cap_; flow = flow_; return; }
};

int lp = 0, f[210], nxt[40010];
Edge edge[40010];
inline void add(int x, int y, int z) {edge[lp] = Edge(x, y, z, 0); nxt[lp] = f[x]; f[x] = lp++; return; }

int n, rec[210];

int l, r, q[210], p[210], a[210];
inline void qset() { l = 1; r = 0; return; }
inline void qadd(int x) { q[++r] = x; return; }
inline bool qempty() {return l > r; }
inline int qtop() { return q[l]; }
inline void qpop() { l++; return; }

int lans = 0, ans[210][210], vis[210];

bool is_prime(int x){
	for(int i = 2; i * i <= x; i++)
		if(x % i == 0){
//			printf("%d 0\n", x);
			return false;
		}
//	printf("%d 1\n", x);
	return true;
}

void dfs(int x){
	ans[lans][0]++;
	ans[lans][ans[lans][0]] = x;
	vis[x] = 1;
	for(int t = f[x]; t != -1; t = nxt[t])
		if((vis[edge[t].to] == 0) && (edge[t].flow != 0)){
			dfs(edge[t].to);
			break;
		}
	return;
}

int main(){
	n = get_int();
	for(int i = 1; i <= n; i++) rec[i] = get_int();

	memset(f, 255, sizeof(f));
	for(int i = 1; i <= n; i++)
		if(rec[i] % 2 == 1) add(0, i, 2), add(i, 0, 0); else add(i, n + 1, 2), add(n + 1, i, 0);
	for(int i = 1; i <= n; i++) if(rec[i] % 2 == 1)
		for(int j = 1; j <= n; j++) if(rec[j] % 2 == 0)
			if(is_prime(rec[i] + rec[j]))
				add(i, j, 1), add(j, i, 0);

	int flow = 0;
	for(;;){
		memset(a, 0, sizeof(a));
		a[0] = INF;
		qset();
		qadd(0);
//		printf("\n");
		while(!qempty()){
			int x = qtop(); qpop();
//			printf("%d\n", x);
			for(int t = f[x]; t != -1; t = nxt[t]){
				Edge &e = edge[t];
				if(a[e.to]) continue;
				if(e.flow >= e.cap) continue;
				a[e.to] = min(a[x], e.cap - e.flow);
				p[e.to] = t;
				qadd(e.to);
			}
			if(a[n + 1]) break;
		}
		if(!a[n + 1]) break;
		flow += a[n + 1];
		for(int t = n + 1; t != 0; t = edge[p[t]].from) {
			edge[p[t]].flow += a[n + 1];
			edge[p[t] ^ 1].flow -= a[n + 1];
//			printf("%d %d\n", edge[p[t]].from, edge[p[t]].to);
		}
	}

	if(flow != n) {
		printf("Impossible\n");
		return 0;
	}

	memset(vis, 0, sizeof(vis));
	memset(ans, 0, sizeof(ans));
	vis[0] = 1; vis[n + 1] = 1;
	for(int i = 1; i <= n; i++)
		if(!vis[i]) { lans++; dfs(i); }
	printf("%d\n", lans);
	for(int i = 1; i <= lans; i++){
		printf("%d ", ans[i][0]);
		for(int j = 1; j <= ans[i][0]; j++) printf("%d ", ans[i][j]);
		printf("\n");
	}
	return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <utility>
#include <queue>
#define INF 1<<25
#define vvi vector<vector<int> >

using namespace std;

int mark[100000];
int cap[203][203], f[203][203];
int val[203], par[203];
int N, S=201, T=202;
int maxflow = 0;
int odd = 0, even = 0;
int vis[203];
vvi adj;
vvi temp;
int augment_path(int v, int mf){
    int u = par[v];
    if(v == S) {
        return mf;
    }
    int flow = cap[u][v]-f[u][v];
    bool backedge = false;
    if(flow <= 0 && f[v][u] > 0) {
        backedge = true;
    }
    if(backedge) {
        mf = min(mf, f[v][u]);
    } else {
        mf = min(mf, flow);
    }
    mf = augment_path(u, mf);
    f[v][u] -= mf;
    f[u][v] += mf;

    return mf;
}

void edmondskarp() {
    maxflow = 0;
    while(1) {
        bool augmented = false;
        for(int i=0;i<203;++i)vis[i] = 0;
        queue<int> q;
        q.push(S);
        vis[S] = 1;
        while(!q.empty()){
            int u = q.front();
            q.pop();
            for(int i=0;i<203;++i){
                if((cap[u][i]-f[u][i]>0 || f[i][u] > 0)  && !vis[i]) {
                    vis[i] = 1;
                    par[i]=u;
                    if(i==T) {
                        maxflow += augment_path(T, INF);
                        augmented = true;
                        break;
                    }
                    else q.push(i);
                }
            }
            if(augmented) {
                break;
            }
        }
        if(!augmented) {
            break;
        }
    }
}

void dfs(int u) {
    vis[u] = 1;
    temp.back().push_back(u);
    for(int i=0;i<adj[u].size();++i){
        if(!vis[adj[u][i]]) {
            dfs(adj[u][i]);
        }
    }
}

int main(){
    //eratóstenes
    for(int i=2;i*i<100000;++i){
        for(int j=i;j*i<100000;++j){
            mark[i*j] = 1;
        }
    }
    scanf("%d",&N);
    for(int i=0;i<N;++i){
        scanf("%d",&val[i]);
    }
    for(int i=0;i<N;++i){
        if(val[i]%2) {
            //ímpares do lado esquerdo do grafo bipartido,
            //capacidade da aresta é 2 para garantir que
            //cada vértice se conecta a somente outros dois,
            //pois cada raposa se senta ao lado de no máximo
            //duas outras raposas
            cap[S][i] = 2;
            ++odd;
        } else {
            //pares do lado direito do grafo bipartido
            cap[i][T] = 2;
            ++even;
        }
        for(int j=i+1;j<N;++j){
            //não podem sentar juntos, pois a soma não dá um primo
            if(mark[val[i]+val[j]]) {
                continue;
            }
            //c.c. podem se sentar juntos.
            if(val[i]%2) {
                cap[i][j] = 1;
            }
            else {
                cap[j][i] = 1;
            }
        }
    }
    edmondskarp();
    if(odd * 2 != even * 2 || even * 2 != maxflow) {
        printf("Impossible\n");
        return 0;
    }
    adj = vvi (N+3);
    for(int i=0;i<N;++i){
        for(int j=0;j<N;++j){
            if(cap[i][j] > 0 && f[i][j]>0){
                adj[i].push_back(j);
                adj[j].push_back(i);
            }
        }
    }
    for(int i=0;i<N;++i)vis[i]=0;
    for(int i=0;i<N;++i){
        if(!vis[i]) {
            temp.push_back(vector<int>());
            dfs(i);
        }
    }
    printf("%d\n",(int)temp.size());
    for(int i=0;i<temp.size();++i){
        printf("%d", (int)temp[i].size());
        for(int j=0;j<temp[i].size();++j){
            printf(" %d",temp[i][j]+1);
        }
        printf("\n");
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <utility>
#include <queue>
#define INF 1<<25
#define vvi vector<vector<int> >

using namespace std;

int mark[100000];
int cap[203][203], f[203][203];
int val[203], par[203];
int N, S=201, T=202;
int maxflow = 0;
int odd = 0, even = 0;
int vis[203];
vvi adj;
vvi temp;
int augment_path(int v, int mf){
    int u = par[v];
    if(v == S) {
        return mf;
    }
    bool backedge = false;
    if(cap[u][v]-f[u][v] <= 0 && f[v][u] > 0) backedge = true;
    if(backedge) {
        mf = min(mf, f[v][u]);
    } else {
        mf = min(mf, cap[u][v] - f[u][v]);
    }
    mf = augment_path(u, mf);
    f[v][u] -= mf;
    f[u][v] += mf;
    /*if(backedge) {

    } else {

    }*/
    return mf;
}

void edmondskarp() {
    maxflow = 0;
    while(1) {
        bool augmented = false;
        for(int i=0;i<203;++i)vis[i] = 0;
        queue<int> q;
        q.push(S);
        vis[S] = 1;
        while(!q.empty()){
            int u = q.front();
            q.pop();
            for(int i=0;i<203;++i){
                if((cap[u][i]-f[u][i]>0 || f[i][u] > 0)  && !vis[i]) {
                    vis[i] = 1;
                    par[i]=u;
                    if(i==T) {
                        maxflow += augment_path(T, INF);
                        augmented = true;
                        break;
                    }
                    else q.push(i);
                }
            }
            if(augmented)break;
        }
        if(!augmented)break;
    }
}

void dfs(int u) {
    vis[u] = 1;
    temp.back().push_back(u);
    for(int i=0;i<adj[u].size();++i){
        if(!vis[adj[u][i]]) {
            dfs(adj[u][i]);
        }
    }
}

int main(){
    for(int i=2;i*i<100000;++i){
        for(int j=i;j*i<100000;++j){
            mark[i*j] = 1;
        }
    }
    scanf("%d",&N);
    for(int i=0;i<N;++i){
        scanf("%d",&val[i]);
    }
    for(int i=0;i<N;++i){
        if(val[i]%2) {
            cap[S][i] = 2;
            ++odd;
        } else {
            cap[i][T] = 2;
            ++even;
        }
        for(int j=i+1;j<N;++j){
            if(mark[val[i]+val[j]]) {
                continue;
            }
            if(val[i]%2) {
                cap[i][j] = 1;
            }
            else {
                cap[j][i] = 1;
            }
        }
    }
    edmondskarp();
    if(odd * 2 != even * 2 || even * 2 != maxflow) {
        printf("Impossible\n");
        return 0;
    }
    adj = vvi (N+3);
    for(int i=0;i<N;++i){
        for(int j=0;j<N;++j){
            if(cap[i][j] > 0 && f[i][j]>0){
                adj[i].push_back(j);
                adj[j].push_back(i);
            }
        }
    }
    for(int i=0;i<N;++i)vis[i]=0;
    for(int i=0;i<N;++i){
        if(!vis[i]) {
            temp.push_back(vector<int>());
            dfs(i);
        }
    }
    printf("%d\n",(int)temp.size());
    for(int i=0;i<temp.size();++i){
        printf("%d", (int)temp[i].size());
        for(int j=0;j<temp[i].size();++j){
            printf(" %d",temp[i][j]+1);
        }
        printf("\n");
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <utility>
#include <queue>
#define INF 1<<25
#define MAX_V 205
#define vi vector<int>
#define vvi vector<vector<int> >

using namespace std;

int mark[100000];
int cap[203][203], f[203][203];
int val[203], p[203];
int N, S=201, T=202;
int maxflow = 0;
int odd = 0, even = 0;
int seen[203];
vvi adj;
vvi temp;

int augment_path(int v, int mf){
    int u = p[v];
    if(v == S) {
        return mf;
    }
    bool reversa = false;
    int flow = cap[u][v]-f[u][v];
    //se se esgotou o fluxo na ida, mas há fluxo
    //na volta, o fluxo a ser considerado é o da reversa (v -> u)
    if(flow <= 0 && f[v][u] > 0) {
        reversa = true;
    }
    if(reversa) {
        mf = min(mf, f[v][u]);
    } else {
        mf = min(mf, flow);
    }
    mf = augment_path(u, mf);
    if(reversa) {
        f[v][u] -= mf;
    } else {
        f[u][v] += mf;
    }
    return mf;
}

void edmondskarp() {
    maxflow = 0;
    while(1) {
        bool augmented = false;
        for(int i=0;i<203;++i) {
            seen[i] = 0;
        }
        queue<int> q;
        q.push(S);
        seen[S] = 1;
        while(!q.empty()){
            int u = q.front();
            q.pop();
            for(int i=0;i<203;++i){
                //se há ainda como passar algo entre os vértices
                if((cap[u][i]-f[u][i]>0 || f[i][u] > 0)  && !seen[i]) {
                    seen[i] = 1;
                    p[i]=u;
                    //se se chegou ao dreno, um caminho foi esgotado
                    if(i==T) {
                        maxflow += augment_path(T, INF);
                        augmented = true;
                        break;
                    }
                    else {
                        q.push(i);
                    }
                }
            }
            if(augmented) {
                break;
            }
        }
        //se se iterou por todos os vértices e não se encontrou um caminho,
        //acaba a execução do algoritmo
        if(!augmented) {
            break;
        }
    }
}

void dfs(int u) {
    seen[u] = 1;
    temp[temp.size()-1].push_back(u);
    for(int i=0;i<adj[u].size();++i){
        if(!seen[adj[u][i]]) {
            dfs(adj[u][i]);
        }
    }
}

int main(){
    //eratóstenes
    for(int i=2;i*i<100000;++i){
        for(int j=i;j*i<100000;++j){
            mark[i*j] = 1;
        }
    }
    scanf("%d",&N);
    for(int i=0;i<N;++i){
        scanf("%d",&val[i]);
    }
    for(int i=0;i<N;++i){
        if(val[i]%2) {
            //ímpares do lado esquerdo do grafo bipartido,
            //capacidade da aresta é 2 para garantir que
            //cada vértice se conecta a somente outros dois,
            //pois cada raposa se senta ao lado de no máximo
            //duas outras raposas
            cap[S][i] = 2;
            odd++;
        } else {
            //pares do lado direito do grafo bipartido
            cap[i][T] = 2;
            even++;
        }
        for(int j=i+1;j<N;++j){
            //não podem sentar juntos, pois a soma não dá um primo
            if(mark[val[i]+val[j]]) {
                continue;
            }
            //c.c. podem se sentar juntos.
            cap[i][j] = 1;
            cap[j][i] = 1;
        }
    }
    for (int i = 0; i < 203; ++i)
    {
        p[i] = -1;
    }
    edmondskarp();
    if(odd * 2 != even * 2 || even * 2 != maxflow) {
        printf("Impossible\n");
        return 0;
    }
    adj = vvi (N+3);
    for(int i=0;i<N;++i){
        for(int j=0;j<N;++j){
            if(cap[i][j] > 0 && f[i][j]>0){
                adj[i].push_back(j);
                adj[j].push_back(i);
            }
        }
    }
    for(int i=0;i<N;++i)seen[i]=0;
    for(int i=0;i<N;++i){
        if(!seen[i]) {
            temp.push_back(vector<int>());
            dfs(i);
        }
    }
    printf("%d\n",(int)temp.size());
    for(int i=0;i<temp.size();++i){
        printf("%d", (int)temp[i].size());
        for(int j=0;j<temp[i].size();++j){
            printf(" %d",temp[i][j]+1);
        }
        printf("\n");
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <utility>
#include <queue>
#define INF 1<<25
#define MAX_V 205
#define vi vector<int>
#define vvi vector<vector<int> >

using namespace std;

int mark[100000];
int cap[203][203], f[203][203];
int val[203], p[203];
int N, S=201, T=202;
int maxflow = 0;
int odd = 0, even = 0;
int seen[203];
vvi adj;
vvi temp;

int augment_path(int v, int mf){
    int u = p[v];
    if(v == S) {
        return mf;
    }
    bool reversa = false;
    int flow = cap[u][v]-f[u][v];
    //se se esgotou o fluxo na ida, mas há fluxo
    //na volta, o fluxo a ser considerado é o da reversa (v -> u)
    if(flow <= 0 && f[v][u] > 0) {
        reversa = true;
    }
    if(reversa) {
        mf = min(mf, f[v][u]);
    } else {
        mf = min(mf, flow);
    }
    mf = augment_path(u, mf);
    f[v][u] -= mf;
    f[u][v] += mf;

    return mf;
}

void edmondskarp() {
    maxflow = 0;
    while(1) {
        bool augmented = false;
        for(int i=0;i<203;++i) {
            seen[i] = 0;
        }
        queue<int> q;
        q.push(S);
        seen[S] = 1;
        while(!q.empty()){
            int u = q.front();
            q.pop();
            for(int i=0;i<203;++i){
                //se há ainda como passar algo entre os vértices
                if((cap[u][i]-f[u][i]>0 || f[i][u] > 0)  && !seen[i]) {
                    seen[i] = 1;
                    p[i]=u;
                    //se se chegou ao dreno, um caminho foi esgotado
                    if(i==T) {
                        maxflow += augment_path(T, INF);
                        augmented = true;
                        break;
                    }
                    else {
                        q.push(i);
                    }
                }
            }
            if(augmented) {
                break;
            }
        }
        //se se iterou por todos os vértices e não se encontrou um caminho,
        //acaba a execução do algoritmo
        if(!augmented) {
            break;
        }
    }
}

void dfs(int u) {
    seen[u] = 1;
    temp[temp.size()-1].push_back(u);
    for(int i=0;i<adj[u].size();++i){
        if(!seen[adj[u][i]]) {
            dfs(adj[u][i]);
        }
    }
}

int main(){
    //eratóstenes
    for(int i=2;i*i<100000;++i){
        for(int j=i;j*i<100000;++j){
            mark[i*j] = 1;
        }
    }
    scanf("%d",&N);
    for(int i=0;i<N;++i){
        scanf("%d",&val[i]);
    }
    for(int i=0;i<N;++i){
        if(val[i]%2) {
            //ímpares do lado esquerdo do grafo bipartido,
            //capacidade da aresta é 2 para garantir que
            //cada vértice se conecta a somente outros dois,
            //pois cada raposa se senta ao lado de no máximo
            //duas outras raposas
            cap[S][i] = 2;
            odd++;
        } else {
            //pares do lado direito do grafo bipartido
            cap[i][T] = 2;
            even++;
        }
        for(int j=i+1;j<N;++j){
            //não podem sentar juntos, pois a soma não dá um primo
            if(mark[val[i]+val[j]]) {
                continue;
            }
            //c.c. podem se sentar juntos.
            cap[i][j] = 1;
            cap[j][i] = 1;
        }
    }
    for (int i = 0; i < 203; ++i)
    {
        p[i] = -1;
    }
    edmondskarp();
    if(odd * 2 != even * 2 || even * 2 != maxflow) {
        printf("Impossible\n");
        return 0;
    }
    adj = vvi (N+3);
    for(int i=0;i<N;++i){
        for(int j=0;j<N;++j){
            if(cap[i][j] > 0 && f[i][j]>0){
                adj[i].push_back(j);
                adj[j].push_back(i);
            }
        }
    }
    for(int i=0;i<N;++i)seen[i]=0;
    for(int i=0;i<N;++i){
        if(!seen[i]) {
            temp.push_back(vector<int>());
            dfs(i);
        }
    }
    printf("%d\n",(int)temp.size());
    for(int i=0;i<temp.size();++i){
        printf("%d", (int)temp[i].size());
        for(int j=0;j<temp[i].size();++j){
            printf(" %d",temp[i][j]+1);
        }
        printf("\n");
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <utility>
#include <queue>
#define INF 1<<25
#define vvi vector<vector<int> >

using namespace std;

int mark[100000];
int cap[203][203], f[203][203];
int val[203], p[203];
int N, S=201, T=202;
int maxflow = 0;
int odd = 0, even = 0;
int seen[203];
vvi adj;
vvi temp;
int augment_path(int v, int mf){
    int u = p[v];
    if(v == S) {
        return mf;
    }
    int flow = cap[u][v]-f[u][v];
    bool backedge = false;
    if(flow <= 0 && f[v][u] > 0) {
        backedge = true;
    }
    if(backedge) {
        mf = min(mf, f[v][u]);
    } else {
        mf = min(mf, flow);
    }
    mf = augment_path(u, mf);
    f[v][u] -= mf;
    f[u][v] += mf;

    return mf;
}

void edmondskarp() {
    maxflow = 0;
    while(1) {
        bool augmented = false;
        for(int i=0;i<203;++i)seen[i] = 0;
        queue<int> q;
        q.push(S);
        seen[S] = 1;
        while(!q.empty()){
            int u = q.front();
            q.pop();
            for(int i=0;i<203;++i){
                if((cap[u][i]-f[u][i]>0 || f[i][u] > 0)  && !seen[i]) {
                    seen[i] = 1;
                    p[i]=u;
                    if(i==T) {
                        maxflow += augment_path(T, INF);
                        augmented = true;
                        break;
                    }
                    else q.push(i);
                }
            }
            if(augmented) {
                break;
            }
        }
        if(!augmented) {
            break;
        }
    }
}

void dfs(int u) {
    seen[u] = 1;
    temp.back().push_back(u);
    for(int i=0;i<adj[u].size();++i){
        if(!seen[adj[u][i]]) {
            dfs(adj[u][i]);
        }
    }
}

int main(){
    //eratóstenes
    for(int i=2;i*i<100000;++i){
        for(int j=i;j*i<100000;++j){
            mark[i*j] = 1;
        }
    }
    scanf("%d",&N);
    for(int i=0;i<N;++i){
        scanf("%d",&val[i]);
    }
    for(int i=0;i<N;++i){
        if(val[i]%2) {
            //ímpares do lado esquerdo do grafo bipartido,
            //capacidade da aresta é 2 para garantir que
            //cada vértice se conecta a somente outros dois,
            //pois cada raposa se senta ao lado de no máximo
            //duas outras raposas
            cap[S][i] = 2;
            odd++;
        } else {
            //pares do lado direito do grafo bipartido
            cap[i][T] = 2;
            even++;
        }
        for(int j=i+1;j<N;++j){
            //não podem sentar juntos, pois a soma não dá um primo
            if(mark[val[i]+val[j]]) {
                continue;
            }
            //c.c. podem se sentar juntos.
            cap[i][j] = 1;
            cap[j][i] = 1;
        }
    }
    for (int i = 0; i < 203; ++i)
    {
        p[i] = -1;
    }
    edmondskarp();
    if(odd * 2 != even * 2 || even * 2 != maxflow) {
        printf("Impossible\n");
        return 0;
    }
    adj = vvi (N+3);
    for(int i=0;i<N;++i){
        for(int j=0;j<N;++j){
            if(cap[i][j] > 0 && f[i][j]>0){
                adj[i].push_back(j);
                adj[j].push_back(i);
            }
        }
    }
    for(int i=0;i<N;++i) {
        seen[i]=0;
    }
    for(int i=0;i<N;++i){
        if(!seen[i]) {
            temp.push_back(vector<int>());
            dfs(i);
        }
    }
    printf("%d\n",(int)temp.size());
    for(int i=0;i<temp.size();++i){
        printf("%d", (int)temp[i].size());
        for(int j=0;j<temp[i].size();++j){
            printf(" %d",temp[i][j]+1);
        }
        printf("\n");
    }
    return 0;
}


#include <stdio.h>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
// #include <unordered_map>
#include <cassert>

#define SHOW(...) {;}
#define REACH_HERE {;}
#undef HHHDEBUG
#ifdef HHHDEBUG
#include "template.h"
#endif

using namespace std;

const int HH = 205;
const int JJ = 500000;

const int MAXFOX = 203;
int n;
int fox[MAXFOX];
int n_odd;
int fox_odd[MAXFOX];
int n_even;
int fox_even[MAXFOX];
int total_n;

struct Edge {
	int from;
	int to;
	int cap;
};

int source, sink;
vector<int> g[HH];
int cap[HH][HH];
int lv[HH];

bool mark_level(int start, int end) {
    memset(lv, -1, sizeof(lv));
    queue<int> q;
    lv[start] = 0;
    q.push(start);
    while (!q.empty()) {
        int cur = q.front(); q.pop();
        for (int i = 0; i < g[cur].size(); ++i) {
        	int next = g[cur][i];
            if (cap[cur][next] != 0 && lv[next] == -1) {
                lv[next] = lv[cur] + 1;
                q.push(next);
            }
        }
    }
    return lv[end] != -1;
}

int augment(int cur, int end, int min_flow) {
    if (cur == end)
        return min_flow;

    int augmented_flow = 0;
    for (int i = 0; i < g[cur].size(); i++) {
    	int next = g[cur][i];
    	if ((lv[next] == lv[cur] + 1 && cap[cur][next] > 0) &&
            (augmented_flow = augment(next, end, min(cap[cur][next], min_flow)))
        ) {
            cap[cur][next] -= augmented_flow;
            cap[next][cur] += augmented_flow;
            return augmented_flow;
        }
    }
    return 0;
}

int dinic(int start, int end) {
	int total = 0;
	int flow = 0;
    while (mark_level(start, end))
        while (flow = augment(start, end, INT_MAX))
        	total += flow;
    return total;
}

void show_cap() {
		printf(" x:");
		for (int j = 0; j < total_n; j++)
			printf(" %3d", j);
		printf("\n");
	for (int i = 0; i < total_n; i++) {
		printf("%2d:", i);
		for (int j = 0; j < total_n; j++)
			printf(" %d/%d", cap[i][j], cap[j][i]);
		printf("\n");
	}
}

bool is_prime(int n) {
    if (n == 1 || n % 2 == 0)
        return false;
    int t = sqrt(n);
    for (int i = 3; i <= t; i += 2)
        if (n % i == 0)
            return false;
    return true;
}

void build_graph() {
	total_n = n + 2;
	source = 0;
	sink = total_n - 1;
	for (int i = 0; i < n_odd; i++) {
		int fox_index = fox_odd[i];
		cap[source][fox_index] = 2;
		g[source].push_back(fox_index);
		g[fox_index].push_back(source);
		SHOW("ADD EDGE", source, i, fox_index);
	}
	for (int i = 0; i < n_even; i++) {
		int fox_index = fox_even[i];
		cap[fox_index][sink] = 2;
		g[fox_index].push_back(sink);
		g[sink].push_back(fox_index);
		SHOW("ADD EDGE", fox_index, sink);
	}
	for (int i = 0; i < n_odd; i++) {
		for (int j = 0; j < n_even; j++) {
			int fox_index_odd = fox_odd[i];
			int fox_index_even = fox_even[j];
			if (is_prime(fox[fox_index_odd] + fox[fox_index_even])) {
				cap[fox_index_odd][fox_index_even] = 1;
				g[fox_index_odd].push_back(fox_index_even);
				g[fox_index_even].push_back(fox_index_odd);
				SHOW("ADD EDGE", fox_index_odd, fox_index_even);
			}
		}
	}
	SHOW(n, n_odd, n_even, total_n, source, sink)
}

bool printed[HH];

vector<int> cur_ans;

int n_table;
stringstream ans;

void print_cur(int a) {
	SHOW(a)
	cur_ans.push_back(a);
	printed[a] = true;
	for (int i = 0; i < g[a].size(); i++) {
		int next = g[a][i];
		if (next != source && next != sink && !printed[next]) {
			SHOW(a, next, fox[a], fox[next], fox[a] % 2, cap[a][next])
			if (fox[a] % 2 == 1 && cap[a][next] == 0) {
				print_cur(next);
				return ;
			}
			else if (fox[a] % 2 == 0 && cap[a][next] == 1) {
				print_cur(next);
				return ;
			}
		}
	}
}

void print_ans() {
	for (int j = 1; j <= n; j++) {
		if (printed[j] == false) {
			n_table++;
			SHOW(j, n_table)
			cur_ans.clear();
			print_cur(j);
			ans << cur_ans.size();
			SHOW(cur_ans.size())
			for (int x : cur_ans)
				ans << " " << x;
			ans << endl;
			SHOW(ans.str())
		}
	}
}

int main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> fox[i];
		if (fox[i] % 2) {
			fox_odd[n_odd] = i;
			n_odd++;
		}
		else {
			fox_even[n_even] = i;
			n_even++;
		}
	}
	// printf("odd:");
	// for (int i = 0; i < n_odd; i++)
	// 	printf(" %d", fox_odd[i]);
	// printf("\n");
	// printf("even:");
	// for (int i = 0; i < n_even; i++)
	// 	printf(" %d", fox_even[i]);
	// printf("\n");

	memset(g, 0, sizeof(g));
	build_graph();
	// show_cap();
	int total_flow = dinic(source, sink);
	// cout << endl;
	// show_cap();
	// printf("tf: %d\n", total_flow);
	SHOW(total_flow)
	if (total_flow == n) {
		print_ans();
		cout << n_table << endl;
		cout << ans.str();
	}
	else
		cout << "Impossible" << endl;
}