use std::mem::swap; use std::io::{self, BufRead}; struct UnionFind{ parent: Vec, num: Vec, } impl UnionFind{ fn new(n: usize)->Self{ let parent = (0..n).into_iter().collect(); let num = vec![1; n]; UnionFind{ parent, num, } } fn find(&mut self, x: usize)->usize{ if x==self.parent[x]{return x;} self.parent[x] = self.find(self.parent[x]); self.parent[x] } fn union(&mut self, u: usize, v: usize){ let (mut pu, mut pv) = (self.find(u), self.find(v)); if pu==pv{return;} if self.num[pu] < self.num[pv]{ swap(&mut pu, &mut pv); } self.num[pu] += self.num[pv]; self.parent[pv] = pu; } fn same(&mut self, u: usize, v: usize)->bool{ self.find(u)==self.find(v) } } fn main(){ let stdin = io::stdin(); let mut iterator = stdin.lock().lines(); let first_line = iterator.next().unwrap().unwrap(); let mut first_iter = first_line.split_whitespace(); let n: usize = first_iter.next().unwrap().parse().unwrap(); let m: usize = first_iter.next().unwrap().parse().unwrap(); let second_line = iterator.next().unwrap().unwrap(); let c: Vec = second_line .split_whitespace() .map(|x| x.parse::().unwrap() - 1) .collect(); let mut e = Vec::new(); for _ in 0..m { let edge_line = iterator.next().unwrap().unwrap(); let mut edge_iter = edge_line.split_whitespace(); let u: usize = edge_iter.next().unwrap().parse::().unwrap() - 1; let v: usize = edge_iter.next().unwrap().parse::().unwrap() - 1; e.push((u, v)); } let mut colour = vec![0; n]; for i in 0..n{ colour[c[i]] += 1; } let mut uf = UnionFind::new(n); let mut ans = 0; for i in 0..n{ ans += (colour[i]-1).max(0); } for &(u, v) in &e{ if uf.same(u, v){continue} if c[u]==c[v]{ uf.union(u, v); ans -= 1; } } println!("{}", ans); }