求调
#include<bits/stdc++.h>
#define int long long
#define Next(i,u)for(int i=head[u];i;i=e[i].nxt)
#define _ 100005
#define ___ 10000005
#define __ 10005
int n,m,head[_],dp[_],tot,size[_],sum,root;
int dis[_],vis[_],pd[___],rev[_],pa[__],q[_],query[__];
using namespace std;
struct node{
int v,nxt,val;
}e[_<<1];
int cnt=0;
void add(int u,int v,int val){
e[++cnt].v=v;
e[cnt].val=val;
e[cnt].nxt=head[u];
head[u]=cnt;
}
void getroot(int u,int fr){
dp[u]=0,size[u]=1;//dp[u]=0算两边,不算自己;
Next(i,u){
int v=e[i].v;
if(v==fr||vis[v])continue;//找了或是父节点则跳过;
getroot(v,u);//继续递归其儿子;
size[u]+=size[v];//加上子树的节点个数;
dp[u]=max(dp[u],size[v]);//比较较多节点的子树(以u为根下);
}
dp[u]=max(dp[u],sum-size[u]);//找两棵子树,求其最大值;
if(dp[u]<dp[root])root=u;//满足其最优,则需满足其两边(任意一边)子节点最少;
}//找重心;
void getdis(int u,int fr){
rev[++tot]=dis[u];//rev记录距离;
Next(i,u){
int v=e[i].v;
if(v==fr||vis[v])continue;//方向,标记;
dis[v]=dis[u]+e[i].val;//根节点u,求v至每个根节点的距离;
getdis(v,u);//向下递归;
}
}
void doit(int u){
int c=0;
Next(i,u){
int v=e[i].v;
if(vis[v])continue;//统计过则过;
tot=0,dis[v]=e[i].val,getdis(v,u);
for(int i=1;i<=tot;i++){
for(int k=1;k<=m;k++){
if(query[k]>=rev[i]){
pa[k]|=pd[query[k]-rev[i]];//按位或(pa 统计答案,query[k]-rev[i]查找有没有距离为(k-rev[i])的);
}
}
}
for(int i=1;i<=tot;i++)q[++c]=rev[i],pd[rev[i]]=1;//记录答案清零为下个点,标记rev;
}
for(int i=1;i<=c;i++)pd[q[i]]=0;//清零;
}
void solve(int u){
vis[u]=pd[0]=1,doit(u);//标记u;
Next(i,u){
int v=e[i].v;
if(vis[v])continue;//标记则跳过;
dp[0]=n,sum=size[v],root=0;//dp[0]=n,root=0(根节点的根节点),sum=size[v](向下递归v时,不包括u自己,size[v]子节点个数,size[v]算v自己);
getroot(v,u),solve(root);//从v开始,所以不加u;
}
}//每次不断找重心,向下递归;
int u,v,w;
signed main(){
cin>>n;
dp[0]=sum=n;
cin>>m;
for(int i=1;i<=n-1;i++)cin>>u>>v>>w,add(u,v,w),add(v,u,w);
for(int i=1;i<=m;i++)cin>>query[i];
getroot(1,0),solve(root);
for(int i=1;i<=m;i++)puts(pa[i]?"AYE":"NAY");
return 0;
}
#7RE