use std::io; struct UnionFind { par: Vec, siz: Vec, } impl UnionFind { fn new(n: usize) -> Self { UnionFind { par: (0..n).collect(), siz: vec![1; n], } } fn root(&mut self, x: usize) -> usize { if self.par[x] == x { return x; } self.par[x] = self.root(self.par[x]); self.par[x] } fn issame(&mut self, x: usize, y: usize) -> bool { self.root(x) == self.root(y) } fn unite(&mut self, mut parent: usize, mut child: usize) -> bool { parent = self.root(parent); child = self.root(child); if parent == child { return false; } if self.siz[parent] < self.siz[child] { std::mem::swap(&mut parent, &mut child); } self.par[child] = parent; self.siz[parent] += self.siz[child]; true } fn size(&mut self, x: usize) -> usize { let root = self.root(x); self.siz[root] } } fn main() { let mut s = String::new(); io::stdin().read_line(&mut s).ok(); let mut itr = s.trim().split_whitespace(); let n: usize = itr.next().unwrap().parse().unwrap(); let m: usize = itr.next().unwrap().parse().unwrap(); let mut uf = UnionFind::new(2 * n); for _ in 0..m { let mut s = String::new(); io::stdin().read_line(&mut s).ok(); let mut itr = s.trim().split_whitespace(); let a: usize = itr.next().unwrap().parse().unwrap(); let b: usize = itr.next().unwrap().parse().unwrap(); uf.unite(a - 1, b - 1 + n); uf.unite(b - 1, a - 1 + n); } let ans = (0..n).all(|x| uf.issame(x, x + n)); if ans { println!("Yes"); } else { println!("No"); } }