Problem p03356 (C++)

Buggy submission (status: Runtime Error):
using namespace std;
#include <bits/stdc++.h>
#define rep(i, n) for (auto i = 0; i < (n); i++)
#define repd(i, n) for (auto i = (n)-1; i >= 0; i--)
#define repf(i, a, b) for (auto i = (a); i <= (b); i++)
#define repe(i, l) for (auto i : l)
#define mem(x, val) memset((x), (val), sizeof(x));
#define rite(x) freopen(x, "w+", stdout);
#define read(x) freopen(x, "rt", stdin);
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define sz(x) ((int)x.size())
#define sqr(x) ((x) * (x))
#define pb push_back
#define clr clear()
#define INF ((int)0x3f3f3f3f)
#define ins insert
#define xx first
#define yy second
#define eps 1e-9
#define endl '\n'
#define _                                                                      \
  ios_base::sync_with_stdio(false);                                            \
  cin.tie(nullptr);                                                            \
  cout.precision(10);                                                          \
  cout << fixed;
template <class T> T abs(T x) { return x > 0 ? x : -x; }
template <class T> T mini(T x, T y) { return x < y ? x : y; }
template <class T> T maxi(T x, T y) { return x < y ? y : x; }
template <class T> T gcd(T a, T b) { return a % b ? gcd(b, a % b) : b; }
typedef long long i64;
typedef unsigned long long ui64;
typedef string st;
typedef vector<int> vi;
typedef vector<vi> vii;
typedef vector<st> vs;
typedef map<int, int> mii;
typedef map<st, int> msi;
typedef set<int> si;
typedef set<st> ss;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef long long ll;
typedef unsigned long long ull;

#define MOD ((int)1e9 + 7)
#define MAX 1000007

class UnionFind { // Funciona indexando desde 1..N
private:
  vi p, rank, setSize; // remember: vi is vector<int>
  int numSets;

public:
  UnionFind(int N) {

    setSize.assign(N, 1);
    numSets = N;
    rank.assign(N, 0);
    p.assign(N, 0);
    for (int i = 0; i < N; i++)
      p[i] = i;
  }
  int findSet(int i) { return (p[i] == i) ? i : (p[i] = findSet(p[i])); }
  bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
  void unionSet(int i, int j) {
    if (!isSameSet(i, j)) {
      numSets--;
      int x = findSet(i), y = findSet(j);
      // rank is used to keep the tree short
      if (rank[x] > rank[y]) {
        p[y] = x;
        setSize[x] += setSize[y];
      } else {
        p[x] = y;
        setSize[y] += setSize[x];
        if (rank[x] == rank[y])
          rank[y]++;
      }
    }
  }
  int numDisjointSets() { return numSets; }
  int sizeOfSet(int i) { return setSize[findSet(i)]; }
};

int main() {
  _
// Solution
#ifdef LOCAL
      read("arc097_b.in");
  // rite("arc097_b.out");
#endif
  int n, m;
  cin >> n >> m;

  int arr[n];
  rep(i, n) cin >> arr[i];

  UnionFind UF(n);
  int cnt = 0;
  rep(i, m) {
    int x, y;
    cin >> x >> y;
    UF.unionSet(x, y);
  }

  rep(i, n) { cnt += (UF.isSameSet(i + 1, arr[i]) || i + 1 == arr[i]); }

  cout << cnt << endl;

#ifdef LOCAL
  // cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << endl;
#endif

  return 0;
}

/*

        g++-6 -std=c++11 arc097_b.cpp -o arc097_b -DLOCAL && ./arc097_b


*/


Fixed submission:
using namespace std;
#include <bits/stdc++.h>
#define rep(i, n) for (auto i = 0; i < (n); i++)
#define repd(i, n) for (auto i = (n)-1; i >= 0; i--)
#define repf(i, a, b) for (auto i = (a); i <= (b); i++)
#define repe(i, l) for (auto i : l)
#define mem(x, val) memset((x), (val), sizeof(x));
#define rite(x) freopen(x, "w+", stdout);
#define read(x) freopen(x, "rt", stdin);
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define sz(x) ((int)x.size())
#define sqr(x) ((x) * (x))
#define pb push_back
#define clr clear()
#define INF ((int)0x3f3f3f3f)
#define ins insert
#define xx first
#define yy second
#define eps 1e-9
#define endl '\n'
#define _                                                                      \
  ios_base::sync_with_stdio(false);                                            \
  cin.tie(nullptr);                                                            \
  cout.precision(10);                                                          \
  cout << fixed;
template <class T> T abs(T x) { return x > 0 ? x : -x; }
template <class T> T mini(T x, T y) { return x < y ? x : y; }
template <class T> T maxi(T x, T y) { return x < y ? y : x; }
template <class T> T gcd(T a, T b) { return a % b ? gcd(b, a % b) : b; }
typedef long long i64;
typedef unsigned long long ui64;
typedef string st;
typedef vector<int> vi;
typedef vector<vi> vii;
typedef vector<st> vs;
typedef map<int, int> mii;
typedef map<st, int> msi;
typedef set<int> si;
typedef set<st> ss;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef long long ll;
typedef unsigned long long ull;

#define MOD ((int)1e9 + 7)
#define MAX 1000007

class UnionFind { // Funciona indexando desde 1..N
private:
  vi p, rank, setSize; // remember: vi is vector<int>
  int numSets;

public:
  UnionFind(int N) {

    setSize.assign(N, 1);
    numSets = N;
    rank.assign(N, 0);
    p.assign(N, 0);
    for (int i = 0; i < N; i++)
      p[i] = i;
  }
  int findSet(int i) { return (p[i] == i) ? i : (p[i] = findSet(p[i])); }
  bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
  void unionSet(int i, int j) {
    if (!isSameSet(i, j)) {
      numSets--;
      int x = findSet(i), y = findSet(j);
      // rank is used to keep the tree short
      if (rank[x] > rank[y]) {
        p[y] = x;
        setSize[x] += setSize[y];
      } else {
        p[x] = y;
        setSize[y] += setSize[x];
        if (rank[x] == rank[y])
          rank[y]++;
      }
    }
  }
  int numDisjointSets() { return numSets; }
  int sizeOfSet(int i) { return setSize[findSet(i)]; }
};

int main() {
  _
// Solution
#ifdef LOCAL
      read("arc097_b.in");
  // rite("arc097_b.out");
#endif
  int n, m;
  cin >> n >> m;

  int arr[n];
  rep(i, n) cin >> arr[i];

  UnionFind UF(n + 7);
  int cnt = 0;
  rep(i, m) {
    int x, y;
    cin >> x >> y;
    UF.unionSet(x, y);
  }

  rep(i, n) { cnt += (UF.isSameSet(i + 1, arr[i]) || i + 1 == arr[i]); }

  cout << cnt << endl;

#ifdef LOCAL
  // cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << endl;
#endif

  return 0;
}

/*

        g++-6 -std=c++11 arc097_b.cpp -o arc097_b -DLOCAL && ./arc097_b


*/