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.Closeable;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Scanner;
import java.util.StringTokenizer;

public class Solution {
	public static final boolean std = true;
	public static final boolean useFastIn = true;
	public static final String inputFile = "seq.in";
	public static final String outputFile = "seq.out";

	public final Scanner in;
	public final RFScanner fin;
	public final PrintWriter out;

	public Solution(Scanner i, PrintWriter o) {
		in = i;
		out = o;
		fin = null;
	}

	public Solution(RFScanner i, PrintWriter o) {
		in = null;
		out = o;
		fin = i;
	}

	public static void main(String[] args) throws Exception {
		Solution s;
		PrintWriter out;
		Reader is;
		Closeable in;
		
		Locale.setDefault(Locale.ENGLISH);

		if (std) {
			is = new InputStreamReader(System.in);
			out = new PrintWriter(System.out);
		} else {
			is = new FileReader(new File(inputFile));
			out = new PrintWriter(new File(outputFile));
		}

		if (useFastIn) {
			in = new RFScanner(is);
			s = new Solution((RFScanner) in, out);
		} else {
			in = new Scanner(is);
			s = new Solution((Scanner) in, out);
		}

		s.run();
		in.close();
		out.close();
	}
	
	

	int n, m;
	G[] g;
	E[] e;
	int sze = 0;
	public void run() throws Exception {
		n = fin.nextInt();
		g = new G[n+2];
		e = new E[n*n+n*2+1];
		for (int i=0; i<n; i++) {
			g[i] = new G(i, fin.nextInt());
		}
		g[n] = new G(n, 0);
		g[n+1] = new G(n+1, 0);
		
		for (int i=0; i<n; i++) {
			G u = g[i];
			if ((u.a&1) == 0) {
				addEdge(u, g[n+1], 2);
				continue;
			}
			addEdge(g[n], u, 2);
			for (int j=0; j<n; j++) {
				G v = g[j];
				if ((v.a&1) != 0) continue;
				if (BigInteger.valueOf(v.a+u.a).isProbablePrime(35)) {
					addEdge(u, v, 1);
				}
			}
		}
		
		maxFlow(g[n], g[n+1]);
		
		int sum = 0;
		for (E e : g[n].links) {
			sum += e.flow;
		}
		
		if (sum != n) {
			out.println("Impossible");
			return;
		}
		
		for (G v : g) {
			v.used = false;
		}
		g[n].used = g[n+1].used = true;
		List<List<G>> ans = new ArrayList<>();
		for (G v : g) {
			if (!v.used) {
				List<G> p = new ArrayList<>();
				ans.add(p);
				v.ansDfs(p);
			}
		}
		
		out.println(ans.size());
		for (List<G> p : ans) {
			out.print(p.size());
			out.print(' ');
			for (G v : p) {
				out.print(v.id+1);
				out.print(' ');
			}
			out.println();
		}
	}

	void addEdge(G u, G v, int c) {
		E ed1 = new E(sze, v, c);
		e[sze++] = ed1;
		E ed2 = new E(sze, u, 0);
		e[sze++] = ed2;
		u.links.add(ed1);
		v.links.add(ed2); 
	}
	
	int qh, qt;
	G[] q;
	void maxFlow(G s, G t) {
		q = new G[g.length];
		while (bfs(s, t));
	}
	boolean bfs(G s, G t) {
		for (G v : g) {
			v.used = false;
			v.inQ = false;
		}
		qh = qt = 0;
		q[qt++] = s;
		while (qh != qt) {
			G v = q[qh++];
			if (qh == q.length) qh = 0;
			v.used = true;
			
			for (E edge : v.links) {
				if (edge.c <= edge.flow) {
					continue;
				}
				G to = edge.to;
				if (!to.used) {
					to.par = v;
					to.pare = edge;
					if (!to.inQ) {
						to.inQ = true;
						q[qt++] = to;
						if (qt == q.length) {
							qt = 0;
						}
					}
				}
			}
		}
		
		if (!t.used) {
			return false;
		}
		
		int add = Integer.MAX_VALUE;
		for (G v = t; v != s; v = v.par) {
			add = Math.min(add, v.pare.c-v.pare.flow);
		}
		for (G v = t; v != s; v = v.par) {
			v.pare.flow += add;
			e[v.pare.id^1].flow -= add;
		}
		return true;
	}
	
	class G {
		public final int id, a;
		public final List<E> links = new ArrayList<>();
		public boolean used, inQ;
		
		public E pare;
		public G par;
		
		
		public G(int i, int age) {
			id = i;
			a = age;
		}
		
		public void ansDfs(List<G> p) {
			if (used) return;
			used = true;
			p.add(this);
			for (E e : links) {
				if (e.flow != 0) {
					e.to.ansDfs(p);
				}
			}
		}
	}
	class E {
		public final int id;
		public final int c;
		public final G to;
		public int flow;
		
		public E(int i, G v, int cap) {
			id = i;
			to = v;
			c = cap;
		}
	}
	
	
	static class RFScanner implements Closeable {
		private BufferedReader reader;
		private StringTokenizer tokenizer;

		public RFScanner(Reader is) {
			reader = new BufferedReader(is);
			tokenizer = new StringTokenizer("");
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		public float nextFloat() throws IOException {
			return Float.parseFloat(next());
		}
		
		public BigInteger nextBigInteger() throws IOException {
			return new BigInteger(next());
		}

		public String next() throws IOException {
			if (hasNext())
				return tokenizer.nextToken();
			return null;
		}
		
		public String nextLine() throws IOException {
			tokenizer = new StringTokenizer("");
			return reader.readLine();
		}

		public boolean hasNext() throws IOException {
			while (!tokenizer.hasMoreTokens()) {
				String s = reader.readLine();
				if (s == null) {
					return false;
				}
				tokenizer = new StringTokenizer(s);
			}
			return true;
		}

		@Override
		public void close() throws IOException {
			reader.close();
		}
	}
}