description: Ivan is playing yet another roguelike computer game. He controls a single hero in the game. The hero has n equipment slots. There is a list of c_i items for the i-th slot, the j-th of them increases the hero strength by a_{i,j}. The items for each slot are pairwise distinct and are listed in the increasing order of their strength increase. So, a_{i,1} < a_{i,2} < ... < a_{i,c_i}.
  
  For each slot Ivan chooses exactly one item. Let the chosen item for the i-th slot be the b_i-th item in the corresponding list. The sequence of choices [b_1, b_2, ..., b_n] is called a build.
  
  The strength of a build is the sum of the strength increases of the items in it. Some builds are banned from the game. There is a list of m pairwise distinct banned builds. It's guaranteed that there's at least one build that's not banned.
  
  What is the build with the maximum strength that is not banned from the game? If there are multiple builds with maximum strength, print any of them.
  
  Input
  
  The first line contains a single integer n (1 ≤ n ≤ 10) — the number of equipment slots.
  
  The i-th of the next n lines contains the description of the items for the i-th slot. First, one integer c_i (1 ≤ c_i ≤ 2 ⋅ 10^5) — the number of items for the i-th slot. Then c_i integers a_{i,1}, a_{i,2}, ..., a_{i,c_i} (1 ≤ a_{i,1} < a_{i,2} < ... < a_{i,c_i} ≤ 10^8).
  
  The sum of c_i doesn't exceed 2 ⋅ 10^5.
  
  The next line contains a single integer m (0 ≤ m ≤ 10^5) — the number of banned builds.
  
  Each of the next m lines contains a description of a banned build — a sequence of n integers b_1, b_2, ..., b_n (1 ≤ b_i ≤ c_i).
  
  The builds are pairwise distinct, and there's at least one build that's not banned.
  
  Output
  
  Print the build with the maximum strength that is not banned from the game. If there are multiple builds with maximum strength, print any of them.
  
  Examples
  
  Input
  
  
  3
  3 1 2 3
  2 1 5
  3 2 4 6
  2
  3 2 3
  3 2 2
  
  
  Output
  
  
  2 2 3 
  
  
  Input
  
  
  3
  3 1 2 3
  2 1 5
  3 2 4 6
  2
  3 2 3
  2 2 3
  
  
  Output
  
  
  1 2 3
  
  
  Input
  
  
  3
  3 1 2 3
  2 1 5
  3 2 4 6
  2
  3 2 3
  2 2 3
  
  
  Output
  
  
  3 2 2
  
  
  Input
  
  
  4
  1 10
  1 4
  1 7
  1 3
  0
  
  
  Output
  
  
  1 1 1 1 
