Problem p03100 (C++)

Buggy submission (status: Runtime Error):
#include <stdio.h>
int gcd(int a, int b) {
  if (b == 0) {
    return a;
  }
  return gcd(b, a % b);
}
int a[65536], b[65536], c[65536];
int fa1[1048576], fa2[1048576];
int findroot1(int x) {
  if (fa1[x] == x) {
    return x;
  }
  return fa1[x] = findroot1(fa1[x]);
}
int findroot2(int x) {
  if (fa2[x] == x) {
    return x;
  }
  return fa2[x] = findroot2(fa2[x]);
}
int main() {
  int n, m, q, mod;
  scanf("%d%d%d%d", &n, &m, &q, &mod);
  int g = mod;
  for (int i = 0; i < m; i++) {
    scanf("%d%d%d", &a[i], &b[i], &c[i]);
    if (i) {
      g = gcd(g, c[i] - c[i - 1]);
    }
  }
  mod = gcd(mod, g * 3);
  for (int i = 0; i < m; i++) {
    c[i] %= mod;
  }
  for (int i = 0; i < mod; i++) {
    fa1[i] = i;
  }
  for (int i = 0; i < mod; i++) {
    int x = findroot1(i);
    int y = findroot1(i * 4 % mod);
    fa1[x] = y;
  }
  int dd = mod / g;
  for (int i = 1; i <= n * dd * 2; i++) {
    fa2[i] = i;
  }
  int st = c[0] % g;
  for (int i = 0; i < m; i++) {
    c[i] -= st;
    c[i] /= g;
    for (int j = 0; j < 2; j++) {
      for (int k = 0; k < dd; k++) {
        int x = findroot2(a[i] + j * n + k * n * 2);
        int y = findroot2(b[i] + (j ^ 1) * n + ((k + k + c[i]) % dd) * n * 2);
        fa2[x] = y;
        x = findroot2(b[i] + j * n + k * n * 2);
        y = findroot2(a[i] + (j ^ 1) * n + ((k + k + c[i]) % dd) * n * 2);
        fa2[x] = y;
      }
    }
  }
  while (q--) {
    int s, t, r;
    scanf("%d%d%d", &s, &t, &r);
    r = (r + st) % mod;
    bool ok = false;
    for (int i = 0; i < 2; i++) {
      for (int j = 0; j < dd; j++) {
        if (findroot2(s + i * n + j * n * 2) == findroot2(t)) {
          if (findroot1(((st << i) + j * g) % mod) == findroot1(r)) {
            ok = true;
          }
        }
      }
    }
    if (ok) {
      printf("YES\n");
    } else {
      printf("NO\n");
    }
  }
  return 0;
}

Fixed submission:
#include <stdio.h>
int gcd(int a, int b) {
  if (a < 0) {
    a = -a;
  }
  if (b < 0) {
    b = -b;
  }
  if (b == 0) {
    return a;
  }
  return gcd(b, a % b);
}
int a[65536], b[65536], c[65536];
int fa1[1048576], fa2[1048576];
int findroot1(int x) {
  if (fa1[x] == x) {
    return x;
  }
  return fa1[x] = findroot1(fa1[x]);
}
int findroot2(int x) {
  if (fa2[x] == x) {
    return x;
  }
  return fa2[x] = findroot2(fa2[x]);
}
int main() {
  int n, m, q, mod;
  scanf("%d%d%d%d", &n, &m, &q, &mod);
  int g = mod;
  for (int i = 0; i < m; i++) {
    scanf("%d%d%d", &a[i], &b[i], &c[i]);
    if (i) {
      g = gcd(g, c[i] - c[i - 1]);
    }
  }
  mod = gcd(mod, g * 3);
  for (int i = 0; i < m; i++) {
    c[i] %= mod;
  }
  for (int i = 0; i < mod; i++) {
    fa1[i] = i;
  }
  for (int i = 0; i < mod; i++) {
    int x = findroot1(i);
    int y = findroot1(i * 4 % mod);
    fa1[x] = y;
  }
  int dd = mod / g;
  for (int i = 1; i <= n * dd * 2; i++) {
    fa2[i] = i;
  }
  int st = c[0] % g;
  for (int i = 0; i < m; i++) {
    c[i] -= st;
    c[i] /= g;
    for (int j = 0; j < 2; j++) {
      for (int k = 0; k < dd; k++) {
        int x = findroot2(a[i] + j * n + k * n * 2);
        int y = findroot2(b[i] + (j ^ 1) * n + ((k + k + c[i]) % dd) * n * 2);
        fa2[x] = y;
        x = findroot2(b[i] + j * n + k * n * 2);
        y = findroot2(a[i] + (j ^ 1) * n + ((k + k + c[i]) % dd) * n * 2);
        fa2[x] = y;
      }
    }
  }
  while (q--) {
    int s, t, r;
    scanf("%d%d%d", &s, &t, &r);
    r = (r + st) % mod;
    bool ok = false;
    for (int i = 0; i < 2; i++) {
      for (int j = 0; j < dd; j++) {
        if (findroot2(s + i * n + j * n * 2) == findroot2(t)) {
          if (findroot1(((st << i) + j * g) % mod) == findroot1(r)) {
            ok = true;
          }
        }
      }
    }
    if (ok) {
      printf("YES\n");
    } else {
      printf("NO\n");
    }
  }
  return 0;
}