Problem p03450 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

typedef long long lint;
typedef unsigned long long ulint;
const int MOD = 1000000007;

template <unsigned long long SIZE> class unionFind {
protected:
  long long uni[SIZE];
  long long diff_weight[SIZE];

public:
  unionFind() {
    for (int i = 0; i < SIZE; i++) {
      uni[i] = -1;
      diff_weight[i] = 0;
    }
  }
  unsigned long long root(unsigned long long a) {
    if (a >= SIZE)
      throw std::range_error(
          "The given index is larger than the size of the tree.");
    if (uni[a] < 0)
      return a;
    else {
      unsigned long long r = root(uni[a]);
      diff_weight[a] += diff_weight[uni[a]];
      return uni[a] = r;
    }
  }
  long long weight(unsigned long long a) {
    root(a);
    return diff_weight[a];
  }
  long long diff(unsigned long long a, unsigned long long b) {
    if (isSame(a, b))
      return weight(b) - weight(a);
    else
      return INT64_MAX;
  }
  unsigned long long count(unsigned long long a) { return -uni[root(a)]; }
  bool merge(unsigned long long a, unsigned long long b, long long w = 1) {
    w += weight(a);
    w -= weight(b);
    a = root(a);
    b = root(b);
    if (a == b)
      return false;
    if (uni[a] > uni[b]) {
      swap(a, b);
      w = (-w);
    }
    uni[a] += uni[b];
    uni[b] = a;
    diff_weight[b] = w;
    return true;
  }
  bool isSame(unsigned long long a, unsigned long long b) {
    return root(a) == root(b);
  }
};

int main() {
  int N, M;
  cin >> N >> M;
  unionFind<100000> uf;
  for (int i = 0; i < M; i++) {
    int L, R, D;
    cin >> L >> R >> D;
    if (uf.isSame(L, R)) {
      if (uf.diff(L, R) != D) {
        cout << "No" << endl;
        return 0;
      }
    } else
      uf.merge(L, R, D);
  }
  cout << "Yes" << endl;

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

typedef long long lint;
typedef unsigned long long ulint;
const int MOD = 1000000007;

template <unsigned long long SIZE> class unionFind {
protected:
  long long uni[SIZE];
  long long diff_weight[SIZE];

public:
  unionFind() {
    for (int i = 0; i < SIZE; i++) {
      uni[i] = -1;
      diff_weight[i] = 0;
    }
  }
  unsigned long long root(unsigned long long a) {
    if (a >= SIZE)
      throw std::range_error(
          "The given index is larger than the size of the tree.");
    if (uni[a] < 0)
      return a;
    else {
      unsigned long long r = root(uni[a]);
      diff_weight[a] += diff_weight[uni[a]];
      return uni[a] = r;
    }
  }
  long long weight(unsigned long long a) {
    root(a);
    return diff_weight[a];
  }
  long long diff(unsigned long long a, unsigned long long b) {
    if (isSame(a, b))
      return weight(b) - weight(a);
    else
      return INT64_MAX;
  }
  unsigned long long count(unsigned long long a) { return -uni[root(a)]; }
  bool merge(unsigned long long a, unsigned long long b, long long w = 1) {
    w += weight(a);
    w -= weight(b);
    a = root(a);
    b = root(b);
    if (a == b)
      return false;
    if (uni[a] > uni[b]) {
      swap(a, b);
      w = (-w);
    }
    uni[a] += uni[b];
    uni[b] = a;
    diff_weight[b] = w;
    return true;
  }
  bool isSame(unsigned long long a, unsigned long long b) {
    return root(a) == root(b);
  }
};

int main() {
  int N, M;
  cin >> N >> M;
  unionFind<100001> uf;
  for (int i = 0; i < M; i++) {
    int L, R, D;
    cin >> L >> R >> D;
    if (uf.isSame(L, R)) {
      if (uf.diff(L, R) != D) {
        cout << "No" << endl;
        return 0;
      }
    } else
      uf.merge(L, R, D);
  }
  cout << "Yes" << endl;

  return 0;
}