Problem: A pitch-black room

When I woke up, Mr. A was in a pitch-black room. Apparently, Mr. A got lost in a dungeon consisting of N rooms. You couldn't know which room A got lost in, but fortunately he got a map of the dungeon. Let's show A the way to go and lead to a bright room.

It is known that M of the N rooms are pitch black, and the D_1, D_2, ..., and D_Mth rooms are pitch black, respectively. Also, there are exactly K one-way streets from all the rooms in order, and the roads from the i-th room are v_ {i, 1}, v_ {i, 2}, ..., v_ {i, respectively. , K} Connected to the third room. You can follow the a_1, a_2, ..., a_lth roads in order from the room you are in for Mr. A. However, when Mr. A reaches the bright room, he ignores the subsequent instructions. You cannot know the information of the room where Mr. A is currently before and after the instruction, so you must give the instruction sequence so that you can reach the bright room no matter which room you are in. Answer the length of the shortest of such instructions.

Constraints

* 2 ≤ N ≤ 100
* 1 ≤ M ≤ min (16, N − 1)
* 1 ≤ K ≤ N
* 1 ≤ D_i ≤ N
* D_i are all different
* 1 ≤ v_ {i, j} ≤ N
* All dark rooms can reach at least one bright room



Input Format

Input is given from standard input in the following format.


NMK
D_1 D_2 ... D_M
v_ {1,1} v_ {1,2} ... v_ {1,K}
v_ {2,1} v_ {2,2} ... v_ {2, K}
...
v_ {N, 1} v_ {N, 2} ... v_ {N, K}


Output Format

Print the answer in one line.

Sample Input 1


4 2 2
1 2
twenty four
3 1
4 2
13


Sample Output 1


2


<image>
If you give the instruction 1, 1

* If A's initial position is room 1, the second move will reach room 3.
* If A's initial position is room 2, the first move will reach room 3.



Sample Input 2


3 2 2
1 2
twenty three
1 2
twenty one


Sample Output 2


3


<image>
If you give instructions 2, 1, 2

* If A's initial position is room 1, the first move will reach room 3.
* If A's initial position is room 2, the third move will reach room 3.



Sample Input 3


6 3 3
one two Three
4 1 1
2 5 2
3 3 6
4 4 4
5 5 5
6 6 6


Sample Output 3


3


<image>
Beware of unconnected cases and cases with self-edges and multiple edges.





Example

Input

4 2 2
1 2
2 4
3 1
4 2
1 3


Output

2

Solution (in JAVA):

Solution:
import java.util.LinkedList;
import java.util.Queue;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.NoSuchElementException;

public class Main {

