/*
本题利用了容斥原理的性质
*/
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=1e5+10,M=2e5+10;
int d1[N]; //存编号为i的查询中起点之间的最短距离
int d2[N]; //存编号为i的查询中终点之间的最短距离
int d3[N]; //存编号为i的查询中第一组起点和终点之间的 最短距离
int d4[N]; //存编号为i的查询中第二组起点和终点之间的 最短距离
int st[N];
int p[N];
struct Node
{
int id;
int x; //有关系的另外一个点的编号
int f; //属于三个类别中的哪个类别
};
vector<Node> g[N]; //存与每个点相关的要求之间最短距离的另外一个点,以及所在查询的编号
int e[M],ne[M],h[N],idx;
int dis[N];
void add(int a,int b)
{
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
int find(int x)
{
if(x!=p[x]) p[x]=find(p[x]);
return p[x];
}
void dfs(int u,int fa,int distance)
{
dis[u]=distance;
for(int i=h[u];i!=-1;i=ne[i])
{
int j=e[i];
if(j==fa) continue;
dfs(j,u,distance+1);
}
}
void tarjan(int u)
{
st[u]=1;
for(int i=h[u];i!=-1;i=ne[i])
{
int j=e[i];
if(!st[j])
{
tarjan(j);
p[j]=u;
}
}
for(auto it:g[u])
{
int id=it.id;
int j=it.x; //另外一个点
int f=it.f; //类别
int p=find(j);
int res=dis[u]+dis[j]-2*dis[p];
if(f==1)
{
d1[id]=res;
}
else if(f==2)
{
d2[id]=res;
}
else if(f==3)
{
d3[id]=res;
}
else if(f==4)
{
d4[id]=res;
}
}
st[u]=2;
}
int main()
{
int n,q;
scanf("%d%d",&n,&q);
memset(h,-1,sizeof h);
for(int i=0;i<n-1;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
for(int i=1;i<=n;i++)
p[i]=i;
for(int i=1;i<=q;i++)
{
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
g[a].push_back({i,c,1});
g[a].push_back({i,b,3});
g[b].push_back({i,d,2});
g[b].push_back({i,a,3});
g[c].push_back({i,a,1});
g[c].push_back({i,d,4});
g[d].push_back({i,b,2});
g[d].push_back({i,c,4});
}
dfs(1,-1,0); //求所有点到根节点的距离
tarjan(1); //3集合深搜算法
for(int i=1;i<=q;i++)
{
//1.取起点与起点之间的距离
int dis1=d1[i];
//2.取终点与终点之间的距离
int dis2=d2[i];
//3.存起点与终点之间的距离
int dis3=d3[i];
int dis4=d4[i];
if(dis3+dis4>=dis1+dis2)
{
puts("Y");
}
else puts("N");
}
return 0;
}