#include <bits/stdc++.h>
using namespace std;

struct FB {
    vector<int> stk;
    unordered_set<int> addr;
};

struct AB {
    int sta;
    int siz;
    int req;
};

int clz(int n) {
    if (n <= 1) return 0;
    int k = 0;
    while ((1 << k) < n) k++;
    return k;
}

int main() {
    int T;
    cin >> T;
    cin.ignore();
    for (int tc = 0; tc < T; tc++) {
        if (tc) cout << "\n";
        string ln;
        while (getline(cin, ln)) {
            if (!ln.empty()) break;
        }
        if (ln.empty()) break;
        int U, L;
        stringstream ss(ln);
        ss >> U >> L;
        int tot = 1 << U, minb = 1 << L;
        map<int, FB> fb;
        fb[tot].stk.push_back(0);
        fb[tot].addr.insert(0);
        map<char, AB> abm;
        while (getline(cin, ln)) {
            if (ln.empty()) break;
            char P;
            int S;
            stringstream ssp(ln);
            ssp >> P >> S;
            if (S > 0) {
                int rq = S, asz = 1;
                while (asz < rq) asz <<= 1;
                if (asz < minb) asz = minb;
                int km = clz(asz), fs = 0;
                for (int k = km; k <= U; k++) {
                    int sz = 1 << k;
                    if (!fb[sz].stk.empty()) {
                        fs = sz;
                        break;
                    }
                }
                int cs = fs, addr = -1;
                while (cs > asz) {
                    addr = fb[cs].stk.back();
                    fb[cs].stk.pop_back();
                    fb[cs].addr.erase(addr);
                    int hs = cs / 2, l = addr, r = addr + hs;
                    fb[hs].stk.push_back(r);
                    fb[hs].addr.insert(r);
                    fb[hs].stk.push_back(l);
                    fb[hs].addr.insert(l);
                    cs = hs;
                }
                addr = fb[asz].stk.back();
                fb[asz].stk.pop_back();
                fb[asz].addr.erase(addr);
                AB ab;
                ab.sta = addr;
                ab.siz = asz;
                ab.req = rq;
                abm[P] = ab;
            }
            else {
                auto it = abm.find(P);
                if (it != abm.end()) {
                    int addr = it->second.sta, siz = it->second.siz;
                    abm.erase(it);
                    int cs = siz, ca = addr;
                    while (cs < tot) {
                        int buddy = ca ^ cs;
                        if (fb[cs].addr.find(buddy) == fb[cs].addr.end()) break;
                        auto itf = find(fb[cs].stk.begin(), fb[cs].stk.end(), buddy);
                        if (itf == fb[cs].stk.end()) break;
                        fb[cs].stk.erase(itf);
                        fb[cs].addr.erase(buddy);
                        ca = min(ca, buddy);
                        cs <<= 1;
                    }
                    fb[cs].stk.push_back(ca);
                    fb[cs].addr.insert(ca);
                }
            }
        }
        vector<pair<int, string>> blk;
        for (auto &p : abm) {
            blk.emplace_back(p.second.sta, string(1, p.first) + ":" + to_string(p.second.req));
        }
        for (auto &p : fb) {
            int sz = p.first;
            for (auto &a : p.second.stk) {
                blk.emplace_back(a, "Hole:" + to_string(sz));
            }
        }
        sort(blk.begin(), blk.end(), [&](const pair<int, string> &a, const pair<int, string> &b) -> bool {
            return a.first < b.first;
        });
        for (int i = 0; i < blk.size(); i++) {
            cout << blk[i].second << "\n";
        }
    }
} make this code more optimal for example where it can be make less actions but make the code behave the same. also you can introduce new functions if it makes code better and shorter