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

public class cf290E {
	static boolean[] primes = new boolean[20010];
	public static void main(String[] args) throws Exception {
		// BufferedReader in = new BufferedReader(new FileReader("cf290E.in"));
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		
		int n = Integer.parseInt(in.readLine());
		String[] arr = in.readLine().split(" ");
		
		int[] a = new int[arr.length];
		for(int i = 0; i < a.length; i++) {
			a[i] = Integer.parseInt(arr[i]);
		}
		Arrays.fill(primes, true);
		primes[0] = false;
		primes[1] = false;
		for(int i = 2; i < primes.length; i++) {
			if(primes[i]) {
				for(int j = 2 * i; j < primes.length; j += i) {
					primes[j] = false;
				}
			}
		}
		Node[] verts = new Node[n];
		for(int i = 0; i < n; i++) {
			verts[i] = new Node(i, a[i]);
		}
		if(n % 2 == 1) {
			System.out.println("Impossible");
			return;
		}
		ArrayList<Integer> evens = new ArrayList<Integer>();
		ArrayList<Integer> odds = new ArrayList<Integer>();
		boolean[][] padj = new boolean[n][n];
		for(int i = 0; i < n; i++) {
			for(int j = 0; j < n; j++) {
				if(primes[a[i] + a[j]]) {
					padj[i][j] = true;
					padj[j][i] = true;
				}
			}
		}
		for(int i = 0; i < n; i++) {
			if(verts[i].val % 2 == 0) {
				evens.add(i);
			} else {
				odds.add(i);
			}
		}
		int[][] adj = new int[n + 2][n + 2];
		for(int i = 0; i < evens.size(); i++) {
			adj[0][i + 1] = 2;
		}
		for(int i = 0; i < odds.size(); i++) {
			adj[i + evens.size() + 1][n + 1] = 2;
		}
		for(int i = 0; i < evens.size(); i++) {
			for(int j = 0; j < odds.size(); j++) {
				if(padj[evens.get(i)][odds.get(j)]) {
					adj[i + 1][j + evens.size() + 1] = 1;
				}
			}
		}
		int[][] copy = new int[n + 2][n + 2];
		for(int i = 0; i < n + 2; i++) {
			for(int j = 0; j < n + 2; j++) {
				copy[i][j] = adj[i][j];
			}
		}
		boolean works = true;
		int tot = 0;
		while(works) {
			int curr = 0;
			boolean[] hV = new boolean[n + 2];
			Node2[] verts2 = new Node2[n + 2];
			for(int i = 0; i < n + 2; i++) {
				verts2[i] = new Node2(i);
			}
			verts2[0].ad.addLast(0);
			verts2[0].cap = Integer.MAX_VALUE >> 1;
			hV[0] = true;
			boolean works2 = true;
			while(curr != n + 1 && curr != -1) {
				hV[curr] = true;
				for(int i = 0; i < n + 2; i++) {
					if(!hV[i] && verts2[i].cap < Math.min(verts2[curr].cap, adj[curr][i])) {
						verts2[i].cap = Math.min(verts2[curr].cap, adj[curr][i]);
						verts2[i].ad = new ArrayDeque<Integer>(verts2[curr].ad);
						verts2[i].ad.addLast(i);
					}
				}
				int ind = -1;
				int max = 0;
				for(int i = 0; i < n + 2; i++) {
					if(!hV[i] && verts2[i].cap > max) {
						max = verts2[i].cap;
						ind = i;
					}
				}
				curr = ind;
			}
			if(curr == -1) {
				works = false;
			} else {
				tot += verts2[n + 1].cap;
				ArrayDeque<Integer> ad = verts2[n + 1].ad;
				int prev = ad.pollFirst();
				while(!ad.isEmpty()) {
					adj[prev][ad.peekFirst()] -= verts2[n + 1].cap;
					adj[ad.peekFirst()][prev] += verts2[n + 1].cap;
					prev = ad.pollFirst();
				}
			}
		}
		// for(int i = 0; i < n + 2; i++) {
		// 	for(int j = 0; j < n + 2; j++) {
		// 		System.out.print(adj[i][j] + (j == n + 1 ? "\n" : " "));
		// 	}
		// }
		if(tot != n) {
			System.out.println("Impossible");
		} else {
			boolean[][] newadj = new boolean[n][n];
			for(int i = 0; i < evens.size(); i++) {
				for(int j = 0; j < odds.size(); j++) {
					if(copy[i + 1][j + evens.size() + 1] - adj[i + 1][j + evens.size() + 1] != 0 && i < j + evens.size()) {
						newadj[evens.get(i)][odds.get(j)] = true;
					}
				}
			}
			Node3[] verts3 = new Node3[n];
			for(int i = 0; i < n; i++) {
				verts3[i] = new Node3(i);
			}
			for(int i = 0; i < n; i++) {
				for(int j = 0; j < n; j++) {
					if(newadj[i][j]) {
						verts3[i].adj.add(j);
						verts3[j].adj.add(i);
					}
				}
			}
			// for(int i = 0; i < n; i++) {
			// 	System.out.println(verts3[i].adj);
			// }
			int count = 0;
			ArrayList<ArrayList<Integer>> lists = new ArrayList<ArrayList<Integer>>();
			boolean[] hV = new boolean[n];
			for(int i = 0; i < n; i++) {
				if(!hV[i]) {
					count++;
					hV[i] = true;
					ArrayList<Integer> templist = new ArrayList<Integer>();
					templist.add(i);
					int curr = i;
					boolean works3 = true;
					while(works3) {
						// System.out.println(verts3[curr].adj);
						int x = verts3[curr].adj.get(0);
						int y = verts3[curr].adj.get(1);
						if(!templist.contains(x)) {
							templist.add(x);
							curr = x;
							hV[curr] = true;
						} else {
							if(!templist.contains(y)) {
								templist.add(y);
								curr = y;
								hV[curr] = true;
							} else {
								works3 = false;
							}
						}
					}
					lists.add(templist);
				}
			}
			System.out.println(count);
			for(ArrayList<Integer> tmp : lists) {
				System.out.print(tmp.size());
				for(int foo : tmp) {
					System.out.print(" " + (foo + 1));
				}
				System.out.println();
			}
		}
	}

	static class Node3 {
		ArrayList<Integer> adj = new ArrayList<Integer>();
		int id;

		public Node3(int i) {
			id = i;
		}
	}

	static class Node2 {
		int cap, id;
		ArrayDeque<Integer> ad = new ArrayDeque<Integer>();

		public Node2(int i) {
			id = i;
			cap = 0;
		}
	}

	static class Node {
		int val, id;

		public Node(int i, int tempv) {
			id = i;
			val = tempv;
		}
	}
}