3 800 300 2 30 50 25 80 600 1 50 130 400 3 40 70 30 40 35 60
210
//
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=110000;
int boxn,money;//箱子数量,总钱数
int dp[maxn],f[maxn];//加上当前最大价值,前i行最大价值
int boxv[60];//箱子花费
int num[60];//箱子带物品个数
int c[60][20],v[60][20];//物品花费,价值
int main()
{
while(scanf("%d%d",&boxn,&money)==2)
{
for(int i=1;i<=boxn;i++)
{
scanf("%d%d",&boxv[i],&num[i]);
for(int j=1;j<=num[i];j++) scanf("%d%d",&c[i][j],&v[i][j]);
}
memset(f,0,sizeof(f));
memset(dp,0,sizeof(dp));
for(int i=1;i<=boxn;i++)
{
for(int j=boxv[i];j<=money;j++) dp[j]=f[j-boxv[i]];//加上当前箱子的花费
for(int j=1;j<=num[i];j++)
{
for(int k=money;k>=c[i][j]+boxv[i];k--)
{
dp[k]=max(dp[k],dp[k-c[i][j]]+v[i][j]);
}
}
for(int j=boxv[i];j<=money;j++) f[j]=max(f[j],dp[j]);
}
printf("%d\n",f[money]);
}
return 0;
}