Buggy python submission (verdict: Runtime Error):
n,m = map(int, input().split())
p = list(map(int, input().split()))

par = [i for i in range(n)]
#rootの計算量は、parが最初の状態に近いほど値は小さくて、高々O(n)
def root(x):
	tmp = par[x]
	if tmp == x:
		return x
	else:
		a = root(tmp)
		par[x] = a
		return a

def merge(x, y):
	x = root(x)
	y = root(y)
	if x != y:
		par[x] = y
		return

for i in range(m):
	x, y = map(int, input().split())
	merge(x-1, y-1)
	print(par)

ans = 0

for i in range(n):
	if p[i]-1 == i:
		ans += 1
	elif root(p[i]-1) == root(i):
		ans += 1
print(ans)

Fixed submission:
n,m = map(int, input().split())
p = list(map(int, input().split()))

par = [i for i in range(n)]
#rootの計算量は、parが最初の状態に近いほど値は小さくて、高々O(n)
def root(x):
	tmp = par[x]
	if tmp == x:
		return x
	else:
		a = root(tmp)
		par[x] = a
		return a

def merge(x, y):
	x = root(x)
	y = root(y)
	if x != y:
		par[x] = y
		return

for i in range(m):
	x, y = map(int, input().split())
	merge(x-1, y-1)
	#print(par)

ans = 0

for i in range(n):
	if p[i]-1 == i:
		ans += 1
	elif root(p[i]-1) == root(i):
		ans += 1
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
N, M = list(map(int, input().split()))
sigma = list(map(int, input().split()))
gokans = []

for i in range(M):
    pair = tuple(map(int, input().split()))
    gokans.append(pair)

def connected(i, j, paths):
    if [pair for pair in paths if i in pair] and [pair for pair in paths if j in pair]:
        new_chain_i = [pair for pair in paths if i in pair]
        new_chain_j = [pair for pair in paths if j in pair]
        for pair in set(new_chain_i + new_chain_j):
            paths.remove(pair)
        narabi_i = set([couple[0] for couple in new_chain_i] + [couple[1] for couple in new_chain_i])
        narabi_j = set([couple[0] for couple in new_chain_j] + [couple[1] for couple in new_chain_j])
        if narabi_i & narabi_j != set():
            return True

        while new_chain_i and new_chain_j:
            new_chain_i_kari = []
            new_chain_j_kari = []

            for pair in new_chain_i:
                new_chain_i_kari += [couple for couple in paths if set(couple) & set(pair) != set()]
            for pair in new_chain_j:
                new_chain_j_kari += [couple for couple in paths if set(couple) & set(pair) != set()]
            new_chain_i = new_chain_i_kari
            new_chain_j = new_chain_j_kari

            for pair in set(new_chain_i + new_chain_j):
                paths.remove(pair)
            narabi_i = set([couple[0] for couple in new_chain_i] + [couple[1] for couple in new_chain_i])
            narabi_j = set([couple[0] for couple in new_chain_j] + [couple[1] for couple in new_chain_j])
            if narabi_i & narabi_j != set():
                return True
        return False
    else:
        return False

count = 0
for i in range(1, N+1):
    if i != sigma[i-1]:
        gokans1 = gokans.copy()
        if connected(i, sigma[i-1], gokans1):
            count += 1
    else:
        count += 1
print(count)

Fixed submission:
n,m = map(int, input().split())
p = list(map(int, input().split()))

par = [i for i in range(n)]
#rootの計算量は、parが最初の状態に近いほど値は小さくて、高々O(n)
def root(x):
	tmp = par[x]
	if tmp == x:
		return x
	else:
		a = root(tmp)
		par[x] = a
		return a

def merge(x, y):
	x = root(x)
	y = root(y)
	if x != y:
		par[x] = y
		return

for i in range(m):
	x, y = map(int, input().split())
	merge(x-1, y-1)
	#print(par)

ans = 0

for i in range(n):
	if p[i]-1 == i:
		ans += 1
	elif root(p[i]-1) == root(i):
		ans += 1
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
N, M = list(map(int, input().split()))
sigma = list(map(int, input().split()))
gokans = []

