CodeEff/ECCO huggingface dataset:
# Original solution
import heapq
from collections import deque
from functools import lru_cache

N,K = list(map(int,input().split()))
lim = min(N,K)
V = list(map(int,input().split()))
D = V.copy()
have = []
heapq.heapify(have)

#@lru_cache(maxsize = None)
def recur(d,h,n):
  if n == lim:
    #print(h)
    return sum(h)
  else:
    a = d[0]
    b = d[-1]
    ha = h.copy()
    hb = h.copy()
    heapq.heappush(ha,a)
    heapq.heappush(hb,b)
    reta = recur(d[1:],ha,n + 1)
    retb = recur(d[:-1],hb,n + 1)
    if len(h) == 0:
      return max(reta,retb)
    else:
      heapq.heappop(h)
      retc = recur(d,h,n + 1)
      return max(reta,retb,retc)
    
print((max(recur(D,have,0),0)))

# Optimized solution
import heapq
from collections import deque
from functools import lru_cache

N,K = list(map(int,input().split()))
V = list(map(int,input().split()))
ans = 0

for l in range(0,K + 1):
  for r in range(0,K - l + 1):
    d = K - r - l
    tmp = 0
    have = []
    if l + r > N:
      continue
    for i in range(0,l):
      tmp += V[i]
      have.append(V[i])
    for j in range(N - r,N):
      tmp += V[j]
      have.append(V[j])
    h = len(have)
    #print(have)
    have = sorted(have)
    for k in range(0,d):
      #print(have,sum(have))
      if k >= h:
        break
      if have[k] > 0:
        break
      tmp -= have[k]
    ans = max(tmp,ans)
    
print(ans)
# Original solution
def gcd(a,b):
    i = 2
    temp = 1
    while(i <= b):
        while(a % i == 0 and b % i == 0):
            temp = temp * i
            a = a / i
            b = b / i
        if(i % 2 == 0):
            i = i + 1
        else:
            i = i + 2
    print(temp)

l = input().split()
if(int(l[0]) > int(l[1])):
    gcd(int(l[0]),int(l[1]))
else:
    gcd(int(l[1]),int(l[0]))


# Optimized solution
def gcd(a,b):
    if(b):
        return gcd(b,a%b)
    return a

l = input().split()
if(int(l[0]) > int(l[1])):
    print(gcd(int(l[0]),int(l[1])))
else:
    print(gcd(int(l[1]),int(l[0])))
# Original solution
a, b = list(map(int, input().split()))
c = []
if a > b:
    a, b = b, a
while True:
    for i in range(a):
        #print(a, i)
        x = i + 2
        if a%x == 0:
            if b%x == 0:
                c.append(x)
                a = a//x
                b = b//x
                #print(c)
                break
    if i > a**0.5:
        break
s = 1
for j in c:
    s = s * j
print(s)



# Optimized solution
a, b = list(map(int, input().split()))
c = []
if a > b:
    a, b = b, a
if b%a == 0:
    print(a)
