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.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author qianyin
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task510E solver = new Task510E();
        solver.solve(1, in, out);
        out.close();
    }

    static class Task510E {
        boolean[] isPrime = null;
        private Task510E.Vertex[] vs;

        private void sieve(int limit) {
            if (isPrime != null) return;
            isPrime = new boolean[limit];
            Arrays.fill(isPrime, true);

            isPrime[0] = false;
            isPrime[1] = false;

            for (int i = 2; i * i < limit; i += (i == 2) ? 1 : 2) {
                if (isPrime[i]) {
                    for (int j = i * i; j < limit; j += i) {
                        isPrime[j] = false;
                    }
                }
            }
        }

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int a[] = new int[n], odd = 0;
            for (int i = 0; i < n; i++) {
                a[i] = in.nextInt();
                odd += a[i] % 2;
            }

            if (n % 2 == 1 || odd * 2 != n) {
                out.println("Impossible");
                return;
            } else {
                sieve(20001);
            }

            Task510E.Vertex source = new Task510E.Vertex(), sink = new Task510E.Vertex();
            vs = new Task510E.Vertex[n + 2];
            for (int i = 0; i < n; i++) {
                vs[i] = new Task510E.Vertex();
                vs[i].id = i;
            }
            vs[n] = source;
            vs[n + 1] = sink;

            for (int i = 0; i < n; i++) {
                if (a[i] % 2 == 0) {
                    addEdge(source, vs[i], 2);
                    for (int j = 0; j < n; j++) {
                        if (isPrime[a[i] + a[j]]) {
                            addEdge(vs[i], vs[j], 1);
                        }
                    }
                } else {
                    addEdge(vs[i], sink, 2);
                }
            }

            int result = maxFlow(source, sink, n);
            if (result != n) {
                out.println("Impossible");
                return;
            } else {
                for (int i = 0; i < n; i++) vs[i].mark = false;

                List<List<Integer>> links = new ArrayList<>();
                for (int i = 0; i < n; i++) {
                    if (a[i] % 2 == 0 && !vs[i].mark) {
                        links.add(getLink(vs[i]));
                    }
                }

                out.println(links.size());
                for (List<Integer> link : links) {
                    out.print(link.size());
                    for (int x : link) {
                        out.printf(" %d", x);
                    }
                    out.println();
                }
            }
        }

        private List<Integer> getLink(Task510E.Vertex to) {
            List<Integer> link = new ArrayList<>();
            int flow = 1;
            while (!to.mark) {
                to.mark = true;
                link.add(to.id + 1);
                for (Task510E.Edge e : to.outgo) {
                    if (!e.to.mark && e.flow == flow) {
                        to = e.to;
                        flow = -flow;
                        break;
                    }
                }
            }
            return link;
        }

        private int maxFlow(Task510E.Vertex source, Task510E.Vertex sink, int n) {
            int result = 0;
            while (true) {
                for (Task510E.Vertex v : vs) {
                    v.mark = false;
                }

                int by = source.dfs(sink, n);
                if (by == 0) break;
                result += by;
            }
            return result;
        }

        private void addEdge(Task510E.Vertex a, Task510E.Vertex b, int cap) {
            Task510E.Edge ab = new Task510E.Edge(b, cap, 0), ba = new Task510E.Edge(a, 0, 0);
            ab.rev = ba;
            ba.rev = ab;
            a.outgo.add(ab);
            b.outgo.add(ba);
        }

        static class Edge {
            Task510E.Vertex to;
            Task510E.Edge rev;
            int cap;
            int flow;

            Edge(Task510E.Vertex to, int cap, int flow) {
                this.to = to;
                this.cap = cap;
                this.flow = flow;
            }

        }

        static class Vertex {
            List<Task510E.Edge> outgo = new ArrayList<>();
            boolean mark;
            int ptr = 0;
            int id;

            public int dfs(Task510E.Vertex sink, int max) {
                if (this == sink) return max;
                mark = true;
                for (int i = 0; i < outgo.size(); i++) {
                    Task510E.Edge edge = outgo.get(ptr);
                    ptr++;
                    if (ptr == outgo.size()) ptr = 0;

                    if (!edge.to.mark && edge.cap > 0) {
                        int by = edge.to.dfs(sink, Math.min(max, edge.cap));
                        if (by > 0) {
                            edge.flow += by;
                            edge.cap -= by;
                            edge.rev.flow -= by;
                            edge.rev.cap += by;
                            return by;
                        }
                    }
                }
                return 0;
            }

        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream));
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

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

    }
}