Language: C++

#include <iostream>

# define REP(i,n) for(int i=0; i<n; i++)
# define MAX_N 10005

using namespace std;

int par[MAX_N];
int rank[MAX_N];

void init(int n){
	//cout << "init" << endl;
	REP(i,n){
		par[i] = i;
		rank[i] = 0;
	}
}

int find(int x){
	//cout << "find " << x << endl;
	//printf("find(%d), par[%d] = %d\n", x, x, par[x]);
	if (par[x] == x){
		return x;
	}else{
		par[x] = find(par[x]);
		return par[x];
	}
}

void unite(int x, int y){
	//cout << "unite " << x << " " << y << endl;
	x = find(x);
	y = find(y);
	if (x==y) return;
	//cout << x << " " << y << endl;
	
	if (rank[x]<rank[y]){
		par[x] = y;
	}else{
		par[y] = x;
		if (rank[x]==rank[y]) rank[x]++;
	}
}

bool same(int x, int y){
	//cout << "same" << x << " " << y << endl;
	return (find(x)==find(y));
}

int main(){
	int n, m, p[MAX_N], x[MAX_N], y[MAX_N], ans;
	
	cin >> n >> m;
	for (int i=1; i<=n; i++){
		cin >> p[i];
	}
	REP(i,m){
		cin >> x[i] >> y[i];
	}
	ans = 0;
	
	init(n+1);
	
	REP(i,m){
		unite(p[x[i]], p[y[i]]);
		//cout << same(p[x[i]], p[y[i]]) << endl;
		/*REP(k,n){
			printf("%d par:%d, rank:%d\n", k+1, par[k+1], rank[k+1]);
		}
		printf("find(1) = %d, par[1] = %d\n", find(1), par[1]);*/
	}
	
	for (int i=1; i<=n; i++){
		//cout << same(i,p[i]) << "\n";
		if (same(i,p[i])) ans++;
	}
	
	cout << ans << endl;
  	
  	return 0;
}



Compiler output:
a.cc: In function 'void init(int)':
a.cc:15:17: error: reference to 'rank' is ambiguous
   15 |                 rank[i] = 0;
      |                 ^~~~
In file included from /usr/include/c++/14/bits/move.h:37,
                 from /usr/include/c++/14/bits/exception_ptr.h:41,
                 from /usr/include/c++/14/exception:166,
                 from /usr/include/c++/14/ios:41,
                 from /usr/include/c++/14/ostream:40,
                 from /usr/include/c++/14/iostream:41,
                 from a.cc:1:
/usr/include/c++/14/type_traits:1437:12: note: candidates are: 'template<class> struct std::rank'
 1437 |     struct rank
      |            ^~~~
a.cc:9:5: note:                 'int rank [10005]'
    9 | int rank[MAX_N];
      |     ^~~~
a.cc: In function 'void unite(int, int)':
a.cc:37:13: error: reference to 'rank' is ambiguous
   37 |         if (rank[x]<rank[y]){
      |             ^~~~
/usr/include/c++/14/type_traits:1437:12: note: candidates are: 'template<class> struct std::rank'
 1437 |     struct rank
      |            ^~~~
a.cc:9:5: note:                 'int rank [10005]'
    9 | int rank[MAX_N];
      |     ^~~~
a.cc:37:21: error: reference to 'rank' is ambiguous
   37 |         if (rank[x]<rank[y]){
      |                     ^~~~
/usr/include/c++/14/type_traits:1437:12: note: candidates are: 'template<class> struct std::rank'
 1437 |     struct rank
      |            ^~~~
a.cc:9:5: note:                 'int rank [10005]'
    9 | int rank[MAX_N];
      |     ^~~~
a.cc:41:21: error: reference to 'rank' is ambiguous
   41 |                 if (rank[x]==rank[y]) rank[x]++;
      |                     ^~~~
/usr/include/c++/14/type_traits:1437:12: note: candidates are: 'template<class> struct std::rank'
 1437 |     struct rank
      |            ^~~~
a.cc:9:5: note:                 'int rank [10005]'
    9 | int rank[MAX_N];
      |     ^~~~
a.cc:41:30: error: reference to 'rank' is ambiguous
   41 |                 if (rank[x]==rank[y]) rank[x]++;
      |                              ^~~~
/usr/include/c++/14/type_traits:1437:12: note: candidates are: 'template<class> struct std::rank'
 1437 |     struct rank
      |            ^~~~
a.cc:9:5: note:                 'int rank [10005]'
    9 | int rank[MAX_N];
      |     ^~~~
a.cc:41:39: error: reference to 'rank' is ambiguous
   41 |                 if (rank[x]==rank[y]) rank[x]++;
      |                                       ^~~~
/usr/include/c++/14/type_traits:1437:12: note: candidates are: 'template<class> struct std::rank'
 1437 |     struct rank
      |            ^~~~
a.cc:9:5: note:                 'int rank [10005]'
    9 | int rank[MAX_N];
      |     ^~~~