//花了些时间,弄明白了样例的输入输出
//如何转化为算法,还没有眉目
//http://blog.csdn.net/hehe_54321/article/details/75368187此文代码写得不错
//ans[i][j]表示第i个结点以下共j个用户观看时最大的赚钱量
//(仍然没有想到)ans[u][i]=max{ans[u][i-j]+ans[v][j]-w}
//具体解释:
/*
ans[i][j][k]表示第i个结点以下前k个子结点中有j个用户观看时最大的赚钱量
ye[v]为v及以下叶节点数量
则对于边(u,v,w),ans[i][j][k]=max{ans[i][j-p][k-1]+ans[v][p][ye[v]]-w}(0<=p<=j,1<=j<=Σ(t属于前k个子结点的编号)ye[t])
省去k一维,则需要j从大到小循环:
ans[i][j]=max{ans[i][j-p]+ans[v][p]-w}(0<=p<=j,1<=j<=Σ(t属于前k个子结点)ye[t])
*/
/*
f(i, j),表示子树i转播给j个用户的最大收益值
这题可以看作是树上的分组背包,每个子树看作是一组物品,这一组物品可以取1个,2个...j个
然后就是套用分组背包的算法了
*/
//程序有两个地方比较难理解:
//1、如何保证在取数过程中,叶结点无重复,如f[i][i-j]中的叶结点 f[v][j]中的叶结点不重复
//2、for(i=ye[u];i>0;i--)正确 for(i=1;i<=ye[u];i++)错误
//针对样例1,列出动态规划过程,能说明上述问题
//for(i=ye[u];i>0;i--)正确 过程如下:
f[1][1]=max(f[1][1],f[1][1]+f[5][0]-3)
f[1][1]=max(f[1][1],f[1][0]+f[5][1]-3) 1->5 取一个 最大值
f[2][1]=max(f[2][1],f[2][1]+f[4][0]-3)
f[2][1]=max(f[2][1],f[2][0]+f[4][1]-3) 2->4 取一个 最大值
f[2][2]=max(f[2][2],f[2][2]+f[3][0]-2)
f[2][2]=max(f[2][2],f[2][1]+f[3][1]-2)
f[2][2]=max(f[2][2],f[2][0]+f[3][2]-2) 2->4 2->3 取两个 最大值
f[2][1]=max(f[2][1],f[2][1]+f[3][0]-2)
f[2][1]=max(f[2][1],f[2][0]+f[3][1]-2) 2->4 2->3 取一个 最大值
f[1][3]=max(f[1][3],f[1][3]+f[2][0]-2)
f[1][3]=max(f[1][3],f[1][2]+f[2][1]-2)
f[1][3]=max(f[1][3],f[1][1]+f[2][2]-2)
f[1][3]=max(f[1][3],f[1][0]+f[2][3]-2) 1->5 1->4 1->3 取三个 最大值
f[1][2]=max(f[1][2],f[1][2]+f[2][0]-2)
f[1][2]=max(f[1][2],f[1][1]+f[2][1]-2)
f[1][2]=max(f[1][2],f[1][0]+f[2][2]-2) 1->5 1->4 1->3 取两个 最大值
f[1][1]=max(f[1][1],f[1][1]+f[2][0]-2)
f[1][1]=max(f[1][1],f[1][0]+f[2][1]-2) 1->5 1->4 1->3 取一个 最大值
//for(i=1;i<=ye[u];i++)错误 过程如下:
f[1][1]=max(f[1][1],f[1][1]+f[5][0]-3)
f[1][1]=max(f[1][1],f[1][0]+f[5][1]-3) 1->5 取一个 最大值
f[2][1]=max(f[2][1],f[2][1]+f[4][0]-3)
f[2][1]=max(f[2][1],f[2][0]+f[4][1]-3) 2->4 取一个 最大值
f[2][1]=max(f[2][1],f[2][1]+f[3][0]-2)
f[2][1]=max(f[2][1],f[2][0]+f[3][1]-2) 2->4 2->3 取一个 最大值
f[2][2]=max(f[2][2],f[2][2]+f[3][0]-2)
f[2][2]=max(f[2][2],f[2][1]+f[3][1]-2)
f[2][2]=max(f[2][2],f[2][0]+f[3][2]-2) 2->4 2->3 取两个 最大值
f[1][1]=max(f[1][1],f[1][1]+f[2][0]-2)
f[1][1]=max(f[1][1],f[1][0]+f[2][1]-2) 1->5 1->4 1->3 取一个 最大值
f[1][2]=max(f[1][2],f[1][2]+f[2][0]-2)
f[1][2]=max(f[1][2],f[1][1]+f[2][1]-2)
//此处有问题 f[1][1]可能是1->4 故f[1][2]有可能取成 1->4 1->4 错误从此处开始
f[1][2]=max(f[1][2],f[1][0]+f[2][2]-2) 1->5 1->4 1->3 取两个 最大值
f[1][3]=max(f[1][3],f[1][3]+f[2][0]-2)
f[1][3]=max(f[1][3],f[1][2]+f[2][1]-2)
f[1][3]=max(f[1][3],f[1][1]+f[2][2]-2)
f[1][3]=max(f[1][3],f[1][0]+f[2][3]-2) 1->5 1->4 1->3 取三个 最大值
//分析的过程中,同时将上述的两个顾虑问题解决。
//2017-9-1 17:55 AC
#include <stdio.h>
#include <string.h>
#define INF 999999
int head[3100],cnt=0,ye[3100],f[3100][3100];//f[i][j] i节点及以下共j个用户的最大收益 因收益有正有负,故初始化为绝对值比较大的负数
struct node{//邻接表
int to,next,c;
}e[3100];//有向图
void addedge(int u,int v,int c){
cnt++,e[cnt].to=v,e[cnt].c=c,e[cnt].next=head[u],head[u]=cnt;
}
int max(int a,int b){
return a>b?a:b;
}
void dfs(int u){
int v,b,i,j,c;//b边
b=head[u];
while(b){
v=e[b].to,c=e[b].c;
dfs(v);
ye[u]+=ye[v];
for(i=ye[u];i>=1;i--)
for(j=0;j<=i;j++)
f[u][i]=max(f[u][i],f[u][i-j]+f[v][j]-c);//1 此处写成 f[u][j]=max(f[i][j],f[u][i-j]+f[v][j]-c);
b=e[b].next;
}
}
int main(){
int n,m,i,j,p,k,a,c,ans=-INF;
memset(head,0,sizeof(head));
memset(ye,0,sizeof(ye));
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
f[i][j]=-INF;
for(i=1;i<=n;i++)
f[i][0]=0;//取0个,值为0
p=n-m;
for(i=1;i<=p;i++){
scanf("%d",&k);
for(j=1;j<=k;j++){
scanf("%d%d",&a,&c);
addedge(i,a,c);
}
}
for(i=p+1;i<=n;i++){
scanf("%d",&c);
f[i][1]=c,ye[i]=1;
}
dfs(1);
for(i=ye[1];i>=1;i--){
ans=i;
if(f[1][i]>=0)break;
}
printf("%d\n",ans);
return 0;
}