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 static java.lang.Math.*;

import java.lang.reflect.Array;
import java.util.*;
import java.util.function.*;
import java.lang.*;

public class Main {
    final static boolean debug = false;
    final static String fileName = "";
    final static boolean useFiles = false;

    public static void main(String[] args) throws FileNotFoundException {
        long start;
        if (debug)
            start = System.nanoTime();
        InputStream inputStream;
        OutputStream outputStream;
        if (useFiles) {
            inputStream = new FileInputStream(fileName + ".in");
            outputStream = new FileOutputStream(fileName + ".out");
        } else {
            inputStream = System.in;
            outputStream = System.out;
        }
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task solver = new Task(in, out);
        solver.solve();
        if(debug)
            out.println((System.nanoTime() - start) / 1e+9);
        out.close();
    }
}

class Dinic {
    final int inf = (int) (1e+9);
    int[][] capacity, flow;
    int n, source, target;
    int[] d, last;

    public Dinic(int[][] c, int s, int t) {
        capacity = c;
        n = c.length;
        d = new int[n];
        last = new int[n];
        flow = new int[n][n];
        source = s;
        target = t;
    }

    private boolean bfs() {
        Arrays.fill(d, -1);
        Queue<Integer> queue = new ArrayDeque<>();
        queue.add(source);
        d[source] = 0;
        while (!queue.isEmpty()) {
            int vertex = queue.remove();
            for (int i = 0; i < n; i++) {
                if (d[i] == -1 && capacity[vertex][i] - flow[vertex][i] > 0) {
                    d[i] = d[vertex] + 1;
                    queue.add(i);
                }
            }
        }
        return d[target] != -1;
    }

    private int dfs(int v, int addedFlow) {
        if (addedFlow == 0 || v == target)
            return addedFlow;
        for (; last[v] < n; last[v]++) {
            int i = last[v];
            if (d[i] == d[v] + 1) {
                int added = dfs(i, Math.min(addedFlow, capacity[v][i] - flow[v][i]));
                flow[v][i] += added;
                flow[i][v] -= added;
                if (added != 0)
                    return added;
            }
        }
        return 0;
    }

    long maxFlow() {
        while (bfs()) {
            Arrays.fill(last, 0);
            while (dfs(source, inf) > 0);
        }
        long result = 0;
        for (int i = 0; i < n; i++) {
            result += flow[source][i];
        }
        return result;
    }
}
class Task {
    void fail(){
        out.println("Impossible");
    }

    public void solve() {
        int n = in.nextInt();
        int[] a = new int[n];
        int maxA = 0;
        for (int i = 0; i < n; i++) {
            a[i] = in.nextInt();
            maxA = max(maxA, a[i]);
        }
        boolean[] isPrime = new boolean[2 * maxA + 1];
        Arrays.fill(isPrime, true);
        for (int i = 2; i * i < isPrime.length; i++) {
            if (isPrime[i]) {
                for (int j = i * i; j < isPrime.length; j += i) {
                    isPrime[j] = false;
                }
            }
        }
        int[][] c = new int[n + 2][n + 2];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (isPrime[a[i] + a[j]])
                    if (a[i] % 2 == 0)
                        c[i][j] = 1;
                    else
                        c[j][i] = 1;
            }
        }
        int source = n;
        int target = n + 1;
        for (int i = 0; i < n; i++) {
            if (a[i] % 2 == 0) {
                c[source][i] = 2;
            } else {
                c[i][target] = 2;
            }
        }
        Dinic din = new Dinic(c, source, target);
        int flow = (int)din.maxFlow();
        int[][] f = din.flow;
//        Debug.print2DArray(out, din.flow);
//        out.println();
//        Debug.print2DArray(out, din.capacity);
        if (flow != n) {
            fail();
            return;
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                f[i][j] = abs(f[i][j]);
            }
        }
        boolean[] used = new boolean[n];
        ArrayList<ArrayList<Integer>> foxes = new ArrayList<>();
        for (int curr = 0; curr < n; curr++) {
            if (!used[curr]) {
                ArrayList<Integer> circle = new ArrayList<>();
                foxes.add(circle);
                for (; curr != -1; ) {
                    used[curr] = true;
                    circle.add(curr);
                    int next = -1;
                    for (int i = 0; i < n; i++) {
                        if (f[curr][i] == 1 && !used[i]) {
                            next = i;
                            break;
                        }
                    }
                    curr = next;
                }
            }
        }
        out.println(foxes.size());
        for (ArrayList<Integer> circle : foxes) {
            out.print(circle.size() + " ");
            for (Integer fox : circle) {
                out.print(fox + 1 + " ");
            }
            out.println();
        }
    }

    private InputReader in;
    private PrintWriter out;

    Task(InputReader in, PrintWriter out) {
        this.in = in;
        this.out = out;
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        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 double nextDouble(){
        return Double.parseDouble(next());
    }

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

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

    public byte nextByte(){
        return Byte.parseByte(next());
    }
}