#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector< vector<int> > dp(1000, vector<int>(10001, -1));
int maxProfit(vector< pair<int, int> >& bags, int maxWeight, int index) {
if (index == bags.size()) {
return 0;
}
if (dp[index][maxWeight] != -1) {
return dp[index][maxWeight];
}
if (bags[index].first > maxWeight) {
return dp[index][maxWeight] = maxProfit(bags, maxWeight, index + 1);
}
int selected = bags[index].second + maxProfit(bags, maxWeight - bags[index].first, index + 1);
int notSelected = maxProfit(bags, maxWeight, index + 1);
return dp[index][maxWeight] = max(selected, notSelected);
}
int getMaxProfit(vector<pair <int, int> >& bags, int maxWeight) {
// dp.resize(bags.size(), vector<int>(maxWeight + 1, -1));
return maxProfit(bags, maxWeight, 0);
}
int main() {
int nInstances;
// printf("Enter number of instances: \n");
cin >> nInstances;
while (nInstances--) {
int maxWeight;
int nBags;
// printf("Enter max weight of the truck: \n");
cin >> maxWeight >> nBags;
vector<pair<int, int> > bags(nBags);
for (int i = 0; i < nBags; i++) {
int weight;
int profit;
// printf("Enter weight and profit of bag %d: \n", i + 1);
cin >> weight >> profit;
bags[i].first = weight;
bags[i].second = profit;
}
cout << "Hey stupid robber, you can get: " + getMaxProfit(bags, maxWeight);
}
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8YWxnb3JpdGhtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKCnZlY3RvcjwgdmVjdG9yPGludD4gPiBkcCgxMDAwLCB2ZWN0b3I8aW50PigxMDAwMSwgLTEpKTsKaW50IG1heFByb2ZpdCh2ZWN0b3I8IHBhaXI8aW50LCBpbnQ+ID4mIGJhZ3MsIGludCBtYXhXZWlnaHQsIGludCBpbmRleCkgewogICAgaWYgKGluZGV4ID09IGJhZ3Muc2l6ZSgpKSB7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBpZiAoZHBbaW5kZXhdW21heFdlaWdodF0gIT0gLTEpIHsKICAgICAgICByZXR1cm4gZHBbaW5kZXhdW21heFdlaWdodF07CiAgICB9CiAgICBpZiAoYmFnc1tpbmRleF0uZmlyc3QgPiBtYXhXZWlnaHQpIHsKICAgICAgICByZXR1cm4gZHBbaW5kZXhdW21heFdlaWdodF0gPSBtYXhQcm9maXQoYmFncywgbWF4V2VpZ2h0LCBpbmRleCArIDEpOwogICAgfQogICAgaW50IHNlbGVjdGVkID0gYmFnc1tpbmRleF0uc2Vjb25kICsgbWF4UHJvZml0KGJhZ3MsIG1heFdlaWdodCAtIGJhZ3NbaW5kZXhdLmZpcnN0LCBpbmRleCArIDEpOwogICAgaW50IG5vdFNlbGVjdGVkID0gbWF4UHJvZml0KGJhZ3MsIG1heFdlaWdodCwgaW5kZXggKyAxKTsKICAgIHJldHVybiBkcFtpbmRleF1bbWF4V2VpZ2h0XSA9IG1heChzZWxlY3RlZCwgbm90U2VsZWN0ZWQpOwp9CmludCBnZXRNYXhQcm9maXQodmVjdG9yPHBhaXIgPGludCwgaW50PiA+JiBiYWdzLCBpbnQgbWF4V2VpZ2h0KSB7CiAgICAvLyBkcC5yZXNpemUoYmFncy5zaXplKCksIHZlY3RvcjxpbnQ+KG1heFdlaWdodCArIDEsIC0xKSk7CiAgICByZXR1cm4gbWF4UHJvZml0KGJhZ3MsIG1heFdlaWdodCwgMCk7Cn0KCmludCBtYWluKCkgewoKICAgIGludCBuSW5zdGFuY2VzOwogICAgLy8gcHJpbnRmKCJFbnRlciBudW1iZXIgb2YgaW5zdGFuY2VzOiBcbiIpOwogICAgY2luID4+IG5JbnN0YW5jZXM7CiAgICB3aGlsZSAobkluc3RhbmNlcy0tKSB7CiAgICAgICAgaW50IG1heFdlaWdodDsKICAgICAgICBpbnQgbkJhZ3M7CiAgICAgICAgLy8gcHJpbnRmKCJFbnRlciBtYXggd2VpZ2h0IG9mIHRoZSB0cnVjazogXG4iKTsKICAgICAgICBjaW4gPj4gbWF4V2VpZ2h0ID4+IG5CYWdzOwogICAgICAgIHZlY3RvcjxwYWlyPGludCwgaW50PiA+IGJhZ3MobkJhZ3MpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbkJhZ3M7IGkrKykgewogICAgICAgICAgICBpbnQgd2VpZ2h0OwogICAgICAgICAgICBpbnQgcHJvZml0OwogICAgICAgICAgICAvLyBwcmludGYoIkVudGVyIHdlaWdodCBhbmQgcHJvZml0IG9mIGJhZyAlZDogXG4iLCBpICsgMSk7CiAgICAgICAgICAgIGNpbiA+PiB3ZWlnaHQgPj4gcHJvZml0OwogICAgICAgICAgICBiYWdzW2ldLmZpcnN0ID0gd2VpZ2h0OwogICAgICAgICAgICBiYWdzW2ldLnNlY29uZCA9IHByb2ZpdDsKICAgICAgICB9CiAgICAgICAgY291dCA8PCAiSGV5IHN0dXBpZCByb2JiZXIsIHlvdSBjYW4gZ2V0OiAiICsgZ2V0TWF4UHJvZml0KGJhZ3MsIG1heFdlaWdodCk7CiAgICB9Cn0K