for i in range(M):
    pair = tuple(map(int, input().split()))
    gokans.append(pair)

def connected(i, j, paths):
    if [pair for pair in paths if i in pair] and [pair for pair in paths if j in pair]:
        chain_i = [pair for pair in paths if i in pair]
        chain_j = [pair for pair in paths if j in pair]
        for pair in set(chain_i + chain_j):
            paths.remove(pair)
        narabi_i = set([couple[0] for couple in chain_i] + [couple[1] for couple in chain_i])
        narabi_j = set([couple[0] for couple in chain_j] + [couple[1] for couple in chain_j])
        if narabi_i & narabi_j != set():
            return True
        new_chain_i = [0]
        new_chain_j = [1]
        while new_chain_i or new_chain_j:
            new_chain_i = []
            new_chain_j = []
            for pair in chain_i:
                new_chain_i += [couple for couple in paths if set(couple) & set(pair) != set()]
            for pair in chain_j:
                new_chain_j += [couple for couple in paths if set(couple) & set(pair) != set()]
            for pair in set(new_chain_i + new_chain_j):
                paths.remove(pair)
            chain_i += new_chain_i
            chain_j += new_chain_j
            narabi_i = set([couple[0] for couple in new_chain_i] + [couple[1] for couple in new_chain_i])
            narabi_j = set([couple[0] for couple in new_chain_j] + [couple[1] for couple in new_chain_j])
            if narabi_i & narabi_j != set():
                return True
        return False
    else:
        return False

count = 0
for i in range(1, N+1):
    if i != sigma[i-1]:
        gokans1 = gokans.copy()
        if connected(i, sigma[i-1], gokans1):
            count += 1
    else:
        count += 1
print(count)

Fixed submission:
n,m = map(int, input().split())
p = list(map(int, input().split()))

par = [i for i in range(n)]
#rootの計算量は、parが最初の状態に近いほど値は小さくて、高々O(n)
def root(x):
	tmp = par[x]
	if tmp == x:
		return x
	else:
		a = root(tmp)
		par[x] = a
		return a

def merge(x, y):
	x = root(x)
	y = root(y)
	if x != y:
		par[x] = y
		return

for i in range(m):
	x, y = map(int, input().split())
	merge(x-1, y-1)
	#print(par)

ans = 0

for i in range(n):
	if p[i]-1 == i:
		ans += 1
	elif root(p[i]-1) == root(i):
		ans += 1
print(ans)

Buggy python submission (verdict: Runtime Error):
N, M = list(map(int, input().split()))
sigma = list(map(int, input().split()))
gokans = []

for i in range(M):
    pair = list(map(int, input().split()))
    gokans.append(pair)

def connected(i, j, paths, chains):
    old_chain = []
    if i == 1:
        for pair in chains:
            paths.remove(pair)
    narabi = [couple[0] for couple in chains] + [couple[1] for couple in chains]
    if j in narabi:
        return True

    while chains != old_chain:
        old_chain = chains
        for pair in chains:
            new_chain = [couple for couple in paths if set(couple) & set(pair) != set()]
            chains += new_chain
            for pair in new_chain:
                paths.remove(pair)
        narabi = [couple[0] for couple in chains] + [couple[1] for couple in chains]
        if j in narabi:
            return True
    return False

count = 0
chain = []
for i in range(1, N+1):
    if i != sigma[i-1]:
        gokans1 = gokans.copy()
        chain += [pair for pair in gokans if i in pair]
        if ([pair for pair in gokans if i in pair] != []) and [pair for pair in paths if sigma[i-1] in pair] and connected(i, sigma[i-1], gokans1, chain):
            count += 1
    else:
        count += 1

print(count)

Fixed submission:
n,m = map(int, input().split())
p = list(map(int, input().split()))

par = [i for i in range(n)]
#rootの計算量は、parが最初の状態に近いほど値は小さくて、高々O(n)
def root(x):
	tmp = par[x]
	if tmp == x:
		return x
	else:
		a = root(tmp)
		par[x] = a
		return a

def merge(x, y):
	x = root(x)
	y = root(y)
	if x != y:
		par[x] = y
		return

