#include using namespace std; using ll = long long; // Approximate solver: a finite beam does not guarantee the optimal X_c (or C). constexpr int BEAM_WIDTH = 256; constexpr int PERSON[6][2] = {{0, -1}, {1, -1}, {2, -1}, {0, 1}, {0, 2}, {1, 2}}; struct State { array count{}; array used{}; ll score = 0; }; void solve() { int n; array stamina; cin >> n >> stamina[0] >> stamina[1] >> stamina[2]; array, 6> value; for (int i = 0; i < n; ++i) { int type; ll score; cin >> type >> score; value[type - 1].push_back(score); } for (auto &a : value) sort(a.rbegin(), a.rend()); vector beam(1); vector answer; for (int depth = 1; depth <= n; ++depth) { vector candidates; candidates.reserve(beam.size() * 6); for (const State &s : beam) { for (int t = 0; t < 6; ++t) { if (s.count[t] == (int)value[t].size()) continue; int a = PERSON[t][0], b = PERSON[t][1]; if (s.used[a] == stamina[a] || (b != -1 && s.used[b] == stamina[b])) continue; State next = s; next.score += value[t][next.count[t]++]; ++next.used[a]; if (b != -1) ++next.used[b]; candidates.push_back(next); } } if (candidates.empty()) break; // Different orders of choosing the same six prefixes are one state. sort(candidates.begin(), candidates.end(), [](const State &a, const State &b) { return a.count < b.count; }); candidates.erase(unique(candidates.begin(), candidates.end(), [](const State &a, const State &b) { return a.count == b.count; }), candidates.end()); const int keep = min(BEAM_WIDTH, candidates.size()); partial_sort(candidates.begin(), candidates.begin() + keep, candidates.end(), [](const State &a, const State &b) { if (a.score != b.score) return a.score > b.score; return a.count < b.count; }); candidates.resize(keep); answer.push_back(candidates.front().score); beam = move(candidates); } cout << answer.size(); for (ll x : answer) cout << ' ' << x; cout << '\n'; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int test_cases; cin >> test_cases; while (test_cases--) solve(); }