Problem p00909 (C++) — buggy submission, verdict: Runtime Error

#include <cstdio>
#include <iostream>
#include <string>
#include <vector>

using namespace std;
using T = int;

struct WeightedUnionFind {
  vector<int> parent;
  vector<T> weight;
  vector<int> myrank;
  // 親は小さい
  WeightedUnionFind(int n) : parent(n, -1), weight(n, 0), myrank(n, 0) {}
  bool Find(int x, int y) { return find_root(x) == find_root(y); }
  int find_root(int x) {
    if (parent[x] < 0) {
      return x;
    } else {
      int pare = find_root(parent[x]);
      weight[x] += weight[parent[x]];
      return parent[x] = pare;
    }
  }
  T Weight(int x) {
    find_root(x);
    return weight[x];
  }
  // x <= y
  bool Union(int x, int y, int w) {
    w += Weight(x);
    w -= Weight(y);
    x = find_root(x);
    y = find_root(y);

    if (x != y) {
      if (myrank[y] < myrank[x]) {
        swap(x, y);
        w = -w;
      }
      parent[x] += parent[y];
      parent[y] = x;
      weight[y] = w;
      if (myrank[x] == myrank[y])
        myrank[x]++;
      return true;
    } else {
      return false;
    }
  }
  int size(int x) { return -parent[find_root(x)]; }
  T diff(int x, int y) { return Weight(x) - Weight(y); }
};

int main() {
  int N, M;
  int a, b, d;
  // string str;
  char str;
  for (;;) {
    cin >> N >> M;

    if (N == 0)
      break;
    WeightedUnionFind wuf(N);
    for (int i = 0; i < M; i++) {
      cin >> str;
      if (str == '!') {
        cin >> a >> b >> d;
        a--;
        b--;
        wuf.Union(a, b, d);
      } else {
        cin >> a >> b;
        a--;
        b--;
        if (wuf.Find(a, b)) {
          cout << wuf.diff(b, a) << "\\n";
        } else {
          cout << "UNKNOWN"
               << "\\n";
        }
      }
    }
  }
  return 0;
}


Error: 0

Fixed submission:

#include <iostream>
#include <vector>

using namespace std;
using T = int;

struct WeightedUnionFind {
  vector<int> parent;
  vector<T> weight;
  // 親は小さい

  WeightedUnionFind(int n) {
    parent = vector<int>(n, -1);
    weight = vector<T>(n, 0);
  }
  bool Find(int x, int y) { return root(x) == root(y); }
  int root(int x) {
    if (parent[x] < 0) {
      return x;
    } else {
      int pare = root(parent[x]);
      weight[x] += weight[parent[x]];
      return parent[x] = pare;
    }
  }
  T Weight(int x) {
    root(x);
    return weight[x];
  }
  // x <= y
  bool Union(int x, int y, int w) {
    w += Weight(x);
    w -= Weight(y);
    x = root(x);
    y = root(y);

    if (x != y) {
      if (parent[y] < parent[x]) {
        swap(x, y);
        w = -w;
      }
      parent[x] += parent[y];
      parent[y] = x;
      weight[y] = w;
      return true;
    } else {
      return false;
    }
  }
  int size(int x) { return -parent[root(x)]; }
  T diff(int x, int y) { return Weight(x) - Weight(y); }
};

int main() {
  for (;;) {
    int N, M;
    int a, b, d;
    char str;
    cin >> N >> M;
    if (N == 0)
      break;
    WeightedUnionFind wuf(N);
    for (int i = 0; i < M; i++) {
      cin >> str;
      if (str == '!') {
        cin >> a >> b >> d;
        wuf.Union(a, b, d);
      } else {
        cin >> a >> b;
        if (wuf.Find(a, b)) {
          cout << wuf.diff(b, a) << endl;
        } else {
          cout << "UNKNOWN" << endl;
        }
      }
    }
  }
  return 0;
}