for i in range(m):
	x, y = map(int, input().split())
	merge(x-1, y-1)
	#print(par)

ans = 0

for i in range(n):
	if p[i]-1 == i:
		ans += 1
	elif root(p[i]-1) == root(i):
		ans += 1
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
N, M = list(map(int, input().split()))
sigma = list(map(int, input().split()))
gokans = []

for i in range(M):
    pair = list(map(int, input().split()))
    gokans.append(pair)

def connected(i, j, paths):
    if [pair for pair in paths if i in pair] and [pair for pair in paths if j in pair]:
        i_start = [pair for pair in paths if i in pair]
        chain = i_start
        old_chain = []
        for pair in chain:
            paths.remove(pair)

        while chain != old_chain:
            old_chain = chain
            for pair in chain:
                new_chain = [couple for couple in paths if set(couple) & set(pair) != set()]
                chain += new_chain
                for pair in new_chain:
                    paths.remove(pair)
            narabi = [couple[0] for couple in chain] + [couple[1] for couple in chain]
            if j in narabi:
                return True
        return False
    else:
        return False

count = 0
for i in range(1, N+1):
    if i != sigma[i-1]:
        gokans1 = gokans.copy()
        if connected(i, sigma[i-1], gokans1):
            count += 1
    else:
        count += 1

print(count)

Fixed submission:
n,m = map(int, input().split())
p = list(map(int, input().split()))

par = [i for i in range(n)]
#rootの計算量は、parが最初の状態に近いほど値は小さくて、高々O(n)
def root(x):
	tmp = par[x]
	if tmp == x:
		return x
	else:
		a = root(tmp)
		par[x] = a
		return a

def merge(x, y):
	x = root(x)
	y = root(y)
	if x != y:
		par[x] = y
		return

for i in range(m):
	x, y = map(int, input().split())
	merge(x-1, y-1)
	#print(par)

ans = 0

for i in range(n):
	if p[i]-1 == i:
		ans += 1
	elif root(p[i]-1) == root(i):
		ans += 1
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
N, M = list(map(int, input().split()))
sigma = list(map(int, input().split()))
gokans = []

for i in range(M):
    pair = list(map(int, input().split()))
    gokans.append(pair)

def connected(i, j, paths):
    if [pair for pair in paths if i in pair] and [pair for pair in paths if j in pair]:
        i_start = [pair for pair in paths if i in pair]
        chain = i_start
        old_chain = []
        for pair in chain:
            paths.remove(pair)

        while chain != old_chain:
            old_chain = chain
            for pair in chain:
                new_chain = [couple for couple in paths if set(couple) & set(pair) != set()]
                chain += new_chain
                for pair in new_chain:
                    paths.remove(pair)
            narabi = [couple[0] for couple in chain] + [couple[1] for couple in chain]
            if j in narabi:
                return True
        return False
    else:
        return False

table1 = [[] for _ in range(N)]
for i in range(1, N+1):
    for j in range(i+1, N+1):
        gokans1 = gokans.copy()
        if connected(i, j, gokans1):
            table1[i-1].append(j)

count = 0
for i in range(1, N+1):
    if i < sigma[i-1]:
        if sigma[i-1] in table1[i-1]:
            count += 1
    elif i > sigma[i-1]:
        if i in table1[sigma[i-1]-1]:
            count += 1
    else:
        count += 1

print(count)

Fixed submission:
n,m = map(int, input().split())
p = list(map(int, input().split()))

par = [i for i in range(n)]
#rootの計算量は、parが最初の状態に近いほど値は小さくて、高々O(n)
def root(x):
	tmp = par[x]
	if tmp == x:
		return x
	else:
		a = root(tmp)
		par[x] = a
		return a

def merge(x, y):
	x = root(x)
	y = root(y)
	if x != y:
		par[x] = y
		return

for i in range(m):
	x, y = map(int, input().split())
	merge(x-1, y-1)
	#print(par)

ans = 0

for i in range(n):
	if p[i]-1 == i:
		ans += 1
	elif root(p[i]-1) == root(i):
		ans += 1
print(ans)