mod util { pub trait Join { fn join(self, sep: &str) -> String; } impl Join for I where I: Iterator, T: std::fmt::Display, { fn join(self, sep: &str) -> String { let mut s = String::new(); use std::fmt::*; for (i, v) in self.enumerate() { if i > 0 { write!(&mut s, "{}", sep).ok(); } write!(&mut s, "{}", v).ok(); } s } } } // ---------- begin scannner ---------- #[allow(dead_code)] mod scanner { use std::str::FromStr; pub struct Scanner<'a> { it: std::str::SplitWhitespace<'a>, } impl<'a> Scanner<'a> { pub fn new(s: &'a String) -> Scanner<'a> { Scanner { it: s.split_whitespace(), } } pub fn next(&mut self) -> T { self.it.next().unwrap().parse::().ok().unwrap() } pub fn next_bytes(&mut self) -> Vec { self.it.next().unwrap().bytes().collect() } pub fn next_chars(&mut self) -> Vec { self.it.next().unwrap().chars().collect() } pub fn next_vec(&mut self, len: usize) -> Vec { (0..len).map(|_| self.next()).collect() } } } // ---------- end scannner ---------- use std::io::Write; use std::collections::*; type Map = BTreeMap; type Set = BTreeSet; type Deque = VecDeque; fn main() { use std::io::Read; let mut s = String::new(); std::io::stdin().read_to_string(&mut s).unwrap(); let mut sc = scanner::Scanner::new(&s); let out = std::io::stdout(); let mut out = std::io::BufWriter::new(out.lock()); run(&mut sc, &mut out); } fn run(sc: &mut scanner::Scanner, out: &mut std::io::BufWriter) { let t: u32 = sc.next(); for _ in 0..t { let n: usize = sc.next(); let m: usize = sc.next(); let mut p = vec![(N, N); m]; for p in p.iter_mut() { p.0 = sc.next::() - 1; } for p in p.iter_mut() { p.1 = sc.next::() - 1; } let mut value = [-1i8; N]; for i in 0..N { value[i] = (i + 1) as i8 * -1; } let mut used = vec![false; m]; let mut ban = vec![false; n - 1]; dfs(value, 0, &p, &mut used, &mut ban); use util::*; if ban.iter().any(|b| *b) { writeln!(out, "No").ok(); let b = (1..n).filter(|x| ban[*x - 1]).collect::>(); writeln!(out, "{}", b.len()).ok(); writeln!(out, "{}", b.iter().join(" ")).ok(); } else { writeln!(out, "Yes").ok(); let b = (0..m).filter(|x| !used[*x]).map(|x| x + 1).collect::>(); writeln!(out, "{}", b.len()).ok(); writeln!(out, "{}", b.iter().join(" ")).ok(); } } } const N: usize = 27; fn dfs(value: [i8; N], po: usize, p: &[(usize, usize)], used: &mut [bool], ban: &mut [bool]) { if po == p.len() { for i in 0..ban.len() { let l = value[i]; let r = value[i + 1]; ban[i] |= l == 1 && r == 0; ban[i] |= l < 0 && r == 0; ban[i] |= l == 1 && r < 0; ban[i] |= l < 0 && r < 0 && l != r; } return; } let (x, y) = p[po]; let l = value[x]; let r = value[y]; if l == r { dfs(value, po + 1, p, used, ban); return; } if l >= 0 && r >= 0 { let mut v = value; if l > r { v.swap(x, y); used[po] = true; } dfs(v, po + 1, p, used, ban); return; } if l < 0 && r < 0 { used[po] = true; let mut v = value; for v in v.iter_mut() { if *v == r { *v = l; } } dfs(v, po + 1, p, used, ban); let cl = value.iter().filter(|v| **v == l).count(); let cr = value.iter().filter(|v| **v == r).count(); if cl == 1 || cr == 1 { let mut v = value; v[x] = 0; v[y] = 1; dfs(v, po + 1, p, used, ban); } else { for &(a, b) in [(0, 1), (1, 0)].iter() { let mut v = value; for v in v.iter_mut() { if *v == l { *v = a; } else if *v == r { *v = b; } } v[x] = 0; v[y] = 1; dfs(v, po + 1, p, used, ban); } } return; } if value[x] < 0 { let mut v = value; if v[y] == 0 { used[po] = true; v.swap(x, y); } dfs(v, po + 1, p, used, ban); } else if value[y] < 0 { let mut v = value; if v[x] == 1 { used[po] = true; v.swap(x, y); } dfs(v, po + 1, p, used, ban); } else { unreachable!() } }