public class Main { static MyPrintWriter pw = MyPrintWriter.getInstance(); static FastScanner sc = FastScanner.getInstance(); public static void main(java.lang.String[] args) throws java.io.IOException { new Main().run(args); Main.pw.flush(); } void run(java.lang.String[] args) throws java.io.IOException { int T = Main.sc.nextInt(); for (int TEST = 0; TEST < T; TEST++) { int N = Main.sc.nextInt(); int[] A = Main.sc.nextInts(N); int[] B = Main.sc.nextInts(N); int[] x = new int[2 * N]; int[] y = new int[2 * N]; for (int i = 0; i < N; i++) { x[2 * i] = i; y[2 * i] = A[i]; x[(2 * i) + 1] = i; y[(2 * i) + 1] = B[i]; } int ans = IntpairPoset.maximumKChainsLength(x, y, 2, true); Main.pw.println(ans); } } } class FastScanner { private static FastScanner instance = null; private final java.io.InputStream in = java.lang.System.in; private final byte[] buffer = new byte[1 << 16]; private int ptr = 0; private int buflen = 0; private FastScanner() { } public static FastScanner getInstance() { if (FastScanner.instance == null) { FastScanner.instance = new FastScanner(); } return FastScanner.instance; } private boolean hasNextByte() { if (ptr < buflen) { return true; } ptr = 0; try { buflen = in.read(buffer); } catch (java.io.IOException e) { e.printStackTrace(); } return buflen > 0; } private int readByte() { if (hasNextByte()) { return buffer[ptr++]; } else { return -1; } } private boolean isPrintableChar(int c) { return (33 <= c) && (c <= 126); } public boolean hasNext() { while (hasNextByte() && (!isPrintableChar(buffer[ptr]))) { ptr++; } return hasNextByte(); } public long nextLong() { if (!hasNext()) { throw new java.util.NoSuchElementException(); } long n = 0; boolean minus = false; int b = readByte(); if (b == '-') { minus = true; b = readByte(); } while ((b >= '0') && (b <= '9')) { // n = n * 10 + (b - '0'); n = ((n << 1) + (n << 3)) + (b - '0'); b = readByte(); } return minus ? -n : n; } public int nextInt() { return ((int) (nextLong())); } public int[] nextInts(int n) { int[] a = new int[n]; for (int i = 0; i < n; ++i) { a[i] = nextInt(); } return a; } } class IntpairPoset { /** * {@code strict = false} では {@code x[i] <= x[j] && y[i] <= y[j]}、 * {@code strict = true} では {@code x[i] < x[j] && y[i] < y[j]} となる chain を考える。 * 互いに素な高々 {@code k} 本の chain に含まれる点の個数の最大値を返す。 * {@code k = 0} のときは0を返す。 * * 計算量: O(N log N + N min(k, N) log N)、空間計算量: O(N) * * @param x * 各点の第1座標 * @param y * 各点の第2座標 * @param k * chain の本数の上限。0以上でなければならない * @param strict * chain 内の座標をともに狭義増加させる場合は {@code true}、 * ともに広義増加させる場合は {@code false} * @return 高々 {@code k} 本の chain の長さの和の最大値 */ public static int maximumKChainsLength(int[] x, int[] y, int k, boolean strict) { // 未テスト if ((x.length != y.length) || (k < 0)) { throw new java.lang.AssertionError(); } int n = x.length; if ((n == 0) || (k == 0)) { return 0; } int[] X = x.clone(); int[] Y = y.clone(); java.lang.Integer[] order = new java.lang.Integer[n]; for (int i = 0; i < n; i++) { order[i] = i; } java.util.Arrays.sort(order, (i, j) -> { if (X[i] != X[j]) { return java.lang.Integer.compare(X[i], X[j]); } return strict ? java.lang.Integer.compare(Y[j], Y[i]) : java.lang.Integer.compare(Y[i], Y[j]); }); int[] sortedY = new int[n]; for (int i = 0; i < n; i++) { sortedY[i] = Y[order[i]]; } k = java.lang.Math.min(k, n); int[][] rows = new int[k][0]; int[] sizes = new int[k]; int answer = 0; for (int i = 0; i < n; i++) { int value = sortedY[i]; for (int row = 0; row < k; row++) { int left = 0; int right = sizes[row]; while (left < right) { int mid = (left + right) >>> 1; if (strict ? rows[row][mid] < value : rows[row][mid] <= value) { left = mid + 1; } else { right = mid; } } if (left == sizes[row]) { if (sizes[row] == rows[row].length) { int newLength = java.lang.Math.max(1, rows[row].length * 2); rows[row] = java.util.Arrays.copyOf(rows[row], newLength); } rows[row][sizes[row]++] = value; answer++; break; } int bumped = rows[row][left]; rows[row][left] = value; value = bumped; } } return answer; } } class MyPrintWriter extends java.io.PrintWriter { private static MyPrintWriter instance = null; private MyPrintWriter() { super(java.lang.System.out); } public static MyPrintWriter getInstance() { if (MyPrintWriter.instance == null) { MyPrintWriter.instance = new MyPrintWriter(); } return MyPrintWriter.instance; } public MyPrintWriter(java.io.PrintStream out) { super(out); } } // --- Original Code --- // // 誤読対策 // // 1.問題文を読む // // 2.目を閉じて、問題文を頭の中で再構成する // // 3.もう一度問題文を読み、再構成した問題と合っているかを確かめる // // import java.io.IOException; // import java.util.ArrayList; // import java.util.Arrays; // import java.util.Collections; // import java.util.Random; // // import library.tools.FastScanner; // import library.tools.MergeFiles; // import library.tools.MyPrintWriter; // import library.util.ArrayUtils; // import library.util.Sieve; // import library.util.algebra.strategy.longs.LongCommutativeMonoidStrategy; // import library.util.graph.grid.Grid4neighborAlgorithms; // import library.util.poset.BooleanLattice; // import library.util.poset.IntpairPoset; // import library.util.segtree.CompressedSparseBinaryIndexedTree2D; // import library.util.seq.SortedArrays; // // public class Main { // // static MyPrintWriter pw = MyPrintWriter.getInstance(); // static FastScanner sc = FastScanner.getInstance(); // Random r=new Random(); // // public static void main(String[] args) throws IOException { // new Main().run(args); // pw.flush(); // MergeFiles.export(); // } // // Random rnd=new Random(); // // void run(String[] args) throws IOException { // int T=sc.nextInt(); // for (int TEST = 0; TEST < T; TEST++) { // int N=sc.nextInt(); // int[]A=sc.nextInts(N); // int[]B=sc.nextInts(N); // int[]x=new int[2*N]; // int[]y=new int[2*N]; // for (int i = 0; i < N; i++) { // x[2*i]=i; // y[2*i]=A[i]; // x[2*i+1]=i; // y[2*i+1]=B[i]; // } // int ans=IntpairPoset.maximumKChainsLength(x, y, 2, true); // pw.println(ans); // } // } // // // // void tr(Object...objects) { // System.out.println(Arrays.deepToString(objects)); // } // // } //