系统维护没法看前人的经验qwq
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
struct edge{
int next,to;
}a[N<<1];
int cnt,head[N],h[N],p[N][20];//h(ide)是高度,p(arent)是N节点向上2的i次方所得的节点
int n,q;
void add(int u,int v){
a[++cnt].next=head[u];
a[cnt].to=v;
head[u]=cnt;
}
void dfs(int u,int fa){
h[u]=h[fa]+1;//深度+1
p[u][0]=fa;
for(int i=1;(1<<i)<=h[u];++i) p[u][i]=p[p[u][i-1]][i-1];
for(int i=head[u];i;i=a[i].next) if(fa!=a[i].to) dfs(a[i].to,u);
}
int lca(int u,int v){
int d=abs(h[u]-h[v]);
for(int i=0;(1<<i)<=d;++i)
if(d&(1<<i)) u=p[u][i];//调到同一个高度
for(int i=17;i>=0;--i){
if(p[u][i]!=p[v][i])//如果向上跳2的i次方个节点后还不是相同的祖先
u=p[u][i],v=p[v][i];//那就向上跳
}//最后由于2的i次方等于那玩意
return p[u][0];//所以还要向上2的0次方
}
int main(){
scanf("%d%d",&n,&q);
for(int i=1;i<n;++i){
int u,v;
scanf("%d%d",&u,&v);//这道题。。。似乎是无向图
add(u,v);add(v,u);
}
dfs(1,1);
for(int i=1;i<=q;++i){
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
int x=lca(a,b);int y=lca(c,d);//我们可以发现如果路径交叉那么a,b的lca一定交c,d
if(x==y){
printf("Y\n");
continue;
}
if(h[x]>h[y]){//那么一定是x点交在cd路径上
if(lca(c,x)==x||lca(d,x)==x) printf("Y\n");
else printf("N\n");
}
if(h[x]<h[y]){//那么一定是y点交ab路径上
if(lca(c,y)==y||lca(d,y)==y) printf("Y\n");
else printf("N\n");
}
}
return 0;
}