Buggy python submission (verdict: Time Limit Exceeded):
N,M = map(int,input().split())
P = list(map(int,input().split()))
L = [set(map(int,input().split())) for i in [None]*M]

LSET = L[:]
loop = True
while loop:
    loop = False
    LSET2 = []
    i = 0
    while i < len(LSET):
        j = i + 1
        tmp = LSET[i]
        if not tmp:
            i += 1
            continue
        while j < len(LSET):
            if  LSET[j] and not tmp.isdisjoint(LSET[j]):
                tmp |= LSET[j]
                loop = True
                LSET[j] = None
            j += 1
        LSET2.append(tmp)
        i += 1
    LSET = LSET2[:]

result = len([i for i in set(range(1,N+1)).difference(*LSET) if i == P[i-1]])
result += sum([ len({P[i-1] for i in s} & s )for s in LSET])
print(result)

Fixed submission:
class UnionFind:
    def __init__(self,size):
        self.L = [{'parent':i,'rank':0} for i in range(size)]

    def find(self,x):
        if self.L[x]['parent'] != x:
            self.L[x]['parent'] = self.find(self.L[x]['parent'])
        return self.L[x]['parent']

    def union(self,x,y):
        x_root = self.find(x)
        y_root = self.find(y)
        if x_root == y_root:
            return
        if self.L[x_root]['rank'] < self.L[y_root]['rank']:
            x_root,y_root = y_root,x_root

        self.L[y_root]['parent'] = x_root
        if self.L[x_root]['rank'] == self.L[y_root]['rank']:
            self.L[x_root]['rank'] += 1
    
    def __str__(self):
        return str([i['parent'] for i in self.L])

if __name__ == '__main__':
    N,M = map(int,input().split())
    P = list(map(int,input().split()))
    graph = UnionFind(N)
    for i in [None]*M:
        x,y = map(int,input().split())
        graph.union(x-1,y-1)
    count = 0
    for i,v in enumerate(P):
        if graph.find(i) == graph.find(v-1):
            count += 1
    print(count)

Buggy python submission (verdict: Time Limit Exceeded):
N,M = map(int,input().split())
P = list(map(int,input().split()))
L = [set(map(int,input().split())) for i in [None]*M]

LSET = L[:]
loop = True
while loop:
    loop = False
    LSET2 = []
    i = 0
    while i < len(LSET):
        j = i + 1
        tmp = LSET[i]
        if not tmp:
            i += 1
            continue
        while j < len(LSET):
            if  LSET[j] and not tmp.isdisjoint(LSET[j]):
                tmp |= LSET[j]
                loop = True
                LSET[j] = None
            j += 1
        LSET2.append(tmp)
        i += 1
    LSET = LSET2[:]

result = len([i for i in set(range(1,N+1)).difference(*LSET) if i == P[i-1]])
PSET = [{P[i-1] for i in s}for s in LSET]
result += sum([len(l&p) for l,p in zip(LSET,PSET)])
print(result)

Fixed submission:
class UnionFind:
    def __init__(self,size):
        self.L = [{'parent':i,'rank':0} for i in range(size)]

    def find(self,x):
        if self.L[x]['parent'] != x:
            self.L[x]['parent'] = self.find(self.L[x]['parent'])
        return self.L[x]['parent']

    def union(self,x,y):
        x_root = self.find(x)
        y_root = self.find(y)
        if x_root == y_root:
            return
        if self.L[x_root]['rank'] < self.L[y_root]['rank']:
            x_root,y_root = y_root,x_root

        self.L[y_root]['parent'] = x_root
        if self.L[x_root]['rank'] == self.L[y_root]['rank']:
            self.L[x_root]['rank'] += 1
    
    def __str__(self):
        return str([i['parent'] for i in self.L])

if __name__ == '__main__':
    N,M = map(int,input().split())
    P = list(map(int,input().split()))
    graph = UnionFind(N)
    for i in [None]*M:
        x,y = map(int,input().split())
        graph.union(x-1,y-1)
    count = 0
    for i,v in enumerate(P):
        if graph.find(i) == graph.find(v-1):
            count += 1
    print(count)

Buggy python submission (verdict: Time Limit Exceeded):
N,M = map(int,input().split())
P = list(map(int,input().split()))
L = [set(map(int,input().split())) for i in [None]*M]

LSET = L[:]
loop = True
while loop:
    loop = False
    LSET2 = []
    i = 0
    while i < len(LSET):
        j = i + 1
        tmp = LSET[i]
        if not tmp:
            i += 1
            continue
        while j < len(LSET):
            if  LSET[j] and not LSET[i].isdisjoint(LSET[j]):
                tmp |= LSET[j]
                loop = True
                LSET[j] = None
            j += 1
        LSET2.append(tmp)
        i += 1
    LSET = LSET2[:]

result = len([i for i in set(range(1,N+1)).difference(*LSET) if i == P[i-1]])
PSET = [{P[i-1] for i in s}for s in LSET]
LPSET = [l&p for l,p in zip(LSET,PSET)]
result += sum([len(i)for i in LPSET])
print(result)

Fixed submission:
class UnionFind:
    def __init__(self,size):
        self.L = [{'parent':i,'rank':0} for i in range(size)]

    def find(self,x):
        if self.L[x]['parent'] != x:
            self.L[x]['parent'] = self.find(self.L[x]['parent'])
        return self.L[x]['parent']

    def union(self,x,y):
        x_root = self.find(x)
        y_root = self.find(y)
        if x_root == y_root:
            return
        if self.L[x_root]['rank'] < self.L[y_root]['rank']:
            x_root,y_root = y_root,x_root

        self.L[y_root]['parent'] = x_root
        if self.L[x_root]['rank'] == self.L[y_root]['rank']:
            self.L[x_root]['rank'] += 1
    
    def __str__(self):
        return str([i['parent'] for i in self.L])

if __name__ == '__main__':
    N,M = map(int,input().split())
    P = list(map(int,input().split()))
    graph = UnionFind(N)
    for i in [None]*M:
        x,y = map(int,input().split())
        graph.union(x-1,y-1)
    count = 0
    for i,v in enumerate(P):
        if graph.find(i) == graph.find(v-1):
            count += 1
    print(count)