human
Solve in Python:
We have a permutation of the integers from 1 through N, p_1, p_2, .., p_N.
We also have M pairs of two integers between 1 and N (inclusive), represented as (x_1,y_1), (x_2,y_2), .., (x_M,y_M).
AtCoDeer the deer is going to perform the following operation on p as many times as desired so that the number of i (1 ≤ i ≤ N) such that p_i = i is maximized:
 - Choose j such that 1 ≤ j ≤ M, and swap p_{x_j} and p_{y_j}.
Find the maximum possible number of i such that p_i = i after operations.

-----Constraints-----
 - 2 ≤ N ≤ 10^5
 - 1 ≤ M ≤ 10^5
 - p is a permutation of integers from 1 through N.
 - 1 ≤ x_j,y_j ≤ N
 - x_j ≠ y_j
 - If i ≠ j, \{x_i,y_i\} ≠ \{x_j,y_j\}.
 - All values in input are integers.

-----Input-----
Input is given from Standard Input in the following format:
N M
p_1 p_2 .. p_N
x_1 y_1
x_2 y_2
:
x_M y_M

-----Output-----
Print the maximum possible number of i such that p_i = i after operations.

-----Sample Input-----
5 2
5 3 1 4 2
1 3
5 4

-----Sample Output-----
2

If we perform the operation by choosing j=1, p becomes 1 3 5 4 2, which is optimal, so the answer is 2.
 Write me a Python code to find the maximum possible number of i such that p_i = i after operations?
assistant
#Here is Python code to find the maximum possible number of i such that p_i = i after operations.

import math,itertools,fractions,heapq,collections,bisect,sys,queue,copy

sys.setrecursionlimit(10**7)
inf=10**20
mod=10**9+7
dd=[(-1,0),(0,1),(1,0),(0,-1)]
ddn=[(-1,0),(-1,1),(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1)]

def LI(): return [int(x) for x in sys.stdin.readline().split()]
# def LF(): return [float(x) for x in sys.stdin.readline().split()]
def I(): return int(sys.stdin.readline())
def F(): return float(sys.stdin.readline())
def LS(): return sys.stdin.readline().split()
def S(): return input()

# Union-Find -- START --
class UnionFind():
  def __init__(self,sz):
    self.sz=sz
    self.data=[-1]*sz
    self.amount=[0]*sz

  def unite(self,x,y):
    x=self.find(x)
    y=self.find(y)
    if x==y:
      return False
    self.amount[x]+=self.amount[y]
    self.amount[y]+=self.amount[x]
    if self.data[x]>self.data[y]:
      x,y=y,x
    self.data[x]+=self.data[y]
    self.data[y]=x
    return True

  def find(self,k):
    if self.data[k]<0:
      return k
    self.data[k]=self.find(self.data[k])
    return self.data[k]

  def size(self,k):
    return -self.data[self.find(k)]

  def set_amount(self,k,k_amount):
    self.amount[k]=k_amount

  def get_amount(self,k):
    return self.amount[k]
# Union-Find --- END ---

def main():
  n,k=LI()
  l=LI()
  d={}
  uf=UnionFind(n)
  for i,x in enumerate(l):
    x-=1
    d[i]=x
  
  for _ in range(k):
    a,b=LI()
    uf.unite(a-1,b-1)

  ans=0
  for x in l:
    x-=1
    if uf.find(x)==uf.find(d[x]):
      ans+=1

  return ans

# main()
print((main()))