using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 50010
int gcd(int a,int b){
	while (b){
		int k=a%b;
		a=b,b=k;
	}
	return a;
}
int n,m,p;
struct EDGE{
	int to,c;
	EDGE *las;
} e[N*2];
int ne;
EDGE *last[N];
void link(int u,int v,int c){
	e[ne]=(EDGE){v,c,last[u]};
	last[u]=e+ne++;
}
int g,d,z;
int pz[2][1000010];
struct Dsu{
	Dsu *p;
	Dsu *getfa(){return p==this?p:p=p->getfa();}
} *f[N][2][3];
bool check(int S,int T,int R){
	for (int j=0;j<2;++j)
		for (int k=0;k<3;++k){
			int t=((z+R-k*g)%d+d)%d;
			if (pz[j][t] && f[T][0][0]->getfa()==f[S][j][k]->getfa())
				return 1;			
		}
	return 0;
}
int main(){
	int Q;
	scanf("%d%d%d%d",&n,&m,&Q,&p);
	for (int i=1;i<=m;++i){
		int u,v,c;
		scanf("%d%d%d",&u,&v,&c);
		link(u,v,c),link(v,u,c);
	}
	g=p;
	for (int i=1;i<=n;++i){
		int c1=last[i]->c;
		for (EDGE *ei=last[i]->las;ei;ei=ei->las)
			g=gcd(g,gcd((c1-ei->c+p)%p,(ei->c-c1+p)%p));
	}
	d=gcd(3*g,p);
	z=last[1]->c%g;
	for (int i=1;i<=n;++i)
		for (EDGE *ei=last[i]->las;ei;ei=ei->las)
			ei->c-=z;
	for (int i=1;i<=n;++i)
		for (int j=0;j<2;++j)
			for (int k=0;k<3;++k){
				f[i][j][k]=new Dsu;
				f[i][j][k]->p=f[i][j][k];
			}
	pz[0][z]=1;
	pz[1][z*2%d]=1;
	if (z){
		for (int x=z*4%d;x!=z;x=x*4%d)
			pz[0][x]=1;
		for (int x=z*8%d;x!=z*2%d;x=x*4%d)
			pz[1][x]=1;
	}
	for (int i=1;i<=n;++i)
		for (int j=0;j<2;++j)
			for (int k=0;k<3;++k)
				for (EDGE *ei=last[i];ei;ei=ei->las){
					int j_=(j+1)%2,k_=(k*2+ei->c/g)%(d/g);
					f[ei->to][j_][k_]->getfa()->p=f[i][j][k]->getfa();
				}
	while (Q--){
		int S,T,R;
		scanf("%d%d%d",&S,&T,&R);
		if (check(S,T,R))
			printf("YES\n");
		else
			printf("NO\n");
	}
	return 0;
}
















