Problem p03100 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define SZ(x) ((int)x.size())
#define L(i, u) for (register int i = head[u]; i; i = nxt[i])
#define rep(i, a, b) for (register int i = (a); i <= (b); i++)
#define per(i, a, b) for (register int i = (a); i >= (b); i--)
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef pair<int, int> Pii;
typedef vector<int> Vi;
template <class T> inline void read(T &x) {
  x = 0;
  char c = getchar();
  int f = 1;
  while (!isdigit(c)) {
    if (c == '-')
      f = -1;
    c = getchar();
  }
  while (isdigit(c)) {
    x = x * 10 + c - '0';
    c = getchar();
  }
  x *= f;
}
template <class T> inline void umin(T &x, T y) { x = x < y ? x : y; }
template <class T> inline void umax(T &x, T y) { x = x > y ? x : y; }
inline ui R() {
  static ui seed = 416;
  return seed ^= seed >> 5, seed ^= seed << 17, seed ^= seed >> 13;
}
const int N = 300500;
int n, m, q, mo, fa[N], A[N], B[N], C[N], g, z;
bool ok[2][1020000];
int gcd(int a, int b) { return !b ? a : gcd(b, a % b); }
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
void merge(int x, int y) {
  x = find(x);
  y = find(y);
  fa[x] = y;
}
int getid(int x, int p, int q) { // 01 012
  return 6 * (x - 1) + p * 3 + q + 1;
}
int main() {
  read(n);
  read(m);
  read(q);
  read(mo);
  rep(i, 1, m) {
    read(A[i]);
    read(B[i]);
    read(C[i]);
    g = gcd(g, C[i] - C[1]);
  }
  g = gcd(g, mo);
  mo = gcd(3 * g, mo);
  z = C[1] % g;
  rep(i, 1, n * 6) fa[i] = i;
  for (int x = z % mo, cnt = 0; cnt <= mo; cnt++) {
    ok[0][x] = 1;
    x = 2LL * x % mo;
    ok[1][x] = 1;
    x = 2LL * x % mo;
  }
  rep(i, 1, m) {
    int u = A[i], v = B[i], w = (C[i] - z) / g;
    rep(p, 0, 1) rep(q, 0, 2)
        merge(getid(u, p, q), getid(v, p ^ 1, (2 * q + w) % 3));
    swap(u, v);
    rep(p, 0, 1) rep(q, 0, 2)
        merge(getid(u, p, q), getid(v, p ^ 1, (2 * q + w) % 3));
  }
  while (q--) {
    int s, t, r;
    read(s);
    read(t);
    read(r);
    bool res = 0;
    rep(p, 0, 1)
        rep(q, 0, 2) if (find(getid(t, 0, 0)) == find(getid(s, p, q))) {
      res |= ok[p][((r + z - q * g) % mo + mo) % mo];
      //	if(ok[p][((r+z-q*g)%mo+mo)%mo])cerr<<p<<'
      //'<<((r+z-q*g)%mo+mo)%mo<<endl;
    }
    printf("%s\n", res ? "YES" : "NO");
  }
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define SZ(x) ((int)x.size())
#define L(i, u) for (register int i = head[u]; i; i = nxt[i])
#define rep(i, a, b) for (register int i = (a); i <= (b); i++)
#define per(i, a, b) for (register int i = (a); i >= (b); i--)
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef pair<int, int> Pii;
typedef vector<int> Vi;
template <class T> inline void read(T &x) {
  x = 0;
  char c = getchar();
  int f = 1;
  while (!isdigit(c)) {
    if (c == '-')
      f = -1;
    c = getchar();
  }
  while (isdigit(c)) {
    x = x * 10 + c - '0';
    c = getchar();
  }
  x *= f;
}
template <class T> inline void umin(T &x, T y) { x = x < y ? x : y; }
template <class T> inline void umax(T &x, T y) { x = x > y ? x : y; }
inline ui R() {
  static ui seed = 416;
  return seed ^= seed >> 5, seed ^= seed << 17, seed ^= seed >> 13;
}
const int N = 300500;
int n, m, q, mo, fa[N], A[N], B[N], C[N], g, z;
bool ok[2][1020000];
int gcd(int a, int b) { return !b ? a : gcd(b, a % b); }
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
void merge(int x, int y) {
  x = find(x);
  y = find(y);
  fa[x] = y;
}
int getid(int x, int p, int q) { // 01 012
  return 6 * (x - 1) + p * 3 + q + 1;
}
int main() {
  read(n);
  read(m);
  read(q);
  read(mo);
  rep(i, 1, m) {
    read(A[i]);
    read(B[i]);
    read(C[i]);
    g = gcd(g, C[i] - C[1] > 0 ? C[i] - C[1] : -(C[i] - C[1]));
  }
  g = gcd(g, mo);
  mo = gcd(3 * g, mo);
  z = C[1] % g;
  rep(i, 1, n * 6) fa[i] = i;
  for (int x = z % mo, cnt = 0; cnt <= mo; cnt++) {
    ok[0][x] = 1;
    x = 2LL * x % mo;
    ok[1][x] = 1;
    x = 2LL * x % mo;
  }
  rep(i, 1, m) {
    int u = A[i], v = B[i], w = (C[i] - z) / g;
    rep(p, 0, 1) rep(q, 0, 2)
        merge(getid(u, p, q), getid(v, p ^ 1, (2 * q + w) % 3));
    swap(u, v);
    rep(p, 0, 1) rep(q, 0, 2)
        merge(getid(u, p, q), getid(v, p ^ 1, (2 * q + w) % 3));
  }
  while (q--) {
    int s, t, r;
    read(s);
    read(t);
    read(r);
    bool res = 0;
    rep(p, 0, 1)
        rep(q, 0, 2) if (find(getid(t, 0, 0)) == find(getid(s, p, q))) {
      res |= ok[p][((r + z - q * g) % mo + mo) % mo];
      //	if(ok[p][((r+z-q*g)%mo+mo)%mo])cerr<<p<<'
      //'<<((r+z-q*g)%mo+mo)%mo<<endl;
    }
    printf("%s\n", res ? "YES" : "NO");
  }
  return 0;
}