/*
    题意:给出一些物品,有价值,数量,价格
    还有一些限制,限制的组里面只能选一种物品,问D钱最多能获得的价值

    按组分阶段,然后根据物品数量分别做0-1,完全,多重背包(logn)

    之前做的都是一维数组的背包,换成滚动数组时注意更新的顺序!!!

*/

#include
<cstdio>
#include
<cstring>
#include
<algorithm>
#include
<vector>
#include
<cctype>

using namespace std;

const int MAXN = 1030;
const int INF = 1000000000;

int price[MAXN] , num[MAXN] , val[MAXN];
int dp[2][MAXN] , _dp[MAXN];
vector
<int> group[MAXN];
bool vi[MAXN];
char str[10000];

int main()
{    
    
//freopen("in","r",stdin);

    
int n , D;
    
while~scanf("%d%d",&n,&D) )
    
{
        group[
0].clear();
        
for(int i = 1 ; i <= n ; i++)
        
{
            group[i].clear();
            vi[i] 
= false;
            scanf(
"%d%d%d" , &num[i] , &val[i] , &price[i]);
        }


        
int G;
        scanf(
"%d\n",&G);
        
for(int i = 0 ; i < G ; i++)
        
{
            gets(str);
            
for(int j = 0 ;str[j] ; )
            
{
                
if(isdigit(str[j]))
                
{
                    
int x = 0;
                    
while(isdigit(str[j]))
                        x 
= 10*+ str[j++]-'0';
                    group[i].push_back(x);
                    vi[x] 
= true;
                }

                
else j++;
            }

        }


        
for(int i = 1 ; i <= n ; i++)
        
{
            
if(vi[i])continue;
            group[G
++].push_back(i);
        }

    
        
int pre = 0 , now = 1;
        dp[pre][
0= 0;
        
for(int i = 1 ; i <= D; i++)
            dp[pre][i] 
= -INF;
        
for(int i = 0 ; i < G ; i++)
        
{
            dp[now][
0= 0;
            
for(int j = 1 ; j <= D; j++)
                dp[now][j] 
= -INF;
            
for(int ii = 0 ; ii < group[i].size() ; ii++)
            
{
                
int id = group[i][ii];

                
if(num[id] == 1)//0-1 pack
                {
                    
for(int j = price[id] ; j <= D; j++)
                        dp[now][j] 
= max(dp[now][j] , dp[pre][j-price[id]] + val[id]);
                }

                
else if(num[id] == 0)//complete pack
                {
                    
for(int j = 0 ; j <= D; j ++)//多开一个数组
                        _dp[j] = dp[pre][j];
                    
for(int j = price[id] ; j <= D; j++)
                    
{
                        _dp[j] 
= max(_dp[j] , _dp[j-price[id]] + val[id]);
                        dp[now][j] 
= max(dp[now][j] , _dp[j]);
                    }

                }

                
else//
                {
                    
for(int j = 0 ; j <= D; j ++)//多开一个数组
                        _dp[j] = dp[pre][j];
                    
int amount = num[id] , k = 1;
                    
while(amount > 0)
                    
{
                        
if(k>amount)k = amount;
                        amount 
-= k;
                        
for(int j = D ; j >= k*price[id] ; j--)//注意是在新的基础上_dp[j]
                        {
                            _dp[j] 
= max(_dp[j] , _dp[j-k*price[id]] + k*val[id]);
                            dp[now][j] 
= max(dp[now][j] , _dp[j] );
                        }

                        k
<<=1;
                    }

                }

            }

            
for(int j = 0 ; j <= D; j++)//记得要更新!! 
                dp[now][j] = max(dp[now][j] , dp[pre][j]);
            swap(pre,now);
        }

        
if(dp[pre][D] < 0)puts("i'm sorry");
        
else printf("%d\n",dp[pre][D]);
    }

    
return 0;
}