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.util.Arrays;
import java.util.ArrayList;
import java.util.ArrayDeque;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.io.BufferedReader;
import java.awt.Point;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.io.FileReader;
import java.io.IOException;
import java.util.StringTokenizer;

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

class TaskC {

    private final int source = 0;
    private final int sink = 1;
    private ArrayList<ArrayList<Integer>> edges = new ArrayList<>();
    private HashMap<Point, Integer> costs = new HashMap<>();

    public void solve(int testNumber, InputReader in, OutputWriter out) {
        for (int i = 0; i < 2; i++) {
            edges.add(new ArrayList<>());
        }
        final int n = in.readInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = in.readInt();
        }
        boolean[] isPrime = getPrimes();
        int[] node = new int[n];
        for (int i = 0; i < n; i++) {
            node[i] = addVertex();
            if (a[i] % 2 == 0) {
                addEdge(source, node[i], 2);
            } else {
                addEdge(node[i], sink, 2);
            }
            for (int j = 0; j < i; j++) {
                if (isPrime[a[i] + a[j]]) {
                    if (a[i] % 2 == 0) {
                        addEdge(node[i], node[j], 1);
                    } else {
                        addEdge(node[j], node[i], 1);
                    }
                }
            }
        }
        if (maxFlow() == n) {
            ArrayList<ArrayList<Integer>> graph = new ArrayList<>();
            for (int i = 0; i < n; i++) {
                graph.add(new ArrayList<>());
            }
            for (int i = 0; i < n; i++) if (a[i] % 2 == 0) {
                graph.add(new ArrayList<>());
                for (int j = 0; j < n; j++) {
                    Point p = new Point(node[i], node[j]);
                    if (costs.containsKey(p) && costs.get(p) == 0) {
                        graph.get(i).add(j);
                        graph.get(j).add(i);
                    }
                }
            }
            ArrayDeque<ArrayDeque<Integer>> tables = new ArrayDeque<>();
            boolean[] visited = new boolean[n];
            for (int i = 0; i < n; i++) if (!visited[i]) {
                ArrayDeque<Integer> stack = new ArrayDeque<>();
                ArrayDeque<Integer> all = new ArrayDeque<>();
                stack.push(i);
                visited[i] = true;
                while (!stack.isEmpty()) {
                    int now = stack.pop();
                    all.push(now + 1);
                    for (int neigh: graph.get(now)) if (!visited[neigh]) {
                        stack.push(neigh);
                        visited[neigh] = true;
                        break;
                    }
                }
                tables.push(all);
            }
            out.println(tables.size());
            int total = 0;
            while (!tables.isEmpty()) {
                ArrayDeque<Integer> now = tables.pop();
                int prev = -1;
                if (now.size() % 2 > 0) {
                    throw new RuntimeException("Wrong size\n");
                }
                out.print(now.size());
                while (!now.isEmpty()) {
                    int temp = now.pop();
                    total++;
                    if (prev > -1 && !isPrime[a[prev - 1] + a[temp - 1]]) {
                        throw new RuntimeException("Not prime\n");
                    }
                    prev = temp;
                    out.print(" " + temp);
                }
                out.println();
            }
            if (total != n) {
                throw new RuntimeException("Not quite right\n");
            }
        } else {
            out.println("Impossible");
        }
    }

    private int addVertex() {
        int ret = edges.size();
        edges.add(new ArrayList<>());
        return ret;
    }

    private void addEdge(int u, int v, int cost) {
        edges.get(u).add(v);
        edges.get(v).add(u);
        costs.put(new Point(u, v), cost);
        costs.put(new Point(v, u), 0);
    }

    private int maxFlow() {
        int res = 0;
        int temp;
        while ((temp = findPath()) > 0) {
            res += temp;
        }
        return res;
    }

    private int findPath() {
        ArrayDeque<Integer> stack = new ArrayDeque<>();
        final int n = edges.size();
        boolean[] visited = new boolean[n];
        int[] before = new int[n];
        Arrays.fill(before, -1);
        visited[source] = true;
        stack.push(source);
        while (!stack.isEmpty()) {
            int node = stack.pop();
            for (int neigh: edges.get(node)) if (!visited[neigh] && costs.get(new Point(node, neigh)) > 0) {
                //System.out.println(node + " " + neigh + " " + (neigh == sink));
                visited[neigh] = true;
                before[neigh] = node;
                stack.push(neigh);
                if (neigh == sink) {
                    stack.clear();
                    break;
                }
            }
        }
        if (before[sink] == -1) {
            return 0;
        }
        int min = (int)1e9;
        int node = sink;
        while (node != source) {
            min = Math.min(min, costs.get(new Point(before[node], node)));
            node = before[node];
        }
        node = sink;
        while (node != source) {
            Point a = new Point(before[node], node);
            Point b = new Point(node, before[node]);
            costs.put(a, costs.get(a) - min);
            costs.put(b, costs.get(b) + min);
            node = before[node];
        }
        return min;
    }

    private boolean[] getPrimes() {
        boolean[] isPrime = new boolean[(int)1e5];
        Arrays.fill(isPrime, true);
        isPrime[0] = isPrime[1] = true;
        int max = (int)Math.sqrt(isPrime.length - 1);
        for (int i = 2; i <= max; i++) {
            if (isPrime[i]) {
                for (int j = i * 2; j < isPrime.length; j += i) {
                    isPrime[j] = false;
                }
            }
        }
        return isPrime;
    }
}

class InputReader {
    private BufferedReader input;
    private StringTokenizer line = new StringTokenizer("");

    public InputReader(InputStream in) {
        input = new BufferedReader(new InputStreamReader(in));
    }

    public void fill() {
        try {
            if(!line.hasMoreTokens()) line = new StringTokenizer(input.readLine());
        } catch(IOException io) { io.printStackTrace(); System.exit(0);}
    }

    public int readInt() {
        fill();
        return Integer.parseInt(line.nextToken());
    }
}

class OutputWriter {
    private PrintWriter output;

    public OutputWriter(OutputStream out) {
        output = new PrintWriter(out);
    }
// change
    public void print(Object o) {
        output.print(o);
    }

    public void println(Object o) {
        output.println(o);
    }
    public void println() {
        output.println();
    }

    public void close() {
        output.close();
    }
}