Problem: Fox Ciel is participating in a party in Prime Kingdom. There are n foxes there (include Fox Ciel). The i-th fox is ai years old.

They will have dinner around some round tables. You want to distribute foxes such that:

  1. Each fox is sitting at some table. 
  2. Each table has at least 3 foxes sitting around it. 
  3. The sum of ages of any two adjacent foxes around each table should be a prime number. 



If k foxes f1, f2, ..., fk are sitting around table in clockwise order, then for 1 ≤ i ≤ k - 1: fi and fi + 1 are adjacent, and f1 and fk are also adjacent.

If it is possible to distribute the foxes in the desired manner, find out a way to do that.

Input

The first line contains single integer n (3 ≤ n ≤ 200): the number of foxes in this party. 

The second line contains n integers ai (2 ≤ ai ≤ 104).

Output

If it is impossible to do this, output "Impossible".

Otherwise, in the first line output an integer m (<image>): the number of tables.

Then output m lines, each line should start with an integer k -=– the number of foxes around that table, and then k numbers — indices of fox sitting around that table in clockwise order.

If there are several possible arrangements, output any of them.

Examples

Input

4
3 4 8 9


Output

1
4 1 2 4 3


Input

5
2 2 2 2 2


Output

Impossible


Input

12
2 3 4 5 6 7 8 9 10 11 12 13


Output

1
12 1 2 3 6 5 12 9 8 7 10 11 4


Input

24
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25


Output

3
6 1 2 3 6 5 4
10 7 8 9 12 15 14 13 16 11 10
8 17 18 23 22 19 20 21 24

Note

In example 1, they can sit around one table, their ages are: 3-8-9-4, adjacent sums are: 11, 17, 13 and 7, all those integers are primes.

In example 2, it is not possible: the sum of 2+2 = 4 is not a prime number.

Solution (in JAVA):

Solution:
import java.io.*;
import java.util.*;

/*
polyakoff
*/

public class Main {

    static FastReader in;
    static PrintWriter out;
    static Random rand = new Random();
    static final int oo = (int) 2e9;
    static final long OO = (long) 4e18;
    static final int MOD = 998244353;
    static final int N = (int) (5e5 + 5);

    static ArrayList<Integer>[] g;
    static boolean[] vis;

    static class Dinic {
        class Edge {
            int u, v;
            int c, f;

            Edge(int u, int v, int c) {
                this.u = u;
                this.v = v;
                this.c = c;
            }
        }
        int n;
        ArrayList<Edge> edges;
        ArrayList<Integer>[] adj;
        int[] q, d, ptr;

        Dinic(int n) {
            this.n = n;
            edges = new ArrayList<>();
            adj = new ArrayList[n]; Arrays.setAll(adj, i -> new ArrayList<>());
            q = new int[n];
            d = new int[n];
            ptr = new int[n];
        }

        void addEdge(int u, int v, int c) {
            adj[u].add(edges.size());
            edges.add(new Edge(u, v, c));
            adj[v].add(edges.size());
            edges.add(new Edge(v, u, 0));
        }

        int maxFlow(int s, int t) {
            int flow = 0;
            while (bfs(s, t)) {
                Arrays.fill(ptr, 0);
                int delta;
                while ((delta = dfs(s, t, oo)) != 0)
                    flow += delta;
            }
            return flow;
        }

        boolean bfs(int s, int t) {
            int i = 0;
            q[i++] = s;
            Arrays.fill(d, -1);
            d[s] = 0;
            for (int j = 0; j < i; j++) {
                int u = q[j];
                for (int ei : adj[u]) {
                    Edge e = edges.get(ei);
                    if (d[e.v] == -1 && e.f < e.c) {
                        q[i++] = e.v;
                        d[e.v] = d[u] + 1;
                    }
                }
            }
            return d[t] != -1;
        }

        int dfs(int u, int t, int minDelta) {
            if (u == t || minDelta == 0)
                return minDelta;
            for (; ptr[u] < adj[u].size(); ptr[u]++) {
                int ei = adj[u].get(ptr[u]);
                Edge e = edges.get(ei);
                if (d[e.v] == d[u] + 1) {
                    int pushed = dfs(e.v, t, Math.min(minDelta, e.c - e.f));
                    if (pushed > 0) {
                        e.f += pushed;
                        edges.get(ei ^ 1).f -= pushed;
                        return pushed;
                    }
                }
            }
            return 0;
        }
    }

    static boolean isPrime(int a) {
        for (int i = 2; i * i <= a; i++) {
            if (a % i == 0)
                return false;
        }
        return true;
    }

    static void dfs(int u, ArrayList<Integer> table) {
        vis[u] = true;
        table.add(u);
        for (int v : g[u]) {
            if (!vis[v])
                dfs(v, table);
        }
    }

    static void solve() {
        int n = in.nextInt();

        int[] a = new int[n];
        int even = 0, odd = 0;
        for (int i = 0; i < n; i++) {
            a[i] = in.nextInt();
            if (a[i] % 2 == 0)
                even++;
            else
                odd++;
        }

        if (even != odd) {
            out.println("Impossible");
            return;
        }

        Dinic dinic = new Dinic(n + 2);
        int s = n, t = n + 1;

        for (int i = 0; i < n; i++) {
            if (a[i] % 2 == 0)
                dinic.addEdge(s, i, 2);
            else
                dinic.addEdge(i, t, 2);
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (a[i] % 2 == 0 && a[j] % 2 == 1 && isPrime(a[i] + a[j]))
                    dinic.addEdge(i, j, 1);
            }
        }

        int maxFlow = dinic.maxFlow(s, t);

        if (maxFlow != n) {
            out.println("Impossible");
            return;
        }

        g = new ArrayList[n]; Arrays.setAll(g, i -> new ArrayList<>());
        for (Dinic.Edge e : dinic.edges) {
            if (e.f == 1) {
                g[e.u].add(e.v);
                g[e.v].add(e.u);
//                out.println(e.u + " - " + e.v);
            }
        }

        vis = new boolean[n];
        ArrayList<ArrayList<Integer>> tables = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            if (!vis[i]) {
                ArrayList<Integer> table = new ArrayList<>();
                dfs(i, table);
                tables.add(table);
            }
        }

        out.println(tables.size());
        for (ArrayList<Integer> table : tables) {
            out.print(table.size() + " ");
            for (int i : table)
                out.print((i + 1) + " ");
            out.println();
        }


    }

    public static void main(String[] args) throws FileNotFoundException {
        in = new FastReader(System.in);
//        in = new FastReader(new FileInputStream("sometext.txt"));
        out = new PrintWriter(System.out);
//        out = new PrintWriter(new FileOutputStream("output.txt"));

        int T = 1;
//        T = in.nextInt();
        while (T-- > 0)
            solve();

//        Thread thread = new Thread(null, () -> {
//            solve();
//        }, "Main", 1 << 28);
//        thread.start();
//        try {
//            thread.join();
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }

//        out.flush();
        out.close();
    }

    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        FastReader(InputStream is) {
            br = new BufferedReader(new InputStreamReader(is));
        }

        Integer nextInt() {
            return Integer.parseInt(next());
        }

        Long nextLong() {
            return Long.parseLong(next());
        }

        Double nextDouble() {
            return Double.parseDouble(next());
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                st = new StringTokenizer(nextLine());
            }
            return st.nextToken();
        }

        String nextLine() {
            String s = "";
            try {
                s = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return s;
        }
    }

    static void dbg(Object... args) {
        for (Object arg : args)
            out.print(arg + " ");
        out.println();
    }

}