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

public class FoxAndDinner {
	static final int MAX = (int) 1e5+1;
	static int source, sink;
	static boolean[] visited;
	static List<Integer>[] adj;
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		boolean[] isPrime = new boolean[MAX];
		Arrays.fill(isPrime, true);
		isPrime[0] = isPrime[1] = false;
		for(int i = 2 ; i < MAX ; i++)
			for(int j = i+i ; j < MAX ; j+=i)
				isPrime[j] = false;
		int n = scan.nextInt();
		source = n; sink = n+1;
		Flow d = new Flow(n+2);
		int[] a = new int[n];
		for(int i = 0 ; i < n ; i++) {
			a[i] = scan.nextInt();
			if(a[i]%2 == 0)
				d.addEdge(i, sink, 2);
			else
				d.addEdge(source, i, 2);
		}
		for(int u = 0 ; u < n ; u++)
			for(int v = u+1 ; v < n ; v++)
				if(isPrime[a[u]+a[v]])
					if(a[u]%2 == 1)
						d.addEdge(u, v, 1);
					else
						d.addEdge(v, u, 1);
		int maxFlow = d.maxFlow(source, sink);
		if(maxFlow != n) {
			System.out.println("Impossible");
			return;
		}
		adj = new ArrayList[n];
		for(int i = 0 ; i < n ; i++)
			adj[i] = new ArrayList<>();
		for(int u = 0 ; u < n ; u++)
			for(Edge e : d.adj[u])
				if(e.flow == 1) {
					adj[u].add(e.v);
					adj[e.v].add(u);
				}
		List<List<Integer>> cycles = new ArrayList<>();
		visited = new boolean[n];
		for(int i = 0 ; i < n ; i++) {
			if(!visited[i]) {
				visited[i] = true;
				List<Integer> cycle = new ArrayList<>();
				dfs(i, cycle);
				cycles.add(cycle);
			}
		}
		out.println(cycles.size());
		for(int i = 0 ; i < cycles.size() ; i++) {
			out.print(cycles.get(i).size() + " ");
			for(int j = 0 ; j < cycles.get(i).size() ; j++)
				out.print(cycles.get(i).get(j)+1 + " ");
			out.println();
		}
		out.close();
	}
	static void dfs(int u, List<Integer> list) {
		list.add(u);
		for(int v : adj[u])
			if(!visited[v]) {
				visited[v] = true;
				dfs(v, list);
			}
	}
	static class Edge {
		int u, v, flow, cap, reverseEdge;
		public Edge(int start, int end, int hold) {
			u = start;
			v = end;
			flow = 0;
			cap = hold;
		}
		public String toString() {
			return u + " " + v;
		}
	}
	static class Flow {
		void addEdge(int u, int v, int cap) {
			Edge addU = new Edge(u, v, cap);
			addU.reverseEdge = adj[v].size();
			Edge addV = new Edge(v, u, 0);
			addV.reverseEdge = adj[u].size();
			adj[u].add(addU);
			adj[v].add(addV);
		}
		ArrayList<Edge>[] adj;
		int n;
		public Flow(int n) {
			adj = new ArrayList[n];
			this.n = n;
			for(int i = 0; i < n; i++)
				adj[i] = new ArrayList<>();
		}
		int[] level;
		boolean BFS(int source, int sink) {
			level = new int[n];
			Arrays.fill(level, -1);
			level[source] = 0;
			ArrayDeque<Integer> bfs = new ArrayDeque<>();
			bfs.addLast(source);
			while(!bfs.isEmpty()) {
				int now = bfs.pollFirst();
				for(Edge e : adj[now]) {
					if(level[e.v] < 0 && e.flow < e.cap) {
						level[e.v] = level[now] + 1;
						bfs.addLast(e.v);
					}
				}
			}
			return level[sink] != -1;
		}
		int getFlow (int u, int flow, int sink) {
			if(u == sink) 
				return flow;
			for(Edge e : adj[u]) {
				if(level[e.v] == level[u]+1 && e.flow < e.cap) {
					int curFlow = Math.min(flow, e.cap-e.flow);
					int findFlow = getFlow(e.v, curFlow, sink);
					if(findFlow > 0) {
						e.flow+=findFlow;
						adj[e.v].get(e.reverseEdge).flow-=findFlow;
						return findFlow;
					}
				}
			}
			return 0;
		}
		int maxFlow (int source, int sink) {
			if(source == sink) 
				return -1;
			int total = 0;
			while(BFS(source, sink)) {
				int addFlow;
				while((addFlow = getFlow(source, Integer.MAX_VALUE, sink)) > 0 )
					total += addFlow;
			}
			return total;
		}
	}
}
