Problem p03575 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <vector>

using namespace std;
using Int = long long;
Int INF = 1LL << 60;
const Int MOD = 1000000000 + 7;

template <int Modulo = MOD> struct Mint {
  Int val;
  constexpr Mint(Int v = 0) noexcept : val(v % Modulo) {
    if (val < 0)
      v += Modulo;
  }
  constexpr int getmod() { return Modulo; }
  constexpr Mint operator-() const noexcept { return val ? Modulo - val : 0; }
  constexpr Mint operator+(const Mint &r) const noexcept {
    return Mint(*this) += r;
  }
  constexpr Mint operator-(const Mint &r) const noexcept {
    return Mint(*this) -= r;
  }
  constexpr Mint operator*(const Mint &r) const noexcept {
    return Mint(*this) *= r;
  }
  constexpr Mint operator/(const Mint &r) const noexcept {
    return Mint(*this) /= r;
  }
  constexpr Mint &operator+=(const Mint &r) noexcept {
    val += r.val;
    if (val >= Modulo)
      val -= Modulo;
    return *this;
  }
  constexpr Mint &operator-=(const Mint &r) noexcept {
    val -= r.val;
    if (val < 0)
      val += Modulo;
    return *this;
  }
  constexpr Mint &operator*=(const Mint &r) noexcept {
    val = val * r.val % Modulo;
    return *this;
  }
  constexpr Mint &operator/=(const Mint &r) noexcept {
    Int a = r.val, b = Modulo, u = 1, v = 0;
    while (b) {
      Int t = a / b;
      a -= t * b;
      swap(a, b);
      u -= t * v;
      swap(u, v);
    }
    val = val * u % Modulo;
    if (val < 0)
      val += Modulo;
    return *this;
  }
  constexpr bool operator==(const Mint &r) const noexcept {
    return this->val == r.val;
  }
  constexpr bool operator!=(const Mint &r) const noexcept {
    return this->val != r.val;
  }
  friend ostream &operator<<(ostream &os, const Mint<Modulo> &x) noexcept {
    return os << x.val;
  }
  friend istream &operator>>(istream &is, Mint<Modulo> &x) noexcept {
    Int tmp;
    is >> tmp;
    x = Mint<Modulo>(tmp);
    return is;
  }
  friend constexpr Mint<Modulo> modpow(const Mint<Modulo> &a, Int n) noexcept {
    Mint res(1), tmp = a;
    while (n > 0) {
      if (n & 1)
        res *= tmp;
      tmp *= tmp;
      n >>= 1;
    }
    return res;
  }
};

using mint = Mint<>;

class UnionFind {
private:
  vector<Int> data;

public:
  Int root(Int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  UnionFind(Int size) : data(size, -1) {}
  bool same(Int x, Int y) { return root(x) == root(y); }
  Int size(Int x) { return -data[root(x)]; }

  bool unite(Int x, Int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x])
        swap(x, y);
      data[x] += data[y];
      data[y] = x;
      return true;
    } else {
      return false;
    }
  }
};

int main() {

  cin.tie(nullptr);
  ios::sync_with_stdio(false);

  Int N, M;
  cin >> N >> M;

  vector<Int> a(N), b(N);
  for (Int i = 0; i < M; i++) {
    cin >> a[i] >> b[i];
    a[i]--;
    b[i]--;
  }

  Int ans = 0;
  Int temp;
  for (Int i = 0; i < M; i++) { // 組み合わせiを繋げない場合
    UnionFind tree(N);
    for (Int j = 0; j < M; j++) {
      if (i == j)
        continue;
      tree.unite(a[j], b[j]);
    }

    temp = tree.root(0);
    // 根が一個でも異なるとout
    for (Int j = 1; j < N; j++) {
      if (temp != tree.root(j)) {
        ans++;
        break;
      }
    }
  }

  cout << ans << "\n";
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <vector>

using namespace std;
using Int = long long;
Int INF = 1LL << 60;
const Int MOD = 1000000000 + 7;

template <int Modulo = MOD> struct Mint {
  Int val;
  constexpr Mint(Int v = 0) noexcept : val(v % Modulo) {
    if (val < 0)
      v += Modulo;
  }
  constexpr int getmod() { return Modulo; }
  constexpr Mint operator-() const noexcept { return val ? Modulo - val : 0; }
  constexpr Mint operator+(const Mint &r) const noexcept {
    return Mint(*this) += r;
  }
  constexpr Mint operator-(const Mint &r) const noexcept {
    return Mint(*this) -= r;
  }
  constexpr Mint operator*(const Mint &r) const noexcept {
    return Mint(*this) *= r;
  }
  constexpr Mint operator/(const Mint &r) const noexcept {
    return Mint(*this) /= r;
  }
  constexpr Mint &operator+=(const Mint &r) noexcept {
    val += r.val;
    if (val >= Modulo)
      val -= Modulo;
    return *this;
  }
  constexpr Mint &operator-=(const Mint &r) noexcept {
    val -= r.val;
    if (val < 0)
      val += Modulo;
    return *this;
  }
  constexpr Mint &operator*=(const Mint &r) noexcept {
    val = val * r.val % Modulo;
    return *this;
  }
  constexpr Mint &operator/=(const Mint &r) noexcept {
    Int a = r.val, b = Modulo, u = 1, v = 0;
    while (b) {
      Int t = a / b;
      a -= t * b;
      swap(a, b);
      u -= t * v;
      swap(u, v);
    }
    val = val * u % Modulo;
    if (val < 0)
      val += Modulo;
    return *this;
  }
  constexpr bool operator==(const Mint &r) const noexcept {
    return this->val == r.val;
  }
  constexpr bool operator!=(const Mint &r) const noexcept {
    return this->val != r.val;
  }
  friend ostream &operator<<(ostream &os, const Mint<Modulo> &x) noexcept {
    return os << x.val;
  }
  friend istream &operator>>(istream &is, Mint<Modulo> &x) noexcept {
    Int tmp;
    is >> tmp;
    x = Mint<Modulo>(tmp);
    return is;
  }
  friend constexpr Mint<Modulo> modpow(const Mint<Modulo> &a, Int n) noexcept {
    Mint res(1), tmp = a;
    while (n > 0) {
      if (n & 1)
        res *= tmp;
      tmp *= tmp;
      n >>= 1;
    }
    return res;
  }
};

using mint = Mint<>;

class UnionFind {
private:
  vector<Int> data;

public:
  Int root(Int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  UnionFind(Int size) : data(size, -1) {}
  bool same(Int x, Int y) { return root(x) == root(y); }
  Int size(Int x) { return -data[root(x)]; }

  bool unite(Int x, Int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x])
        swap(x, y);
      data[x] += data[y];
      data[y] = x;
      return true;
    } else {
      return false;
    }
  }
};

int main() {

  cin.tie(nullptr);
  ios::sync_with_stdio(false);

  Int N, M;
  cin >> N >> M;

  vector<Int> a(M), b(M);
  for (Int i = 0; i < M; i++) {
    cin >> a[i] >> b[i];
    a[i]--;
    b[i]--;
  }

  Int ans = 0;
  Int temp;
  for (Int i = 0; i < M; i++) { // 組み合わせiを繋げない場合
    UnionFind tree(N);
    for (Int j = 0; j < M; j++) {
      if (i == j)
        continue;
      tree.unite(a[j], b[j]);
    }

    temp = tree.root(0);
    // 根が一個でも異なるとout
    for (Int j = 1; j < N; j++) {
      if (temp != tree.root(j)) {
        ans++;
        break;
      }
    }
  }

  cout << ans << "\n";
}