output_description: Print the maximum possible number of i such that p_i = i after operations.
  
  * * *
input_description: 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
attempt: # -*- coding: utf-8 -*-
  
  #############
  # Libraries #
  #############
  
  import sys
  
  input = sys.stdin.readline
  
  import math
  
  # from math import gcd
  import bisect
  import heapq
  from collections import defaultdict
  from collections import deque
  from collections import Counter
  from functools import lru_cache
  
  #############
  # Constants #
  #############
  
  MOD = 10**9 + 7
  INF = float("inf")
  AZ = "abcdefghijklmnopqrstuvwxyz"
  
  #############
  # Functions #
  #############
  
  
  ######INPUT######
  def I():
      return int(input().strip())
  
  
  def S():
      return input().strip()
  
  
  def IL():
      return list(map(int, input().split()))
  
  
  def SL():
      return list(map(str, input().split()))
  
  
  def ILs(n):
      return list(int(input()) for _ in range(n))
  
  
  def SLs(n):
      return list(input().strip() for _ in range(n))
  
  
  def ILL(n):
      return [list(map(int, input().split())) for _ in range(n)]
  
  
  def SLL(n):
      return [list(map(str, input().split())) for _ in range(n)]
  
  
  ######OUTPUT######
  def P(arg):
      print(arg)
      return
  
  
  def Y():
      print("Yes")
      return
  
  
  def N():
      print("No")
      return
  
  
  def E():
      exit()
  
  
  def PE(arg):
      print(arg)
      exit()
  
  
  def YE():
      print("Yes")
      exit()
  
  
  def NE():
      print("No")
      exit()
  
  
  #####Shorten#####
  def DD(arg):
      return defaultdict(arg)
  
  
  #####Inverse#####
  def inv(n):
      return pow(n, MOD - 2, MOD)
  
  
  ######Combination######
  kaijo_memo = []
  
  
  def kaijo(n):
      if len(kaijo_memo) > n:
          return kaijo_memo[n]
      if len(kaijo_memo) == 0:
          kaijo_memo.append(1)
      while len(kaijo_memo) <= n:
          kaijo_memo.append(kaijo_memo[-1] * len(kaijo_memo) % MOD)
      return kaijo_memo[n]
  
  
  gyaku_kaijo_memo = []
  
  
  def gyaku_kaijo(n):
      if len(gyaku_kaijo_memo) > n:
          return gyaku_kaijo_memo[n]
      if len(gyaku_kaijo_memo) == 0:
          gyaku_kaijo_memo.append(1)
      while len(gyaku_kaijo_memo) <= n:
          gyaku_kaijo_memo.append(
              gyaku_kaijo_memo[-1] * pow(len(gyaku_kaijo_memo), MOD - 2, MOD) % MOD
          )
      return gyaku_kaijo_memo[n]
  
  
  def nCr(n, r):
      if n == r:
          return 1
      if n < r or r < 0:
          return 0
      ret = 1
      ret = ret * kaijo(n) % MOD
      ret = ret * gyaku_kaijo(r) % MOD
      ret = ret * gyaku_kaijo(n - r) % MOD
      return ret
  
  
  ######Factorization######
  def factorization(n):
      arr = []
      temp = n
      for i in range(2, int(-(-(n**0.5) // 1)) + 1):
          if temp % i == 0:
              cnt = 0
              while temp % i == 0:
                  cnt += 1
                  temp //= i
              arr.append([i, cnt])
      if temp != 1:
          arr.append([temp, 1])
      if arr == []:
          arr.append([n, 1])
      return arr
  
  
  #####MakeDivisors######
  def make_divisors(n):
      divisors = []
      for i in range(1, int(n**0.5) + 1):
          if n % i == 0:
              divisors.append(i)
              if i != n // i:
                  divisors.append(n // i)
      return divisors
  
  
  #####MakePrimes######
  def make_primes(N):
      max = int(math.sqrt(N))
      seachList = [i for i in range(2, N + 1)]
      primeNum = []
      while seachList[0] <= max:
          primeNum.append(seachList[0])
          tmp = seachList[0]
          seachList = [i for i in seachList if i % tmp != 0]
      primeNum.extend(seachList)
      return primeNum
  
  
  #####GCD#####
  def gcd(a, b):
      while b:
          a, b = b, a % b
      return a
  
  
  #####LCM#####
  def lcm(a, b):
      return a * b // gcd(a, b)
  
  
  #####BitCount#####
  def count_bit(n):
      count = 0
      while n:
          n &= n - 1
          count += 1
      return count
  
  
  #####ChangeBase#####
  def base_10_to_n(X, n):
      if X // n:
          return base_10_to_n(X // n, n) + [X % n]
      return [X % n]
  
  
  def base_n_to_10(X, n):
      return sum(int(str(X)[-i - 1]) * n**i for i in range(len(str(X))))
  
  
  def base_10_to_n_without_0(X, n):
      X -= 1
      if X // n:
          return base_10_to_n_without_0(X // n, n) + [X % n]
      return [X % n]
  
  
  #####IntLog#####
  def int_log(n, a):
      count = 0
      while n >= a:
          n //= a
          count += 1
      return count
  
  
  #############
  # Main Code #
  #############
  N, M = IL()
  N = N + 1
  L = [0] + IL()
  
  
  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())
  
  
  U = UnionFind(N)
  for _ in range(M):
      u, v = IL()
      U.union(u, v)
  
  
  DICMEM = DD(list)
  DICNUM = DD(list)
  for i in range(U.n):
      DICMEM[U.find(i)].append(i)
      DICNUM[U.find(i)].append(L[i])
  count = 0
  for r in U.roots():
      DICMEM[r].sort()
      DICNUM[r].sort()
      while DICMEM[r] and DICNUM[r]:
          if DICMEM[r][-1] == DICNUM[r][-1]:
              count += 1
              DICMEM[r].pop()
              DICNUM[r].pop()
          elif DICMEM[r][-1] > DICNUM[r][-1]:
              DICMEM[r].pop()
          else:
              DICNUM[r].pop()
  print(count - 1)
  
problem_description: Statement
  
  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.
samples: [{"input": "5 2\n    5 3 1 4 2\n    1 3\n    5 4", "output": "2\n    \n\nIf we perform the operation by choosing j=1, p becomes `1 3 5 4 2`, which is\noptimal, so the answer is 2.\n\n* * *"}, {"input": "3 2\n    3 2 1\n    1 2\n    2 3", "output": "3\n    \n\nIf we perform the operation by, for example, choosing j=1, j=2, j=1 in this\norder, p becomes `1 2 3`, which is obviously optimal. Note that we may choose\nthe same j any number of times.\n\n* * *"}, {"input": "10 8\n    5 3 6 8 7 10 9 1 2 4\n    3 1\n    4 1\n    5 9\n    2 5\n    6 5\n    3 5\n    8 9\n    7 9", "output": "8\n    \n\n* * *"}, {"input": "5 1\n    1 2 3 4 5\n    1 5", "output": "5\n    \n\nWe do not have to perform the operation."}]