else:
    while True:
        for i in range(a):
            x = i + 2
            #print(a, x)
            if a%x == 0:
                if b%x == 0:
                    c.append(x)
                    a = a//x
                    b = b//x
                    #print(c)
                    break
                elif b%(a//x) == 0:
                    c.append(a//x)
                    a = x
                    b = b//(a//x)
                    #print(c)
                    break
            #if x%1000 == 0:
                #print(x)
            if x > a**0.5:
                break
        if x > a**0.5:
            break
    s = 1
    for j in c:
        s = s * j
    print(s)
# Original solution
import sys
import math

(a, b) = tuple([int(s) for s in input().split()])

if a==b:
    print(a)
    sys.exit(0)

min = a if a < b else b
divisor = 1

i = 2
while i < math.sqrt(min):
    if a % i == 0 and b % i == 0:
        a = a / i
        b = b / i
        divisor = divisor * i
    else:
        i = i + 1

print(divisor)

# Optimized solution
# 1_1_B

def gcd(x, y):
    while x%y != 0:
        x, y = y, x%y
    return y

x, y = list(map(int, input().split()))
print((gcd(x, y)))
# Original solution
x, y = list(map(int, input().split()))
n = min(x, y)

for i in range(1, n+1):
    if x%i==0 and y%i==0:
        gcd = i

print(gcd)

# Optimized solution
x, y = list(map(int, input().split()))
a = max(x, y)
b = min(x, y)
if a%b==0:
    gcd = b
else:
    for i in range(1, a%b+1):
        if b%i==0 and (a%b)%i==0:
            gcd = i

print(gcd)
# Original solution
x, y = list(map(int, input().split()))
a = max(x, y)
b = min(x, y)
if a%b==0:
    gcd = b
else:
    for i in range(1, a%b+1):
        if b%i==0 and (a%b)%i==0:
            gcd = i

print(gcd)

# Optimized solution
x, y = list(map(int, input().split()))
a = max(x, y)
b = min(x, y)

while a%b != 0:
    temp = a
    a = b
    b = temp%b

print(b)
# Original solution
a, b = list(map(int, input().split()))

def gcd(a, b):
    if a == b:
        return a
    big = max(a, b)
    small = min(a, b)
    big_i = big % small
    herf = round(min(small, big_i))
    for i in range(herf, 1, -1):
        if small%i==0 and big_i%i==0:
            return i
    return 1
    
print((gcd(a, b)))



# Optimized solution
a, b = list(map(int, input().split()))

def gcd(a, b):
    if a == b:
        return a
    big = max(a, b)
    small = min(a, b)
    while not big % small == 0:
        big, small = small, big%small
    return small
    
print((gcd(a, b)))
# Original solution
a,b = list(map(int,input().split()))
def gcd(x,y):
    z = max(x,y)  %  min(x,y)
    if z == 0 :
        return [min(x,y),0]
    return gcd(max(x,y),z)

L = gcd(a,b)
K = []
for i in reversed( (list(range(1,L[0]+1))) ) :
    if a % i == 0 and b % i == 0:
        K.append(i)

print((max(K)))



# Optimized solution
a,b = list(map(int,input().split()))
def gcd(x,y):
    q = max(x,y)  %  min(x,y)
    if q == 0 :
        return [min(x,y),0]
    return gcd(min(x,y),q)

L = gcd(a,b)
K = [ i for i in reversed(list(range(1, L[0] +1))) if a % i == 0 ]

print((max(K)))
# Original solution
a,b = list(map(int,input().split()))
def gcd(x,y):
    q = max(x,y)  %  min(x,y)
    if q == 0 :
        return [min(x,y),0]
    return gcd(min(x,y),q)

L = gcd(a,b)
K = [ i for i in reversed(list(range(1, L[0] +1))) if a % i == 0 ]

print((max(K)))



# Optimized solution
a,b = list(map(int,input().split()))
def gcd(x,y):
    q = max(x,y)  %  min(x,y)
    if q == 0 :
        return [min(x,y),0]
    return gcd(min(x,y),q)

print((max(gcd(a,b))))
# Original solution
def gcd(x, y):
    a_x = list()
    a_y = list()

    for i in range(1, x+1):
        if x % i == 0:
            a_x.append(i)

    for i in range(1, y+1):
        if y % i == 0:
            a_y.append(i)

    a_cd = list(set(a_x).intersection(set(a_y)))

    return max(a_cd)

if __name__ == "__main__":
    x, y = list(map(int, input().split()))
    if x > y:
        tmp = x
        x = y
        y = tmp
    print((gcd(x, y)))

# Optimized solution
def gcd(x, y):
    if x < y:
        tmp = x
        x = y
        y = tmp

    while y > 0:
        r = x % y
        x = y
        y = r

    return x

if __name__ == "__main__":
    x, y = list(map(int, input().split()))
    print((gcd(x, y)))
# Original solution
a,b = list(map(int,input().split()))
while a % b != 0:
	a,b = b, a % b
print(b)

# Optimized solution
def gcm(x,y):
    while y:
        x, y = y, x % y
    return x

a,b = list(map(int, input().split()))
print((gcm(a,b)))
# Original solution
x,y = list(map(int,input().split()))
if x==y:
    print(x)
else:
    if y>x:
        tmp = x
        x = y
        y = tmp
    i=2
    ans = 1
    al = []
    while i<=x/2:
        if x % i ==0:
            if y % i==0:
                al.append(i)
                x = x/i
                y = y/i
                continue
        i+=1
    if len(al)==0:
        pass
    else:
        for j in al:
            ans *= j
    print(ans)

# Optimized solution
x,y = list(map(int,input().split()))
if x==y:
    print(x)
else:
    if y>x:
        tmp = x
        x = y
        y = tmp
    i=2
    ans = 1
    al = []
    while i*i<=x:
        if x % i ==0:
            if y % i==0:
                al.append(i)
                x = x/i
                y = y/i
                continue
        i+=1
    if len(al)==0:
        pass
    else:
        for j in al:
            ans *= j
    print(ans)
# Original solution
x,y=list(map(int, input().split()))

def answer(x,y):
 for i in range(y, 0, -1):
  if x % i == 0 and y % i == 0:
   return i
 
if x == y:
 print(x)
elif x >= y:
 print((str(answer(x, x%y))))
else:
 print((str(answer(y, y%x))))

# Optimized solution
x,y=list(map(int, input().split()))

def gcd(x,y):
 if x < y:
  x,y = y,x
 while y > 0:
  r = x % y
  x = y
  y = r
 return x

print((str(gcd(x,y))))
# Original solution
def devisor_list(x):
    result = []
    for n in range(1, x + 1):
        if x % n == 0:
            result.append(n)
    return result

def common_max_element(array1, array2):
    result = []
    for n in array1:
        if n in array2:
            result.append(n)
    return max(result)

x, y = [int(n) for n in input().split()]
print((common_max_element(devisor_list(x), devisor_list(y))))



# Optimized solution
def gcd(x, y):
    if x < y:
        x, y = [y, x]

    while y > 0:
        r = x % y
        x = y
        y = r
    return x

x, y = [int(n) for n in input().split()]
print((gcd(x, y)))
# Original solution
# -*- coding:utf-8 -*-
def gcd(n,m):
    k = max(n,m)
    for i in range(k):
        if n%(k-i) == 0 and m%(k-i) == 0:
            return k-i
x, y = list(map(int,input().split()))
print((gcd(x,y)))

# Optimized solution
# -*- coding:utf-8 -*-
def gcd(n,m):
    if n < m:
        tmp = m
        m = n
        n = tmp
    while m > 0:
        r = n % m
        n = m
        m = r
    return n
    
x, y = list(map(int,input().split()))
print((gcd(x,y)))
# Original solution
dbg = False

a, b = list(map(int, input().split()))

if a > b:
    x, y = a, b
else:
    x, y = b, a

for i in range(1, y+1):
    if y % i == 0:
        gcd_tmp = int(y / i)
        if dbg: print(gcd_tmp)
        if x % gcd_tmp == 0:
            gcd = gcd_tmp
            break

print(gcd)

# Optimized solution
dbg = False

a, b = list(map(int, input().split()))

if a > b:
    x, y = a, b
else:
    x, y = b, a

for i in range(1, int((y+1)/2)+1):
    if y % i == 0:
        gcd_tmp = int(y / i)
        if dbg: print(gcd_tmp)
        if x % gcd_tmp == 0:
            print(gcd_tmp)
            exit()

print((1))
# Original solution
dbg = False

a, b = list(map(int, input().split()))

if a > b:
    x, y = a, b
else:
    x, y = b, a

for i in range(1, int((y+1)/2)+1):
    if y % i == 0:
        gcd_tmp = int(y / i)
        if dbg: print(gcd_tmp)
        if x % gcd_tmp == 0:
            print(gcd_tmp)
            exit()

print((1))

# Optimized solution
dbg = False

a, b = list(map(int, input().split()))

if a > b:
    x, y = a, b
else:
    x, y = b, a

divs = [1]
for i in range(1, int((y+1)/2)+1):
    gcd_tmp = int(y / i)
    if dbg: print(('%d, %d' % (i, gcd_tmp)))
    if i > gcd_tmp:
        break
    if y % i == 0:
        if x % gcd_tmp == 0:
            print(gcd_tmp)
            exit()
        elif x % i == 0:
            divs.append(i)

print((max(divs)))
# Original solution
x, y = input().split()
x = int(x)
y = int(y)
r = 1
while r > 0:
    if x >= y:
        r = x % y
    else:
        r = y % x

    if r != 0:
        x = y
        y = r
    else:
        print(y)

# Optimized solution
def gcd(x, y):
    if y == 0:
        print(x)
        return x
    return gcd(y, x%y)

x, y = list(map(int, input().split()))
if y > x:
    t = y
    y = x
    x = t
gcd(x, y)
# Original solution
a,b = list(map(int,input().split()))
gcd = 1

i = 2
while True:
    c = i
    for i in range(c,min(a,b)+1):
        if a%i == 0 and b%i ==0:
            gcd *= i
            a = int(a/i)
            b = int(b/i)
            break
    else: break
print(gcd)
    

# Optimized solution
a,b = list(map(int,input().split()))

if a<b:
    ret = a
    a = b
    b = ret


def gcd(a,b):
    c = a % b 
    if c == 0:
        return b
    else: 
        return gcd(b,c)

print((str(gcd(a,b))))
# Original solution
x,y=list(map(int,input().split()))

def gg(a,b):
    for d in range(b,0,-1):
        #print(d)
        if a%d==0 and b%d==0:
            return d
if x>y:
    print((gg(x,y)))
else:
    print((gg(y,x)))



# Optimized solution
x,y=list(map(int,input().split()))

def gg(a,b):
    if a%b==0 and b%b==0:
        return b
    return gg(b,a%b)

if x>y:
    print((gg(x,y)))
else:
    print((gg(y,x)))
# Original solution
a,b=list(map(int,input().split()))
z=[]
for i in range(min(a,b)):
    if a%(i+1)==0 and b%(i+1)==0:
        z+=[i+1]
print((max(z)))

# Optimized solution
z=list(map(int,input().split()))
z.sort()
a=0

while True:
    if z[1]==z[0]:
        break
    a=z[1]-z[0]
    if z[0]%a==0:
        z[1] = z[0]
        z[0] = a
        z.sort()
        break
    z[1]=z[0]
    z[0]=a
    z.sort()

print((z[0]))
# Original solution
x, y = list(map(int, input().split()))

s = min(x,y)
l = max(x,y)
for i in reversed(list(range(s+1))):
    if s % i == 0:
        if l % i == 0:
            print(i)
            break


# Optimized solution
x, y = list(map(int, input().split()))
l = max(x, y)
s = min(x, y)

for i in range(x):
    olds = s
    oldl = l
    s = oldl % olds
    l = olds

    if s == 0:
        print(l)
        break
# Original solution
def div(x, y): #x>y
    A = 1
    for i in range(1, x+1):
        if x % i == 0 and y % i == 0:
            A = i
    return A

x, y = list(map(int, input().split(" ")))
print((div(x,y)))





# Optimized solution
import math
def div(x, y): #x>y
    A = 1
    for i in range(1, int(math.sqrt(x))+1):
        if x % i == 0 and y % i == 0:
            A = max(A, i)
        j = int(x/i)
        if x % j == 0 and y % j == 0:
            A = max(A, j)
    return A
x, y = list(map(int, input().split(" ")))
print((div(x,y)))
# Original solution
x,y=list(map(int,input().split()))
xg=set()
yg=set()
for i in range(1,x+1):
    if x%i==0:
        xg.add(i)
for j in range(1,y+1):
    if y%j==0:
        yg.add(j)
gcd=xg & yg
print((max(gcd)))


# Optimized solution
if __name__ == '__main__':
    s = input().split()
    if s[0] < s[1]:
        tmp = s[0]
        s[0] = s[1]
        s[1] = tmp
    while True:
        x = int(s[0]) % int(s[1])
        if x==0:
            break
        s[0] = s[1]
        s[1] = x
 
    print((s[1]))
# Original solution
def greatest_common_divisor(x, y):
    if x > y:
        max = x
    else:
        max = y
    answer = 0
    for i in range(1, max+1):
        if x % i == 0 and y % i == 0:
            answer = i
    return answer

if __name__ == '__main__':
    x, y = [int(x) for x in input().split()]
    print((greatest_common_divisor(x, y)))

# Optimized solution
def greatest_common_divisor(x, y):
    if x < y:
        x, y = y, x

    if y == 0:
        return x
    else:
        return greatest_common_divisor(y, x % y)

if __name__ == '__main__':
    x, y = [int(x) for x in input().split()]
    print((greatest_common_divisor(x, y)))
# Original solution
XY=list(map(int,input().split()))

x=max(XY)
y=min(XY)
x_dy=x%y

ans=0
if x==y:
    ans=x
else:
    for d in range(1,(y+1)//2):
        if y%d==0 and x_dy%d==0:
            ans=d

print(ans)

# Optimized solution
def euclidean_alg(x,y):
    while y:
        x,y=y,x%y
    return x

XY=list(map(int,input().split()))
x=max(XY)
y=min(XY)

print((euclidean_alg(x,y)))
# Original solution
x, y = list(map(int, input().split()))
if x == y:
    print(x)
else:
    for i in range(1, abs(x-y)+1):
        if x % i == y % i == 0:
            j = i
    print(j)

# Optimized solution
x, y = list(map(int, input().split()))
if x < y:
    x,y = y,x
while y:
    x,y = y, x%y
print(x)
# Original solution
x, y = list(map(int, input().split()))
if x < y:
    x,y = y,x
while y:
    x,y = y, x%y
print(x)  

# Optimized solution
a,b=list(map(int,input().split()))
while b:
 a,b=b,a%b
print(a)
# Original solution
a = list(map(int, input().split()))
a.sort()

cd = a[0]
b = a[1]%a[0]

while a[0]%cd != 0 or b%cd != 0:
    cd -= 1

print(cd)

# Optimized solution
a = list(map(int, input().split()))
a.sort()

while a[0] > 0:
    b = a[1]%a[0]
    a[1] = a[0]
    a[0] = b
    
print((a[1]))
# Original solution
a=1/3
while 1:
    z=int(eval(input()))
    if z==0:break
    m=0
    zz=z*z*z
    for x in range(1,int(z/pow(2,a))+1):
        xx=x*x*x
        y=int(pow(zz-xx,a))
        yy=y*y*y
        m=max(m,yy+xx)
    print((zz-m))

# Optimized solution
a=1/3
while 1:
    z=int(eval(input()))
    if z==0:break
    m,zz=0,z*z*z
    for x in range(1,int(z/pow(2,a))+1):
        xx=x*x*x
        y=int(pow(zz-xx,a))
        yy=y*y*y
        m=max(m,yy+xx)
    print((zz-m))
# Original solution
while(1):
    z=int(input())
    if z==0:
        break
    else:
        k=0
        for x in range(1,z+1):
            for y in range(1,z+1):
                if x**3+y**3>z**3:
                    break
                k=max(k,x**3+y**3)
        print(z**3-k)

# Optimized solution
import math

while(1):
    z=int(input())
    if z==0:
        break
    else:
        k=0
        for x in range(1,z):
            y=int(pow(z**3-x**3,1/3.))
            k=max(k,x**3+y**3)
        print(z**3-k)
# Original solution
from itertools import combinations_with_replacement as C
while True:
    z = int(eval(input()))
    if z == 0:
        break
    zzz = pow(z, 3)
    candidates = []
    combinations = list(C(list(range(1, z+1)), 2))
    if len(combinations) >= 100:
        conbinations = combinations[100:]
    for xy in combinations:
        x, y = xy[0], xy[1]
        tmp = pow(x, 3)+pow(y, 3)
        if zzz >= tmp:
            candidates.append(tmp)
    print((zzz-max(candidates)))

# Optimized solution
from itertools import combinations_with_replacement as C
while True:
    z = int(eval(input()))
    if z == 0:
        break
    zzz = pow(z, 3)
    candidates = []
    combinations = list(C(list(range(1, z+1)), 2))
    if z >= 100:
        mid = len(combinations) // 2
        combinations = combinations[mid:]
    for xy in combinations:
        x, y = xy[0], xy[1]
        tmp = pow(x, 3)+pow(y, 3)
        if zzz >= tmp:
            candidates.append(tmp)
    print((zzz-max(candidates)))
# Original solution
n,m= list(map(int,input().split()))
par = [-1]*(n)
def find(x):
    if par[x]<0:return x
    else:
        par[x]=find(par[x])
        return par[x]
def unite(x,y):
    px,py=find(x),find(y)
    if px==py:return False
    else:
        if px<py:px,py=py,px
        par[px]+=par[py]
        par[py]=px
        return True
p= list(map(int,input().split()))
for i in range(m):
    x,y= list(map(int,input().split()))
    unite(x-1,y-1)
gr={}
for c in range(n):#par:
    ap=find(c)
    gr[ap]=gr.get(ap,[])+[c]
g=0
for key in list(gr.keys()):
    temp=[p[index]-1 for index in gr[key]]
    newset = set(gr[key]) & set(temp)
    g+=len(newset)
print(g)

# Optimized solution
n,m= list(map(int,input().split()))
par = [-1]*(n)
def find(x):
    if par[x]<0:return x
    else:
        par[x]=find(par[x])
        return par[x]
def unite(x,y):
    px,py=find(x),find(y)
    if px==py:return False
    else:
        if px<py:px,py=py,px
        par[px]+=par[py]
        par[py]=px
        return True
p= list(map(int,input().split()))
gl=[[] for _ in range(n)]
for i in range(m):
    x,y= list(map(int,input().split()))
    unite(x-1,y-1)
for c in range(n):#par:
    ap=find(c)
    gl[ap].append(c)
g=0
for sg in gl:
    temp=[p[index]-1 for index in sg]
    newset = set(sg) & set(temp)
    g+=len(newset)
print(g)
# Original solution
class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x):
        return -self.parents[self.find(x)]

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        return len(self.roots())

    def all_group_members(self):
        return {r: self.members(r) for r in self.roots()}

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())
n,m=list(map(int,input().split()))
p=list(map(int,input().split()))
uf=UnionFind(n)
for i in range(m):
  x,y=list(map(int,input().split()))
  uf.union(x-1,y-1)
yes=[0]*n
for i in range(n):
  if uf.same(p[i]-1,i):
    yes[p[i]-1]=1
print((sum(yes)))

# Optimized solution
class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x):
        return -self.parents[self.find(x)]

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        return len(self.roots())

    def all_group_members(self):
        return {r: self.members(r) for r in self.roots()}

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())

