Problem p02573 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
const ll llINF = 1LL << 60;
const int iINF = 1e9;

//---Union Find---
struct UnionFind {
  // グループのサイズ、要素の親idx、要素から親までのランクの配列
  vector<int> gsize, parent, rank;

  // コンストラクタ　各配列を初期化
  UnionFind(int N) {
    gsize = vector<int>(N, 1);
    parent = vector<int>(N, -1);
    rank = vector<int>(N);
  }

  // 親を求める
  int findparent(int x) {
    if (parent[x] < 0)
      return x;
    else
      return parent[x] = findparent(parent[x]); // rankが小さくなるよう親を再設定
  }

  // 2要素x,yの属するグループを合併
  bool unite(int x, int y) {
    x = findparent(x);
    y = findparent(y);
    if (x == y)
      return false;

    if (rank[x] < rank[y])
      swap(x, y);
    parent[y] = x;
    gsize[x] += gsize[y];
    gsize[y] = 0;
    if (rank[x] == rank[y])
      rank[x]++;
  }

  // 2要素x,yが同じ集合に属するかどうか
  bool same(int x, int y) { return findparent(x) == findparent(y); }
};

//---main---------------------------------------------
int main() {
  // main
  int N, M;
  cin >> N >> M;

  UnionFind UF(N);

  int Ai, Bi;
  rep(mi, M) {
    cin >> Ai >> Bi;
    Ai--;
    Bi--;
    UF.unite(Ai, Bi);
  }

  int ans = 0;
  for (int gs : UF.gsize)
    chmax(ans, gs);

  // rep(i,N) cout << UF.gsize[i] << " " << UF.parent[i] << " " << UF.rank[i] <<
  // endl;

  cout << ans << endl;

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
const ll llINF = 1LL << 60;
const int iINF = 1e9;

//---Union Find---
struct UnionFind {
  // グループのサイズ、要素の親idx、要素から親までのランクの配列
  vector<int> gsize, parent, rank;

  // コンストラクタ　各配列を初期化
  UnionFind(int N) {
    gsize = vector<int>(N, 1);
    parent = vector<int>(N, -1);
    rank = vector<int>(N);
  }

  // 親を求める
  int findparent(int x) {
    if (parent[x] < 0)
      return x;
    else
      return parent[x] = findparent(parent[x]); // rankが小さくなるよう親を再設定
  }

  // 2要素x,yの属するグループを合併
  bool unite(int x, int y) {
    x = findparent(x);
    y = findparent(y);
    if (x == y)
      return false;

    if (rank[x] < rank[y])
      swap(x, y);
    parent[y] = x;
    gsize[x] += gsize[y];
    gsize[y] = 0;
    if (rank[x] == rank[y])
      rank[x]++;
    return true;
  }

  // 2要素x,yが同じ集合に属するかどうか
  bool same(int x, int y) { return findparent(x) == findparent(y); }
};

//---main---------------------------------------------
int main() {
  // main
  int N, M;
  cin >> N >> M;

  UnionFind UF(N);

  int Ai, Bi;
  rep(mi, M) {
    cin >> Ai >> Bi;
    Ai--;
    Bi--;
    UF.unite(Ai, Bi);
  }

  int ans = 0;
  for (int gs : UF.gsize)
    chmax(ans, gs);

  // rep(i,N) cout << UF.gsize[i] << " " << UF.parent[i] << " " << UF.rank[i] <<
  // endl;

  cout << ans << endl;

  return 0;
}