	private static void solve() {
		int n = nei();
		int m = nei();
		int k = nei();
		int[] ds = nis(m);
		int[][] vs = nis2(n, k);
		for (int i = 0; i < m; i++) {
			ds[i]--;
		}
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < k; j++) {
				vs[i][j]--;
			}
		}
		int[] idxToDark = new int[n];
		for (int i = 0; i < n; i++) {
			idxToDark[i] = -1;
		}
		for (int i = 0; i < m; i++) {
			idxToDark[ds[i]] = i;
		}
		int MAX_BIT = 1 << m;

		int[][] one = new int[MAX_BIT][k];
		for (int j = 0; j < k; j++) {
			for (int i = 0; i < m; i++) {
				int darkIdx = ds[i];
				int toDarkIdx = idxToDark[vs[darkIdx][j]];
				one[1 << i][j] = toDarkIdx == -1 ? 0 : 1 << toDarkIdx;
			}
		}
		int[][] edges = new int[MAX_BIT][k];
		for (int i = 1; i < MAX_BIT; i++) {
			for (int j = 0; j < k; j++) {
				int sub1 = i - 1 & i;
				if (sub1 == 0) {
					edges[i][j] = one[i][j];
					continue;
				}
				int sub2 = i ^ sub1;
				edges[i][j] = edges[sub1][j] | edges[sub2][j];
			}
		}
		Integer[] ints = new Integer[MAX_BIT];
		for (int i = 0; i < MAX_BIT; i++) {
			ints[i] = i;
		}
		Queue<Integer> q = new LinkedList<Integer>();
		q.add(MAX_BIT - 1);
		boolean[] visited = new boolean[MAX_BIT];
		int cost = 0;
		while (!q.isEmpty()) {
			int size = q.size();
			for (int j = 0; j < size; j++) {
				int idx = q.poll().intValue();
				if (visited[idx])
					continue;
				visited[idx] = true;
				if (idx == 0)
					kil(cost);
				for (int i = 0; i < k; i++) {
					if (!visited[ints[edges[idx][i]]])
						q.add(ints[edges[idx][i]]);
				}
			}
			cost++;
		}
	}

	static void out(String val) {
		IO.out(val);
	}

	static void out(Object val) {
		IO.out(String.valueOf(val));
	}

	static void out(int val) {
		IO.out(String.valueOf(val));
	}

	static void out(long val) {
		IO.out(String.valueOf(val));
	}

	static void out(char val) {
		IO.out(String.valueOf(val));
	}

	static void out(float val) {
		IO.out(String.valueOf(val));
	}

	static void out(double val) {
		IO.out(String.valueOf(val));
	}

	static void out(boolean val) {
		IO.out(String.valueOf(val));
	}

	static void kil(String val) {
		IO.out(val);
		IO.flush();
		System.exit(0);
	}

	static void kil(Object val) {
		IO.out(String.valueOf(val));
		IO.flush();
		System.exit(0);
	}

	static void kil(int val) {
		IO.out(String.valueOf(val));
		IO.flush();
		System.exit(0);
	}

	static void kil(long val) {
		IO.out(String.valueOf(val));
		IO.flush();
		System.exit(0);
	}

	static void kil(char val) {
		IO.out(String.valueOf(val));
		IO.flush();
		System.exit(0);
	}

	static void kil(float val) {
		IO.out(String.valueOf(val));
		IO.flush();
		System.exit(0);
	}

	static void kil(double val) {
		IO.out(String.valueOf(val));
		IO.flush();
		System.exit(0);
	}

	static void kil(boolean val) {
		IO.out(String.valueOf(val));
		IO.flush();
		System.exit(0);
	}

	static String nes() {
		return IO.next();
	}

	static int nei() {
		return IO.nextInt();
	}

	static long nel() {
		return IO.nextLong();
	}

	static double ned() {
		return IO.nextDouble();
	}

	static char nec() {
		return IO.nextChar();
	}

	static String[] nss(int n) {
		String[] as = new String[n];
		for (int i = 0; i < n; i++) {
			as[i] = IO.next();
		}
		return as;
	}

	static int[] nis(int n) {
		int[] as = new int[n];
		for (int i = 0; i < n; i++) {
			as[i] = IO.nextInt();
		}
		return as;
	}

	static long[] nls(int n) {
		long[] as = new long[n];
		for (int i = 0; i < n; i++) {
			as[i] = IO.nextLong();
		}
		return as;
	}

	static double[] nds(int n) {
		double[] as = new double[n];
		for (int i = 0; i < n; i++) {
			as[i] = IO.nextDouble();
		}
		return as;
	}

	static char[] ncs(int n) {
		char[] as = new char[n];
		for (int i = 0; i < n; i++) {
			as[i] = IO.nextChar();
		}
		return as;
	}

	static String[][] nss2(int n, int m) {
		String[][] as = new String[n][m];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				as[i][j] = IO.next();
			}
		}
		return as;
	}

	static int[][] nis2(int n, int m) {
		int[][] as = new int[n][m];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				as[i][j] = IO.nextInt();
			}
		}
		return as;
	}

	static long[][] nls2(int n, int m) {
		long[][] as = new long[n][m];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				as[i][j] = IO.nextLong();
			}
		}
		return as;
	}

	static double[][] nds2(int n, int m) {
		double[][] as = new double[n][m];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				as[i][j] = IO.nextDouble();
			}
		}
		return as;
	}

	static char[][] ncs2(int n, int m) {
		char[][] as = new char[n][m];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				as[i][j] = IO.nextChar();
			}
		}
		return as;
	}

	static int parseInt(String val) {
		return Integer.parseInt(val);
	}

	static int parseInt(char val) {
		return Integer.parseInt(String.valueOf(val));
	}

	static long parseLong(String val) {
		return Long.parseLong(val);
	}

	public static void main(String[] args) {
//		try {
		solve();
		IO.flush();
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
	}
}



final class IO {
	private static final InputStream in = System.in;
	private static final PrintWriter out = new PrintWriter(System.out, false);
	private static final byte[] buffer = new byte[1024];
	private static int ptr = 0;
	private static int len = 0;

	private static boolean hasNextByte() {
		if (ptr < len)
			return true;
		ptr = 0;
		try {
			len = in.read(buffer);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return len > 0;
	}

	private static int readByte() {
		if (hasNextByte())
			return buffer[ptr++];
		else
			return -1;
	}

	static boolean hasNext() {
		byte c;
		while (hasNextByte() && ((c = buffer[ptr]) < '!' || c > '~'))
			ptr++;
		return hasNextByte();
	}

	static String next() {
		if (!hasNext())
			throw new NoSuchElementException();
		StringBuilder sb = new StringBuilder();
		int b = readByte();
		while (b >= '!' && b <= '~') {
			sb.append((char) b);
			b = readByte();
		}
		return sb.toString();
	}

	static char nextChar() {
		if (!hasNext())
			throw new NoSuchElementException();
		return (char) readByte();
	}

	static long nextLong() {
		if (!hasNext())
			throw new NoSuchElementException();
		long n = 0;
		int sign = 1;
		int b = readByte();
		if (b == '-') {
			sign = -1;
			b = readByte();
		}
		if (b < '0' || '9' < b)
			throw new NumberFormatException();
		while (true) {
			if ('0' <= b && b <= '9')
				n = n * 10 + b - '0';
			else if (b == -1 || b < '!' || b > '~')
				return n * sign;
			else
				throw new NumberFormatException();
			b = readByte();
		}
	}

	static int nextInt() {
		if (!hasNext())
			throw new NoSuchElementException();
		int n = 0;
		int sign = 1;
		int b = readByte();
		if (b == '-') {
			sign = -1;
			b = readByte();
		}
		if (b < '0' || '9' < b)
			throw new NumberFormatException();
		while (true) {
			if ('0' <= b && b <= '9')
				n = n * 10 + b - '0';
			else if (b == -1 || b < '!' || b > '~')
				return n * sign;
			else
				throw new NumberFormatException();
			b = readByte();
		}
	}

	static double nextDouble() {
		return Double.parseDouble(next());
	}

	static void out(String val) {
		out.println(val);
	}

	static void flush() {
		out.flush();
	}
}