type uf_node = {
  mutable par: int;
  mutable rank: int;
}
;;

let uf_make n = Array.init n (fun i -> { par = i; rank = 0 })
;;

(* 根を求める *)
let rec uf_find uf x =
  if uf.(x).par == x
  then x
  else
    let par = uf.(x).par in
    let v = uf_find uf par in
    uf.(x).par <- v;
    v
;;

(* xとyの集合を併合 *)
let uf_unite uf x y =
  let x = uf_find uf x in
  let y = uf_find uf y in
  if x != y then
    if uf.(x).rank < uf.(y).rank
    then (
      uf.(x).par <- y;
      ()
    )
    else (
      uf.(y).par <- x;
      if uf.(x).rank == uf.(y).rank then (
        uf.(x).rank <- uf.(x).rank + 1;
        ()
      )
    )
;;

let uf_some uf x y = uf_find uf x == uf_find uf y
;;

let dec x = x -1
;;

let tuple2map fa fb (a, b) = (fa a, fb b)
;;

let tuple2 a b = (a, b)
;;

let curry2 f a b = f (a, b)
;;

let uncurry2 f (a, b) = f a b
;;

let (>>) f g x = g (f x)
;;

let (>>>) f g x y = g (f x y)
;;

let () =
  let n, m = Scanf.scanf "%d %d\n" tuple2 in
  let p_list =  List.init n (Fun.const @@ Scanf.scanf "%d " dec) in
  let xy_list = List.init m (Fun.const @@ Scanf.scanf "%d %d\n" (tuple2 >>> tuple2map dec dec)) in
  let uf = uf_make n in
  List.iter (uncurry2 @@ uf_unite uf) xy_list;
  let res = p_list |> List.mapi tuple2 |> List.filter (uncurry2 @@ uf_some uf) |> List.length in
  Printf.printf "%d\n" res
;;
