/*点分治模板,思路:
两个点的路径(可能不是最短的),必定能经过两点所在子树的根
于是我们枚举子树,并求出重心,以重心为根(优化)
用d[u]表示u点到子树根(root)的距离,ans[u]表示距离为u的两个点有多少组
则d[i]+d[j]表示i到j的距离(经过root,可能不是最短)
所以++ans[d[i]+d[j]]
但是,d[i]+d[j]不一定是i到j的最短路长度
d[i]+d[j]-i到j的距离=root到lca(i,j)*2
所以--ans[d[i]+d[j]-w](具体见代码)
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 10010
#include<vector>
#define M 10000001
using
namespace
std;
int
n,dis[N],mn,size[N],root,ans[M],cnt,m,d[N],f[N];
vector<
int
> son[N],t[N];
void
getroot(
int
u,
int
fa){ //求重心,与黑手党类似
++size[u];
int
mx=0;
for
(
int
i=0;i<son[u].size();++i){
int
v=son[u][i],w=t[u][i];
if
(v!=fa&&!f[v]){
getroot(v,u);
size[u]+=size[v];
mx=max(mx,size[v]);
}
}
mx=max(mx,n-size[u]);
if
(mx<mn){
mn=mx;
root=u;
}
}
void
getdeep(
int
u,
int
fa,
int
len){ //求深度
d[++cnt]=len;
for
(
int
i=0;i<son[u].size();++i){
int
v=son[u][i],w=t[u][i];
if
(v!=fa&&!f[v]){
getdeep(v,u,w+len);
}
}
}
void
getans(
int
u,
int
v){ //核心思路
cnt=0;
getdeep(u,-1,0);
for
(
int
i=1;i<=cnt;++i){
for
(
int
j=1;j<=cnt;++j){
int
w=d[i]+d[j];
if
(v==-1&&w<M)++ans[w];
if
(v!=-1&&w+v<M)--ans[w+v];
}
}
}
void
work(
int
u){ //分治
getans(u,-1);
f[u]=1;
for
(
int
i=0;i<son[u].size();++i){
int
v=son[u][i],w=t[u][i];
if
(!f[v]){
getans(v,w*2);
mn=0x7fffffff;
n=size[v];
getroot(v,u);
work(root);
}
}
}
int
main(){
scanf
(
"%d%d"
,&n,&m);
for
(
int
i=1;i<n;++i){
int
u,v,w;
scanf
(
"%d%d%d"
,&u,&v,&w);
son[u].push_back(v);
t[u].push_back(w);
son[v].push_back(u);
t[v].push_back(w);
}
mn=0x7fffffff;
getroot(1,-1); //求重心
work(root);
for
(
int
i=1;i<=m;++i){
int
k;
scanf
(
"%d"
,&k);
if
(ans[k])
printf
(
"AYE\n"
);
else
printf
(
"NAY\n"
);
}
}
//大概就是这样吧,反正我就是这样跟wxk讲的