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.PrintWriter;
import java.util.*;

public class C {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);

        int n = in.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n ; i++) {
            a[i] = in.nextInt();
        }
        boolean[] p = gp(32000);

        int e = 0;
        for (int i = 0; i < n; i++) {
            if (a[i] % 2 == 0) {
                e++;
            }
        }
        if (e != n - e) {
            out.println("Impossible");
            out.flush();
            return;
        }

        MaxFlow flow = new MaxFlow();
        flow.init(n+2);
        for (int i = 0; i < n; i++) {
            if (a[i] % 2 == 0) {
                flow.edge(i, n+1, 2);
            } else {
                flow.edge(n, i, 2);
            }
        }
        for (int i = 0; i < n; i++) {
            if (a[i] % 2 == 1) {
                for (int j = 0 ; j < n ; j++) {
                    if (p[a[i]+a[j]]) {
                        flow.edge(i, j, 1);
                    }
                }
            }
        }
        int ma = flow.max_flow(n, n+1);
        if (ma != n) {
            out.println("Impossible");
            out.flush();
            return;
        }

        int[][] graph = new int[n][n];
        for (int i = 0 ; i < n ; i++) {
            if (a[i] % 2 == 1) {
                for (MaxFlow.Edge ed : flow.graph.get(i)) {
                    if (ed.to < n && ed.cap == 0) {
                        graph[i][ed.to] = graph[ed.to][i] = 1;
                    }
                }
            }
        }

        boolean[] done = new boolean[n];

        List<List<Integer>> group = new ArrayList<>();
        for (int i = 0 ; i < n ; i++) {
            if (!done[i]) {
                List<Integer> l = new ArrayList<>();
                dfs(graph, l, done, i, -1);
                group.add(l);
            }
        }

        out.println(group.size());
        for (List<Integer> l : group) {
            StringBuilder sb = new StringBuilder().append(l.size());
            for (int li : l) {
                sb.append(' ').append(li+1);
            }
            out.println(sb.toString());
        }
        out.flush();
    }

    private static void dfs(int[][] graph, List<Integer> l, boolean[] done, int v, int p) {
        if (done[v]) {
            return;
        }
        done[v] = true;
        l.add(v);
        for (int i = 0 ; i < graph.length ; i++) {
            if (graph[v][i] == 1 && i != p) {
                dfs(graph, l, done, i, v);
                return;
            }
        }
    }

    static boolean[] gp(int max) {
        boolean[] isp = new boolean[max+1];
        Arrays.fill(isp, true);
        isp[1] = false;

        int cnt = 0;
        for (int i = 2 ; i <= max ; i++) {
            if (isp[i]) {
                cnt++;
                for (int j = i*2; j <= max ; j += i) {
                    isp[j] = false;
                }
            }
        }
        return isp;
    }



    static class MaxFlow {
        public class Edge {
            int to;
            int cap;
            int rev;
            public Edge(int _to, int _cap, int _rev) {
                to = _to;
                cap = _cap;
                rev = _rev;
            }
        }
        public Map<Integer, List<Edge>> graph = new HashMap<Integer, List<Edge>>();
        public boolean[] used;
        public void init(int size) {
            for (int i = 0 ; i < size ; i++) {
                graph.put(i, new ArrayList<Edge>());
            }
            used = new boolean[size];
        }
        public void edge(int from, int to, int cap) {
            graph.get(from).add(new Edge(to, cap, graph.get(to).size()));
            graph.get(to).add(new Edge(from, 0, graph.get(from).size() - 1));
        }
        public int dfs(int v, int t, int f) {
            if (v == t) return f;
            used[v] = true;
            for (int i = 0 ; i < graph.get(v).size() ; i++) {
                Edge e = graph.get(v).get(i);
                if (!used[e.to] && e.cap > 0) {
                    int d = dfs(e.to, t, Math.min(f, e.cap));
                    if (d > 0) {
                        e.cap -= d;
                        graph.get(e.to).get(e.rev).cap += d;
                        return d;
                    }
                }
            }
            return 0;
        }
        public int max_flow(int s, int t) {
            int flow = 0;
            while (true) {
                used = new boolean[graph.size()];
                int f = dfs(s, t, Integer.MAX_VALUE);
                if (f == 0) {
                    break;
                }
                flow += f;
            }
            return flow;
        }
        }

    static void debug(Object... o) {
        System.err.println(Arrays.deepToString(o));
    }
}