/*
poj 1655
题意:求树的重心和去掉重心的最大子树
树的重心定义:对于一个树中节点x,当我们删去它时会将原来的树分割成若干个不
相连的部分,
其中每个部分都是一颗子树。
设max_part表示这些部分中最大的一棵子树,若删去节点x能够使得max_part最小,
则称这个点为树的重心
树的重心的性质:
定义1:找到一个点,删除它得到的森林中最大的子树节点数最少,那么这个点就是这棵树的重心。
定义2:删除重心后得到的所有子树,其顶点树必然不超过n/2
性质1:树中所有点到某个点的距离和中,到重心的距离和是最小的;如果有两个重心,那么他们的距离和一样。
性质2:把两个树通过一条边相连得到一个新的树,那么新的树的重心在连接原来两个树的重心的路径上。
性质3:把一个树添加或删除一个叶子,那么它的重心最多只移动一条边的距离。
*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=2e4+100;
struct node
{
int to,next;
}edge[N<<2];
int cc;
int head[N<<2];
void addedge(int from,int to)
{
edge[cc].to=to;
edge[cc].next=head[from];
head[from]=cc++;
}
int Max;
bool vis[N];
int sz[N];//删去u后以i为根的子树的大小
int pos;//搜索到现在使得maxn最小的节点
int n;
void dfs(int u)
{
sz[u]=1;
vis[u]=true;
int maxn=0;
for(int i=head[u];i!=-1;i=edge[i].next){
int to=edge[i].to;
if(vis[to]) continue;
dfs(to);
sz[u]+=sz[to];
maxn=max(maxn,sz[to]);//删去u之后大小最大的子树的大小
}
maxn=max(maxn,n-sz[u]);
if(maxn<Max){
Max=maxn;
pos=u;
}
/*
求所有的树的重心
if(maxn<Max){
vec.clear();
Max=maxn;
vec.push_back(u);
}
else if(maxn==Max){
vec.push_back(u)
}
*/
}
int main()
{
int T;scanf("%d",&T);
while(T--){
cc=0;
memset(sz,0,sizeof(sz));
memset(head,-1,sizeof(head));
memset(vis,false,sizeof(vis));
scanf("%d",&n);
for(int i=0;i<n-1;i++){
int a,b;
scanf("%d %d",&a,&b);
addedge(a,b);
addedge(b,a);
}
Max=1<<29;
dfs(1);
printf("%d %d\n",pos,Max);
}
return 0;
}
/*
https://ac.nowcoder.com/acm/contest/904/E
现在给定一个n个点,n-1条边的树形图(视1号店为根),每个点有一个颜色,
每次询问以x为根的子树中有多少种不同的颜色
这题其实就是dfs搜索到叶节点开始从叶节点往根结点操作
这个思想有点像树形dp或者是树的重心
*/
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+100;
int val[N];
vector<int>mp[N];
set<int>st[N];
int sz[N];
int cc;
vector<int>vv;
void dfs(int u,int fa)
{
for(int i=0;i<mp[u].size();i++){
int to=mp[u][i];
if(to==fa) continue;
dfs(to,u);
for(set<int>::iterator it=st[to].begin();it!=st[to].end();++it){
st[u].insert(*it);
}
}
st[u].insert(val[u]);
sz[u]=st[u].size();
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&val[i]);
for(int i=0;i<n-1;i++){
int a,b;
scanf("%d %d",&a,&b);
mp[a].push_back(b);
mp[b].push_back(a);
}
dfs(1,0);
while(m--){
int x;scanf("%d",&x);
printf("%d\n",sz[x]);
}
return 0;
}
/*
7 10
1 2 3 4 5 6 7
1 2
1 3
2 4
2 5
4 6
6 7
*/