solution: 
  import java.io.BufferedWriter;
  import java.io.DataInputStream;
  import java.io.FileWriter;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.io.OutputStreamWriter;
  import java.io.PrintWriter;
  import java.nio.file.Files;
  import java.nio.file.Path;
  import java.nio.file.Paths;
  import java.util.ArrayList;
  import java.util.Comparator;
  import java.util.HashSet;
  import java.util.PriorityQueue;
  
  public class DTheStrongestBuild {
  
  	public static void main(String[] args) throws Exception {
  		FastScanner sc = new FastScanner(System.in);
  		FastPrinter out = new FastPrinter(System.out);
  		new DTheStrongestBuild().run(sc, out);
  		out.close();
  	}
  
  	public void run(FastScanner sc, FastPrinter out) throws Exception {
  		int N = sc.nextInt();
  		int[][] arr = new int[N][];
  		for (int i = 0; i < N; i++) {
  			int size = sc.nextInt();
  			arr[i] = new int[size];
  			for (int j = 0; j < size; j++) {
  				arr[i][j] = sc.nextInt();
  			}
  		}
  		HashSet<ArrayList<Integer>> banned = new HashSet<>();
  		HashSet<ArrayList<Integer>> vis = new HashSet<>();
  		int M = sc.nextInt();
  		for (int i = 0; i < M; i++) {
  			ArrayList<Integer> list = new ArrayList<>(N + 1);
  			int sum = 0;
  			list.add(0);
  			for (int j = 0; j < N; j++) {
  				int elem = sc.nextInt() - 1;
  				sum += arr[j][elem];
  				list.add(elem);
  			}
  			list.set(0, sum);
  			banned.add(list);
  		}
  		PriorityQueue<ArrayList<Integer>> pq = new PriorityQueue<>(new Comparator<ArrayList<Integer>>() {
  			@Override
  			public int compare(ArrayList<Integer> a, ArrayList<Integer> b) {
  				return b.get(0) - a.get(0);
  			}
  		});
  		int sum = 0;
  		ArrayList<Integer> list = new ArrayList<>(N + 1);
  		list.add(0);
  		for (int i = 0; i < N; i++) {
  			int elem = arr[i].length - 1;
  			list.add(elem);
  			sum += arr[i][elem];
  		}
  		list.set(0, sum);
  		pq.add(list);
  		vis.add(list);
  		while (true) {
  			ArrayList<Integer> cur = pq.poll();
  			if (!banned.contains(cur)) {
  				for (int i = 1; i <= N; i++) {
  					if (i > 1) out.print(" ");
  					out.print(cur.get(i) + 1);
  				}
  				out.println();
  				return;
  			}
  			ArrayList<Integer> next = new ArrayList<>(N + 1);
  			next.addAll(cur);
  			for (int i = 0; i < N; i++) {
  				int curInd = cur.get(i + 1);
  				if (curInd == 0) {
  					continue;
  				}
  				int diff = arr[i][curInd] - arr[i][curInd - 1];
  				next.set(0, cur.get(0) - diff);
  				next.set(i + 1, curInd - 1);
  				if (!vis.contains(next)) {
  					vis.add(next);
  					pq.add(next);
  					next = new ArrayList<>(N + 1);
  					next.addAll(cur);
  				} else {
  					next.set(0, cur.get(0));
  					next.set(i + 1, cur.get(i + 1));
  				}
  			}
  		}
  	}
  
  	static class FastScanner {
  		final private int BUFFER_SIZE = 1 << 10;
  		private DataInputStream din;
  		private byte[] buffer;
  		private int bufferPointer, bytesRead;
  
  		public FastScanner() {
  			this(System.in);
  		}
  
  		public FastScanner(InputStream stream) {
  			din = new DataInputStream(stream);
  			buffer = new byte[BUFFER_SIZE];
  			bufferPointer = bytesRead = 0;
  		}
  
  		public FastScanner(String fileName) throws IOException {
  			Path p = Paths.get(fileName);
  			buffer = Files.readAllBytes(p);
  			bytesRead = buffer.length;
  		}
  
  		int[] nextIntArray(int N) throws IOException {
  			int[] arr = new int[N];
  			for (int i = 0; i < N; i++) {
  				arr[i] = nextInt();
  			}
  			return arr;
  		}
  
  		String nextLine() throws IOException {
  			int c = read();
  			while (c != -1 && isEndline(c))
  				c = read();
  			if (c == -1) {
  				return null;
  			}
  			StringBuilder res = new StringBuilder();
  			do {
  				if (c >= 0) {
  					res.appendCodePoint(c);
  				}
  				c = read();
  			} while (!isEndline(c));
  			return res.toString();
  		}
  
  		boolean isEndline(int c) {
  			return c == '\n' || c == '\r' || c == -1;
  		}
  
  		String next() throws Exception {
  			int c = readOutSpaces();
  			StringBuilder res = new StringBuilder();
  			do {
  				res.appendCodePoint(c);
  				c = read();
  			} while (!isSpaceChar(c));
  			return res.toString();
  		}
  
  		boolean isSpaceChar(int c) {
  			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
  		}
  
  		public int nextInt() throws IOException {
  			int ret = 0;
  			byte c = read();
  			while (c <= ' ')
  				c = read();
  			boolean neg = (c == '-');
  			if (neg) c = read();
  			do {
  				ret = ret * 10 + c - '0';
  			} while ((c = read()) >= '0' && c <= '9');
  
  			if (neg) return -ret;
  			return ret;
  		}
  
  		public long nextLong() throws IOException {
  			long ret = 0;
  			byte c = read();
  			while (c <= ' ')
  				c = read();
  			boolean neg = (c == '-');
  			if (neg) c = read();
  			do {
  				ret = ret * 10 + c - '0';
  			} while ((c = read()) >= '0' && c <= '9');
  			if (neg) return -ret;
  			return ret;
  		}
  
  		public double nextDouble() throws IOException {
  			double ret = 0, div = 1;
  			byte c = read();
  			while (c <= ' ')
  				c = read();
  			boolean neg = (c == '-');
  			if (neg) c = read();
  
  			do {
  				ret = ret * 10 + c - '0';
  			} while ((c = read()) >= '0' && c <= '9');
  
  			if (c == '.') {
  				while ((c = read()) >= '0' && c <= '9') {
  					ret += (c - '0') / (div *= 10);
  				}
  			}
  
  			if (neg) return -ret;
  			return ret;
  		}
  
  		private void fillBuffer() throws IOException {
  			if (din == null) {
  				bufferPointer = 0;
  				bytesRead = -1;
  			} else {
  				bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
  			}
  			if (bytesRead == -1) buffer[0] = -1;
  		}
  
  		private byte read() throws IOException {
  			if (bufferPointer == bytesRead) fillBuffer();
  			return buffer[bufferPointer++];
  		}
  
  		private int readOutSpaces() throws IOException {
  			while (true) {
  				if (bufferPointer == bytesRead) fillBuffer();
  				int c = buffer[bufferPointer++];
  				if (!isSpaceChar(c)) {
  					return c;
  				}
  			}
  		}
  
  		public void close() throws IOException {
  			if (din == null) return;
  			din.close();
  		}
  
  		public int[][] readGraph(int N, int M, boolean zeroIndexed, boolean bidirectional) throws Exception {
  			int[][] adj = new int[N][];
  			int[] numNodes = new int[N];
  			int[][] input = new int[M][2];
  			for (int i = 0; i < M; i++) {
  				int a = nextInt();
  				int b = nextInt();
  				if (zeroIndexed) {
  					a--;
  					b--;
  				}
  				input[i][0] = a;
  				input[i][1] = b;
  				numNodes[a]++;
  				if (bidirectional) numNodes[b]++;
  			}
  			for (int i = 0; i < N; i++) {
  				adj[i] = new int[numNodes[i]];
  				numNodes[i] = 0;
  			}
  			for (int i = 0; i < M; i++) {
  				int a = input[i][0];
  				int b = input[i][1];
  				adj[a][numNodes[a]++] = b;
  				if (bidirectional) adj[b][numNodes[b]++] = a;
  			}
  			return adj;
  		}
  
  		public int[][][] readWeightedGraph(int N, int M, boolean zeroIndexed, boolean bidirectional) throws Exception {
  			int[][][] adj = new int[N][][];
  			int[] numNodes = new int[N];
  			int[][] input = new int[M][3];
  			for (int i = 0; i < M; i++) {
  				int a = nextInt();
  				int b = nextInt();
  				if (zeroIndexed) {
  					a--;
  					b--;
  				}
  				int d = nextInt();
  				input[i][0] = a;
  				input[i][1] = b;
  				input[i][2] = d;
  				numNodes[a]++;
  				if (bidirectional) numNodes[b]++;
  			}
  			for (int i = 0; i < N; i++) {
  				adj[i] = new int[numNodes[i]][2];
  				numNodes[i] = 0;
  			}
  			for (int i = 0; i < M; i++) {
  				int a = input[i][0];
  				int b = input[i][1];
  				int d = input[i][2];
  				adj[a][numNodes[a]][0] = b;
  				adj[a][numNodes[a]][1] = d;
  				numNodes[a]++;
  				if (bidirectional) {
  					adj[b][numNodes[b]][0] = a;
  					adj[b][numNodes[b]][1] = d;
  					numNodes[b]++;
  				}
  			}
  			return adj;
  		}
  	}
  
  	static class FastPrinter {
  		static final char ENDL = '\n';
  		StringBuilder buf;
  		PrintWriter pw;
  
  		public FastPrinter(OutputStream stream) {
  			buf = new StringBuilder();
  			pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(stream)));
  		}
  
  		public FastPrinter(String fileName) throws Exception {
  			buf = new StringBuilder();
  			pw = new PrintWriter(new BufferedWriter(new FileWriter(fileName)));
  		}
  
  		public FastPrinter(StringBuilder buf) {
  			this.buf = buf;
  		}
  
  		public void print(int a) {
  			buf.append(a);
  		}
  
  		public void print(long a) {
  			buf.append(a);
  		}
  
  		public void print(char a) {
  			buf.append(a);
  		}
  
  		public void print(char[] a) {
  			buf.append(a);
  		}
  
  		public void print(double a) {
  			buf.append(a);
  		}
  
  		public void print(String a) {
  			buf.append(a);
  		}
  
  		public void print(Object a) {
  			buf.append(a.toString());
  		}
  
  		public void println() {
  			buf.append(ENDL);
  		}
  
  		public void println(int a) {
  			buf.append(a);
  			buf.append(ENDL);
  		}
  
  		public void println(long a) {
  			buf.append(a);
  			buf.append(ENDL);
  		}
  
  		public void println(char a) {
  			buf.append(a);
  			buf.append(ENDL);
  		}
  
  		public void println(char[] a) {
  			buf.append(a);
  			buf.append(ENDL);
  		}
  
  		public void println(double a) {
  			buf.append(a);
  			buf.append(ENDL);
  		}
  
  		public void println(String a) {
  			buf.append(a);
  			buf.append(ENDL);
  		}
  
  		public void println(Object a) {
  			buf.append(a.toString());
  			buf.append(ENDL);
  		}
  
  		public void printf(String format, Object... args) {
  			buf.append(String.format(format, args));
  		}
  
  		public void close() {
  			pw.print(buf);
  			pw.close();
  		}
  
  		public void flush() {
  			pw.print(buf);
  			pw.flush();
  			buf.setLength(0);
  		}
  
  	}
  
  }