#include #include using namespace std; struct node { int l , r , sum; node *ll , *rr; } pooln[210000] , *t; struct tree { int v; tree *next; } poolt[210000] , *g[210000]; struct so { int i , d , p; } s[120000]; int topt , topn; int n , k; int per[120000]; int siz[210000] , dep[120000] , fa[120000] , son[120000] , top[120000] , w[120000] , wper[120000] , index; int ans; void clear () { int i; for ( i = 1 ; i <= n ; i++ ) { g[i] = NULL; son[i] = 0; } index = topt = topn = 0; ans = 0; } bool cmp ( so x1 , so x2 ) { return x1.d > x2.d; } void add ( int u , int v ) { tree *tmp = &poolt[++topt]; tmp -> v = v; tmp -> next = g[u]; g[u] = tmp; } void dfs1 ( int i , int from ) { siz[i] = 1; for ( tree *j = g[i] ; j ; j = j -> next ) if ( j -> v != from ) { dep[j->v] = dep[i] + 1; dfs1 ( j -> v , i ); siz[i] += siz[j->v]; if ( siz[j->v] > siz[son[i]] ) son[i] = j -> v; } } void dfs2 ( int i , int from ) { w[i] = ++index; wper[index] = per[i]; if ( son[i] ) { top[son[i]] = top[i]; dfs2 ( son[i] , i ); } for ( tree *j = g[i] ; j ; j = j -> next ) if ( j -> v != from && j -> v != son[i] ) { top[j->v] = j -> v; dfs2 ( j -> v , i ); } } void update ( node *id ) { id -> sum = id -> ll -> sum + id -> rr -> sum; } void buildtree ( node *id , int l , int r ) { id -> l = l; id -> r = r; id -> sum = 0; if ( l == r ) return ; int mid = (l+r)/2; id -> ll = &pooln[++topn]; id -> rr = &pooln[++topn]; buildtree ( id -> ll , l , mid ); buildtree ( id -> rr , mid + 1 , r ); } void change ( node *id , int x ) { if ( id -> l == id -> r ) { id -> sum = 1; return ; } int mid = (id->l+id->r)/2; if ( x <= mid ) change ( id -> ll , x ); else change ( id -> rr , x ); update ( id ); } int query ( node *id , int l , int r ) { if ( id -> l == l && id -> r == r ) return id -> sum; int mid = (id->l+id->r)/2; if ( r <= mid ) return query ( id -> ll , l , r ); else { if ( l > mid ) return query ( id -> rr , l , r ); else return query ( id -> ll , l , mid ) + query ( id -> rr , mid + 1 , r ); } } void find ( int x ) { int now = min ( k , dep[x] - 1 ); while ( now >= 0 ) { if ( dep[x] - dep[top[x]] >= now ) { if ( query ( t , w[x] - now , w[x] ) == 0 ) { ans++; change ( t , w[x] - now ); return ; } return ; } else { if ( query ( t , w[top[x]] , w[x] ) > 0 ) { return ; } now -= dep[x] - dep[top[x]] + 1; x = fa[top[x]]; } } } void work () { int i; scanf ( "%d%d" , &n , &k ); for ( i = 2 ; i <= n ; i++ ) { scanf ( "%d" , &fa[i] ); add ( fa[i] , i ); } for ( i = 1 ; i <= n ; i++ ) { scanf ( "%d" , &per[i] ); } dep[1] = 1; dfs1 ( 1 , -1 ); top[1] = 1; dfs2 ( 1 , -1 ); t = &pooln[++topn]; buildtree ( t , 1 , n ); for ( i = 1 ; i <= n ; i++ ) { s[i].i = i; s[i].d = dep[i]; s[i].p = per[i]; } sort ( s + 1 , s + 1 + n , cmp ); ans = 0; for ( i = 1 ; i <= n ; i++ ) { if ( s[i].p ) { find ( s[i].i ); } } printf ( "%d\n" , ans ); } int main () { int t; scanf ( "%d" , &t ); while ( t-- ) { work (); clear (); } return 0; }