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.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

/*

4
3 4 8 9

5
2 2 2 2 2

12
2 3 4 5 6 7 8 9 10 11 12 13

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


 */
public class e {

	public static void main(String[] args) 
	{
		Scanner in = new Scanner(System.in);
		
		boolean[] composite = composite((int)5E4);
		
		int numFoxes = in.nextInt();
		int[] ages = new int[numFoxes];
		
		TidalFlow tf = new TidalFlow(numFoxes*2);
		
		for(int fox1 = 0; fox1 < numFoxes; ++fox1)
		{
			ages[fox1] = in.nextInt();
			
			for(int fox2 = 0; fox2 < fox1; ++fox2)
			{
				if(!composite[ages[fox1] + ages[fox2]])
				{
					//System.out.println("[" +fox1 + "] " +ages[fox1] +", ["+fox2 +"] " +ages[fox2] );
					if(ages[fox1] %2 == 0)
						tf.add(fox1, fox2 + numFoxes, 1);
					else
						tf.add(fox2, fox1 + numFoxes, 1);
				}
			}
			
			tf.add(tf.s, fox1, 2);
			tf.add(fox1 + numFoxes, tf.t, 2);
		}
		in.close();
		
		int flow = tf.getFlow();
		//System.out.println(flow);
		if(flow == numFoxes) 
		{
//			for(int fox1 = 0; fox1 < numFoxes; ++fox1)
//			{
//				System.out.println(fox1+1);
//				for(Edge e: tf.adj[fox1])
//				{
//					if(e.j < numFoxes*2)
//					{
//						System.out.println("("+(e.i+1) +" - " +(e.j- numFoxes +1) +") " +e.carry +" " + e.flow);
//						//System.out.println("("+(e.rev.i- numFoxes) +" - " +e.rev.j +") " +e.rev.carry +" " + e.rev.flow);
//					}
//				}
//				System.out.println("Rev:");
//				for(Edge e: tf.adj[fox1+numFoxes])
//				{
//					if(e.j < numFoxes*2)
//					{
//						System.out.println("("+(e.i+1- numFoxes) +" - " +(e.j +1) +") " +e.carry +" " + e.flow);
//						//System.out.println("("+(e.rev.i- numFoxes) +" - " +e.rev.j +") " +e.rev.carry +" " + e.rev.flow);
//					}
//				}
//				System.out.println();
//			}
			
			ArrayList<ArrayList<Integer>> tables = new ArrayList<ArrayList<Integer>>();
			
			boolean[] used = new boolean[numFoxes];
			for(int fox1 = 0; fox1 < numFoxes; ++fox1)
			{
				if(used[fox1])
					continue;
				
				ArrayDeque<Integer> stk = new ArrayDeque<Integer>();
				stk.add(fox1);
				ArrayList<Integer> list = new ArrayList<Integer>();
				
				while(!stk.isEmpty())
				{
					int node = stk.pop();
					if(used[node])
						continue;
					
					//System.out.println("P: "+node);
					
					used[node] = true;
					list.add(node+1);
					
					for(Edge e: tf.adj[node + (ages[node]%2 == 0?0:numFoxes)])
					{
						int next = e.j - (ages[node]%2 == 1?0:numFoxes);
						//System.out.println("N: "+next);
						if(next < numFoxes && !used[next] && e.flow != 0)
						{
							//System.out.println("A: " +next);
							stk.push(next);
						}
					}
				}
				
				tables.add(list);
			}
			
			System.out.println(tables.size());
			for(ArrayList<Integer> list: tables)
			{
				System.out.print(list.size() + " ");
				for(int i = 0; i < list.size(); ++i)
				{
					int num = list.get(i);
					System.out.print(num +" ");
					//System.out.print("("+ages[num-1]+") ");
					int prime = (ages[num-1]+ages[list.get((i+1)%list.size())-1]);
					//System.out.print("("+prime +") ");
					if(composite[prime])
						prime = 1/0;
				}
				System.out.println();
			}
		}
		else
		{
			System.out.println("Impossible");
		}
	}
	
	public static boolean[] composite(int size)
	{
		boolean[] composite = new boolean[size+1];
		for(int curr = 2; curr*curr < size; ++curr)
		{
			if(composite[curr])
				continue;
			for(int curr2 = curr*curr; curr2 < size; curr2 += curr)
				composite[curr2] = true;
		}
		
//		for(int i = 0; i < 100; ++i)
//		{
//			System.out.print(i +": "+(composite[i]?1:0) +", ");
//		}
//		System.out.println();
		
		return composite;
	}

	
	static class TidalFlow {
		ArrayDeque<Edge> stk = new ArrayDeque<Edge>();
		int N, s, t, oo = 987654321, fptr, bptr;
		ArrayList<Edge>[] adj;
		int[] q, dist, pool;

		@SuppressWarnings("unchecked")
		TidalFlow(int NN) {
			N = (t = (s = NN) + 1) + 1;
			adj = new ArrayList[N];

			for (int i = 0; i < N; adj[i++] = new ArrayList<Edge>())
				;

			dist = new int[N];
			pool = new int[N];
			q = new int[N];
		}

		void add(int i, int j, int cap) {
			Edge fwd = new Edge(i, j, cap, 0);
			Edge rev = new Edge(j, i, 0, 0);
			adj[i].add(rev.rev = fwd);
			adj[j].add(fwd.rev = rev);
		}

		int augment() {
			Arrays.fill(dist, Integer.MAX_VALUE);
			pool[t] = dist[s] = fptr = bptr = 0;
			pool[q[bptr++] = s] = oo;

			while (bptr > fptr && q[fptr] != t)
				for (Edge e : adj[q[fptr++]]) {
					if (dist[e.i] < dist[e.j])
						pool[e.j] += e.carry = Math.min(e.cap - e.flow, pool[e.i]);
					if (dist[e.i] + 1 < dist[e.j] && e.cap > e.flow)
						dist[q[bptr++] = e.j] = dist[e.i] + 1;
				}
			if (pool[t] == 0)
				return 0;

			Arrays.fill(pool, fptr = bptr = 0);
			pool[q[bptr++] = t] = oo;
			while (bptr > fptr)
				for (Edge e : adj[q[fptr++]]) {
					if (pool[e.i] == 0)
						break;
					int f = e.rev.carry = Math.min(pool[e.i], e.rev.carry);
					if (dist[e.i] > dist[e.j] && f != 0) {
						if (pool[e.j] == 0)
							q[bptr++] = e.j;
						pool[e.i] -= f;
						pool[e.j] += f;
						stk.push(e.rev);
					}
				}

			int res = pool[s];
			Arrays.fill(pool, 0);
			pool[s] = res;

			while (stk.size() > 0) {
				Edge e = stk.pop();
				int f = Math.min(e.carry, pool[e.i]);
				pool[e.i] -= f;
				pool[e.j] += f;
				e.flow += f;
				e.rev.flow -= f;
			}
			return res;
		}

		int getFlow() {
			int res = 0, f = 1;
			while (f != 0)
				res += f = augment();
			return res;
		}
	}

	static class Edge {
		int i, j, flow, carry;
		private int cap;
		Edge rev;

		Edge(int ii, int jj, int cc, int ff) {
			i = ii;
			j = jj;
			cap = cc;
			flow = ff;
		}
	}
}