import java.io.OutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.util.stream.IntStream; import java.util.Arrays; import java.util.PriorityQueue; import java.io.BufferedWriter; import java.util.InputMismatchException; import java.io.IOException; import java.util.stream.Stream; import java.io.Writer; import java.io.OutputStreamWriter; import java.io.InputStream; /** * Built using CHelper plug-in * Actual solution is at the top * * @author lewin */ public class string_cutting_lewin { public static void main(String[] args) { InputStream inputStream = System.in; OutputStream outputStream = System.out; InputReader in = new InputReader(inputStream); OutputWriter out = new OutputWriter(outputStream); StringCutting solver = new StringCutting(); int testCount = Integer.parseInt(in.next()); for (int i = 1; i <= testCount; i++) solver.solve(i, in, out); out.close(); } static class StringCutting { public void solve(int testNumber, InputReader in, OutputWriter out) { int k = in.nextInt(); String s = in.next(); StringBuilder ans = new StringBuilder(); for (char let = 'z'; k > 0 && let >= 'a'; let--) { int rr = 0; while (rr < s.length() && s.charAt(rr) == let) { rr++; ans.append(let); } s = s.substring(rr); int needcuts = 0; int count = 0; int last = -1; for (int i = 1; i < s.length(); i++) { if (s.charAt(i) == let) { count++; last = i; } if ((s.charAt(i) == let || s.charAt(i - 1) == let) && (s.charAt(i) != s.charAt(i - 1))) needcuts++; } needcuts = (needcuts + 1) / 2; if (needcuts <= k) { k -= needcuts; for (int i = 0; i < count; i++) ans.append(let); s = s.substring(last + 1); } else { int[] maxd = new int[s.length() + 1]; int[] suff = SuffixArray2.suffixArray(s); int[] mxs = new int[s.length() + 1]; mxs[s.length()] = -1; int[] whichs = new int[s.length() + 1]; int[] rank = AUtils.inverse(suff); int c = 0; for (int i = s.length() - 1; i >= 0; i--) { if (s.charAt(i) == let) { c++; } else { c = 0; } maxd[i] = Math.max(c, maxd[i + 1]); if (rank[i] > mxs[i + 1]) { mxs[i] = rank[i]; whichs[i] = i; } else { mxs[i] = mxs[i + 1]; whichs[i] = whichs[i + 1]; } } PriorityQueue pq = new PriorityQueue<>(); int sum = 0; c = 0; int mx = 0, tt = 0; int suffix = 0, sr = -1; for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == let) { c++; } else { pq.add(c); sum += c; if (pq.size() > k - 1) sum -= pq.poll(); c = 0; } if (sum + maxd[i + 1] >= mx) { int who = whichs[i + 1]; int ar = who + maxd[i + 1] == rank.length ? -1 : rank[who + maxd[i + 1]]; if (sum + maxd[i + 1] > mx || ar > sr) { sr = ar; suffix = whichs[i + 1] + maxd[i + 1]; } mx = sum + maxd[i + 1]; } } for (int i = 0; i < mx; i++) { ans.append(let); } s = s.substring(suffix); break; } } out.println(ans + s); } } static class AUtils { public static int[] inverse(int[] arr) { int n = arr.length; int[] ret = new int[n]; for (int i = 0; i < n; i++) { ret[arr[i]] = i; } return ret; } } static class OutputWriter { private final PrintWriter writer; public OutputWriter(OutputStream outputStream) { writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream))); } public OutputWriter(Writer writer) { this.writer = new PrintWriter(writer); } public void print(Object... objects) { for (int i = 0; i < objects.length; i++) { if (i != 0) { writer.print(' '); } writer.print(objects[i]); } } public void println(Object... objects) { print(objects); writer.println(); } public void close() { writer.close(); } } static class InputReader { private InputStream stream; private byte[] buf = new byte[1 << 16]; private int curChar; private int numChars; public InputReader(InputStream stream) { this.stream = stream; } public int read() { if (this.numChars == -1) { throw new InputMismatchException(); } else { if (this.curChar >= this.numChars) { this.curChar = 0; try { this.numChars = this.stream.read(this.buf); } catch (IOException var2) { throw new InputMismatchException(); } if (this.numChars <= 0) { return -1; } } return this.buf[this.curChar++]; } } public int nextInt() { int c; for (c = this.read(); isSpaceChar(c); c = this.read()) { ; } byte sgn = 1; if (c == 45) { sgn = -1; c = this.read(); } int res = 0; while (c >= 48 && c <= 57) { res *= 10; res += c - 48; c = this.read(); if (isSpaceChar(c)) { return res * sgn; } } throw new InputMismatchException(); } public String next() { int c; while (isSpaceChar(c = this.read())) { ; } StringBuilder result = new StringBuilder(); result.appendCodePoint(c); while (!isSpaceChar(c = this.read())) { result.appendCodePoint(c); } return result.toString(); } public static boolean isSpaceChar(int c) { return c == 32 || c == 10 || c == 13 || c == 9 || c == -1; } } static class SuffixArray2 { public static int[] suffixArray(CharSequence s) { int n = s.length(); Integer[] sa = IntStream.range(0, n).mapToObj(Integer::valueOf).toArray(Integer[]::new); int[] rank = s.chars().toArray(); for (int len = 1; len < n; len *= 2) { long[] rank2 = new long[n]; for (int i = 0; i < n; i++) rank2[i] = ((long) rank[i] << 32) + (i + len < n ? rank[i + len] + 1 : 0); Arrays.sort(sa, (a, b) -> Long.compare(rank2[a], rank2[b])); for (int i = 0; i < n; i++) rank[sa[i]] = i > 0 && rank2[sa[i - 1]] == rank2[sa[i]] ? rank[sa[i - 1]] : i; } return Arrays.stream(sa).mapToInt(Integer::intValue).toArray(); } } }