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:
// package Div2;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class Sketch {
	// Dinic algorithm
	public static final int INF = 100000000;
	public static final int NMAX = 100000;
	
	public static class Edge {
		public int next;
		public int flow;
		public int rev;
		public Edge(int next, int flow, int rev){
			this.next = next;
			this.flow = flow;
			this.rev = rev;
		}
	}

	public static Edge[] edges = new Edge[2*NMAX];
	public static int[] edgeList = new int[2*NMAX];
	public static int[] starts = new int[2*NMAX];
	public static int[] levels = new int[2*NMAX];
	public static int listEnd = 0;
	public static int N = 0;
	
	static {
		for(int i=0; i<2*NMAX; i++){
			edgeList[i] = -1;
			starts[i] = -1;
		}
	}
	
	public static void addEdge(int u, int v, int cap){
		edges[listEnd] = new Edge(v, cap, listEnd+1);
		edgeList[listEnd] = starts[u];
		starts[u] = listEnd++;
		edges[listEnd] = new Edge(u, 0, listEnd-1);
		edgeList[listEnd] = starts[v];
		starts[v] = listEnd++;
	}

	private static boolean mkLevel(){
		for(int i=0; i<N+2; i++){
			levels[i] = -1;
		}
		levels[0] = 0;
		List<Integer> list = new LinkedList<Integer>();
		list.add(0);
		while(list.size()!=0){
			int item = list.get(0);
			list.remove(0);
			if(item == N+1)
				continue;
			for(int t=starts[item]; t!=-1; t=edgeList[t]){
				if(edges[t].flow>0 && levels[edges[t].next] == -1){
					levels[edges[t].next] = levels[item]+1;
					list.add(edges[t].next);
				}
			}
		}
		return levels[N+1]!=-1;
	}

	private static int extend(int start, int cap){
		if(start == N+1){
			return cap;
		}
		int ret = 0;
		for(int t=starts[start]; t!=-1; t=edgeList[t]){
			if(edges[t].flow > 0 && levels[edges[t].next] == levels[start]+1){
				int fl = edges[t].flow;
				if(fl > cap-ret) 
					fl = cap-ret;
				int r = extend(edges[t].next, fl);
				edges[t].flow -= r;
				edges[edges[t].rev].flow += r;
				ret += r;
			}
		}
		
		if(ret==0)
			levels[start] = -1;
		
		return ret;
	}
	
	public static int flow(){
		int ret = 0;
		int r = 0;
		while(mkLevel()){
			while((r = extend(0, INF)) > 0){
				ret += r;
			}
		}
		return ret;
	}
	
	public static boolean isPrime(int n){
		if(n <= 1)
			return false;
		if(n == 2)
			return true;
		int sqt = (int) Math.sqrt(n);
		for(int i=2; i<=sqt; i++){
			if(n%i==0)
				return false;
		}
		return true;
	}

	public static void main(String[] args){
		Scanner input = new Scanner(System.in);
		
		N = input.nextInt();
		int[] ages = new int[N];
		for(int i=0; i<N; i++){
			ages[i] = input.nextInt();
		}
		input.close();

		for(int i=0; i<N; i++){
			if(ages[i]%2==0)
				addEdge(0, i+1, 2);
			else 
				addEdge(i+1, N+1, 2);
		}
		
		for(int i=0; i<N-1; i++){
			for(int j=i+1; j<N; j++){
				if(isPrime(ages[i] + ages[j])){
					if(ages[i]%2==0){
						addEdge(i+1, j+1, 1);
					}
					else 
						addEdge(j+1, i+1, 1);
				}
			}
		}
		
		if(flow()==N){
			List<int[]> partition = new ArrayList<int[]>();
			boolean[] used = new boolean[N+1];
			for(int i=1; i<=N; i++){
				if(!used[i]){
					int[] buf = new int[N];
					buf[0] = i;
					used[i] = true;
					int tail = 1;
					int cur = 0;
					while(cur<tail){
						int item = buf[cur];
						cur++;
						for(int t=starts[item]; t!=-1; t=edgeList[t]){
							int nxt = edges[t].next;
							if(nxt>0 && nxt <=N && (ages[item-1]%2==0 && edges[t].flow==0 || ages[item-1]%2==1 && edges[t].flow==1) 
									&& !used[nxt]){
								buf[tail++] = nxt;
								used[nxt] = true;
								break;
							}
						}
					}
					int[] tbl = new int[tail];
					for(int j=0; j<tail; j++)
						tbl[j] = buf[j];
					partition.add(tbl);
				}
			}
			System.out.println(partition.size());
			for(int i=0; i<partition.size(); i++){
				int[] tmp = partition.get(i);
				System.out.print(tmp.length + " ");
				for(int j=0; j<tmp.length; j++){
					System.out.print(tmp[j] + " ");
				}
				System.out.println();
			}
		}
		else 
			System.out.println("Impossible");
	}
}