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 static java.math.BigInteger.*;
  
  import java.util.*;
  
  public class D {
  
  	public Object solve () {
  		int N = sc.nextInt();
  		A = new long [N][];
  		for (int i : rep(N))
  			A[i] = sc.nextLong(sc.nextInt());
  		int M = sc.nextInt();
  		int [][] B = dec(sc.nextInts(M));
  
  		Random rnd = new Random();
  
  		P = new long [N];
  		for (int i : rep(N))
  			P[i] = probablePrime(40, rnd).longValue();
  		Q = probablePrime(50, rnd).longValue();
  
  		Set<Long> T = new HashSet<>();
  		Map<Long, int []> S = new HashMap<>();
  
  		for (int i : rep(M))
  			T.add(hash(B[i]));
  
  		Queue<long[]> Z = new PriorityQueue<>(lby(0).reversed());
  		int [] x = new int [N];
  		for (int i : rep(N))
  			x[i] = A[i].length - 1;
  		long [] z = calc(x);
  		Z.add(z); S.put(z[1], x);
  
  		for(;;) {
  			z = Z.poll(); x = S.get(z[1]);
  			if (!T.contains(z[1]))
  				return inc(x);
  
  			for (int i : rep(N))
  				if (x[i] > 0) {
  					--x[i];
  					z[0] -= A[i][x[i] + 1] - A[i][x[i]];
  					z[1] = (z[1] + Q - P[i]) % Q;
  
  					if (!S.containsKey(z[1])) {
  						Z.add(z.clone());
  						S.put(z[1], x.clone());
  					}
  
  					z[0] += A[i][x[i] + 1] - A[i][x[i]];
  					z[1] = (z[1] + P[i]) % Q;
  					++x[i];
  				}
  		}
  	}
  
  	long [][] A;
  	long [] P;
  	long Q;
  
  	long hash (int [] B) {
  		int N = B.length;
  		long res = 0;
  
  		for (int i : rep(N))
  			res += B[i] * P[i];
  		res %= Q;
  		return res;
  	}
  
  	long [] calc (int [] x) {
  		int N = x.length;
  		long [] res = { 0, hash(x) };
  		for (int i : rep(N))
  			res[0] += A[i][x[i]];
  		return res;
  	}
  
  	private static final int CONTEST_TYPE = 1;
  
  	private static void init () {
  	}
  
  	private static final int INF = (int) 1e9 + 10;
  	private static int [][] dec (int [] ... E) { return dec(E, INF); }
  	private static int [][] dec (int [][] E, int N) { for (int [] e : E) for (int i = 0; i < e.length && i < N; ++i) --e[i]; return E; }
  	private static int [] inc (int ... A) {
  		for (int i = 0; i < A.length; ++i)
  			++A[i];
  		return A;
  	}
  	private static Comparator<long[]> lby (int j, int ... J) {
  		Comparator<long[]> res = (x, y) -> Long.signum(x[j] - y[j]);
  		for (int i : J)
  			res = res.thenComparing((x, y) -> Long.signum(x[i] - y[i]));
  		return res;
  	}
  	private static int [] rep (int N) { return rep(0, N); }
  	private static int [] rep (int S, int T) { if (S >= T) return new int [0]; int [] res = new int [T-S]; for (int i = S; i < T; ++i) res[i-S] = i; return res; }
  	//////////////////////////////////////////////////////////////////////////////////// OFF
  	private static IOUtils.MyScanner sc = new IOUtils.MyScanner();
  	private static class IOUtils {
  		public static class MyScanner {
  			public String next () { newLine(); return line[index++]; }
  			public int nextInt () { return Integer.parseInt(next()); }
  			public long nextLong () { return Long.parseLong(next()); }
  			public String nextLine () { line = null; return readLine(); }
  			public String [] nextStrings () { return split(nextLine()); }
  			public int [] nextInts () {
  				String [] S = nextStrings(); int N = S.length;
  				int [] res = new int [N];
  				for (int i = 0; i < N; ++i)
  					res[i] = Integer.parseInt(S[i]);
  				return res;
  			}
  			public long [] nextLong (int N) {
  				long [] res = new long [N];
  				for (int i = 0; i < N; ++i)
  					res[i] = nextLong();
  				return res;
  			}
  			public int [][] nextInts (int N) {
  				int [][] res = new int [N][];
  				for (int i = 0; i < N; ++i)
  					res[i] = nextInts();
  				return res;
  			}
  			//////////////////////////////////////////////
  			private boolean eol () { return index == line.length; }
  			private String readLine () {
  				try {
  					int b;
  					StringBuilder res = new StringBuilder();
  					while ((b = System.in.read()) < ' ')
  						continue;
  					res.append((char)b);
  					while ((b = System.in.read()) >= ' ')
  						res.append((char)b);
  					return res.toString();
  				} catch (Exception e) {
  					throw new Error (e);
  				}
  			}
  			private MyScanner () {
  				try {
  					while (System.in.available() == 0)
  						Thread.sleep(1);
  					start();
  				} catch (Exception e) {
  					throw new Error(e);
  				}
  			}
  			private String [] line;
  			private int index;
  			private void newLine () {
  				if (line == null || eol()) {
  					line = split(readLine());
  					index = 0;
  				}
  			}
  			private String [] split (String s) { return s.length() > 0 ? s.split(" ") : new String [0]; }
  		}
  		private static String build (Object o, Object ... A) { return buildDelim(" ", o, A); }
  		private static String buildDelim (String delim, Object o, Object ... A) {
  			java.util.List<String> str = new java.util.ArrayList<>();
  			append(str, o);
  			for (Object p : A)
  				append(str, p);
  			return String.join(delim, str.toArray(new String [0]));
  		}
  		//////////////////////////////////////////////////////////////////////////////////
  		private static java.text.DecimalFormat formatter = new java.text.DecimalFormat("#.#########");
  		private static void start () { if (t == 0) t = millis(); }
  		private static void append (java.util.function.Consumer<Object> f, java.util.function.Consumer<Object> g, Object o) {
  			if (o.getClass().isArray()) {
  				int len = java.lang.reflect.Array.getLength(o);
  				for (int i = 0; i < len; ++i)
  					f.accept(java.lang.reflect.Array.get(o, i));
  			}
  			else if (o instanceof Iterable<?>)
  				((Iterable<?>)o).forEach(f::accept);
  			else
  				g.accept(o instanceof Double ? formatter.format(o) : o);
  		}
  		private static void append (java.util.List<String> str, Object o) {
  			append(x -> append(str, x), x -> str.add(x.toString()), o);
  		}
  		private static java.io.PrintWriter pw = new java.io.PrintWriter(System.out);
  		private static void flush () { pw.flush(); System.out.flush(); }
  		private static void print (Object o, Object ... A) {
  			String res = build(o, A);
  			if (DEBUG == 2)
  				err(res, '(', time(), ')');
  			if (res.length() > 0)
  				pw.println(res);
  			if (DEBUG == 1)
  				flush();
  		}
  		private static void err (Object o, Object ... A) { System.err.println(build(o, A)); }
  		private static int DEBUG;
  		private static void exit () {
  			String end = "------------------" + System.lineSeparator() + time();
  			switch(DEBUG) {
  			case 1: print(end); break;
  			case 2: err(end); break;
  			}
  			IOUtils.pw.close();
  			System.out.flush();
  			System.exit(0);
  		}
  		private static long t;
  		private static long millis () { return System.currentTimeMillis(); }
  		private static String time () { return "Time: " + (millis() - t) / 1000.0; }
  		private static void run (int N) {
  			try { DEBUG = Integer.parseInt(System.getProperties().get("DEBUG").toString()); }
  			catch (Throwable t) {}
  
  			for (int n = 1; n <= N; ++n) {
  				Object res = new D().solve();
  				if (res != null) {
  					@SuppressWarnings("all")
  					Object o = CONTEST_TYPE == 0 ? "Case #" + n + ": " + build(res) : res;
  					print(o);
  				}
  			}
  			exit();
  		}
  	}
  	////////////////////////////////////////////////////////////////////////////////////
  	public static void main (String[] args) {
  		@SuppressWarnings("all")
  		int N = CONTEST_TYPE == 1 ? 1 : sc.nextInt();
  		init();
  		IOUtils.run(N);
  	}
  }
  