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);
    }

	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();
    }
}