Problem p03575 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
#define all(x) (x).begin(), (x).end()    // 昇順ソート
#define rall(v) (v).rbegin(), (v).rend() // 降順ソート
#define INF 1LL << 60
#define F first
#define S second
#define pll pair<ll, ll>
typedef long long int LL;
typedef long long int ll;
const int MOD = 1000000007;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
// sort(all(x))とするとソートできるよ
//  10^x は pow(10,(x))
//  任意のlogは　対数の底の変換を使う    log(N) / log(任意の底)

// union by size + path having
class UnionFind {
public:
  vector<ll> par; // 各元の親を表す配列
  vector<ll> siz; // 素集合のサイズを表す配列(1 で初期化)

  // Constructor
  UnionFind(ll sz_) : par(sz_), siz(sz_, 1LL) {
    for (ll i = 0; i < sz_; ++i)
      par[i] = i; // 初期では親は自分自身
  }
  void init(ll sz_) {
    par.resize(sz_);
    siz.assign(sz_, 1LL); // resize だとなぜか初期化されなかった
    for (ll i = 0; i < sz_; ++i)
      par[i] = i; // 初期では親は自分自身
  }

  // Member Function
  // Find
  ll root(ll x) { // 根の検索
    while (par[x] != x) {
      x = par[x] = par[par[x]]; // x の親の親を x の親とする
    }
    return x;
  }

  // Union(Unite, Merge)
  bool merge(ll x, ll y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    // merge technique（データ構造をマージするテク．小を大にくっつける）
    if (siz[x] < siz[y])
      swap(x, y);
    siz[x] += siz[y];
    par[y] = x;
    return true;
  }

  bool issame(ll x, ll y) { // 連結判定
    return root(x) == root(y);
  }

  ll size(ll x) { // 素集合のサイズ
    return siz[root(x)];
  }
};

int main() {
  // input
  LL N, M, a, b;
  cin >> N >> M;
  vector<pll> G; // 無向グラフ
  rep(i, M) {
    cin >> a >> b;
    a--, b--;
    G[i].F = a;
    G[i].S = b;
  }

  // calc
  UnionFind uf(N);
  ll res = 0;
  rep(i, M) {
    uf.init(N); // 初期化
    rep(j, M) { // これでuf形成。
      if (i == j)
        continue; // この条件分岐で 特定の辺 の形成をスキップしている。
      uf.merge(G[j].F, G[j].S);
    }
    if (uf.size(0) < N)
      res++; // どこでもいいから集合のサイズをチェックして、一か所でも区切れているときカウント
  }
  cout << res << endl;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
#define all(x) (x).begin(), (x).end()    // 昇順ソート
#define rall(v) (v).rbegin(), (v).rend() // 降順ソート
#define INF 1LL << 60
#define F first
#define S second
#define pll pair<ll, ll>
typedef long long int LL;
typedef long long int ll;
const int MOD = 1000000007;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
// sort(all(x))とするとソートできるよ
//  10^x は pow(10,(x))
//  任意のlogは　対数の底の変換を使う    log(N) / log(任意の底)

// union by size + path having
class UnionFind {
public:
  vector<ll> par; // 各元の親を表す配列
  vector<ll> siz; // 素集合のサイズを表す配列(1 で初期化)

  // Constructor
  UnionFind(ll sz_) : par(sz_), siz(sz_, 1LL) {
    for (ll i = 0; i < sz_; ++i)
      par[i] = i; // 初期では親は自分自身
  }
  void init(ll sz_) {
    par.resize(sz_);
    siz.assign(sz_, 1LL); // resize だとなぜか初期化されなかった
    for (ll i = 0; i < sz_; ++i)
      par[i] = i; // 初期では親は自分自身
  }

  // Member Function
  // Find
  ll root(ll x) { // 根の検索
    while (par[x] != x) {
      x = par[x] = par[par[x]]; // x の親の親を x の親とする
    }
    return x;
  }

  // Union(Unite, Merge)
  bool merge(ll x, ll y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    // merge technique（データ構造をマージするテク．小を大にくっつける）
    if (siz[x] < siz[y])
      swap(x, y);
    siz[x] += siz[y];
    par[y] = x;
    return true;
  }

  bool issame(ll x, ll y) { // 連結判定
    return root(x) == root(y);
  }

  ll size(ll x) { // 素集合のサイズ
    return siz[root(x)];
  }
};

int main() {
  // input
  LL N, M, a, b;
  cin >> N >> M;
  vector<pll> G(M); // 無向グラフ
  rep(i, M) {
    cin >> a >> b;
    a--, b--;
    G[i].F = a;
    G[i].S = b;
  }

  // calc
  UnionFind uf(N);
  ll res = 0;
  rep(i, M) {
    uf.init(N); // 初期化
    rep(j, M) { // これでuf形成。
      if (i == j)
        continue; // この条件分岐で 特定の辺 の形成をスキップしている。
      uf.merge(G[j].F, G[j].S);
    }
    if (uf.size(0) < N)
      res++; // どこでもいいから集合のサイズをチェックして、一か所でも区切れているときカウント
  }
  cout << res << endl;
}