n,m=list(map(int,input().split()))
p=list(map(int,input().split()))
uf=UnionFind(n+1)
for i in range(m):
  x,y=list(map(int,input().split()))
  uf.union(p[x-1],p[y-1])
ans=0
for i in range(1,n+1):
  if uf.same(i,p[i-1]):
    ans+=1
print(ans)
# Original solution
import copy

n,m=list(map(int, input().split()))
p=list(map(int, input().split()))
q=list()
for i in range(m):
    q.append(set(map(int, input().split())))
count=0
while count!=5000:
    a=q.pop()
    for j in q:
        if len(j&a) != 0:
            j |=a
            count=0
            break
    else:q=[a]+q
    if count>len(q): break
    count+=1

q2=copy.copy(set(p))
for i in q:
    q2 -= i
    
count2=len([i for i in q2 if i==p[i-1]])

for i in q:
    r=list()
    for j in list(i):
        r.append(p[j-1])
    #print(i,r)
    count2 += len(i&set(r))
print(count2)

# Optimized solution
class UnionFind(object):
    def __init__(self, n=1):
        self.par = [i for i in range(n)]
        self.rank = [0 for _ in range(n)]

    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 x != y:
            if self.rank[x] < self.rank[y]:
                x, y = y, x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1
            self.par[y] = x

    def is_same(self, x, y):
        return self.find(x) == self.find(y)

n,m=list(map(int, input().split()))
p=list(map(int, input().split()))
uf1=UnionFind(n)
for i in range(m):
    a,b=list(map(int, input().split()))
    uf1.union(a-1,b-1)
count=0
for i in range(n):
    if uf1.is_same(i,p[i]-1):count+=1
print(count)