#nullable enable #region var (_input, _iter) = (Array.Empty(), 0); T I() where T : IParsable { while (_iter >= _input.Length) (_input, _iter) = (Console.ReadLine()!.Split(' ', StringSplitOptions.RemoveEmptyEntries), 0); return T.Parse(_input[_iter++], null); } #endregion static T[] Range(int n, Func F) => Enumerable.Range(0, n).Select(_ => F()).ToArray(); int Solve() { var n = I(); var az = Range(n, I); var bz = Range(n, I); var uz = new List(); for (var i = 0; i < n; i++) { var a = az[i]; var b = bz[i]; uz.Add(Math.Max(a, b)); uz.Add(Math.Min(a, b)); } var mins = new List(); var iz = new int[uz.Count].AsSpan(); iz.Fill(int.MaxValue); for (var i = 0; i < uz.Count; i++) { var v = uz[i]; var j = mins.BinarySearch(v); if (j < 0) j = ~j; if (j == mins.Count) mins.Add(v); else mins[j] = v; iz[i] = j; } var res = 0; var pass = 0; var fail = mins.Count + 1; while (Math.Abs(fail - pass) >= 2) { var mid = (fail + pass) / 2; var lis1 = new int[mid]; var next = mid - 1; for (var i = uz.Count - 1; i >= 0; i--) { if (iz[i] != next) continue; lis1[next--] = i; } var used = new HashSet(lis1); var lis2 = new List(); for (var i = 0; i < uz.Count; i++) if (!used.Contains(i)) { var v = uz[i]; var j = ~lis2.BinarySearch(v); if (j < 0) continue; if (j == lis2.Count) lis2.Add(v); else lis2[j] = v; } res = Math.Max(res, mid + lis2.Count); if (lis2[^1] >= uz[lis1[^1]]) pass = mid; else fail = mid; } return res; } var ans = Range(I(), Solve); Console.WriteLine(string.Join(Environment.NewLine, ans));