#nullable enable #region var (_input, _iter) = (Array.Empty(), 0); T I() where T : IParsable { while (_iter >= _input.Length) (_input, _iter) = (Console.ReadLine()!.Split(' '), 0); return T.Parse(_input[_iter++], null); } #endregion static T[] Range(int n, Func F) => Enumerable.Range(0, n).Select(_ => F()).ToArray(); (int, int) Solve() { var n1 = I(); var n2 = I(); var k = I(); var j = I(); var pz1 = Range(n1, I); var cz1 = Range(n1, () => I() - 1); var pz2 = Range(n2, I); var cz2 = Range(n2, () => I() - 1); var sz = Range(k, I); var cd = Range(k, () => new List()); for (var i = 0; i < n2; i++) cd[cz2[i]].Add(pz2[i]); foreach (var l in cd) l.Sort(); var ad = new List(pz2); ad.Sort(); int CountLT(List l, long x) { var pass = -1; var fail = l.Count; while (fail - pass >= 2) { var mid = (pass + fail) >> 1; if (l[mid] <= x) pass = mid; else fail = mid; } return pass + 1; } var pass = long.MaxValue >> 1; var fail = -1L; while (Math.Abs(fail - pass) >= 2) { var mid = (pass + fail) >> 1; var s = 0L; for (var i = 0; i < n1; i++) { var (p1, c1) = (pz1[i], cz1[i]); s += CountLT(ad, mid - p1); s -= CountLT(cd[c1], mid - p1); s += CountLT(cd[c1], mid - p1 + sz[c1]); } if (s >= j) pass = mid; else fail = mid; } var pd = new Dictionary>(); for (var i = 0; i < n2; i++) { var (p2, c2) = (pz2[i], cz2[i]); if (!pd.ContainsKey(p2)) pd[p2] = new(); var l = pd[p2]; if (l.Count == 0) l.Add((c2, i)); else if (l.Count < 2 && l[0].Item1 != c2) l.Add((c2, i)); } for (var i = 0; i < n1; i++) { var (p1, c1) = (pz1[i], cz1[i]); var p2 = pass - p1; if (pd.ContainsKey(p2)) { var l2 = pd[p2]; foreach (var (c2, i2) in l2) { if (c2 != c1) return (i, i2); } } p2 = pass - p1 + sz[c1]; if (pd.ContainsKey(p2)) { var l2 = pd[p2]; foreach (var (c2, i2) in l2) { if (c2 == c1) return (i, i2); } } } throw new Exception(); } var t = I(); var ans = Range(t, Solve).Select(e => (e.Item1 + 1) + " " + (e.Item2 + 1)); Console.WriteLine(string.Join(Environment.NewLine, ans));