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.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.StringTokenizer;

/*

a b c d e f g h


8 17 18 23 22
*/
public class a {
	static boolean[] isprime;
	public static void main(String[] args) throws Exception {
		FastScanner in = new FastScanner(System.in);
		int n = in.nextInt();
		isprime = new boolean[20001];
		Arrays.fill(isprime, true);
		for(int i=2;i<isprime.length;i++) {
			if(!isprime[i]) continue;
			for(int j=i*i;j<isprime.length;j+=i)
				isprime[j] = false;
		}
		int[] vs = new int[n];
		for(int i=0;i<n;i++) {
			vs[i] = in.nextInt();
		}
		Dinic g = new Dinic(n);
		for(int i=0;i<n;i++) {
			if(vs[i] % 2 == 0) {
				g.add(g.s, i, 2, 0);
				for(int j=0;j<n;j++) {
					if(i != j && isprime[vs[i]+vs[j]]) {
						g.add(i, j, 1, 0);
					}
				}
			} else {
				g.add(i, g.t, 2, 0);
			}
		}
		int f = g.flow();
		if(f != n) {
			System.out.println("Impossible");
			return;
		}
		int[] as = new int[n], bs = new int[n];
		for(int i=0;i<n;i++) {
			ArrayList<Integer> match = new ArrayList();
			if(vs[i] % 2 == 1) {
				for(Dinic.Edge e : g.adj[i]) {
					if(e.flow == -1) {
						match.add(e.v2);
					}
				}
			} else {
				for(Dinic.Edge e : g.adj[i]) {
					if(e.flow == 1) {
						match.add(e.v2);
					}
				}
			}
			as[i] = match.get(0);
			bs[i] = match.get(1);
		}
		boolean[] seen = new boolean[n];
		ArrayList<ArrayList<Integer>> lists = new ArrayList();
		for(int s=0;s<n;s++) {
			if(seen[s]) continue;
			ArrayList<Integer> list = new ArrayList();
			int cur = s;
			while(true) {
				seen[cur] = true;
				list.add(cur);
				if(!seen[as[cur]]) {
					cur = as[cur];
				} else if(!seen[bs[cur]]) {
					cur = bs[cur];
				} else {
					break;
				}
			}
			lists.add(list);
		}
		System.out.println(lists.size());
		for(ArrayList<Integer> list : lists) {
			System.out.print(list.size());
			for(int i=0;i<list.size();i++) {
				System.out.print(' ');
				System.out.print(list.get(i)+1);
			}
			System.out.println();
		}
	}
	static class Dinic {
		static class Edge {  int v1, v2, cap, flow; Edge rev;
			Edge(int V1, int V2, int Cap, int Flow) { v1 = V1; v2 = V2; cap = Cap; flow = Flow; }
		}
		
		ArrayDeque<Integer> q;  ArrayList<Edge>[] adj;
		int n, s, t, oo = (int)1E9;
		boolean[] blocked;  int[] dist;
		public Dinic (int N) {
			n = N; s = n++; t = n++;  blocked = new boolean[n];
			dist = new int[n];  q = new ArrayDeque<Integer>();
			adj = new ArrayList[n];  for(int i = 0; i < n; ++i)  adj[i] = new ArrayList<Edge>();
		}
		// Specifying flow can represent minimum flow for circulation.
		void add(int v1, int v2, int cap, int flow) {
			Edge e = new Edge(v1, v2, cap, flow);  Edge rev = new Edge(v2, v1, 0, 0);
			adj[v1].add(rev.rev = e);  adj[v2].add(e.rev = rev);
		}

		//#
		// Only needed if you need remove function
		void remove(int v1, int v2) {
			Edge e;
			for(int i = 0; i < adj[v1].size(); i++) {
				e = adj[v1].get(i);
				if(e.v2 == v2 && e.cap != 0)  adj[v1].remove(i--);
			}

			for(int i = 0; i < adj[v2].size(); i++) {
				e = adj[v2].get(i);
				if(e.v2 == v1 && e.cap == 0)  adj[v2].remove(i--);
			}
		}
		//$
		
		boolean bfs() {
			q.clear();  Arrays.fill(dist, -1);  dist[t] = 0;  q.add(t);
			
			while(!q.isEmpty()) {
				int node = q.poll();
				if(node == s)   return true;
				for(Edge e : adj[node]) {
					if(e.rev.cap > e.rev.flow && dist[e.v2] == -1) {
						dist[e.v2] = dist[node] + 1;  q.add(e.v2);
					}
				}
			}
			return dist[s] != -1;
		}
		
		int dfs(int pos, int min) {
			if(pos == t)  return min;
			int flow = 0;
			for(Edge e : adj[pos]) {
				int cur = 0;
				if(!blocked[e.v2] && dist[e.v2] == dist[pos]-1 && e.cap - e.flow > 0) {
					cur = dfs(e.v2, Math.min(min-flow, e.cap - e.flow));
					e.flow += cur;  e.rev.flow = -e.flow;  flow += cur;
				}
				if(flow == min)  return flow;
			}
			blocked[pos] = flow != min;
			return flow;
		}
		int flow() {
			clear();  int ret = 0;
			while(bfs()) {  Arrays.fill(blocked, false);  ret += dfs(s, oo);  }
			return ret;
		}
		void clear() {  for(ArrayList<Edge> edges : adj)  for(Edge e : edges)  e.flow = 0;  }
		// Convert the given graph into a graph to test for circulation
		Dinic circulation() {
			int[] delta = new int[n];
			for(int node = 0; node < n; ++node) {
				for(Edge e : adj[node]) {
					if(e.cap > 0 && e.flow > 0) {
						delta[e.v1] -= e.flow;  delta[e.v2] += e.flow;
					}
				}
			}
			
			Dinic d = new Dinic(n);
			for(int i = 0; i < n; ++i) 
				if(delta[i] > 0)  d.add(d.s, i, delta[i], 0);
				else if(delta[i] < 0)  d.add(i, d.t, -delta[i], 0);
			
			for(int node = 0; node < n; ++node)
				for(Edge e : adj[node])
					if(e.cap > 0 && e.cap - e.flow > 0)  d.add(e.v1, e.v2, e.cap - e.flow, 0);
			
			return d;
		}
	}
	static class FastScanner {
		BufferedReader br;
		StringTokenizer st;
		public FastScanner(InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
			st = null;
		}
		public String next() throws IOException {
			while(st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}
		public int nextInt() throws NumberFormatException, IOException {
			return Integer.parseInt(next());
		}
	}
}