#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
/*
物品总个数的限制
有时,“二维费用”的条件是以这样一种隐含的方式给出的:
最多只能取M件物品。这事实上相当于每件物品多了一种“件数”的费用,
每个物品的件数费用均为1,
可以付出的最大件数费用为M。
换句话说,设f[v][m]表示付出费用v、最多选m件时可得到的最大价值,
则根据物品的类型(01、完全、多重)用不同的方法循环更新,
最后在f[0..V][0..M]范围内寻找答案。
*/
int dp[1005][1005];
int value[30], weight[30];
int t, n, m, w;
int main()
{
scanf("%d", &t);
while(t--) {
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i++) {
scanf("%d%d", &value[i], &weight[i]);
}
scanf("%d", &w);
memset(dp, 0, sizeof(dp));
for(int i = 0; i < n; i++) {
for(int j = w; j >= weight[i]; j--) {
for(int k = m; k >= 1; k--) {
dp[j][k] = max(dp[j][k], dp[j-weight[i]][k-1] + value[i]);
}
}
}
printf("%d\n", dp[w][m]);
}
return 0;
}
#include <cstring>
#include <cstdio>
using namespace std;
/*
物品总个数的限制
有时,“二维费用”的条件是以这样一种隐含的方式给出的:
最多只能取M件物品。这事实上相当于每件物品多了一种“件数”的费用,
每个物品的件数费用均为1,
可以付出的最大件数费用为M。
换句话说,设f[v][m]表示付出费用v、最多选m件时可得到的最大价值,
则根据物品的类型(01、完全、多重)用不同的方法循环更新,
最后在f[0..V][0..M]范围内寻找答案。
*/
int dp[1005][1005];
int value[30], weight[30];
int t, n, m, w;
int main()
{
scanf("%d", &t);
while(t--) {
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i++) {
scanf("%d%d", &value[i], &weight[i]);
}
scanf("%d", &w);
memset(dp, 0, sizeof(dp));
for(int i = 0; i < n; i++) {
for(int j = w; j >= weight[i]; j--) {
for(int k = m; k >= 1; k--) {
dp[j][k] = max(dp[j][k], dp[j-weight[i]][k-1] + value[i]);
}
}
}
printf("%d\n", dp[w][m]);
}
return 0;
}