Problem p03100 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
using namespace std;
int n, m, Q, Mod, T, UF[301000], Z[50100];
struct point {
  int a, b, c;
} w[101000];
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
int Find(int a) {
  if (a == UF[a])
    return a;
  return UF[a] = Find(UF[a]);
}
void Merge(int a, int b) {
  a = Find(a), b = Find(b);
  if (a != b)
    UF[a] = b;
}
int main() {
  int i, a, b, c, j, k;
  scanf("%d%d%d%d", &n, &m, &Q, &Mod);
  T = Mod;
  for (i = 0; i < m; i++) {
    scanf("%d%d%d", &w[i].a, &w[i].b, &w[i].c);
    w[i].a--, w[i].b--;
    w[m + i] = w[i];
    swap(w[m + i].a, w[m + i].b);
    if (i)
      T = gcd(T, abs(w[i].c - w[i - 1].c));
  }
  m *= 2;
  Mod = gcd(Mod, 3 * T);

  int A = Mod / T;
  int rr = w[0].c % T;
  for (i = 0; i < m; i++) {
    w[i].c -= rr;
  }
  for (i = 0; i < (A * 2) * n; i++)
    UF[i] = i;
  for (i = 0; i < m; i++) {
    a = w[i].a, b = w[i].b, c = (w[i].c % Mod) / T;
    for (j = 0; j < A; j++) {
      Merge(a * (A * 2) + j, b * (A * 2) + A + (2 * j + c) % A);
      Merge(a * (A * 2) + A + j, b * (A * 2) + (2 * j + c) % A);
    }
  }
  int cnt = 0;
  for (i = 0; i < Mod; i++) {
    if (Z[i])
      continue;
    cnt++;
    int x = i;
    while (!Z[x]) {
      Z[x] = cnt;
      x = x * 4 % Mod;
    }
  }
  while (Q--) {
    scanf("%d%d%d", &a, &b, &c);
    a--, b--;
    for (j = 0; j < (A * 2); j++) {
      if (Find(b * (A * 2)) == Find(a * (A * 2) + j)) {
        int t = (rr * (j / A + 1) + (j % A) * T) % Mod;
        if (Z[t] == Z[(c + rr) % Mod]) {
          puts("YES");
          break;
        }
      }
    }
    if (j == (A * 2))
      puts("NO");
  }
}

Fixed submission:
#include <algorithm>
#include <cstdio>
using namespace std;
int n, m, Q, Mod, T, UF[6001000], Z[1000100];
struct point {
  int a, b, c;
} w[101000];
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
int Find(int a) {
  if (a == UF[a])
    return a;
  return UF[a] = Find(UF[a]);
}
void Merge(int a, int b) {
  a = Find(a), b = Find(b);
  if (a != b)
    UF[a] = b;
}
int main() {
  int i, a, b, c, j, k;
  scanf("%d%d%d%d", &n, &m, &Q, &Mod);
  T = Mod;
  for (i = 0; i < m; i++) {
    scanf("%d%d%d", &w[i].a, &w[i].b, &w[i].c);
    w[i].a--, w[i].b--;
    w[m + i] = w[i];
    swap(w[m + i].a, w[m + i].b);
    if (i)
      T = gcd(T, abs(w[i].c - w[i - 1].c));
  }
  m *= 2;
  Mod = gcd(Mod, 3 * T);

  int A = Mod / T;
  int rr = w[0].c % T;
  for (i = 0; i < m; i++) {
    w[i].c -= rr;
  }
  for (i = 0; i < (A * 2) * n; i++)
    UF[i] = i;
  for (i = 0; i < m; i++) {
    a = w[i].a, b = w[i].b, c = (w[i].c % Mod) / T;
    for (j = 0; j < A; j++) {
      Merge(a * (A * 2) + j, b * (A * 2) + A + (2 * j + c) % A);
      Merge(a * (A * 2) + A + j, b * (A * 2) + (2 * j + c) % A);
    }
  }
  int cnt = 0;
  for (i = 0; i < Mod; i++) {
    if (Z[i])
      continue;
    cnt++;
    int x = i;
    while (!Z[x]) {
      Z[x] = cnt;
      x = x * 4 % Mod;
    }
  }
  while (Q--) {
    scanf("%d%d%d", &a, &b, &c);
    a--, b--;
    for (j = 0; j < (A * 2); j++) {
      if (Find(b * (A * 2)) == Find(a * (A * 2) + j)) {
        int t = (rr * (j / A + 1) + (j % A) * T) % Mod;
        if (Z[t] == Z[(c + rr) % Mod]) {
          puts("YES");
          break;
        }
      }
    }
    if (j == (A * 2))
      puts("NO");
  }
}