#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define maxn 2000005
#define ll long long
#define ld double
using namespace std;
#define int long long	
int n, m, q; 
int mod;
ll ksm(ll a, ll b)
{
	if(!b) return 1;
	ll ns = ksm(a, b >> 1);
	ns = ns * ns % mod;
	if(b & 1) ns = ns * a % mod;
	return ns;
}
int pw[maxn];
int phi;
int gcd(int a, int b)
{
	if(!b) return a;
	return gcd(b, a % b);
}
struct eg
{
	int u, v, id;
	eg *next;
}p[maxn], *h[maxn];
int egcnt = 0;
void ade(int u, int v, int id)
{
	eg *n1 = &p[egcnt++];
	n1->u = u, n1->v = v, n1->id = id, n1->next = h[u], h[u] = n1;
}
int a[maxn], b[maxn], c[maxn];
struct th
{
	ll a, b;
	th(){a = 0, b = 0;}
	th(ll x, ll y)
	{
		a = x, b = y;
	}
	bool operator < (const th &x)const
	{
		return a < x.a;
	}
	void otp()
	{
		cout<<a<<" "<<b<<endl;
	}
};
th u(th n1, th n2)
{
	return th((n1.a + n2.a) % phi, (n1.b * pw[n2.a] + n2.b) % mod);
}
ll cal(int a, int b)
{
	if(a == 1) return b;
	return (ksm(a, b + 1) - 1) * ksm(a - 1, phi - 1) % mod;
}
th dv(th n1, th n2)
{
	n1.a %= phi, n2.a %= phi;
	if(n1.a > n2.a) return n2;
	int ns = n2.a / n1.a;
	ll mt = pw[n1.a];
	th n3 = th(ns * n1.a, n1.b * cal(mt, ns - 1) % mod);
	th n4 = th(n2.a - n3.a, (n2.b - (pw[n2.a - n3.a]) * n3.b) % mod);
/*	cout<<"DV"<<endl;
	n1.otp();
	n2.otp();
	n4.otp();*/
//	system("pause");
	return n4;
}
th fr[maxn], ed[maxn]; // fr : 1 到 它 
int vis[maxn];
void dfs(int a)
{
//	cout<<a<<endl;
	vis[a] = 1;
	for(eg *p = h[a]; p; p = p->next)
	{
		if(vis[p->v]) continue;
		fr[p->v] = u(fr[a], th(1, c[p->id]));
		ed[p->v] = u(th(1, c[p->id]), ed[a]);
		dfs(p->v);
	}
}
th tr[maxn];
int trcnt = 0;
int fa[maxn];
int gfa(int a)
{
	if(fa[a] == a) return a;
	return fa[a] = gfa(fa[a]);
}
#undef int
int main()
{
	#define int long long
	cin>>n>>m>>q>>mod; 
	for(int i = 1; i <= mod; i++)
		if(gcd(i, mod) == 1) phi++;
	pw[0] = 1;
	for(int i = 1; i < mod; i++)
		pw[i] = pw[i - 1] * 2 % mod;
	for(int i = 1; i <= m; i++)
		a[i] = i, b[i] = i + 1, c[i] = rand(),
		cin>>a[i]>>b[i]>>c[i], 
		ade(a[i], b[i], i), 
		ade(b[i], a[i], i);
	fr[1] = ed[1] = th(0, 0);
	dfs(1);
	for(int i = 1; i <= m; i++)
	{
		th n1 = th(1, c[i]);
		tr[trcnt++] = u(u(fr[a[i]], n1), ed[b[i]]);
		tr[trcnt++] = u(u(fr[b[i]], n1), ed[a[i]]);
	}
//	for(int i = 0; i < trcnt; i++)
//		tr[i].otp();
//	for(int i = 1; i <= n; i++)
//		cout<<"AFFF"<<i<<endl, fr[i].otp(), ed[i].otp();
	while(1)
	{
		int ns = 0;
		int mtt = maxn, pl = 0;
		for(int i = 0; i < trcnt; i++)
			if(tr[i].a) 
			{
				ns++;
				if(tr[i].a < mtt) pl = i, mtt = tr[i].a;
			}
		if(ns <= 1) break;
	//	cout<<ns<<" "<<pl<<" "<<mtt<<endl;
		for(int i = 0; i < trcnt; i++)
			if(i != pl && tr[i].a)
				tr[i] = dv(tr[pl], tr[i]);
	}
	int nv = mod;
	for(int i = 0; i < trcnt; i++)
		if(tr[i].a == 0)
			nv = gcd(nv, tr[i].b % mod + mod);
	for(int i = 0; i < mod; i++)
		fa[i] = i % nv;
	for(int i = 0; i < trcnt; i++)
		if(tr[i].a)
		{
			for(int j = 0; j < mod; j++)
			{
				int ed = (j * pw[tr[i].a] + tr[i].b) % mod;
				if(ed < 0) ed += mod;
				fa[gfa(j)] = gfa(ed);
			}
		}
//	cout<<"ENEDD"<<endl;
//	for(int i = 0; i < trcnt; i++)	
//		tr[i].otp();
	for(int i = 0; i < q; i++)
	{
		int s, t, r;
		cin>>s>>t>>r;
	//	s = rand() % n + 1, t = rand() % n + 1, r = rand() % mod;
		swap(s, t);
		th x1 = ed[s];
		th x2 = fr[t];
		ll nd = (r - x2.b) * ksm(pw[x2.a], phi - 1) % mod;
		if(nd < 0) nd += mod;
		if(x1.b < 0) x1.b += mod;
	//	cout<<"CAL"<<nd<<" "<<x1.b<<endl;
		if(gfa(x1.b) == gfa(nd)) cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	}
	return 0;
} 
/*
50000
49999
1000
1000


*/

Measured memory_bytes: 131968