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

#include <algorithm>
#include <array>
#include <climits>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <queue>
#include <string>
#include <unordered_map>
#include <vector>

template <typename T> class cUnionFind {
private:
  struct cNode {
    T data;
    size_t parent;
    size_t rank;
    cNode(T data_, size_t parent_, size_t rank_)
        : data(data_), parent(parent_), rank(rank_) {}
  };

private:
  std::vector<cNode> Buf;
  std::unordered_map<T, size_t> Hash;

public:
  cUnionFind() {}

private:
  bool link(T x_, T y_) {
    auto x_itr = Hash.find(x_);
    auto y_itr = Hash.find(y_);

    if (x_itr == Hash.end() || y_itr == Hash.end())
      return true;

    size_t x_index = x_itr->second;
    size_t y_index = y_itr->second;

    if (Buf[x_index].rank > Buf[y_index].rank) {
      Buf[y_index].parent = x_index;
    } else {
      Buf[x_index].parent = y_index;
      if (Buf[x_index].rank == Buf[y_index].rank) {
        ++Buf[y_index].rank;
      }
    }

    return false;
  }
  size_t find_set_helper(size_t index_) {
    if (index_ != Buf[index_].parent) {
      size_t ans_index = find_set_helper(Buf[index_].parent);
      Buf[index_].parent = ans_index;
    }

    return Buf[index_].parent;
  }

public:
  bool make_set(T data_) {
    size_t index = Buf.size();
    Buf.emplace_back(cNode(data_, index, 0));
    auto ans = Hash.insert(std::make_pair(data_, index));
    return !ans.second;
  }
  std::pair<T, bool> find_set(T x_) {
    auto x_itr = Hash.find(x_);
    if (x_itr == Hash.end())
      return std::make_pair(x_, true);

    size_t index = x_itr->second;
    if (Buf[index].parent != index) {
      Buf[index].parent = find_set_helper(Buf[index].parent);
    }

    return std::make_pair(Buf[Buf[index].parent].data, false);
  }
  bool union_set(T x_, T y_) {
    return link(find_set(x_).first, find_set(y_).first);
  }
};

using namespace std;

const double pi = 4 * atan(1.0);

int mod = 1000000007;

int main() {
  int n, q;
  cin >> n >> q;
  cUnionFind<int> UnionFind;
  for (int i = 0; i < n; ++i) {
    UnionFind.make_set(i);
  }

  vector<array<int, 3>> Query(q);
  for (auto &val : Query) {
    int query, x, y;
    cin >> query >> x >> y;
    val = {query, x, y};
  }

  for (const auto &val : Query) {
    int query, x, y;
    query = val[0];
    x = val[1];
    y = val[2];

    if (query == 0) {
      UnionFind.union_set(x, y);
    } else {
      if (UnionFind.find_set(x) == UnionFind.find_set(y)) {
        cout << 1 << endl;
      } else {
        cout << 0 << endl;
      }
    }
  }

  // system("pause");
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <array>
#include <climits>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <queue>
#include <string>
#include <unordered_map>
#include <vector>

template <typename T> class cUnionFind {
private:
  struct cNode {
    T data;
    size_t parent;
    size_t rank;
    cNode(T data_, size_t parent_, size_t rank_)
        : data(data_), parent(parent_), rank(rank_) {}
  };

private:
  std::vector<cNode> Buf;
  std::unordered_map<T, size_t> Hash;

public:
  cUnionFind() {}

private:
  bool link(T x_, T y_) {
    auto x_itr = Hash.find(x_);
    auto y_itr = Hash.find(y_);

    if (x_itr == Hash.end() || y_itr == Hash.end())
      return true;

    size_t x_index = x_itr->second;
    size_t y_index = y_itr->second;

    if (Buf[x_index].rank > Buf[y_index].rank) {
      Buf[y_index].parent = x_index;
    } else {
      Buf[x_index].parent = y_index;
      if (Buf[x_index].rank == Buf[y_index].rank) {
        ++Buf[y_index].rank;
      }
    }

    return false;
  }
  size_t find_set_helper(size_t index_) {
    if (index_ != Buf[index_].parent) {
      size_t ans_index = find_set_helper(index_);
      Buf[index_].parent = ans_index;
    }

    return Buf[index_].parent;
  }

public:
  bool make_set(T data_) {
    size_t index = Buf.size();
    Buf.emplace_back(cNode(data_, index, 0));
    auto ans = Hash.insert(std::make_pair(data_, index));
    return !ans.second;
  }
  std::pair<T, bool> find_set(T x_) {
    auto x_itr = Hash.find(x_);
    if (x_itr == Hash.end())
      return std::make_pair(x_, true);

    size_t index = x_itr->second;
    if (Buf[index].parent != index) {
      Buf[index].parent = find_set_helper(Buf[index].parent);
    }

    return std::make_pair(Buf[Buf[index].parent].data, false);
  }
  bool union_set(T x_, T y_) {
    return link(find_set(x_).first, find_set(y_).first);
  }
};

using namespace std;

const double pi = 4 * atan(1.0);

int mod = 1000000007;

int main() {
  int n, q;
  cin >> n >> q;
  cUnionFind<int> UnionFind;
  for (int i = 0; i < n; ++i) {
    UnionFind.make_set(i);
  }

  for (int i = 0; i < q; ++i) {
    int query, x, y;
    cin >> query >> x >> y;

    if (query == 0) {
      UnionFind.union_set(x, y);
    } else {
      if (UnionFind.find_set(x) == UnionFind.find_set(y)) {
        cout << 1 << endl;
      } else {
        cout << 0 << endl;
      }
    }
  }

  // system("pause");
  return 0;
}