Buggy python submission (verdict: Time Limit Exceeded):
n, m = map(int, input().split())
p = list(map(int, input().split()))
xy = [list(map(int, input().split())) for _ in range(m)]

class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n+1)]
        self.rank = [0] * (n+1)

    # 検索
    def find(self, x):
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]

    # 併合
    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
        else:
            self.par[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    # 同じ集合に属するか判定
    def same_check(self, x, y):
        return self.find(x) == self.find(y)

u = UnionFind(n)
for i in range(m):
    x = xy[i][0]
    y = xy[i][1]
    u.union(x, y)

idx_dict = dict()
keys = []
for i in range(n):
    idx = u.find(i + 1)
    if idx not in keys:
        idx_dict[idx] = [i]
        keys.append(idx)
    else:
        idx_dict[idx].append(i)

counter = 0
for k in keys:
    l = idx_dict[k]
    template = []
    for i in range(len(l)):
        template.append(p[l[i]] - 1)

    counter += len(set(l) & set(template))

print(counter)


Fixed submission:
n, m = map(int, input().split())
p = list(map(int, input().split()))
xy = [list(map(int, input().split())) for _ in range(m)]

from collections import defaultdict
g = defaultdict(list)
for x, y in xy:
    x, y = x - 1, y - 1
    g[x].append(y)
    g[y].append(x)

visited = [0] * n
ans = 0

for i in range(n):
    if visited[i] == 0:
        q = [i]
        visited[i] = 1
        s = set([i])
        while q:
            cur = q.pop()
            for target in g[cur]:
                if visited[target] == 0:
                    visited[target] = 1
                    q.append(target)
                    s.add(target)

        ps = set()
        for j in s:
            ps.add(p[j] - 1)

        intersect = s & ps
        ans += len(list(intersect))
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
n, m = map(int, input().split())
p = list(map(int, input().split()))
xy = [list(map(int, input().split())) for _ in range(m)]

class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n+1)]
        self.rank = [0] * (n+1)

    # 検索
    def find(self, x):
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]

    # 併合
    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
        else:
            self.par[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    # 同じ集合に属するか判定
    def same_check(self, x, y):
        return self.find(x) == self.find(y)

u = UnionFind(n)
for i in range(m):
    x = xy[i][0]
    y = xy[i][1]
    u.union(x, y)

idxs = []
for i in range(1, n+1):
    idxs.append(u.find(i))

idx_dict = dict()
keys = []
for i in range(n):
    if idxs[i] not in keys:
        idx_dict[idxs[i]] = [i]
        keys.append(idxs[i])
    else:
        idx_dict[idxs[i]].append(i)

counter = 0
for k in keys:
    l = idx_dict[k]
    template = []
    for i in range(len(l)):
        template.append(p[l[i]] - 1)

    counter += len(set(l) & set(template))

print(counter)


Fixed submission:
n, m = map(int, input().split())
p = list(map(int, input().split()))
xy = [list(map(int, input().split())) for _ in range(m)]

from collections import defaultdict
g = defaultdict(list)
for x, y in xy:
    x, y = x - 1, y - 1
    g[x].append(y)
    g[y].append(x)

visited = [0] * n
ans = 0

for i in range(n):
    if visited[i] == 0:
        q = [i]
        visited[i] = 1
        s = set([i])
        while q:
            cur = q.pop()
            for target in g[cur]:
                if visited[target] == 0:
                    visited[target] = 1
                    q.append(target)
                    s.add(target)

        ps = set()
        for j in s:
            ps.add(p[j] - 1)

        intersect = s & ps
        ans += len(list(intersect))
print(ans)

Buggy python submission (verdict: Runtime Error):
n, m = map(int, input().split())
p = list(map(int, input().split()))
xy = [list(map(int, input().split())) for _ in range(m)]

class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n+1)]
        self.rank = [0] * (n+1)

    # 検索
    def find(self, x):
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]

    # 併合
    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
        else:
            self.par[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    # 同じ集合に属するか判定
    def same_check(self, x, y):
        return self.find(x) == self.find(y)

u = UnionFind(n)
for i in range(m):
    x = xy[i][0]
    y = xy[i][1]
    u.union(x, y)

idxs = []
for i in range(1, n+1):
    idxs.append(u.find(i))

idx_dict = dict()
keys = []
for i in range(n):
    if idxs[i] not in keys:
        idx_dict[idxs[i]] = [i]
        keys.append(idx[i])
    else:
        idx_dict[idxs[i]].append(i)

counter = 0
for k in keys:
    l = idx_dict[k]
    template = []
    for i in range(len(l)):
        template.append(p[l[i]] - 1)

    counter += len(set(l) & set(template))

print(counter)


Fixed submission:
n, m = map(int, input().split())
p = list(map(int, input().split()))
xy = [list(map(int, input().split())) for _ in range(m)]

from collections import defaultdict
g = defaultdict(list)
for x, y in xy:
    x, y = x - 1, y - 1
    g[x].append(y)
    g[y].append(x)

visited = [0] * n
ans = 0

for i in range(n):
    if visited[i] == 0:
        q = [i]
        visited[i] = 1
        s = set([i])
        while q:
            cur = q.pop()
            for target in g[cur]:
                if visited[target] == 0:
                    visited[target] = 1
                    q.append(target)
                    s.add(target)

        ps = set()
        for j in s:
            ps.add(p[j] - 1)

        intersect = s & ps
        ans += len(list(intersect))
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
n, m = map(int, input().split())
p = list(map(int, input().split()))
xy = [list(map(int, input().split())) for _ in range(m)]

class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n+1)]
        self.rank = [0] * (n+1)

    # 検索
    def find(self, x):
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]

    # 併合
    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
        else:
            self.par[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    # 同じ集合に属するか判定
    def same_check(self, x, y):
        return self.find(x) == self.find(y)

u = UnionFind(n)
for i in range(m):
    x = xy[i][0]
    y = xy[i][1]
    u.union(x, y)

idxs = []
for i in range(1, n+1):
    idxs.append(u.find(i))


idx_dict = dict()
for i in range(n):
    if idxs[i] not in idx_dict.keys():
        idx_dict[idxs[i]] = [i]
    else:
        idx_dict[idxs[i]].append(i)

counter = 0
for k in idx_dict.keys():
    l = idx_dict[k]
    template = []
    for i in range(len(l)):
        template.append(p[l[i]] - 1)

    counter += len(set(l) & set(template))

print(counter)


Fixed submission:
n, m = map(int, input().split())
p = list(map(int, input().split()))
xy = [list(map(int, input().split())) for _ in range(m)]

from collections import defaultdict
g = defaultdict(list)
for x, y in xy:
    x, y = x - 1, y - 1
    g[x].append(y)
    g[y].append(x)

visited = [0] * n
ans = 0

for i in range(n):
    if visited[i] == 0:
        q = [i]
        visited[i] = 1
        s = set([i])
        while q:
            cur = q.pop()
            for target in g[cur]:
                if visited[target] == 0:
                    visited[target] = 1
                    q.append(target)
                    s.add(target)

        ps = set()
        for j in s:
            ps.add(p[j] - 1)

        intersect = s & ps
        ans += len(list(intersect))
print(ans)