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.*;
public class C
{
	public static ArrayList<Edge>[] adj;
	public static int source;
	public static int sink;
	public static int[] dist;
	public static boolean[] blocked;
	
	public static void main(String[] args)
	{
		Scanner in = new Scanner(System.in);
		
		boolean[] prime = new boolean[100001];
		for(int x = 2; x < prime.length; x++)
		{
			prime[x] = true;
		}
		
		for(int y = 2; y * y < prime.length; y++)
		{
			if(prime[y])
			{
				for(int z = y * y; z < prime.length; z += y)
				{
					prime[z] = false;
				}
			}
		}
		
		int n = in.nextInt();
		
		int[] ages = new int[n];
		for(int x = 0; x < n; x++)
		{
			ages[x] = in.nextInt();
		}
		
		ArrayList<Integer>[] graph = new ArrayList[n];
		for(int y = 0; y < graph.length; y++)
		{
			graph[y] = new ArrayList<Integer>();
		}
		
		for(int z = 0; z < ages.length; z++)
		{
			for(int a = z + 1; a < ages.length; a++)
			{
				if(prime[ages[z] + ages[a]])
				{
					graph[z].add(a);
					graph[a].add(z);
				}
			}
		}
		
		ArrayDeque<Integer> queue = new ArrayDeque<Integer>();
		int[] color = new int[n];
		Arrays.fill(color, -1);
		for(int b = 0; b < graph.length; b++)
		{
			if(color[b] == -1)
			{
				color[b] = 0;
				queue.add(b);
				
				while(queue.size() > 0)
				{
					int node = queue.remove();
					
					for(int next : graph[node])
					{
						if(color[next] == -1)
						{
							color[next] = 1 - color[node];
							queue.add(next);
						}
					}
				}
			}
		}
		
		adj = new ArrayList[n + 2];
		for(int c = 0; c < adj.length; c++)
		{
			adj[c] = new ArrayList<Edge>();
		}
		
		source = n;
		sink = n + 1;
		
		for(int d = 0; d < color.length; d++)
		{
			if(color[d] == 0)
			{
				add(source, d, 2);
				
				for(int e : graph[d])
				{
					add(d, e, 1);
				}
			}
			else
			{
				add(d, sink, 2);
			}
		}
		
		int flow = dinic();
		
		if(flow < n)
		{
			System.out.println("Impossible");
		}
		else
		{
			graph = new ArrayList[n];
			for(int f = 0; f < graph.length; f++)
			{
				graph[f] = new ArrayList<Integer>();
			}
			
			for(int g = 0; g < n; g++)
			{
				if(color[g] == 0)
				{
					for(Edge e : adj[g])
					{
						if(e.end != source && e.capacity == 0)
						{
							graph[g].add(e.end);
							graph[e.end].add(g);
						}
					}
				}
			}
			
			ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
			boolean[] visited = new boolean[n];
			for(int h = 0; h < graph.length; h++)
			{
				if(!visited[h])
				{
					ArrayList<Integer> table = new ArrayList<Integer>();
					
					visited[h] = true;
					table.add(h);
					
					queue = new ArrayDeque<Integer>();
					visited[graph[h].get(0)] = true;
					queue.add(graph[h].get(0));
					
					while(queue.size() > 0)
					{
						int node = queue.remove();
						
						table.add(node);
						
						for(int next : graph[node])
						{
							if(!visited[next])
							{
								visited[next] = true;
								queue.add(next);
							}
						}
					}
					
					result.add(table);
				}
			}
			
			System.out.println(result.size());
			for(ArrayList<Integer> table : result)
			{
				System.out.print(table.size());
				for(int i : table)
				{
					System.out.print(" " + (i + 1));
				}
				
				System.out.println();
			}
		}
	}
	
	public static void add(int a, int b, int cap)
	{
		Edge e1 = new Edge(b, cap);
		Edge e2 = new Edge(a, 0);
		e1.rev = e2;
		e2.rev = e1;
		adj[a].add(e1);
		adj[b].add(e2);
	}
	
	public static int dinic()
	{
		int result = 0;
		
		dist = new int[adj.length];
		
		while(getLevels())
		{
			blocked = new boolean[adj.length];
			result += blockingFlow(source, Integer.MAX_VALUE);
		}
		
		return result;
	}
	
	public static boolean getLevels()
	{
		Arrays.fill(dist, -1);
		ArrayDeque<Integer> queue = new ArrayDeque<Integer>();
		
		dist[source] = 0;
		queue.add(source);
		
		while(queue.size() > 0)
		{
			int node = queue.remove();
			
			for(Edge e : adj[node])
			{
				if(dist[e.end] == -1 && e.capacity > 0)
				{
					dist[e.end] = dist[node] + 1;
					queue.add(e.end);
				}
			}
		}
		
		return dist[sink] != -1;
	}
	
	public static int blockingFlow(int node, int flow)
	{
		if(flow == 0)
		{
			return 0;
		}
		else if(node == sink)
		{
			return flow;
		}
		else
		{
			int ret = 0;
			for(Edge e : adj[node])
			{
				if(!blocked[e.end] && dist[e.end] == dist[node] + 1 && e.capacity > 0)
				{
					int current = blockingFlow(e.end, Math.min(flow, e.capacity));
					e.capacity -= current;
					e.rev.capacity += current;
					flow -= current;
					ret += current;
				}
			}
			
			blocked[node] |= (flow > 0);
			
			return ret;
		}
	}
	
	static class Edge
	{
		int end;
		int capacity;
		Edge rev;
		
		public Edge(int e, int c)
		{
			end = e;
			capacity = c;
		}
	}
}