#include<bits/stdc++.h>
using namespace std;

vector<int> t[100010],v;
pair<int,int> mi[1000101],PO;
int po[11],poo,n,m,q,g,mod,S,T,R,fa[600010],z,col[1000101],Col[2],bel[1000101],len[1000101],Fa[50010];
struct node{int x,y,c;}e[100010];

bool cmp(node a,node b) {return a.c<b.c;}
int nxt(int x) {return (x+x>=g?x+x-g:x+x);}
int gcd(int a,int b) {return (!b)?a:gcd(b,a%b);}
int ask(int x) {return fa[x]==x?x:fa[x]=ask(fa[x]);}
int Ask(int x) {return Fa[x]==x?x:Fa[x]=Ask(Fa[x]);}

bool bfs(int x)
{
	bool Bo=1;
	v.push_back(x);
	for (int i=0,siz=t[x].size(); i<siz; i++)
		if (col[t[x][i]]==-1) 
		{
			col[t[x][i]]=col[x]^1;
			if (!bfs(t[x][i])) Bo=0;
		} else
		if (col[t[x][i]]==col[x]) Bo=0;
	return Bo;
}

void unite(int x,int y)
{
	int p=ask(x),q=ask(y);
	if (p==q) return; 
	fa[p]=q;
}

int main()
{
	scanf("%d%d%d%d",&n,&m,&q,&mod);
	for (int i=1; i<=n; i++) t[i].clear(),Fa[i]=i;
	for (int i=1; i<=m; i++) 
	{
		scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].c),e[i].c%=mod;
		t[e[i].x].push_back(e[i].y),t[e[i].y].push_back(e[i].x);
		Fa[Ask(e[i].x)]=Ask(e[i].y);
	}
	sort(e+1,e+1+m,cmp),g=0;
	for (int i=1; i<m; i++) g=gcd(g,e[i+1].c-e[i].c); 
	g=gcd(g,mod),z=e[1].c%g;
	if (gcd(g*3,mod)==g) 
	{
		memset(col,-1,sizeof(col));
		for (int i=1; i<=n; i++) if (col[i]==-1)
		{
			v.clear();
			if (bfs(col[i]=1))
			{
				for (int i:v) Col[col[i]]=i;
				for (int i:v)
				{
					if (col[i]) swap(Col[0],Col[1]);
					fa[(i-1)*6+1]=fa[(i-1)*6+2]=fa[(i-1)*6+3]=(Col[0]-1)*6+1;
					fa[(i-1)*6+4]=fa[(i-1)*6+5]=fa[(i-1)*6+6]=(Col[1]-1)*6+1;
					if (col[i]) swap(Col[0],Col[1]);
				}
			} else for (int i:v) for (int j=1; j<=6; j++) fa[(i-1)*6+j]=1;
		}
	}
	else
	{
		for (int i=1; i<=6*n; i++) fa[i]=i;
		for (int i=1; i<=m; i++) e[i].c=(e[i].c%(3*g))/g;
		for (int i=1; i<=m; i++) 
			for (int j=0; j<3; j++)
			{
				int k=(j*2+e[i].c)%3;
				unite((e[i].x-1)*6+j+1,(e[i].y-1)*6+k+4);
				unite((e[i].x-1)*6+j+4,(e[i].y-1)*6+k+1);
				unite((e[i].y-1)*6+j+1,(e[i].x-1)*6+k+4);
				unite((e[i].y-1)*6+j+4,(e[i].x-1)*6+k+1);
			}
	}
	memset(col,-1,sizeof(col));
	for (int i=0,nw; i<g; i++)
		if (col[i]==-1)
		{
			nw=i,len[nw]=1,bel[nw]=nw,col[nw]=0,nw=nxt(nw);
			while (nw!=i) bel[nw]=i,col[nw]=len[i],len[i]++,nw=nxt(nw);
		}
	mi[0]=(g==1?make_pair(1,0):make_pair(0,1));
	for (int i=1; i<=g; i++)
	{
		mi[i].second=nxt(mi[i-1].second);
		mi[i].first=(mi[i-1].first+mi[i-1].first)%3;
		if (mi[i].second&1) mi[i].first=(mi[i].first+1)%3;
	}
	while (q--)
	{
		scanf("%d%d%d",&S,&T,&R),R=(R+z)%(3*g),poo=R/g,R%=g;
		if (bel[R]!=bel[z]||Ask(S)!=Ask(T)) {puts("NO"); continue;}
		PO=mi[(col[z]<=col[R]?col[R]-col[z]:col[R]+len[bel[z]]-col[z])];
		PO.first*=z,PO.first+=(1ll*PO.second*z/g),PO.first%=3,PO.second=1ll*PO.second*z%g;
		po[0]=(poo-PO.first+3)%3; 
		for (int i=1; i<10; i++) 
		{
			PO.first=(1ll*PO.first*g%3*mi[len[bel[z]]].first+1ll*PO.first*mi[len[bel[z]]].second+1ll*PO.second*mi[len[bel[z]]].first+1ll*PO.second*mi[len[bel[z]]].second/g)%3;
			PO.second=1ll*mi[len[bel[z]]].second*PO.second%g;
			po[i]=(poo-PO.first+3)%3;
		}
		bool bo=0;
		if (len[bel[z]]&1)
		{
			int x=6*(T-1)+1;
			for (int y=0; y<6; y++)
				if (ask(x)==ask(6*(S-1)+y+1))
				{
					if ((y<3)^((col[R]&1)==(col[z]&1))^(col[R]<col[z])) bo|=(y%3==po[1]||y%3==po[3]||y%3==po[5]||y%3==po[7]||y%3==po[9]);
					else bo|=(y%3==po[0]||y%3==po[2]||y%3==po[4]||y%3==po[6]||y%3==po[8]);
				}
		} else
		{
			int x=6*(T-1)+1;
			for (int y=0; y<6; y++)
				if (ask(x)==ask(6*(S-1)+y+1))
					if ((y<3)==((col[R]&1)==(col[z]&1))) 
						bo|=(y%3==po[0]||y%3==po[1]||y%3==po[2]||y%3==po[3]||y%3==po[4]||y%3==po[5]||y%3==po[6]||y%3==po[7]||y%3==po[8]||y%3==po[9]);
		}
		puts(bo?"YES":"NO");
	}
	return 0;
} 

Measured memory_bytes: 24960