Problem: You are given n strings s1, s2, ..., sn consisting of characters 0 and 1. m operations are performed, on each of them you concatenate two existing strings into a new one. On the i-th operation the concatenation saisbi is saved into a new string sn + i (the operations are numbered starting from 1). After each operation you need to find the maximum positive integer k such that all possible strings consisting of 0 and 1 of length k (there are 2k such strings) are substrings of the new string. If there is no such k, print 0.

Input

The first line contains single integer n (1 ≤ n ≤ 100) — the number of strings. The next n lines contain strings s1, s2, ..., sn (1 ≤ |si| ≤ 100), one per line. The total length of strings is not greater than 100.

The next line contains single integer m (1 ≤ m ≤ 100) — the number of operations. m lines follow, each of them contains two integers ai abd bi (1 ≤ ai, bi ≤ n + i - 1) — the number of strings that are concatenated to form sn + i.

Output

Print m lines, each should contain one integer — the answer to the question after the corresponding operation.

Example

Input

5
01
10
101
11111
0
3
1 2
6 5
4 4


Output

1
2
0

Note

On the first operation, a new string "0110" is created. For k = 1 the two possible binary strings of length k are "0" and "1", they are substrings of the new string. For k = 2 and greater there exist strings of length k that do not appear in this string (for k = 2 such string is "00"). So the answer is 1.

On the second operation the string "01100" is created. Now all strings of length k = 2 are present.

On the third operation the string "1111111111" is created. There is no zero, so the answer is 0.

Solution (in JAVA):

Solution:
import java.util.*;
import java.io.*;
public class d {
	public static void main(String[] arg) throws IOException {
		new d();
	}
	String[] s;
	HashSet<String>[][] hs;
	int K = 30;
	public d() throws IOException {
		FastScanner in = new FastScanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int n = in.nextInt();
		s = new String[n+102];
		for(int i = 0; i < n; i++) s[i] = in.next();
		
		int m = in.nextInt();
		hs = new HashSet[n+102][K];
		for(int i = 0; i < hs.length; i++) for(int j = 0; j < K; j++) hs[i][j] = new HashSet<String>();
		for(int i = 0; i < n; i++) {
			for(int j = 0; j < s[i].length(); j++) {
				for(int k = j+1; k <= s[i].length(); k++) {
					String str = s[i].substring(j, k);
					if(str.length() < K) hs[i][str.length()].add(str);
				}
			}
		}
		for(int i = 0; i < m; i++) {
			int a = in.nextInt()-1;
			int b = in.nextInt()-1;
			merge(a, b, n+i);
			int ans = 0;
			for(int k = 0; k < K; k++) {
				if(hs[i+n][k].size() == (1<<k)) {
					ans = Math.max(ans, k);
				}
			}
			out.println(ans);
		}
		in.close(); out.close();
	}
	void merge(int a, int b, int idx) {
		s[idx] = s[a]+s[b];
		for(int i = 0; i < K; i++) {
			for(String s : hs[a][i]) {
				hs[idx][i].add(s);
			}
			for(String s : hs[b][i]) {
				hs[idx][i].add(s);
			}
		}
		for(int i = 0; i < s[idx].length(); i++) {
			for(int j = i+1; j <= s[idx].length(); j++) {
				String str = s[idx].substring(i, j);
				if(str.contains(" ")) continue;
				if(str.length() < K)
					hs[idx][str.length()].add(str);
			}
		}
		if(s[idx].length() > 2*K) {
			s[idx] = s[idx].substring(0, K)+" "+s[idx].substring(s[idx].length()-K, s[idx].length());
		}
		
	}
	class Edge {
		int a, b, w;
		int to;
		public Edge(int a, int b, int w) {
			this.a = a;
			this.b = b;
			this.w = w;
		}
		public Edge(int to, int w) {
			this.to = to;
			this.w = w;
		}
	}
	class FastScanner {
		BufferedReader br;
		StringTokenizer st;
		public FastScanner(InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
			st = new StringTokenizer("");
		}
		public String next() throws IOException {
			while(!st.hasMoreTokens()) st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}
		public void close() throws IOException {
			br.close();
		}
		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}
	}
}