#include <bits/stdc++.h>
using namespace std;
/*
We build a segment tree over the integer-encoded characters [0..25].
Each node stores a pair: (min_char_in_range, rightmost_position_of_that_min_char).
Merge rule for two children L and R:
- If L.first < R.first, take L.
- If R.first < L.first, take R.
- If they are equal, take whichever has the larger position (to push the 'worse'
character as far right as possible).
Then, we iterate i = 0 .. n-1 (as long as m > 0). At each i:
1) Query the suffix [i+1 .. n-1] to find (minChar, pos).
2) If minChar < arr[i], swap arr[i] and arr[pos], update both leaves in the tree, m--.
3) Otherwise, do nothing. Move to i+1.
This yields the lexicographically smallest result after at most m swaps.
Time per test: O(n log n). Sum of n over all tests ≤ 2e5.
*/
struct SegTree {
int n;
int size;
// st[k] = { min_char_in_that_node, rightmost_index_of_that_char }
vector<pair<int,int>> st;
// Merge two nodes a, b
static pair<int,int> merge_pair(const pair<int,int> &a, const pair<int,int> &b) {
if (a.first < b.first) return a;
if (b.first < a.first) return b;
// a.first == b.first
if (a.second > b.second) return a;
return b;
}
SegTree(const vector<int> &arr) {
n = (int)arr.size();
size = 1;
while (size < n) size <<= 1;
st.assign(2 * size, { 100, -1 });
// 100 is bigger than any valid char index (0..25), so it acts as "infinity".
// Build leaves
for (int i = 0; i < n; i++) {
st[size + i] = { arr[i], i };
}
// Build internal nodes
for (int idx = size - 1; idx >= 1; idx--) {
st[idx] = merge_pair(st[2*idx], st[2*idx + 1]);
}
}
// Point update: set position pos to value new_char
void update(int pos, int new_char) {
int idx = size + pos;
st[idx] = { new_char, pos };
idx >>= 1;
while (idx >= 1) {
st[idx] = merge_pair(st[2*idx], st[2*idx + 1]);
idx >>= 1;
}
}
// Query range [l..r], 0-based inclusive
pair<int,int> query(int l, int r) {
pair<int,int> resL = { 100, -1 };
pair<int,int> resR = { 100, -1 };
l += size;
r += size;
while (l <= r) {
if (l & 1) {
resL = merge_pair(resL, st[l]);
l++;
}
if (!(r & 1)) {
resR = merge_pair(st[r], resR);
r--;
}
l >>= 1;
r >>= 1;
}
return merge_pair(resL, resR);
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) {
int n;
long long m;
string s;
cin >> n >> m;
cin >> s;
// Encode 'a'->0, 'b'->1, ..., 'z'->25
vector<int> arr(n);
for (int i = 0; i < n; i++) {
arr[i] = s[i] - 'a';
}
SegTree seg(arr);
int i = 0;
while (i < n && m > 0) {
if (i == n - 1) break;
// Query suffix [i+1 .. n-1]
auto [minChar, pos] = seg.query(i + 1, n - 1);
if (minChar < arr[i]) {
// Perform swap in arr, then update segment tree
int old_i = arr[i];
int old_pos = arr[pos];
arr[i] = old_pos;
arr[pos] = old_i;
seg.update(i, arr[i]);
seg.update(pos, arr[pos]);
m--;
}
i++;
}
// Output resulting string
for (int x : arr) {
char c = char('a' + x);
cout << c;
}
cout << "\n";
}
return 0;
}