#include<bits/stdc++.h>
using namespace std;
struct node
{
int tp,x,y; //tp(0,1,2)为3种操作
}b[10];
int n,m;
int a[4];
int w[10];
bool fl;
int p,k,t;
int vis[10],c[10];
//num:当前有多少人
//sum:当前在的人的能力和
//st:在的集合状态(4个位置,1为在,0为不在)
//tot:一开始的能力和
int st,sum,num,tot;
int turn(string s)
{
if(s[0]=='T') return 0;
if(s[0]=='K') return 1;
if(s[0]=='N') return 2;
if(s[0]=='J') return 3;
}
//暴力搜索出所有行动方案(全排列),再判断每一种方案是否可行
void dfs(int dep,int tmp) //深度,前面通过了多少关(每个人的能力值加了多少个1)
{
if(dep>t) //判断这个方案是否可行
{
int sum1=sum+tmp*num,st1=st,islv=num;
//能力值和,在的人的集合,被救出来的人数
for(int i=1;i<=t;i++) //枚举每一次操作
{
int id=c[i];
int tp=b[id].tp,x=b[id].x,y=b[id].y;
if(tp==0) sum1+=x;
if(tp==1)
{
if(sum1>=x)
{
sum1+=a[y]+tmp;
st1|=(1<<y);
islv++;
}
}
else
if((st1&x)==x) fl=1;
if(islv==4) fl=1;
}
return;
}
for(int i=1;i<=k;i++)
{
if(!vis[i])
{
c[dep]=i; //枚举下一个位置该填什么
vis[i]=1;
dfs(dep+1,tmp);
vis[i]=0;
}
}
}
bool check(int x)
{
fl=0;
dfs(1,x);
return fl;
}
int mk[105]; //取答案时的标记数组
int ans[105]; //答案数组
int main()
{
// freopen("travel.in","r",stdin);
// freopen("travel.out","w",stdout);
cin >> n >> m;
for(int i=0;i<4;i++)
{
cin >> a[i];
tot+=a[i];
}
for(int o=1;o<=n;o++)
{
num=4;
st=(1<<4)-1;
sum=tot;
cin >> p >> k >> t;
for(int i=1;i<=p;i++)
{
string ss;
cin >> ss;
int l=turn(ss);
num--; //少一个人
st^=(1<<l); //将这一位清零
sum-=a[l]; //减去能力值
}
for(int i=1;i<=k;i++)
{
char op;
cin >> op;
if(op=='G')
{
int x;
cin >> x;
b[i]=((node){0,x,0});
}
else if(op=='S')
{
int x; string ss;
cin >> ss >> x;
b[i]=((node){1,x,turn(ss)});
}
else
{
int x; string ss;
cin >> x;
int nw=0;
// nw:当前的人物是否存在
for(int i=1;i<=x;i++)
{
cin >> ss;
int l=turn(ss);
nw|=(1<<l);
}
b[i]={2,nw,0};
}
}
// 二分:通过这个需要至少多少初始值
int l=0,r=101;
while(l+1<r)
{
int mid=(l+r)/2;
if(check(mid))
{
w[o]=mid;
r=mid;
}
else l=mid;
}
}
for(int o=1;o<=m;o++)
{
bool flag=0;
for(int i=1;i<=n;i++)
{
if(!mk[i]&&w[i]<=o)
{
flag=1;
ans[o]=i;
mk[i]=1;
break;
}
}
if(!flag)
{
cout << -1;
exit(0);
}
}
for(int i=1;i<=m;i++) cout << ans[i] << " ";
return 0;
}
WA15,样例输出1 2 3 4
,求救