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.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;


public class D {
	
	static boolean[] prime = new boolean[10005 * 2];
	
	static int[][] adj;
	
	static int[] par;
	static List<Integer> ages = new ArrayList<>();
	
	
	public static void main(String[] args) throws IOException {

		Scanner in = new Scanner(System.in);
		
		sieve();
		
		int v = in.nextInt();
		
		if(v % 2 != 0) {
			System.out.println("Impossible");
			return;
		}
		
		adj = new int[v+2][v+2];
		par = new int[v+10];
				
		int e = 0;
		int o = 0;
		
		for(int i=1; i<=v; i++) {
			int x = in.nextInt();
			ages.add(x);
			if(x % 2 == 0) {
				e++;
			}
			else {
				o++;
			}
		}
		
		if(e != o) {
			System.out.println("Impossible");
			return;
		}
		
		for(int i=0; i<ages.size(); i++) {
			for(int j=0; j<i; j++) {
				if(prime[ages.get(i) + ages.get(j)]) {
					if(ages.get(i) % 2 == 0) {
						adj[j+1][i+1] = 1;
					}
					else {
						adj[i+1][j+1] = 1;
					}
				}
			}
			
			if(ages.get(i) % 2 == 0) {
				adj[i+1][adj.length-1] = 2;
			}
			else {
				adj[0][i+1] = 2;
			}
		}
				
		if(maxFlow(0, adj.length-1) != v) {
			System.out.println("Impossible");
			return;
		}
	
		boolean[] vis = new boolean[adj.length];
		
		List<List<Integer>> res = new ArrayList<>();
		
		for(int i=1; i<adj.length-1; i++) {
			if(ages.get(i-1) % 2 == 1 && !vis[i]) {
				ArrayList<Integer> set = new ArrayList<>();
				dfs(i, vis, set, 1);
				res.add(set);
			}
		}
		
		System.out.println(res.size());
		
		for(List<Integer> ans : res) {
			System.out.print(ans.size() + " ");
			
			for(int n : ans) {
				System.out.print(n + " ");
			}
			System.out.println();
		}	
	}
	
	private static void dfs(int i, boolean[] vis, ArrayList<Integer> set, int div) {
		vis[i] = true;
		set.add(i);
		
		for(int j=1; j<adj.length-1; j++) {
			if(div == 0) {
				if(!vis[j] && adj[i][j] > 0 && ages.get(j-1) % 2 == 1 ) {
					dfs(j, vis, set, 1);
				}
			}
			else {
				if(!vis[j] && adj[i][j] == 0 && ages.get(j-1) % 2 == 0 && prime[ages.get(i-1) + ages.get(j-1)]) {
					dfs(j, vis, set, 0);
				}
			}
		}
		
	}

	static void union(int x, int y) {
		
		int k = find(x);
		int oink = find(y);
		
		par[k] = oink;
		
	}
	
	static int find(int x) {
		
		if(par[x] == x) {
			return x;
		}
		else {
			return par[x] = find(par[x]);
		}
	}
	
	private static int maxFlow(int s, int t) {
		
		int[] par = new int[adj.length];
		
		int ans = 0;
		
		while(bfs(s, t, par)) {
			
			int flow = Integer.MAX_VALUE;
			
			for(int i=t; i!=s; i=par[i]) {
				flow = Math.min(adj[par[i]][i], flow);
			}
			
			
			
			for(int i=t; i!=s; i=par[i]) {
				adj[par[i]][i] -= flow;
				adj[i][par[i]] += flow;
			}
			
			ans += flow;
		}
		
		return ans;
	}



	private static boolean bfs(int s, int t, int[] par) {
		
		for(int i=0; i<par.length; i++) {
			par[i] = -1;
		}
		
		Queue<Integer> q = new LinkedList<>();
		
		par[s] = s;
		q.offer(s);
		
		while(!q.isEmpty()) {
			
			int cur = q.poll();
			
			if(cur == t) {
				return true;
			}
			
			for(int i=0; i<adj.length; i++) {
				if(adj[cur][i] > 0 && par[i] == -1) {
					par[i] = cur;
					q.offer(i);
				}
			}
		}
		
		
		return false;
	}


	static void sieve() {
		for(int i=0; i<prime.length; i++) {
			prime[i] = true;
		}
		
		for(int i=2; i<prime.length; i++) {
			if(!prime[i]) {
				continue;
			}
			
			for(int j=i+i; j<prime.length; j+=i) {
				prime[j] = false;
			}
		}
	}
	
}