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.*;
  import java.util.*;
  
  public class D {
  
      // 注意不要用Arrays.sort()
      // 注意Math.pow可能导致精度问题
      // 注意int溢出问题
      static class Task {
  
          private Set<String> set;
          private List<Integer>[] listArr;
          private int n;
          private Map<String, int[]> memoMap;
  
          private String arr2String(int[] indexArr) {
              StringBuilder sb = new StringBuilder();
              for (int i = 0; i < n; i++) {
                  int curIdx = indexArr[i];
                  sb.append(curIdx);
                  sb.append(",");
              }
              return sb.toString();
          }
  
          private int getSum(int[] indexArr) {
              int sum = 0;
              for (int i = 0; i < n; i++) {
                  sum += listArr[i].get(indexArr[i] - 1);
              }
              return sum;
          }
  
          private int[] dp(int[] indexArr) {
              String key = arr2String(indexArr);
              if (!set.contains(key)) {
                  int[] resIndexArr = Arrays.copyOf(indexArr, n);
                  return resIndexArr;
              }
  
              if (memoMap.containsKey(key)) {
                  return memoMap.get(key);
              }
  
              // 如果当前indexArr不合法，则往左遍历
              int[] ansIndexArr = new int[n];
              int ansMaxSum = 0;
              for (int i = 0; i < n; i++) {
                  if (indexArr[i] <= 1) {
                      continue;
                  }
                  indexArr[i]--;
                  int[] tmpIndexArr = dp(indexArr);
                  if (tmpIndexArr == null) {
                      indexArr[i]++;
                      continue;
                  }
                  
                  int sum = getSum(tmpIndexArr);
                  if (sum > ansMaxSum) {
                      ansMaxSum = sum;
                      ansIndexArr = tmpIndexArr;
                  }
                  indexArr[i]++;
              }
  
              if (ansMaxSum == 0) {
                  memoMap.put(key, null);
                  return null;
              }
  
              memoMap.put(key, ansIndexArr);
              return ansIndexArr;
          }
  
          public void solve(int testNumber, InputReader in, PrintWriter out) {
              n = in.nextInt();
              listArr = new ArrayList[n];
              int[] indexArr = new int[n];
              for (int i = 0; i < n; i++) {
                  int c = in.nextInt();
                  listArr[i] = new ArrayList<>();
                  for (int j = 0; j < c; j++) {
                      listArr[i].add(in.nextInt());
                  }
                  indexArr[i] = c;
              }
  
              int m = in.nextInt();
              set = new HashSet<>();
              for (int i = 0; i < m; i++) {
                  StringBuilder sb = new StringBuilder();
                  for (int j = 0; j < n; j++) {
                      sb.append(in.nextInt());
                      sb.append(",");
                  }
                  set.add(sb.toString());
              }
  
              memoMap = new HashMap<>();
              int[] ansArr = dp(indexArr);
              for (int i = 0; i < n; i++) {
                  out.print(ansArr[i] + " ");
              }
              out.println();
          }
      }
  
      private static void sort(double[] arr) {
          Double[] objArr = Arrays.stream(arr).boxed().toArray(Double[]::new);
          Arrays.sort(objArr);
          for (int i = 0; i < arr.length; i++) {
              arr[i] = objArr[i];
          }
      }
  
      private static void sortDesc(double[] arr) {
          Double[] objArr = Arrays.stream(arr).boxed().toArray(Double[]::new);
          Arrays.sort(objArr);
          for (int i = 0; i < arr.length; i++) {
              arr[i] = objArr[arr.length - i - 1];
          }
      }
  
      private static void sort(int[] arr) {
          Integer[] objArr = Arrays.stream(arr).boxed().toArray(Integer[]::new);
          Arrays.sort(objArr);
          for (int i = 0; i < arr.length; i++) {
              arr[i] = objArr[i];
          }
      }
  
      private static void sortDesc(int[] arr) {
          Integer[] objArr = Arrays.stream(arr).boxed().toArray(Integer[]::new);
          Arrays.sort(objArr);
          for (int i = 0; i < arr.length; i++) {
              arr[i] = objArr[arr.length - i - 1];
          }
      }
  
      private static void sort(long[] arr) {
          Long[] objArr = Arrays.stream(arr).boxed().toArray(Long[]::new);
          Arrays.sort(objArr);
          for (int i = 0; i < arr.length; i++) {
              arr[i] = objArr[i];
          }
      }
  
      private static void sortDesc(long[] arr) {
          Long[] objArr = Arrays.stream(arr).boxed().toArray(Long[]::new);
          Arrays.sort(objArr);
          for (int i = 0; i < arr.length; i++) {
              arr[i] = objArr[arr.length - i - 1];
          }
      }
  
      private static void solve() {
          InputStream inputStream = System.in;
          OutputStream outputStream = System.out;
          InputReader in = new InputReader(inputStream);
          PrintWriter out = new PrintWriter(outputStream);
          Task task = new Task();
          task.solve(1, in, out);
          out.close();
      }
  
      public static void main(String[] args) {
          new Thread(null, () -> solve(), "1", 1 << 26).start();
      }
  
      static class InputReader {
  
          public BufferedReader reader;
          public StringTokenizer tokenizer;
  
          public InputReader(InputStream stream) {
              reader = new BufferedReader(new InputStreamReader(stream), 32768);
              tokenizer = null;
          }
  
          public String next() {
              while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                  try {
                      tokenizer = new StringTokenizer(reader.readLine());
                  } catch (IOException e) {
                      throw new RuntimeException(e);
                  }
              }
              return tokenizer.nextToken();
          }
  
          public int nextInt() {
              return Integer.parseInt(next());
          }
  
          public long nextLong() {
              return Long.parseLong(next());
          }
  
          public double nextDouble() {
              return Double.parseDouble(next());
          }
  
      }
  
  }