#[doc = " https://github.com/akiradeveloper/rust-comp-snippets"]
#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
#[allow(unused_imports)]
use std::iter::FromIterator;
#[macro_export]
macro_rules ! chmax { ( $ x : expr , $ ( $ v : expr ) ,+ ) => { $ ( $ x = std :: cmp :: max ( $ x ,$ v ) ; ) + } ; }
#[macro_export]
macro_rules ! chmin { ( $ x : expr , $ ( $ v : expr ) ,+ ) => { $ ( $ x = std :: cmp :: min ( $ x ,$ v ) ; ) + } ; }
#[macro_export]
macro_rules ! max { ( $ x : expr ) => ( $ x ) ; ( $ x : expr , $ ( $ xs : expr ) ,+ ) => { std :: cmp :: max ( $ x , max ! ( $ ( $ xs ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! min { ( $ x : expr ) => ( $ x ) ; ( $ x : expr , $ ( $ xs : expr ) ,+ ) => { std :: cmp :: min ( $ x , min ! ( $ ( $ xs ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! dvec { ( $ t : expr ; $ len : expr ) => { vec ! [ $ t ; $ len ] } ; ( $ t : expr ; $ len : expr , $ ( $ rest : expr ) ,* ) => { vec ! [ dvec ! ( $ t ; $ ( $ rest ) ,* ) ; $ len ] } ; }
#[macro_export]
macro_rules ! cfor { ( ; $ ( $ rest : tt ) * ) => { cfor ! ( ( ) ; $ ( $ rest ) * ) } ; ( $ ( $ init : stmt ) ,+; ; $ ( $ rest : tt ) * ) => { cfor ! ( $ ( $ init ) ,+; ! false ; $ ( $ rest ) * ) } ; ( $ ( $ init : stmt ) ,+; $ cond : expr ; ; $ body : block ) => { cfor ! { $ ( $ init ) ,+; $ cond ; ( ) ; $ body } } ; ( $ ( $ init : stmt ) ,+; $ cond : expr ; $ ( $ step : expr ) ,+; $ body : block ) => { { $ ( $ init ; ) + while $ cond { let mut _first = true ; let mut _continue = false ; loop { if ! _first { _continue = true ; break } _first = false ; $ body } if ! _continue { break } $ ( $ step ; ) + } } } ; }
#[doc = " main"]
#[allow(unused_imports)]
use std::io::{stdin, stdout, BufWriter, Write};
#[macro_export]
macro_rules ! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut parser = Parser :: from_str ( $ s ) ; input_inner ! { parser , $ ( $ r ) * } } ; ( parser = $ parser : ident , $ ( $ r : tt ) * ) => { input_inner ! { $ parser , $ ( $ r ) * } } ; ( new_stdin_parser = $ parser : ident , $ ( $ r : tt ) * ) => { let stdin = std :: io :: stdin ( ) ; let reader = std :: io :: BufReader :: new ( stdin . lock ( ) ) ; let mut $ parser = Parser :: new ( reader ) ; input_inner ! { $ parser , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { input ! { new_stdin_parser = parser , $ ( $ r ) * } } ; }
#[macro_export]
macro_rules ! input_inner { ( $ parser : ident ) => { } ; ( $ parser : ident , ) => { } ; ( $ parser : ident , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ parser , $ t ) ; input_inner ! { $ parser $ ( $ r ) * } } ; }
#[macro_export]
macro_rules ! read_value { ( $ parser : ident , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ parser , $ t ) ) ,* ) } ; ( $ parser : ident , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ parser , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ parser : ident , chars ) => { read_value ! ( $ parser , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ parser : ident , usize1 ) => { read_value ! ( $ parser , usize ) - 1 } ; ( $ parser : ident , $ t : ty ) => { $ parser . next ::<$ t > ( ) . expect ( "Parse error" ) } ; }
use std::io;
use std::io::BufRead;
use std::str;
pub struct Parser<R> {
    reader: R,
    buf: Vec<u8>,
    pos: usize,
}
impl Parser<io::Empty> {
    pub fn from_str(s: &str) -> Parser<io::Empty> {
        Parser {
            reader: io::empty(),
            buf: s.as_bytes().to_vec(),
            pos: 0,
        }
    }
}
impl<R: BufRead> Parser<R> {
    pub fn new(reader: R) -> Parser<R> {
        Parser {
            reader: reader,
            buf: vec![],
            pos: 0,
        }
    }
    pub fn update_buf(&mut self) {
        self.buf.clear();
        self.pos = 0;
        loop {
            let (len, complete) = {
                let buf2 = self.reader.fill_buf().unwrap();
                self.buf.extend_from_slice(buf2);
                let len = buf2.len();
                if len == 0 {
                    break;
                }
                (len, buf2[len - 1] <= 0x20)
            };
            self.reader.consume(len);
            if complete {
                break;
            }
        }
    }
    pub fn next<T: str::FromStr>(&mut self) -> Result<T, T::Err> {
        loop {
            let mut begin = self.pos;
            while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                begin += 1;
            }
            let mut end = begin;
            while end < self.buf.len() && (self.buf[end] > 0x20) {
                end += 1;
            }
            if begin != self.buf.len() {
                self.pos = end;
                return str::from_utf8(&self.buf[begin..end]).unwrap().parse::<T>();
            } else {
                self.update_buf();
            }
        }
    }
}
#[allow(unused_macros)]
macro_rules ! debug { ( $ ( $ a : expr ) ,* ) => { eprintln ! ( concat ! ( $ ( stringify ! ( $ a ) , " = {:?}, " ) ,* ) , $ ( $ a ) ,* ) ; } }
#[doc = " https://github.com/hatoo/competitive-rust-snippets"]
const BIG_STACK_SIZE: bool = true;
#[allow(dead_code)]
fn main() {
    use std::thread;
    if BIG_STACK_SIZE {
        thread::Builder::new()
            .stack_size(32 * 1024 * 1024)
            .name("solve".into())
            .spawn(solve)
            .unwrap()
            .join()
            .unwrap();
    } else {
        solve();
    }
}
fn solve() {
    let out = stdout();
    let mut out = BufWriter::new(out.lock());
    input!{
        new_stdin_parser = parser,
        n: usize, m: usize,
        e: [(usize,usize);n-1],
    }

    let mut g = HLDecomposition::new(n);
    for (u,v) in e {
        let u = u-1;
        let v = v-1;
        g.connect(u,v);
    }
    g.build(0);

    for _ in 0..m {
        input!{
            parser = parser,
            k: usize,
            v: [usize;k],
        }
        let mut xs = vec![];
        for i in 0..k {
            let x = v[i]-1;
            if x != 0 && g.par[x].unwrap() != 0 {
                let up = g.par[x].unwrap();
                let depth = g.depth[up] as i64;
                xs.push((depth, up));
            } else {
                // let depth = g.depth[x] as i64;
                // xs.push((depth, x));
            }
        }
        xs.sort();
        let mut y = vec![];
        for x in xs {
            y.push(x.1);
        }
        // dbg!(&y);
        let m = y.len();
        let mut ok = true;
        if m > 0 {
            let top = y[0];
            for i in 0..m {
                let u = y[i];
                let lca = g.lca(top, u);
                if lca != top {
                    ok = false;
                }
            }
        }
        writeln!(out,"{}",if ok {"YES"} else {"NO"});
    }
}
struct HLDecomposition {
    n: usize,
    g: Vec<Vec<usize>>,
    subcnt: Vec<usize>,
    depth: Vec<usize>,
    pub par: Vec<Option<usize>>,
    heavy_next: Vec<Option<usize>>,
    heavy_head: Vec<usize>,
    real_to_virt: Vec<usize>,
    pub virt_to_real: Vec<usize>,
}
impl HLDecomposition {
    pub fn new(n: usize) -> Self {
        HLDecomposition {
            n: n,
            g: vec![vec![]; n],
            subcnt: vec![0; n],
            depth: vec![0; n],
            par: vec![None; n],
            heavy_next: vec![None; n],
            heavy_head: vec![n; n],
            real_to_virt: vec![n; n],
            virt_to_real: vec![n; n],
        }
    }
    pub fn connect(&mut self, u: usize, v: usize) {
        self.g[u].push(v);
        self.g[v].push(u);
    }
    #[doc = "O(N)"]
    pub fn build(&mut self, root: usize) {
        self.dfs1(root);
        self.dfs2(root);
        self.bfs(root);
    }
    fn dfs1(&mut self, root: usize) {
        self.depth[root] = 0;
        self.par[root] = None;
        self.dfs1_sub(root, None);
    }
    fn dfs1_sub(&mut self, u: usize, par: Option<usize>) -> usize {
        let mut cnt = 1;
        for v in self.g[u].clone() {
            if Some(v) == par {
                continue;
            }
            self.depth[v] = self.depth[u] + 1;
            self.par[v] = Some(u);
            cnt += self.dfs1_sub(v, Some(u));
        }
        self.subcnt[u] = cnt;
        cnt
    }
    fn dfs2(&mut self, root: usize) {
        self.dfs2_sub(root, None);
    }
    fn dfs2_sub(&mut self, u: usize, par: Option<usize>) {
        let mut maxv = 0;
        let mut heavy_next = None;
        let cld = self.g[u].clone();
        for &v in &cld {
            if Some(v) == par {
                continue;
            }
            if self.subcnt[v] > maxv {
                maxv = self.subcnt[v];
                heavy_next = Some(v);
            }
        }
        if let Some(hn) = heavy_next {
            self.heavy_next[u] = Some(hn);
            self.dfs2_sub(hn, Some(u));
        }
        for &v in &cld {
            if Some(v) == par || Some(v) == heavy_next {
                continue;
            }
            self.dfs2_sub(v, Some(u));
        }
    }
    fn bfs(&mut self, root: usize) {
        let mut cur_virt_id = 0;
        let mut q = VecDeque::new();
        q.push_back(root);
        while let Some(h) = q.pop_front() {
            let mut cur0 = Some(h);
            while cur0.is_some() {
                let cur = cur0.unwrap();
                self.real_to_virt[cur] = cur_virt_id;
                self.virt_to_real[cur_virt_id] = cur;
                cur_virt_id += 1;
                self.heavy_head[cur] = h;
                for v in self.g[cur].clone() {
                    if Some(v) == self.par[cur] || Some(v) == self.heavy_next[cur] {
                        continue;
                    }
                    q.push_back(v);
                }
                cur0 = self.heavy_next[cur];
            }
        }
    }
    #[doc = "O(log N)"]
    pub fn lca(&self, u: usize, v: usize) -> usize {
        let mut l = u;
        let mut r = v;
        loop {
            if self.real_to_virt[l] > self.real_to_virt[r] {
                std::mem::swap(&mut l, &mut r);
            }
            if self.heavy_head[l] == self.heavy_head[r] {
                return l;
            }
            r = self.par[self.heavy_head[r]].unwrap();
        }
    }
    #[doc = "returns a list of [l,r]. O(N)"]
    pub fn vertex_decomposition(&self) -> Vec<(usize, usize)> {
        let mut vhead = vec![self.n; self.n];
        for i in 0..self.n {
            vhead[i] = self.real_to_virt[self.heavy_head[i]];
        }
        let mut hs = std::collections::HashMap::new();
        for x in vhead {
            *hs.entry(x).or_insert(0) += 1;
        }
        let mut res = vec![];
        for (k, v) in hs {
            res.push((k, k + v - 1));
        }
        res
    }
    #[doc = "return a list of [l,r]. edge is represented by the child with larger virtual id. O(N)"]
    pub fn edge_decomposition(&self) -> Vec<(usize, usize)> {
        let V = self.vertex_decomposition();
        let mut res = vec![];
        for (u, v) in V {
            let u = if u == 0 { 1 } else { u };
            res.push((u, v));
        }
        res
    }
    #[doc = "O(logN)"]
    pub fn vertex_decomposition_between(&self, u: usize, v: usize) -> Vec<(usize, usize)> {
        let mut res = vec![];
        let mut l = u;
        let mut r = v;
        loop {
            if self.real_to_virt[l] > self.real_to_virt[r] {
                std::mem::swap(&mut l, &mut r);
            }
            let p = (
                std::cmp::max(self.real_to_virt[self.heavy_head[r]], self.real_to_virt[l]),
                self.real_to_virt[r],
            );
            res.push(p);
            if self.heavy_head[l] != self.heavy_head[r] {
                r = self.par[self.heavy_head[r]].unwrap();
            } else {
                break;
            }
        }
        res
    }
    #[doc = "O(logN)"]
    pub fn edge_decomposition_between(&self, u: usize, v: usize) -> Vec<(usize, usize)> {
        let mut res = vec![];
        let mut l = u;
        let mut r = v;
        loop {
            if self.real_to_virt[l] > self.real_to_virt[r] {
                std::mem::swap(&mut l, &mut r);
            }
            if self.heavy_head[l] != self.heavy_head[r] {
                let p = (self.real_to_virt[self.heavy_head[r]], self.real_to_virt[r]);
                res.push(p);
                r = self.par[self.heavy_head[r]].unwrap();
            } else {
                if l != r {
                    let p = (self.real_to_virt[l] + 1, self.real_to_virt[r]);
                    res.push(p);
                }
                break;
            }
        }
        res
    }
    pub fn distance(&self, u: usize, v: usize) -> usize {
        self.depth[u] + self.depth[v] - 2 * self.depth[self.lca(u, v)]
    }
}


#[doc = " https://github.com/akiradeveloper/rust-comp-snippets"]
#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
#[allow(unused_imports)]
use std::iter::FromIterator;
#[macro_export]
macro_rules ! chmax { ( $ x : expr , $ ( $ v : expr ) ,+ ) => { $ ( $ x = std :: cmp :: max ( $ x ,$ v ) ; ) + } ; }
#[macro_export]
macro_rules ! chmin { ( $ x : expr , $ ( $ v : expr ) ,+ ) => { $ ( $ x = std :: cmp :: min ( $ x ,$ v ) ; ) + } ; }
#[macro_export]
macro_rules ! max { ( $ x : expr ) => ( $ x ) ; ( $ x : expr , $ ( $ xs : expr ) ,+ ) => { std :: cmp :: max ( $ x , max ! ( $ ( $ xs ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! min { ( $ x : expr ) => ( $ x ) ; ( $ x : expr , $ ( $ xs : expr ) ,+ ) => { std :: cmp :: min ( $ x , min ! ( $ ( $ xs ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! dvec { ( $ t : expr ; $ len : expr ) => { vec ! [ $ t ; $ len ] } ; ( $ t : expr ; $ len : expr , $ ( $ rest : expr ) ,* ) => { vec ! [ dvec ! ( $ t ; $ ( $ rest ) ,* ) ; $ len ] } ; }
#[macro_export]
macro_rules ! cfor { ( ; $ ( $ rest : tt ) * ) => { cfor ! ( ( ) ; $ ( $ rest ) * ) } ; ( $ ( $ init : stmt ) ,+; ; $ ( $ rest : tt ) * ) => { cfor ! ( $ ( $ init ) ,+; ! false ; $ ( $ rest ) * ) } ; ( $ ( $ init : stmt ) ,+; $ cond : expr ; ; $ body : block ) => { cfor ! { $ ( $ init ) ,+; $ cond ; ( ) ; $ body } } ; ( $ ( $ init : stmt ) ,+; $ cond : expr ; $ ( $ step : expr ) ,+; $ body : block ) => { { $ ( $ init ; ) + while $ cond { let mut _first = true ; let mut _continue = false ; loop { if ! _first { _continue = true ; break } _first = false ; $ body } if ! _continue { break } $ ( $ step ; ) + } } } ; }
#[doc = " main"]
#[allow(unused_imports)]
use std::io::{stdin, stdout, BufWriter, Write};
#[macro_export]
macro_rules ! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut parser = Parser :: from_str ( $ s ) ; input_inner ! { parser , $ ( $ r ) * } } ; ( parser = $ parser : ident , $ ( $ r : tt ) * ) => { input_inner ! { $ parser , $ ( $ r ) * } } ; ( new_stdin_parser = $ parser : ident , $ ( $ r : tt ) * ) => { let stdin = std :: io :: stdin ( ) ; let reader = std :: io :: BufReader :: new ( stdin . lock ( ) ) ; let mut $ parser = Parser :: new ( reader ) ; input_inner ! { $ parser , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { input ! { new_stdin_parser = parser , $ ( $ r ) * } } ; }
#[macro_export]
macro_rules ! input_inner { ( $ parser : ident ) => { } ; ( $ parser : ident , ) => { } ; ( $ parser : ident , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ parser , $ t ) ; input_inner ! { $ parser $ ( $ r ) * } } ; }
#[macro_export]
macro_rules ! read_value { ( $ parser : ident , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ parser , $ t ) ) ,* ) } ; ( $ parser : ident , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ parser , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ parser : ident , chars ) => { read_value ! ( $ parser , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ parser : ident , usize1 ) => { read_value ! ( $ parser , usize ) - 1 } ; ( $ parser : ident , $ t : ty ) => { $ parser . next ::<$ t > ( ) . expect ( "Parse error" ) } ; }
use std::io;
use std::io::BufRead;
use std::str;
pub struct Parser<R> {
    reader: R,
    buf: Vec<u8>,
    pos: usize,
}
impl Parser<io::Empty> {
    pub fn from_str(s: &str) -> Parser<io::Empty> {
        Parser {
            reader: io::empty(),
            buf: s.as_bytes().to_vec(),
            pos: 0,
        }
    }
}
impl<R: BufRead> Parser<R> {
    pub fn new(reader: R) -> Parser<R> {
        Parser {
            reader: reader,
            buf: vec![],
            pos: 0,
        }
    }
    pub fn update_buf(&mut self) {
        self.buf.clear();
        self.pos = 0;
        loop {
            let (len, complete) = {
                let buf2 = self.reader.fill_buf().unwrap();
                self.buf.extend_from_slice(buf2);
                let len = buf2.len();
                if len == 0 {
                    break;
                }
                (len, buf2[len - 1] <= 0x20)
            };
            self.reader.consume(len);
            if complete {
                break;
            }
        }
    }
    pub fn next<T: str::FromStr>(&mut self) -> Result<T, T::Err> {
        loop {
            let mut begin = self.pos;
            while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                begin += 1;
            }
            let mut end = begin;
            while end < self.buf.len() && (self.buf[end] > 0x20) {
                end += 1;
            }
            if begin != self.buf.len() {
                self.pos = end;
                return str::from_utf8(&self.buf[begin..end]).unwrap().parse::<T>();
            } else {
                self.update_buf();
            }
        }
    }
}
#[allow(unused_macros)]
macro_rules ! debug { ( $ ( $ a : expr ) ,* ) => { eprintln ! ( concat ! ( $ ( stringify ! ( $ a ) , " = {:?}, " ) ,* ) , $ ( $ a ) ,* ) ; } }
#[doc = " https://github.com/hatoo/competitive-rust-snippets"]
const BIG_STACK_SIZE: bool = true;
#[allow(dead_code)]
fn main() {
    use std::thread;
    if BIG_STACK_SIZE {
        thread::Builder::new()
            .stack_size(32 * 1024 * 1024)
            .name("solve".into())
            .spawn(solve)
            .unwrap()
            .join()
            .unwrap();
    } else {
        solve();
    }
}
fn solve() {
    let out = stdout();
    let mut out = BufWriter::new(out.lock());
    input!{
        new_stdin_parser = parser,
        n: usize, m: usize,
        e: [(usize,usize);n-1],
    }

    let mut g = HLDecomposition::new(n);
    for (u,v) in e {
        let u = u-1;
        let v = v-1;
        g.connect(u,v);
    }
    g.build(0);

    for _ in 0..m {
        input!{
            parser = parser,
            k: usize,
            v: [usize;k],
        }
        let mut xs = vec![];
        for i in 0..k {
            let x = v[i]-1;
            if x != 0 && g.par[x].unwrap() != 0 {
                let up = g.par[x].unwrap();
                let depth = g.depth[up] as i64;
                xs.push((depth, up));
            } else {
                // let depth = g.depth[x] as i64;
                // xs.push((depth, x));
            }
        }
        xs.sort();
        xs.dedup();

        let mut y = vec![];
        for x in xs {
            y.push(x.1);
        }
        // dbg!(&y);
        let m = y.len();
        let mut ok = true;
        if m > 0 {
            let top = y[0];
            for i in 0..m {
                let u = y[i];
                let lca = g.lca(top, u);
                if lca != top {
                    ok = false;
                }
            }
        }
        writeln!(out,"{}",if ok {"YES"} else {"NO"});
    }
}
struct HLDecomposition {
    n: usize,
    g: Vec<Vec<usize>>,
    subcnt: Vec<usize>,
    depth: Vec<usize>,
    pub par: Vec<Option<usize>>,
    heavy_next: Vec<Option<usize>>,
    heavy_head: Vec<usize>,
    real_to_virt: Vec<usize>,
    pub virt_to_real: Vec<usize>,
}
impl HLDecomposition {
    pub fn new(n: usize) -> Self {
        HLDecomposition {
            n: n,
            g: vec![vec![]; n],
            subcnt: vec![0; n],
            depth: vec![0; n],
            par: vec![None; n],
            heavy_next: vec![None; n],
            heavy_head: vec![n; n],
            real_to_virt: vec![n; n],
            virt_to_real: vec![n; n],
        }
    }
    pub fn connect(&mut self, u: usize, v: usize) {
        self.g[u].push(v);
        self.g[v].push(u);
    }
    #[doc = "O(N)"]
    pub fn build(&mut self, root: usize) {
        self.dfs1(root);
        self.dfs2(root);
        self.bfs(root);
    }
    fn dfs1(&mut self, root: usize) {
        self.depth[root] = 0;
        self.par[root] = None;
        self.dfs1_sub(root, None);
    }
    fn dfs1_sub(&mut self, u: usize, par: Option<usize>) -> usize {
        let mut cnt = 1;
        for v in self.g[u].clone() {
            if Some(v) == par {
                continue;
            }
            self.depth[v] = self.depth[u] + 1;
            self.par[v] = Some(u);
            cnt += self.dfs1_sub(v, Some(u));
        }
        self.subcnt[u] = cnt;
        cnt
    }
    fn dfs2(&mut self, root: usize) {
        self.dfs2_sub(root, None);
    }
    fn dfs2_sub(&mut self, u: usize, par: Option<usize>) {
        let mut maxv = 0;
        let mut heavy_next = None;
        let cld = self.g[u].clone();
        for &v in &cld {
            if Some(v) == par {
                continue;
            }
            if self.subcnt[v] > maxv {
                maxv = self.subcnt[v];
                heavy_next = Some(v);
            }
        }
        if let Some(hn) = heavy_next {
            self.heavy_next[u] = Some(hn);
            self.dfs2_sub(hn, Some(u));
        }
        for &v in &cld {
            if Some(v) == par || Some(v) == heavy_next {
                continue;
            }
            self.dfs2_sub(v, Some(u));
        }
    }
    fn bfs(&mut self, root: usize) {
        let mut cur_virt_id = 0;
        let mut q = VecDeque::new();
        q.push_back(root);
        while let Some(h) = q.pop_front() {
            let mut cur0 = Some(h);
            while cur0.is_some() {
                let cur = cur0.unwrap();
                self.real_to_virt[cur] = cur_virt_id;
                self.virt_to_real[cur_virt_id] = cur;
                cur_virt_id += 1;
                self.heavy_head[cur] = h;
                for v in self.g[cur].clone() {
                    if Some(v) == self.par[cur] || Some(v) == self.heavy_next[cur] {
                        continue;
                    }
                    q.push_back(v);
                }
                cur0 = self.heavy_next[cur];
            }
        }
    }
    #[doc = "O(log N)"]
    pub fn lca(&self, u: usize, v: usize) -> usize {
        let mut l = u;
        let mut r = v;
        loop {
            if self.real_to_virt[l] > self.real_to_virt[r] {
                std::mem::swap(&mut l, &mut r);
            }
            if self.heavy_head[l] == self.heavy_head[r] {
                return l;
            }
            r = self.par[self.heavy_head[r]].unwrap();
        }
    }
    #[doc = "returns a list of [l,r]. O(N)"]
    pub fn vertex_decomposition(&self) -> Vec<(usize, usize)> {
        let mut vhead = vec![self.n; self.n];
        for i in 0..self.n {
            vhead[i] = self.real_to_virt[self.heavy_head[i]];
        }
        let mut hs = std::collections::HashMap::new();
        for x in vhead {
            *hs.entry(x).or_insert(0) += 1;
        }
        let mut res = vec![];
        for (k, v) in hs {
            res.push((k, k + v - 1));
        }
        res
    }
    #[doc = "return a list of [l,r]. edge is represented by the child with larger virtual id. O(N)"]
    pub fn edge_decomposition(&self) -> Vec<(usize, usize)> {
        let V = self.vertex_decomposition();
        let mut res = vec![];
        for (u, v) in V {
            let u = if u == 0 { 1 } else { u };
            res.push((u, v));
        }
        res
    }
    #[doc = "O(logN)"]
    pub fn vertex_decomposition_between(&self, u: usize, v: usize) -> Vec<(usize, usize)> {
        let mut res = vec![];
        let mut l = u;
        let mut r = v;
        loop {
            if self.real_to_virt[l] > self.real_to_virt[r] {
                std::mem::swap(&mut l, &mut r);
            }
            let p = (
                std::cmp::max(self.real_to_virt[self.heavy_head[r]], self.real_to_virt[l]),
                self.real_to_virt[r],
            );
            res.push(p);
            if self.heavy_head[l] != self.heavy_head[r] {
                r = self.par[self.heavy_head[r]].unwrap();
            } else {
                break;
            }
        }
        res
    }
    #[doc = "O(logN)"]
    pub fn edge_decomposition_between(&self, u: usize, v: usize) -> Vec<(usize, usize)> {
        let mut res = vec![];
        let mut l = u;
        let mut r = v;
        loop {
            if self.real_to_virt[l] > self.real_to_virt[r] {
                std::mem::swap(&mut l, &mut r);
            }
            if self.heavy_head[l] != self.heavy_head[r] {
                let p = (self.real_to_virt[self.heavy_head[r]], self.real_to_virt[r]);
                res.push(p);
                r = self.par[self.heavy_head[r]].unwrap();
            } else {
                if l != r {
                    let p = (self.real_to_virt[l] + 1, self.real_to_virt[r]);
                    res.push(p);
                }
                break;
            }
        }
        res
    }
    pub fn distance(&self, u: usize, v: usize) -> usize {
        self.depth[u] + self.depth[v] - 2 * self.depth[self.lca(u, v)]
    }
}


#[doc = " https://github.com/akiradeveloper/rust-comp-snippets"]
#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
#[allow(unused_imports)]
use std::iter::FromIterator;
#[macro_export]
macro_rules ! chmax { ( $ x : expr , $ ( $ v : expr ) ,+ ) => { $ ( $ x = std :: cmp :: max ( $ x ,$ v ) ; ) + } ; }
#[macro_export]
macro_rules ! chmin { ( $ x : expr , $ ( $ v : expr ) ,+ ) => { $ ( $ x = std :: cmp :: min ( $ x ,$ v ) ; ) + } ; }
#[macro_export]
macro_rules ! max { ( $ x : expr ) => ( $ x ) ; ( $ x : expr , $ ( $ xs : expr ) ,+ ) => { std :: cmp :: max ( $ x , max ! ( $ ( $ xs ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! min { ( $ x : expr ) => ( $ x ) ; ( $ x : expr , $ ( $ xs : expr ) ,+ ) => { std :: cmp :: min ( $ x , min ! ( $ ( $ xs ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! dvec { ( $ t : expr ; $ len : expr ) => { vec ! [ $ t ; $ len ] } ; ( $ t : expr ; $ len : expr , $ ( $ rest : expr ) ,* ) => { vec ! [ dvec ! ( $ t ; $ ( $ rest ) ,* ) ; $ len ] } ; }
#[macro_export]
macro_rules ! cfor { ( ; $ ( $ rest : tt ) * ) => { cfor ! ( ( ) ; $ ( $ rest ) * ) } ; ( $ ( $ init : stmt ) ,+; ; $ ( $ rest : tt ) * ) => { cfor ! ( $ ( $ init ) ,+; ! false ; $ ( $ rest ) * ) } ; ( $ ( $ init : stmt ) ,+; $ cond : expr ; ; $ body : block ) => { cfor ! { $ ( $ init ) ,+; $ cond ; ( ) ; $ body } } ; ( $ ( $ init : stmt ) ,+; $ cond : expr ; $ ( $ step : expr ) ,+; $ body : block ) => { { $ ( $ init ; ) + while $ cond { let mut _first = true ; let mut _continue = false ; loop { if ! _first { _continue = true ; break } _first = false ; $ body } if ! _continue { break } $ ( $ step ; ) + } } } ; }
#[doc = " main"]
#[allow(unused_imports)]
use std::io::{stdin, stdout, BufWriter, Write};
#[macro_export]
macro_rules ! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut parser = Parser :: from_str ( $ s ) ; input_inner ! { parser , $ ( $ r ) * } } ; ( parser = $ parser : ident , $ ( $ r : tt ) * ) => { input_inner ! { $ parser , $ ( $ r ) * } } ; ( new_stdin_parser = $ parser : ident , $ ( $ r : tt ) * ) => { let stdin = std :: io :: stdin ( ) ; let reader = std :: io :: BufReader :: new ( stdin . lock ( ) ) ; let mut $ parser = Parser :: new ( reader ) ; input_inner ! { $ parser , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { input ! { new_stdin_parser = parser , $ ( $ r ) * } } ; }
#[macro_export]
macro_rules ! input_inner { ( $ parser : ident ) => { } ; ( $ parser : ident , ) => { } ; ( $ parser : ident , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ parser , $ t ) ; input_inner ! { $ parser $ ( $ r ) * } } ; }
#[macro_export]
macro_rules ! read_value { ( $ parser : ident , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ parser , $ t ) ) ,* ) } ; ( $ parser : ident , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ parser , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ parser : ident , chars ) => { read_value ! ( $ parser , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ parser : ident , usize1 ) => { read_value ! ( $ parser , usize ) - 1 } ; ( $ parser : ident , $ t : ty ) => { $ parser . next ::<$ t > ( ) . expect ( "Parse error" ) } ; }
use std::io;
use std::io::BufRead;
use std::str;
pub struct Parser<R> {
    reader: R,
    buf: Vec<u8>,
    pos: usize,
}
impl Parser<io::Empty> {
    pub fn from_str(s: &str) -> Parser<io::Empty> {
        Parser {
            reader: io::empty(),
            buf: s.as_bytes().to_vec(),
            pos: 0,
        }
    }
}
impl<R: BufRead> Parser<R> {
    pub fn new(reader: R) -> Parser<R> {
        Parser {
            reader: reader,
            buf: vec![],
            pos: 0,
        }
    }
    pub fn update_buf(&mut self) {
        self.buf.clear();
        self.pos = 0;
        loop {
            let (len, complete) = {
                let buf2 = self.reader.fill_buf().unwrap();
                self.buf.extend_from_slice(buf2);
                let len = buf2.len();
                if len == 0 {
                    break;
                }
                (len, buf2[len - 1] <= 0x20)
            };
            self.reader.consume(len);
            if complete {
                break;
            }
        }
    }
    pub fn next<T: str::FromStr>(&mut self) -> Result<T, T::Err> {
        loop {
            let mut begin = self.pos;
            while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                begin += 1;
            }
            let mut end = begin;
            while end < self.buf.len() && (self.buf[end] > 0x20) {
                end += 1;
            }
            if begin != self.buf.len() {
                self.pos = end;
                return str::from_utf8(&self.buf[begin..end]).unwrap().parse::<T>();
            } else {
                self.update_buf();
            }
        }
    }
}
#[allow(unused_macros)]
macro_rules ! debug { ( $ ( $ a : expr ) ,* ) => { eprintln ! ( concat ! ( $ ( stringify ! ( $ a ) , " = {:?}, " ) ,* ) , $ ( $ a ) ,* ) ; } }
#[doc = " https://github.com/hatoo/competitive-rust-snippets"]
const BIG_STACK_SIZE: bool = true;
#[allow(dead_code)]
fn main() {
    use std::thread;
    if BIG_STACK_SIZE {
        thread::Builder::new()
            .stack_size(32 * 1024 * 1024)
            .name("solve".into())
            .spawn(solve)
            .unwrap()
            .join()
            .unwrap();
    } else {
        solve();
    }
}
fn solve() {
    let out = stdout();
    let mut out = BufWriter::new(out.lock());
    input!{
        new_stdin_parser = parser,
        n: usize, m: usize,
        e: [(usize,usize);n-1],
    }

    let mut g = HLDecomposition::new(n);
    for (u,v) in e {
        let u = u-1;
        let v = v-1;
        g.connect(u,v);
    }
    g.build(0);

    for _ in 0..m {
        input!{
            parser = parser,
            k: usize,
            v: [usize;k],
        }
        let mut xs = vec![];
        for i in 0..k {
            let x = v[i]-1;
            if x != 0 && g.par[x].unwrap() != 0 {
                let up = g.par[x].unwrap();
                let depth = g.depth[up] as i64;
                xs.push((depth, up));
            } else {
                // let depth = g.depth[x] as i64;
                // xs.push((depth, x));
            }
        }
        xs.sort();
        xs.dedup();

        let mut y = vec![];
        for x in xs {
            y.push(x.1);
        }
        // dbg!(&y);
        let m = y.len();
        let mut ok = true;
        if m > 0 {
            for i in 0..m-1 {
                let a = y[i];
                let b = y[i+1];
                let lca = g.lca(a, b);
                if lca != a {
                    ok = false;
                }
            }
        }
        writeln!(out,"{}",if ok {"YES"} else {"NO"});
    }
}
struct HLDecomposition {
    n: usize,
    g: Vec<Vec<usize>>,
    subcnt: Vec<usize>,
    depth: Vec<usize>,
    pub par: Vec<Option<usize>>,
    heavy_next: Vec<Option<usize>>,
    heavy_head: Vec<usize>,
    real_to_virt: Vec<usize>,
    pub virt_to_real: Vec<usize>,
}
impl HLDecomposition {
    pub fn new(n: usize) -> Self {
        HLDecomposition {
            n: n,
            g: vec![vec![]; n],
            subcnt: vec![0; n],
            depth: vec![0; n],
            par: vec![None; n],
            heavy_next: vec![None; n],
            heavy_head: vec![n; n],
            real_to_virt: vec![n; n],
            virt_to_real: vec![n; n],
        }
    }
    pub fn connect(&mut self, u: usize, v: usize) {
        self.g[u].push(v);
        self.g[v].push(u);
    }
    #[doc = "O(N)"]
    pub fn build(&mut self, root: usize) {
        self.dfs1(root);
        self.dfs2(root);
        self.bfs(root);
    }
    fn dfs1(&mut self, root: usize) {
        self.depth[root] = 0;
        self.par[root] = None;
        self.dfs1_sub(root, None);
    }
    fn dfs1_sub(&mut self, u: usize, par: Option<usize>) -> usize {
        let mut cnt = 1;
        for v in self.g[u].clone() {
            if Some(v) == par {
                continue;
            }
            self.depth[v] = self.depth[u] + 1;
            self.par[v] = Some(u);
            cnt += self.dfs1_sub(v, Some(u));
        }
        self.subcnt[u] = cnt;
        cnt
    }
    fn dfs2(&mut self, root: usize) {
        self.dfs2_sub(root, None);
    }
    fn dfs2_sub(&mut self, u: usize, par: Option<usize>) {
        let mut maxv = 0;
        let mut heavy_next = None;
        let cld = self.g[u].clone();
        for &v in &cld {
            if Some(v) == par {
                continue;
            }
            if self.subcnt[v] > maxv {
                maxv = self.subcnt[v];
                heavy_next = Some(v);
            }
        }
        if let Some(hn) = heavy_next {
            self.heavy_next[u] = Some(hn);
            self.dfs2_sub(hn, Some(u));
        }
        for &v in &cld {
            if Some(v) == par || Some(v) == heavy_next {
                continue;
            }
            self.dfs2_sub(v, Some(u));
        }
    }
    fn bfs(&mut self, root: usize) {
        let mut cur_virt_id = 0;
        let mut q = VecDeque::new();
        q.push_back(root);
        while let Some(h) = q.pop_front() {
            let mut cur0 = Some(h);
            while cur0.is_some() {
                let cur = cur0.unwrap();
                self.real_to_virt[cur] = cur_virt_id;
                self.virt_to_real[cur_virt_id] = cur;
                cur_virt_id += 1;
                self.heavy_head[cur] = h;
                for v in self.g[cur].clone() {
                    if Some(v) == self.par[cur] || Some(v) == self.heavy_next[cur] {
                        continue;
                    }
                    q.push_back(v);
                }
                cur0 = self.heavy_next[cur];
            }
        }
    }
    #[doc = "O(log N)"]
    pub fn lca(&self, u: usize, v: usize) -> usize {
        let mut l = u;
        let mut r = v;
        loop {
            if self.real_to_virt[l] > self.real_to_virt[r] {
                std::mem::swap(&mut l, &mut r);
            }
            if self.heavy_head[l] == self.heavy_head[r] {
                return l;
            }
            r = self.par[self.heavy_head[r]].unwrap();
        }
    }
    #[doc = "returns a list of [l,r]. O(N)"]
    pub fn vertex_decomposition(&self) -> Vec<(usize, usize)> {
        let mut vhead = vec![self.n; self.n];
        for i in 0..self.n {
            vhead[i] = self.real_to_virt[self.heavy_head[i]];
        }
        let mut hs = std::collections::HashMap::new();
        for x in vhead {
            *hs.entry(x).or_insert(0) += 1;
        }
        let mut res = vec![];
        for (k, v) in hs {
            res.push((k, k + v - 1));
        }
        res
    }
    #[doc = "return a list of [l,r]. edge is represented by the child with larger virtual id. O(N)"]
    pub fn edge_decomposition(&self) -> Vec<(usize, usize)> {
        let V = self.vertex_decomposition();
        let mut res = vec![];
        for (u, v) in V {
            let u = if u == 0 { 1 } else { u };
            res.push((u, v));
        }
        res
    }
    #[doc = "O(logN)"]
    pub fn vertex_decomposition_between(&self, u: usize, v: usize) -> Vec<(usize, usize)> {
        let mut res = vec![];
        let mut l = u;
        let mut r = v;
        loop {
            if self.real_to_virt[l] > self.real_to_virt[r] {
                std::mem::swap(&mut l, &mut r);
            }
            let p = (
                std::cmp::max(self.real_to_virt[self.heavy_head[r]], self.real_to_virt[l]),
                self.real_to_virt[r],
            );
            res.push(p);
            if self.heavy_head[l] != self.heavy_head[r] {
                r = self.par[self.heavy_head[r]].unwrap();
            } else {
                break;
            }
        }
        res
    }
    #[doc = "O(logN)"]
    pub fn edge_decomposition_between(&self, u: usize, v: usize) -> Vec<(usize, usize)> {
        let mut res = vec![];
        let mut l = u;
        let mut r = v;
        loop {
            if self.real_to_virt[l] > self.real_to_virt[r] {
                std::mem::swap(&mut l, &mut r);
            }
            if self.heavy_head[l] != self.heavy_head[r] {
                let p = (self.real_to_virt[self.heavy_head[r]], self.real_to_virt[r]);
                res.push(p);
                r = self.par[self.heavy_head[r]].unwrap();
            } else {
                if l != r {
                    let p = (self.real_to_virt[l] + 1, self.real_to_virt[r]);
                    res.push(p);
                }
                break;
            }
        }
        res
    }
    pub fn distance(&self, u: usize, v: usize) -> usize {
        self.depth[u] + self.depth[v] - 2 * self.depth[self.lca(u, v)]
    }
}


//! Generic utility for reading data from standard input, based on [voxl's
//! stdin wrapper](http://codeforces.com/contest/702/submission/19589375).
#![allow(unused_imports)]
use std::cmp::{max, min};
use std::collections::{HashMap, HashSet, VecDeque};
use std::io::{self, BufWriter, Write};

#[derive(Default)]
struct Scanner {
    #[allow(dead_code)]
    buffer: Vec<String>,
}

impl Scanner {
    #[allow(dead_code)]
    fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            io::stdin().read_line(&mut input).expect("Failed read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
}

const MAX: usize = std::usize::MAX;

#[derive(Debug)]
struct DFS {
    tree: Vec<Vec<usize>>,
    parent: Vec<usize>,
    depth: Vec<usize>,
    t: u64,
    tin: Vec<u64>,
    tout: Vec<u64>,
}

impl DFS {
    fn new(tree: Vec<Vec<usize>>) -> Self {
        let n = tree.len();
        Self {
            tree,
            parent: vec![MAX; n],
            depth: vec![MAX; n],
            t: 0,
            tin: vec![std::u64::MAX; n],
            tout: vec![std::u64::MAX; n],
        }
    }

    fn dfs(&mut self) {
        self.dfs_helper(0, 0, 0);
    }

    fn dfs_helper(&mut self, curr: usize, par: usize, dep: usize) {
        self.parent[curr] = par;
        self.depth[curr] = dep;
        self.tin[curr] = self.t;
        self.t += 1;
        for &next in &self.tree[curr].clone() {
            self.dfs_helper(next, curr, dep + 1);
        }
        self.tout[curr] = self.t;
        self.t += 1;
    }

    // whether u is an ancestor of v
    fn is_ancestor(&self, u: usize, v: usize) -> bool {
        self.tin[u] <= self.tin[v] && self.tout[u] >= self.tout[v]
    }
}

fn solve<T: Write>(scan: &mut Scanner, out: &mut BufWriter<T>) {
    let n: usize = scan.next();
    let m: usize = scan.next();

    let mut tree: Vec<Vec<usize>> = vec![vec![]; n];
    for _ in 0..n - 1 {
        let u: usize = scan.next::<usize>() - 1;
        let v: usize = scan.next::<usize>() - 1;
        tree[u].push(v);
    }

    // dbg!(&tree);

    let mut sol = DFS::new(tree);
    sol.dfs();

    // dbg!(&sol);
    for _ in 0..m {
        let k: usize = scan.next();
        let nodes: Vec<usize> = (0..k).map(|_| scan.next::<usize>() - 1).collect();

        // except root and node at the max depth, replace each node by its parent
        // now check that all the (transformed) nodes are ancestors of the deepest node
        // note that a node is its own parent

        let mut deepest_node = nodes[0];
        for &node in &nodes {
            if sol.depth[node] > sol.depth[deepest_node] {
                deepest_node = node;
            }
        }

        let possible = nodes
            .iter()
            .map(|&v| if v != deepest_node { sol.parent[v] } else { v })
            .all(|v| sol.is_ancestor(v, deepest_node));

        if possible {
            writeln!(out, "YES").ok();
        } else {
            writeln!(out, "NO").ok();
        }
    }
}

fn main() {
    let mut scan = Scanner::default();
    let mut out = BufWriter::new(io::stdout());
    solve(&mut scan, &mut out);
}


//! Generic utility for reading data from standard input, based on [voxl's
//! stdin wrapper](http://codeforces.com/contest/702/submission/19589375).
#![allow(unused_imports)]
use std::cmp::{max, min};
use std::collections::{HashMap, HashSet, VecDeque};
use std::io::{self, BufWriter, Write};

#[derive(Default)]
struct Scanner {
    #[allow(dead_code)]
    buffer: Vec<String>,
}

impl Scanner {
    #[allow(dead_code)]
    fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            io::stdin().read_line(&mut input).expect("Failed read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
}

const MAX: usize = std::usize::MAX;

#[derive(Debug)]
struct DFS {
    tree: Vec<Vec<usize>>,
    parent: Vec<usize>,
    depth: Vec<usize>,
    t: u64,
    tin: Vec<u64>,
    tout: Vec<u64>,
}

impl DFS {
    fn new(tree: Vec<Vec<usize>>) -> Self {
        let n = tree.len();
        Self {
            tree,
            parent: vec![MAX; n],
            depth: vec![MAX; n],
            t: 0,
            tin: vec![std::u64::MAX; n],
            tout: vec![std::u64::MAX; n],
        }
    }

    fn dfs(&mut self) {
        self.dfs_helper(0, 0, 0);
    }

    fn dfs_helper(&mut self, curr: usize, par: usize, dep: usize) {
        self.parent[curr] = par;
        self.depth[curr] = dep;
        self.tin[curr] = self.t;
        self.t += 1;
        for &next in &self.tree[curr].clone() {
            if next != par {
                self.dfs_helper(next, curr, dep + 1);
            }
        }
        self.tout[curr] = self.t;
        self.t += 1;
    }

    // whether u is an ancestor of v
    fn is_ancestor(&self, u: usize, v: usize) -> bool {
        self.tin[u] <= self.tin[v] && self.tout[u] >= self.tout[v]
    }
}

fn solve<T: Write>(scan: &mut Scanner, out: &mut BufWriter<T>) {
    let n: usize = scan.next();
    let m: usize = scan.next();

    let mut tree: Vec<Vec<usize>> = vec![vec![]; n];
    for _ in 0..n - 1 {
        let u: usize = scan.next::<usize>() - 1;
        let v: usize = scan.next::<usize>() - 1;
        tree[u].push(v);
        tree[v].push(u);
    }

    // dbg!(&tree);

    let mut sol = DFS::new(tree);
    sol.dfs();

    // dbg!(&sol);
    for _ in 0..m {
        let k: usize = scan.next();
        let nodes: Vec<usize> = (0..k).map(|_| scan.next::<usize>() - 1).collect();

        // except root and node at the max depth, replace each node by its parent
        // now check that all the (transformed) nodes are ancestors of the deepest node
        // note that a node is its own parent

        let mut deepest_node = nodes[0];
        for &node in &nodes {
            if sol.depth[node] > sol.depth[deepest_node] {
                deepest_node = node;
            }
        }

        let possible = nodes
            .iter()
            .map(|&v| if v != deepest_node { sol.parent[v] } else { v })
            .all(|v| sol.is_ancestor(v, deepest_node));

        if possible {
            writeln!(out, "YES").ok();
        } else {
            writeln!(out, "NO").ok();
        }
    }
}

fn main() {
    let mut scan = Scanner::default();
    let mut out = BufWriter::new(io::stdout());
    solve(&mut scan, &mut out);
}


//! Generic utility for reading data from standard input, based on [voxl's
//! stdin wrapper](http://codeforces.com/contest/702/submission/19589375).
#![allow(unused_imports)]
use std::cmp::{max, min};
use std::collections::{HashMap, HashSet, VecDeque};
use std::io::{self, BufWriter, Write};

#[derive(Default)]
struct Scanner {
    #[allow(dead_code)]
    buffer: Vec<String>,
}

impl Scanner {
    #[allow(dead_code)]
    fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            io::stdin().read_line(&mut input).expect("Failed read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
}

type Node = usize;
type Tree = HashMap<Node, HashSet<Node>>;

// fn compute_paths(tree: &Tree, current_path: &mut HashSet<Node>, paths: &mut Vec<HashSet<Node>>) {
//     unimplemented!();
// }

fn dfs<T: Write>(
    out: &mut BufWriter<T>,
    tree: &Tree,
    curr: Node,
    current_path: &mut Vec<Node>,
    target: HashSet<Node>,
) -> bool {
    // writeln!(out, "dfs from: {}", curr).ok();
    if tree[&curr].is_empty() {
        // leaf node reached, now check for the target vertices
        let mut target = target.clone();
        for &mut n in current_path {
            // 1. node was required
            if target.contains(&n) {
                target.remove(&n);
            }

            // 2. any of node's children were required
            for &child in &tree[&n] {
                if target.contains(&child) {
                    target.remove(&child);
                }
            }

            // target is empty => we have found all the required nodes
            if target.is_empty() {
                return true;
            }
        }
        return false;
    }

    for &next in &tree[&curr] {
        current_path.push(next);
        if dfs(out, tree, next, current_path, target.clone()) {
            return true;
        }
        current_path.pop();
    }
    false
}

fn solve<T: Write>(scan: &mut Scanner, out: &mut BufWriter<T>) {
    // println!("inside solve()");
    let n: usize = scan.next();
    let m: usize = scan.next();

    let mut tree: Tree = HashMap::new();
    // println!("empty tree: {:?}", &tree);
    for _i in 0..n - 1 {
        // println!("reading line i: {}", i);
        let u: usize = scan.next();
        let v: usize = scan.next();
        let _ = tree.entry(v).or_default();
        let neighbours = tree.entry(u).or_default();
        (*neighbours).insert(v);
    }

    dbg!("tree: {:?}", &tree);

    for _ in 0..m {
        let k: usize = scan.next();
        let vertices: HashSet<Node> = (0..k).map(|_| scan.next()).collect();
        // writeln!(out, "search for: {:?}", &vertices).ok();
        if dfs(out, &tree, 1, &mut vec![1], vertices.clone()) {
            writeln!(out, "YES").ok();
        } else {
            writeln!(out, "NO").ok();
        }
    }
}

fn main() {
    // println!("inside main");
    let mut scan = Scanner::default();
    let mut out = BufWriter::new(io::stdout());
    // println!("about to call solve()");
    solve(&mut scan, &mut out);
}


//! Generic utility for reading data from standard input, based on [voxl's
//! stdin wrapper](http://codeforces.com/contest/702/submission/19589375).
#![allow(unused_imports)]
use std::cmp::{max, min};
use std::collections::{HashMap, HashSet, VecDeque};
use std::io::{self, BufWriter, Write};

#[derive(Default)]
struct Scanner {
    #[allow(dead_code)]
    buffer: Vec<String>,
}

impl Scanner {
    #[allow(dead_code)]
    fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            io::stdin().read_line(&mut input).expect("Failed read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
}

const MAX: usize = std::usize::MAX;

#[derive(Debug)]
struct DFS {
    tree: Vec<Vec<usize>>,
    parent: Vec<usize>,
    depth: Vec<usize>,
    t: usize,
    tin: Vec<usize>,
    tout: Vec<usize>,
}

impl DFS {
    fn new(tree: Vec<Vec<usize>>) -> Self {
        let n = tree.len();
        Self {
            tree,
            parent: vec![MAX; n],
            depth: vec![MAX; n],
            t: 0,
            tin: vec![MAX; n],
            tout: vec![MAX; n],
        }
    }

    fn dfs(&mut self) {
        self.dfs_helper(0, 0, 0);
    }

    fn dfs_helper(&mut self, curr: usize, par: usize, dep: usize) {
        self.parent[curr] = par;
        self.depth[curr] = dep;
        self.tin[curr] = self.t;
        self.t += 1;
        for &next in &self.tree[curr].clone() {
            self.dfs_helper(next, curr, dep + 1);
        }
        self.tout[curr] = self.t;
        self.t += 1;
    }

    // whether u is an ancestor of v
    fn is_ancestor(&self, u: usize, v: usize) -> bool {
        self.tin[u] <= self.tin[v] && self.tout[u] >= self.tout[v]
    }
}

fn solve<T: Write>(scan: &mut Scanner, out: &mut BufWriter<T>) {
    let n: usize = scan.next();
    let m: usize = scan.next();

    let mut tree: Vec<Vec<usize>> = vec![vec![]; n];
    for _ in 0..n - 1 {
        let u: usize = scan.next::<usize>() - 1;
        let v: usize = scan.next::<usize>() - 1;
        tree[u].push(v);
    }

    // dbg!(&tree);

    let mut sol = DFS::new(tree);
    sol.dfs();

    // dbg!(&sol);
    for _ in 0..m {
        let k: usize = scan.next();
        let nodes: Vec<usize> = (0..k).map(|_| scan.next::<usize>() - 1).collect();

        // except root and node at the max depth, replace each node by its parent
        // now check that all the (transformed) nodes are ancestors of the deepest node
        // note that a node is its own parent

        let mut deepest_node = nodes[0];
        for &node in &nodes {
            if sol.depth[node] > sol.depth[deepest_node] {
                deepest_node = node;
            }
        }

        let possible = nodes
            .iter()
            .map(|&v| if v != deepest_node { sol.parent[v] } else { v })
            .all(|v| sol.is_ancestor(v, deepest_node));

        if possible {
            writeln!(out, "YES").ok();
        } else {
            writeln!(out, "NO").ok();
        }
    }
}

fn main() {
    let mut scan = Scanner::default();
    let mut out = BufWriter::new(io::stdout());
    solve(&mut scan, &mut out);
}


//! Generic utility for reading data from standard input, based on [voxl's
//! stdin wrapper](http://codeforces.com/contest/702/submission/19589375).
#![allow(unused_imports)]
use std::cmp::{max, min};
use std::collections::{HashMap, HashSet, VecDeque};
use std::io::{self, BufWriter, Write};

#[derive(Default)]
struct Scanner {
    #[allow(dead_code)]
    buffer: Vec<String>,
}

impl Scanner {
    #[allow(dead_code)]
    fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            io::stdin().read_line(&mut input).expect("Failed read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
}

const MAX: usize = std::usize::MAX;

#[derive(Debug)]
struct DFS {
    tree: Vec<Vec<usize>>,
    parent: Vec<usize>,
    depth: Vec<usize>,
    t: u64,
    tin: Vec<u64>,
    tout: Vec<u64>,
}

impl DFS {
    fn new(tree: Vec<Vec<usize>>) -> Self {
        let n = tree.len();
        Self {
            tree,
            parent: vec![MAX; n],
            depth: vec![MAX; n],
            t: 0,
            tin: vec![std::u64::MAX; n],
            tout: vec![std::u64::MAX; n],
        }
    }

    fn dfs(&mut self) {
        self.dfs_helper(0, 0, 0);
    }

    fn dfs_helper(&mut self, curr: usize, par: usize, dep: usize) {
        self.parent[curr] = par;
        self.depth[curr] = dep;
        self.tin[curr] = self.t;
        self.t += 1;
        for &next in &self.tree[curr].clone() {
            if next != par {
                self.dfs_helper(next, curr, dep + 1);
            }
        }
        self.tout[curr] = self.t;
        self.t += 1;
    }

    // whether u is an ancestor of v
    fn is_ancestor(&self, u: usize, v: usize) -> bool {
        self.tin[u] <= self.tin[v] && self.tout[u] >= self.tout[v]
    }
}

fn solve<T: Write>(scan: &mut Scanner, out: &mut BufWriter<T>) {
    let n: usize = scan.next();
    let m: usize = scan.next();

    let mut tree: Vec<Vec<usize>> = vec![vec![]; n];
    for _ in 0..n - 1 {
        let u: usize = scan.next::<usize>() - 1;
        let v: usize = scan.next::<usize>() - 1;
        tree[u].push(v);
        // tree[v].push(u);
    }

    // dbg!(&tree);

    let mut sol = DFS::new(tree);
    sol.dfs();

    // dbg!(&sol);
    for _ in 0..m {
        let k: usize = scan.next();
        let nodes: Vec<usize> = (0..k).map(|_| scan.next::<usize>() - 1).collect();

        // except root and node at the max depth, replace each node by its parent
        // now check that all the (transformed) nodes are ancestors of the deepest node
        // note that a node is its own parent

        let mut deepest_node = nodes[0];
        for &node in &nodes {
            if sol.depth[node] > sol.depth[deepest_node] {
                deepest_node = node;
            }
        }

        let possible = nodes
            .iter()
            .map(|&v| if v != deepest_node { sol.parent[v] } else { v })
            .all(|v| sol.is_ancestor(v, deepest_node));

        if possible {
            writeln!(out, "YES").ok();
        } else {
            writeln!(out, "NO").ok();
        }
    }
}

fn main() {
    let mut scan = Scanner::default();
    let mut out = BufWriter::new(io::stdout());
    solve(&mut scan, &mut out);
}


//! Generic utility for reading data from standard input, based on [voxl's
//! stdin wrapper](http://codeforces.com/contest/702/submission/19589375).
#![allow(unused_imports)]
use std::cmp::{max, min};
use std::collections::{HashMap, HashSet, VecDeque};
use std::io::{self, BufWriter, Write};

#[derive(Default)]
struct Scanner {
    #[allow(dead_code)]
    buffer: Vec<String>,
}

impl Scanner {
    #[allow(dead_code)]
    fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            io::stdin().read_line(&mut input).expect("Failed read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
}

type Node = usize;
type Tree = HashMap<Node, HashSet<Node>>;

// fn compute_paths(tree: &Tree, current_path: &mut HashSet<Node>, paths: &mut Vec<HashSet<Node>>) {
//     unimplemented!();
// }

fn dfs<T: Write>(
    out: &mut BufWriter<T>,
    tree: &Tree,
    curr: Node,
    current_path: &mut Vec<Node>,
    target: HashSet<Node>,
) -> bool {
    // writeln!(out, "dfs from: {}", curr).ok();
    if tree[&curr].is_empty() {
        // leaf node reached, now check for the target vertices
        let mut target = target.clone();
        for &mut n in current_path {
            // 1. node was required
            if target.contains(&n) {
                target.remove(&n);
            }

            // 2. any of node's children were required
            for &child in &tree[&n] {
                if target.contains(&child) {
                    target.remove(&child);
                }
            }

            // target is empty => we have found all the required nodes
            if target.is_empty() {
                return true;
            }
        }
        return false;
    }

    for &next in &tree[&curr] {
        current_path.push(next);
        if dfs(out, tree, next, current_path, target.clone()) {
            return true;
        }
        current_path.pop();
    }
    false
}

fn solve<T: Write>(scan: &mut Scanner, out: &mut BufWriter<T>) {
    // println!("inside solve()");
    let n: usize = scan.next();
    let m: usize = scan.next();

    let mut tree: Tree = HashMap::new();
    // println!("empty tree: {:?}", &tree);
    for _i in 0..n - 1 {
        // println!("reading line i: {}", i);
        let u: usize = scan.next();
        let v: usize = scan.next();
        let _ = tree.entry(v).or_default();
        let neighbours = tree.entry(u).or_default();
        (*neighbours).insert(v);
    }

    // println!("tree: {:#?}", &tree);

    for _ in 0..m {
        let k: usize = scan.next();
        let vertices: HashSet<Node> = (0..k).map(|_| scan.next()).collect();
        // writeln!(out, "search for: {:?}", &vertices).ok();
        if dfs(out, &tree, 1, &mut vec![1], vertices.clone()) {
            writeln!(out, "YES").ok();
        } else {
            writeln!(out, "NO").ok();
        }
    }
}

fn main() {
    // println!("inside main");
    let mut scan = Scanner::default();
    let mut out = BufWriter::new(io::stdout());
    // println!("about to call solve()");
    solve(&mut scan, &mut out);
}


macro_rules! parse_line {
    ($t: ty) => ({
        let mut a_str = String::new();
        std::io::stdin().read_line(&mut a_str).expect("read error");
        let a_str = a_str.trim();
        a_str.parse::<$t>().expect("parse error")
    });
    ($($t: ty),+) => ({
        let mut a_str = String::new();
        std::io::stdin().read_line(&mut a_str).expect("read error");
        let mut a_iter = a_str.split_whitespace();
        (
            $(
            a_iter.next().unwrap().parse::<$t>().expect("parse error"),
            )+
        )
    })
}

#[allow(unused_macros)]
macro_rules! parse_line_to_vec {
    ($t: ty) => {{
        let mut a_str = String::new();
        std::io::stdin().read_line(&mut a_str).expect("read error");
        (a_str
            .split_whitespace()
            .map(|x| x.parse::<$t>().unwrap())
            .collect::<Vec<$t>>())
    }};
}

use std::io::Write;

fn dfs(u: usize, p: usize, d: usize, gr: &Vec<Vec<usize>>,
       lvls: &mut Vec<usize>, links: &mut Vec<Vec<usize>>) {
    lvls[u] = d;
    if u != p {
        let mut p = p;
        links[u].push(p);
        while links[u].len() <= links[p].len() {
            p = links[p][links[u].len() - 1];
            links[u].push(p);
        }
    }
    for &v in &gr[u] {
        if v == p {
            continue;
        }
        dfs(v, u, d + 1, gr, lvls, links);
    }
}

fn solve(writer: &mut std::io::BufWriter<std::io::Stdout>) {
    let (n, m) = parse_line!(usize, usize);
    let mut gr = vec![Vec::new(); n];
    for _ in 1..n {
        let (u, v) = parse_line!(usize, usize);
        gr[u - 1].push(v - 1);
        gr[v - 1].push(u - 1);
    }
    let mut lvls = vec![0; n];
    let mut links = vec![Vec::new(); n];
    dfs(0, 0, 0, &gr, &mut lvls, &mut links);
    for _ in 0..m {
        let mut v = parse_line_to_vec!(usize);
        v[0] = v.pop().unwrap();
        for x in &mut v {
            *x -= 1;
        }
        v.sort_unstable_by_key(|x| !lvls[*x]);
        if *v.last().unwrap() == 0 {
            v.pop();
        }
        if v.is_empty() {
            writeln!(writer, "YES").unwrap();
            continue;
        }
        let mut u = links[v[0]][0];
        let mut ptr = 0;
        'outer: loop {
            while ptr < v.len() && lvls[v[ptr]] == lvls[u] + 1 {
                if links[v[ptr]][0] != u {
                    break 'outer;
                }
                ptr += 1;
            }
            if ptr == v.len() {
                break;
            }
            let lvl = lvls[v[ptr]] - 1;
            let mut diff = lvls[u] - lvl;
            while diff > 0 {
                let step = std::mem::size_of_val(&diff) * 8 - 1 - diff.leading_zeros() as usize;
                diff -= 1 << step;
                u = links[u][step];
            }
        }
        writeln!(writer, "{}", if ptr == v.len() {"YES"} else {"NO"}).unwrap();
    }
}

fn main() {
    let mut writer = std::io::BufWriter::new(std::io::stdout());
    let tests = 1; // parse_line!(usize);
    for _ in 0..tests {
        solve(&mut writer);
    }
}


macro_rules! parse_line {
    ($t: ty) => ({
        let mut a_str = String::new();
        std::io::stdin().read_line(&mut a_str).expect("read error");
        let a_str = a_str.trim();
        a_str.parse::<$t>().expect("parse error")
    });
    ($($t: ty),+) => ({
        let mut a_str = String::new();
        std::io::stdin().read_line(&mut a_str).expect("read error");
        let mut a_iter = a_str.split_whitespace();
        (
            $(
            a_iter.next().unwrap().parse::<$t>().expect("parse error"),
            )+
        )
    })
}

#[allow(unused_macros)]
macro_rules! parse_line_to_vec {
    ($t: ty) => {{
        let mut a_str = String::new();
        std::io::stdin().read_line(&mut a_str).expect("read error");
        (a_str
            .split_whitespace()
            .map(|x| x.parse::<$t>().unwrap())
            .collect::<Vec<$t>>())
    }};
}

use std::io::Write;

fn dfs(u: usize, p: usize, d: usize, gr: &Vec<Vec<usize>>,
       lvls: &mut Vec<usize>, links: &mut Vec<Vec<usize>>) {
    lvls[u] = d;
    if u != p {
        let mut p = p;
        links[u].push(p);
        while links[u].len() <= links[p].len() {
            p = links[p][links[u].len() - 1];
            links[u].push(p);
        }
    }
    for &v in &gr[u] {
        if v == p {
            continue;
        }
        dfs(v, u, d + 1, gr, lvls, links);
    }
}

fn solve(writer: &mut std::io::BufWriter<std::io::Stdout>) {
    let (n, m) = parse_line!(usize, usize);
    let mut gr = vec![Vec::new(); n];
    for _ in 1..n {
        let (u, v) = parse_line!(usize, usize);
        gr[u - 1].push(v - 1);
        gr[v - 1].push(u - 1);
    }
    let mut lvls = vec![0; n];
    let mut links = vec![Vec::new(); n];
    dfs(0, 0, 0, &gr, &mut lvls, &mut links);
    eprintln!("{:?}", links);
    for _ in 0..m {
        let mut v = parse_line_to_vec!(usize);
        v[0] = v.pop().unwrap();
        for x in &mut v {
            *x -= 1;
        }
        v.sort_unstable_by_key(|x| !lvls[*x]);
        if *v.last().unwrap() == 0 {
            v.pop();
        }
        if v.is_empty() {
            writeln!(writer, "YES").unwrap();
            continue;
        }
        let mut u = links[v[0]][0];
        let mut ptr = 0;
        'outer: loop {
            while ptr < v.len() && lvls[v[ptr]] == lvls[u] + 1 {
                if links[v[ptr]][0] != u {
                    break 'outer;
                }
                ptr += 1;
            }
            if ptr == v.len() {
                break;
            }
            let lvl = lvls[v[ptr]] - 1;
            let mut diff = lvls[u] - lvl;
            while diff > 0 {
                let step = std::mem::size_of_val(&diff) * 8 - 1 - diff.leading_zeros() as usize;
                diff -= 1 << step;
                u = links[u][step];
            }
        }
        writeln!(writer, "{}", if ptr == v.len() {"YES"} else {"NO"}).unwrap();
    }
}

fn main() {
    let mut writer = std::io::BufWriter::new(std::io::stdout());
    let tests = 1; // parse_line!(usize);
    for _ in 0..tests {
        solve(&mut writer);
    }
}


use std::io::{stdin, stdout, BufWriter, Write};

#[derive(Default)]
struct Scanner {
    buffer: Vec<String>,
}

impl Scanner {
    fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            stdin().read_line(&mut input).expect("Failed read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
}

#[derive(Default, Clone)]
struct NodeData {
    dad: usize,
    depth: usize,
    discovery: usize,
    finish: usize,
}

fn dfs(node: usize, tick: &mut usize, v: &Vec<Vec<usize>>, node_data: &mut Vec<NodeData>) {
    node_data[node].discovery = *tick;
    *tick += 1;
    for nxt in &v[node] {
        if *nxt == node_data[node].dad {
            continue;
        }
        node_data[*nxt].dad = node;
        node_data[*nxt].depth = node_data[node].depth + 1;
        dfs(*nxt, tick, v, node_data);
    }
    node_data[node].finish = *tick;
}

fn query(mut q_vec: Vec<usize>, node_data: &Vec<NodeData>) -> bool {
    let mut pivot = 0;
    for node in &mut q_vec {
        if node_data[*node].depth > node_data[pivot].depth {
            pivot = *node;
        }
        if *node != 0 {
            *node = node_data[*node].dad;
        }
    }

    let mut ret = true;
    for node in &q_vec {
        ret &= node_data[*node].discovery <= node_data[pivot].discovery
            && node_data[*node].finish >= node_data[pivot].discovery;
    }

    ret
}

fn main() {
    let mut scanner = Scanner::default();
    let out = &mut BufWriter::new(stdout());

    let n = scanner.next::<usize>();
    let m = scanner.next::<usize>();

    let mut v: Vec<Vec<usize>> = vec![Vec::new(); n];
    for _ in 0..n - 1 {
        let a = scanner.next::<usize>() - 1;
        let b = scanner.next::<usize>() - 1;
        v[a].push(b);
        v[b].push(a);
    }

    let mut node_data = vec![
        NodeData {
            dad: n,
            ..Default::default()
        };
        n
    ];

    let mut tick = 0;
    dfs(0, &mut tick, &v, &mut node_data);

    for _ in 0..m {
        let k = scanner.next::<usize>();
        let q_vec: Vec<usize> = (0..k).map(|_| scanner.next::<usize>() - 1).collect();
        if query(q_vec, &node_data) {
            writeln!(out, "YES").ok();
        } else {
            writeln!(out, "NO").ok();
        }
    }
}


use std::io::{stdin, stdout, BufWriter, Write};

#[derive(Default)]
struct Scanner {
    buffer: Vec<String>,
}

impl Scanner {
    fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            stdin().read_line(&mut input).expect("Failed read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
}

#[derive(Default, Clone, Debug)]
struct NodeData {
    dad: usize,
    depth: usize,
    discovery: usize,
    finish: usize,
}

unsafe fn dfs(node: usize, v: &Vec<Vec<usize>>, node_data: &mut Vec<NodeData>) {
    static mut TICK: usize = 0;
    node_data[node].discovery = TICK;
    TICK += 1;
    for nxt in &v[node] {
        if *nxt == node_data[node].dad {
            continue;
        }
        node_data[*nxt].dad = node;
        node_data[*nxt].depth = node_data[node].depth + 1;
        dfs(*nxt, v, node_data);
    }
    node_data[node].finish = TICK;
}

fn query(mut q_vec: Vec<usize>, node_data: &Vec<NodeData>) -> bool {
    let mut pivot = 0;
    for node in &mut q_vec {
        if node_data[*node].depth > node_data[pivot].depth {
            pivot = *node;
        }
        if *node != 0 {
            *node = node_data[*node].dad;
        }
    }

    let mut ret = true;
    for node in &q_vec {
        ret &= node_data[*node].discovery <= node_data[pivot].discovery
            && node_data[*node].finish >= node_data[pivot].discovery;
    }

    ret
}

fn main() {
    let mut scanner = Scanner::default();
    let out = &mut BufWriter::new(stdout());

    let n = scanner.next::<usize>();
    let m = scanner.next::<usize>();

    let mut v: Vec<Vec<usize>> = vec![Vec::new(); n];
    for _ in 0..n - 1 {
        let a = scanner.next::<usize>() - 1;
        let b = scanner.next::<usize>() - 1;
        v[a].push(b);
        v[b].push(a);
    }

    let mut node_data = vec![
        NodeData {
            dad: n,
            ..Default::default()
        };
        n
    ];

    unsafe {
        dfs(0, &v, &mut node_data);
    }

    for _ in 0..m {
        let k = scanner.next::<usize>();
        let q_vec: Vec<usize> = (0..k).map(|_| scanner.next::<usize>() - 1).collect();
        if query(q_vec, &node_data) {
            writeln!(out, "YES").ok();
        } else {
            writeln!(out, "NO").ok();
        }
    }
}


#![allow(unused_imports)]
#![allow(dead_code)]

use std::cmp::{max, min};
use std::collections::HashMap;
use std::collections::HashSet;
use std::io::{stdin, stdout, BufWriter, Write};

#[derive(Default)]
struct Scanner {
    buffer: Vec<String>,
}

impl Scanner {
    fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().unwrap();
            }
            let mut input = String::new();
            stdin().read_line(&mut input).unwrap();
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
}

// #define MAXN 40001
// #define LOGN 16+1
// struct LCA {
//    int n, lg;
//    int timer;
//    bool used[MAXN];
//    int up[MAXN][LOGN];
//    int tin[MAXN], tout[MAXN];
//    int lca(int a, int b);
//    bool upper(int a, int b);
//    void dfs(const vector<vi>& g, int v, int p);
//    void dfs_iter(const vector<vi>& g, int root);
//    void prepare(const vector<vi>& g, int root);
// };

// void LCA::dfs(const vector<vi>& g, int v, int p) {
//    used[v] = true;
//    tin[v] = ++timer;
//    up[v][0] = p;
//    for (int i = 1; i <= lg; i++)
//       up[v][i] = up[up[v][i-1]][i-1];
//    rep(i, l(g[v]))
//       if (!used[g[v][i]])
//          dfs(g, g[v][i], v);
//    tout[v] = ++timer;
// }

// void LCA::prepare(const vector<vi>& g, int root) {
//    n = l(g);
//    CLEAR(used);
//    for (lg = 1; (1<<lg) <= n; lg++);
//    //dfs(g, root, root);
//    dfs_iter(g, root);
// }

// bool LCA::upper(int a, int b) {
//    return tin[a] <= tin[b] && tout[a] >= tout[b];
// }

// int LCA::lca(int a, int b) {
//    if (upper(a, b)) return a;
//    if (upper(b, a)) return b;
//    for (int i = lg; i >= 0; i--)
//       if (!upper(up[a][i], b))
//          a = up[a][i];
//    return up[a][0];
// }

fn dfs(v: usize, p: usize, g: &Vec<Vec<usize>>, par: &mut Vec<usize>, t_in: &mut Vec<i32>, t_out: &mut Vec<i32>, timer: &mut i32) {
    par[v] = p;
    *timer += 1;
    t_in[v] = *timer;
    for i in 0..g[v].len() {
        let v2 = g[v][i];
        if v2 != p {
            dfs(v2, v, g, par, t_in, t_out, timer);
        }
    }
    *timer += 1;
    t_out[v] = *timer;
}

fn solve<T: Write>(scan: &mut Scanner, out: &mut BufWriter<T>) {
    let n: usize = scan.next();
    let m: usize = scan.next();
    let mut g: Vec<Vec<usize>> = vec![Vec::new(); n];
    for _ in 0..n-1 {
        let u: usize = scan.next::<usize>() - 1;
        let v: usize = scan.next::<usize>() - 1;
        g[u].push(v);
        g[v].push(u);
    }
    let mut timer = 1;
    let mut par: Vec<usize> = vec![n; n];
    let mut t_in: Vec<i32> = vec![-1; n];
    let mut t_out: Vec<i32> = vec![-1; n];
    dfs(0, n, &g, &mut par, &mut t_in, &mut t_out, &mut timer);
    par[0] = 0;
    for _ in 0..m {
        let k: usize = scan.next();
        let a: Vec<usize> = (0..k).map(|_| scan.next::<usize>()-1).collect();
        let b: Vec<usize> = (0..k).map(|i| par[a[i]]).collect();
        let mut c: Vec<(i32, usize, i32)> = (0..k).map(|i| (t_in[b[i]], b[i], t_out[b[i]])).collect();
        c.sort();
        let mut ok = true;
        for i in 1..k {
            let x = c[i-1];
            let y = c[i];
            if y.2 > x.2 {
                ok = false;
            }
        }
        writeln!(out, "{}", if ok {"YES"} else {"NO"}).unwrap();
    }
}

fn main() {
    let mut scan = Scanner::default();
    let out = stdout();
    let mut out = BufWriter::new(out.lock());
    solve(&mut scan, &mut out);
}


#![allow(unused_imports)]
#![allow(dead_code)]

use std::cmp::{max, min};
use std::collections::HashMap;
use std::collections::HashSet;
use std::io::{stdin, stdout, BufWriter, Write};

#[derive(Default)]
struct Scanner {
    buffer: Vec<String>,
}

impl Scanner {
    fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().unwrap();
            }
            let mut input = String::new();
            stdin().read_line(&mut input).unwrap();
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
}

// #define MAXN 40001
// #define LOGN 16+1
// struct LCA {
//    int n, lg;
//    int timer;
//    bool used[MAXN];
//    int up[MAXN][LOGN];
//    int tin[MAXN], tout[MAXN];
//    int lca(int a, int b);
//    bool upper(int a, int b);
//    void dfs(const vector<vi>& g, int v, int p);
//    void dfs_iter(const vector<vi>& g, int root);
//    void prepare(const vector<vi>& g, int root);
// };

// void LCA::dfs(const vector<vi>& g, int v, int p) {
//    used[v] = true;
//    tin[v] = ++timer;
//    up[v][0] = p;
//    for (int i = 1; i <= lg; i++)
//       up[v][i] = up[up[v][i-1]][i-1];
//    rep(i, l(g[v]))
//       if (!used[g[v][i]])
//          dfs(g, g[v][i], v);
//    tout[v] = ++timer;
// }

// void LCA::prepare(const vector<vi>& g, int root) {
//    n = l(g);
//    CLEAR(used);
//    for (lg = 1; (1<<lg) <= n; lg++);
//    //dfs(g, root, root);
//    dfs_iter(g, root);
// }

// bool LCA::upper(int a, int b) {
//    return tin[a] <= tin[b] && tout[a] >= tout[b];
// }

// int LCA::lca(int a, int b) {
//    if (upper(a, b)) return a;
//    if (upper(b, a)) return b;
//    for (int i = lg; i >= 0; i--)
//       if (!upper(up[a][i], b))
//          a = up[a][i];
//    return up[a][0];
// }

fn dfs(v: usize, p: usize, g: &Vec<Vec<usize>>, par: &mut Vec<usize>, t_in: &mut Vec<i32>, t_out: &mut Vec<i32>, timer: &mut i32) {
    par[v] = p;
    *timer += 1;
    t_in[v] = *timer;
    for i in 0..g[v].len() {
        let v2 = g[v][i];
        if v2 != p {
            dfs(v2, v, g, par, t_in, t_out, timer);
        }
    }
    *timer += 1;
    t_out[v] = *timer;
}

fn solve<T: Write>(scan: &mut Scanner, out: &mut BufWriter<T>) {
    let n: usize = scan.next();
    let m: usize = scan.next();
    let mut g: Vec<Vec<usize>> = vec![Vec::new(); n];
    for _ in 0..n-1 {
        let u: usize = scan.next::<usize>() - 1;
        let v: usize = scan.next::<usize>() - 1;
        g[u].push(v);
        g[v].push(u);
    }
    let mut timer = 1;
    let mut par: Vec<usize> = vec![n; n];
    let mut t_in: Vec<i32> = vec![-1; n];
    let mut t_out: Vec<i32> = vec![-1; n];
    dfs(0, n, &g, &mut par, &mut t_in, &mut t_out, &mut timer);
    par[0] = 0;
    for _ in 0..m {
        let k: usize = scan.next();
        let a: Vec<usize> = (0..k).map(|_| scan.next::<usize>()-1).collect();
        let mut b: Vec<usize> = (0..k).map(|i| par[a[i]]).collect();
        b.sort();
        let mut ok = true;
        for i in 1..k {
            let x = b[i-1];
            let y = b[i];
            if !(t_in[x] <= t_in[y] && t_out[x] >= t_out[y]) && !(t_in[x] <= t_in[y] && t_out[x] >= t_out[y]) {
                ok = false;
            }
        }
        writeln!(out, "{}", if ok {"YES"} else {"NO"}).unwrap();
    }
}

fn main() {
    let mut scan = Scanner::default();
    let out = stdout();
    let mut out = BufWriter::new(out.lock());
    solve(&mut scan, &mut out);
}


#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
use std::io::{Write, BufWriter};
// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
macro_rules! input {
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

macro_rules! input_inner {
    ($next:expr) => {};
    ($next:expr, ) => {};

    ($next:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };
}

macro_rules! read_value {
    ($next:expr, ( $($t:tt),* )) => {
        ( $(read_value!($next, $t)),* )
    };

    ($next:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    };

    ($next:expr, chars) => {
        read_value!($next, String).chars().collect::<Vec<char>>()
    };

    ($next:expr, usize1) => {
        read_value!($next, usize) - 1
    };

    ($next:expr, [ $t:tt ]) => {{
        let len = read_value!($next, usize);
        (0..len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    }};

    ($next:expr, $t:ty) => {
        $next().parse::<$t>().expect("Parse error")
    };
}

#[allow(unused)]
macro_rules! debug {
    ($($format:tt)*) => (write!(std::io::stderr(), $($format)*).unwrap());
}
#[allow(unused)]
macro_rules! debugln {
    ($($format:tt)*) => (writeln!(std::io::stderr(), $($format)*).unwrap());
}

fn dfs(v: usize, p: usize, g: &[Vec<usize>], par: &mut [usize], euler: &mut [(i32, i32)], cnt: &mut i32) {
    par[v] = p;
    let st = *cnt;
    *cnt += 1;
    for &w in &g[v] {
        if p == w { continue; }
        dfs(w, v, g, par, euler, cnt);
    }
    let en = *cnt;
    euler[v] = (st, en);
}

fn solve() {
    let out = std::io::stdout();
    let mut out = BufWriter::new(out.lock());
    macro_rules! puts {
        ($($format:tt)*) => (let _ = write!(out,$($format)*););
    }
    input! {
        n: usize, m: usize,
        ab: [(usize1, usize1); n - 1],
        v: [[usize1]; m],
    }
    let mut g = vec![vec![]; n];
    for &(a, b) in &ab {
        g[a].push(b);
        g[b].push(a);
    }
    let mut par = vec![0; n];
    let mut euler = vec![(0, 0); n];
    let mut cnt = 0;
    dfs(0, n, &g, &mut par, &mut euler, &mut cnt);
    for v in v {
        let mut v: Vec<_> = v.into_iter().map(|v| if v == 0 { 0 } else { par[v] })
            .map(|v| euler[v]).collect();
        v.sort();
        let ok = (0..v.len() - 1).all(|i| {
            v[i].1 >= v[i + 1].1
        });
        puts!("{}\n", if ok { "YES" } else { "NO" });
    }
}

fn main() {
    // In order to avoid potential stack overflow, spawn a new thread.
    let stack_size = 104_857_600; // 100 MB
    let thd = std::thread::Builder::new().stack_size(stack_size);
    thd.spawn(|| solve()).unwrap().join().unwrap();
}


package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strconv"
)

var reader io.Reader
var scanner *bufio.Scanner

func Init(io io.Reader, max_token_size int) {
	reader = bufio.NewReader(io)
	scanner = bufio.NewScanner(reader)
	// max token size
	scanner.Split(bufio.ScanWords)
	scanner.Buffer([]byte{}, max_token_size)
}

func stderr(v ...interface{}) {
	fmt.Fprintln(os.Stderr, v...)
}

func die(v ...interface{}) {
	fmt.Fprintln(os.Stderr, v...)
	os.Exit(1)
}

func NextInt() int {
	bytes := NextBytes()
	i, err := Atoi(bytes)
	if err != nil {
		die(err)
	}
	return i
}
func NextInt64() int64 {
	bytes := NextBytes()
	i, err := Atoi64(bytes)
	if err != nil {
		die(err)
	}
	return i
}

func NextBytes() []byte {
	if !scanner.Scan() {
		die(scanner.Err())
	}
	bytes := scanner.Bytes()
	copied := make([]byte, len(bytes))
	copy(copied, bytes)
	return copied
}

func Atoi(b []byte) (int, error) {
	neg := false
	if b[0] == '+' {
		b = b[1:]
	} else if b[0] == '-' {
		neg = true
		b = b[1:]
	}
	n := 0
	for _, v := range b {
		if v < '0' || v > '9' {
			return 0, strconv.ErrSyntax
		}
		n = n*10 + int(v-'0')
	}
	if neg {
		return -n, nil
	}
	return n, nil
}

func Atoi64(b []byte) (int64, error) {
	neg := false
	if b[0] == '+' {
		b = b[1:]
	} else if b[0] == '-' {
		neg = true
		b = b[1:]
	}
	var n int64
	for _, v := range b {
		if v < '0' || v > '9' {
			return 0, strconv.ErrSyntax
		}
		n = n*10 + int64(v-'0')
	}
	if neg {
		return -n, nil
	}
	return n, nil
}

func ExtendByteArray(a []byte, size int) []byte {
	if size <= len(a) {
		return a
	} else {
		return append(a, make([]byte, size-len(a))...)
	}
}

func ExtendIntArray(a []int, size int) []int {
	if size <= len(a) {
		return a
	} else {
		return append(a, make([]int, size-len(a))...)
	}
}

func reverseInts(a []int) {
	for l, r := 0, len(a)-1; l < r; l, r = l+1, r-1 {
		a[l], a[r] = a[r], a[l]
	}
}

func unique(a []int) int {
	newLen := 0
	n := len(a)
	for i := 0; i < n; i++ {
		if newLen == 0 || a[i] != a[newLen-1] {
			a[newLen] = a[i]
			newLen++
		}
	}
	return newLen
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

type Graph struct {
	n     int
	m     int
	edges int
	fst   []int
	nxt   []int
	end   []int
}

func (g *Graph) Add(a, b int) {
	g.nxt[g.edges] = g.fst[a]
	g.fst[a] = g.edges
	g.end[g.edges] = b
	g.edges++
}

func (g *Graph) Adjacent(a int, fn func(b int)) {
	for u := g.fst[a]; u != -1; u = g.nxt[u] {
		fn(g.end[u])
	}
}

func NewGraph(n, m int) *Graph {
	g := &Graph{n, m, 0, make([]int, n), make([]int, m), make([]int, m)}
	for i := 0; i < n; i++ {
		g.fst[i] = -1
	}
	return g
}

type Tree struct {
	g *Graph
	// maxLogHeight int
	root   int
	parent []int
	// up           [][]int
	h        []int
	entrance []int
	exit     []int
}

func (t *Tree) GoDown(v int, par int, time int) int {
	t.parent[v] = par
	t.entrance[v] = time
	time++
	// for i := 1; i < t.maxLogHeight; i++ {
	// 	t.up[v][i] = t.up[t.up[v][i-1]][i-1]
	// }
	t.g.Adjacent(v, func(to int) {
		if to == par {
			return
		}
		t.h[to] = t.h[v] + 1
		time = t.GoDown(to, v, time)
	})
	t.exit[v] = time
	time++
	// stderr("vertex", v, "entrance", t.entrance[v], "exit", t.exit[v])
	return time
}

func (t *Tree) Prepare() {
	t.GoDown(t.root, t.root, 0)
}

func (t *Tree) IsParent(u, v int) bool {
	return t.entrance[u] <= t.entrance[v] && t.exit[u] >= t.exit[v]
}

// func (t *Tree) LCA(u, v int) int {
// 	if t.IsParent(u, v) {
// 		return u
// 	}
// 	for h := t.maxLogHeight - 1; h >= 0; {
// 		for h >= 0 && t.IsParent(t.up[u][h], v) {
// 			h--
// 		}
// 		if h >= 0 {
// 			u = t.up[u][h]
// 		}
// 	}
// 	return t.up[u][0]
// }

// func (t *Tree) Distance(u, v int) int {
// 	lca := t.LCA(u, v)
// 	// stderr("lca of", u, v, "is", lca)
// 	return t.h[u] + t.h[v] - 2*t.h[lca]
// }

func NewTree(g *Graph) *Tree {
	parent := make([]int, g.n)
	// !!!!!!!!!!!!!!!!!!!!!
	// var mh = 18
	// up := make([][]int, g.n)
	// for i := 0; i < g.n; i++ {
	// 	up[i] = make([]int, mh)
	// }
	h := make([]int, g.n)
	entrance := make([]int, g.n)
	exit := make([]int, g.n)
	return &Tree{g, 0, parent, h, entrance, exit}
}

func main() {
	inf := os.Stdin
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()
	// inf, err := os.Open("a.in")
	// if err != nil {
	// 	die(err)
	// }
	// out, err := os.Create("a.out")
	// if err != nil {
	// 	die(err)
	// }
	// defer out.Close()
	Init(inf, 1000010)

	n, m := NextInt(), NextInt()
	g := NewGraph(n, 2*(n-1))

	for i := 0; i < n-1; i++ {
		u, v := NextInt()-1, NextInt()-1
		g.Add(u, v)
		g.Add(v, u)
	}

	t := NewTree(g)
	t.Prepare()

	v := make([]int, 200000)
	for i := 0; i < m; i++ {
		k := NextInt()
		maxH := -1
		maxV := -1
		for j := 0; j < k; j++ {
			v[j] = NextInt() - 1
			if t.h[v[j]] > maxH {
				maxH = t.h[v[j]]
				maxV = v[j]
			}
		}
		u := t.parent[maxV]
		ok := true
		for j := 0; ok && j < k; j++ {
			if !t.IsParent(t.parent[v[j]], u) {
				ok = false
			}
		}
		if ok {
			fmt.Fprintln(out, "YES")
		} else {
			fmt.Fprintln(out, "NO")
		}
	}

}


package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func CF1328E(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()

	var n, q, v, w, k int
	Fscan(in, &n, &q)
	g := make([][]int, n)
	for i := 1; i < n; i++ {
		Fscan(in, &v, &w)
		v--
		w--
		g[v] = append(g[v], w)
		g[w] = append(g[w], v)
	}

	const mx = 19
	pa := make([][mx]int, n)
	dep := make([]int, n)
	var dfs func(v, p, d int)
	dfs = func(v, p, d int) {
		pa[v][0] = p
		dep[v] = d
		for _, w := range g[v] {
			if w != p {
				dfs(w, v, d+1)
			}
		}
	}
	dfs(0, -1, 0)
	for k := 0; k+1 < mx; k++ {
		for v := range pa {
			if p := pa[v][k]; p != -1 {
				pa[v][k+1] = pa[p][k]
			} else {
				pa[v][k+1] = -1
			}
		}
	}
	_lca := func(v, w int) int {
		if dep[v] > dep[w] {
			v, w = w, v
		}
		for k := 0; k < mx; k++ {
			if (dep[w]-dep[v])>>k&1 == 1 {
				w = pa[w][k]
			}
		}
		if v == w {
			return v
		}
		for k := mx - 1; k >= 0; k-- {
			if pa[v][k] != pa[w][k] {
				v, w = pa[v][k], pa[w][k]
			}
		}
		return pa[v][0]
	}

o:
	for ; q > 0; q-- {
		Fscan(in, &k)
		vs := make([]int, k)
		maxDep, maxV := 0, 0
		for i := range vs {
			Fscan(in, &v)
			v--
			if dep[v] > maxDep {
				maxDep, maxV = dep[v], v
			}
			vs[i] = v
		}
		for _, v := range vs {
			if dep[v]-dep[_lca(maxV, v)] > 1 {
				Fprintln(out, "NO")
				continue o
			}
		}
		Fprintln(out, "YES")
	}
}

func main() { CF1328E(os.Stdin, os.Stdout) }


package main

import (
	"bufio"
	"fmt"
	"os"
)

const N  = 200020
const LOG = 18

var n, m int
var a[N][] int
var dist[N] int
var dd[N] bool
var parent[N][LOG] int

func dfs(u int)  {
	dd[u] = true
	for _, v := range a[u] {
		if dd[v] == false {
			dist[v] = dist[u] + 1
			parent[v][0] = u
			dfs(v)
		}
	}
}

func makeLCA()  {
	parent[1][0] = 1
	dfs(1)
	for j := 1; j < LOG; j++ {
		for i := 1; i <= n; i++ {
			parent[i][j] = parent[parent[i][j - 1]][j - 1]
		}
	}
}

func isParentOfV(u int, v int) bool {
	if u == v {
		return true
	}

	var du = dist[u]
	var dv = dist[v]

	if du > dv {
		return false
	}

	var dx = dv - du
	for j := LOG - 1; j >= 0; j-- {
		if ((dx >> uint(j)) & 1) == 1 {
			v = parent[v][j]
		}
	}

	return u == v
}

func check(path[]int, node int) bool {
	for _, u := range path {
		var v = parent[u][0]
		if !isParentOfV(u, node) && !isParentOfV(v, node) {
			return false
		}
	}
	return true
}

func main()  {
	var reader = bufio.NewReader(os.Stdin)
	var writer = bufio.NewWriter(os.Stdout)
	defer writer.Flush()
	fmt.Fscanf(reader, "%d %d\n", &n, &m)

	for i := 1; i <= n; i++ {
		a[i] = make([]int, 0)
	}

	for i := 1; i < n; i++ {
		var u, v int
		fmt.Fscanf(reader, "%d %d\n", &u, &v)
		a[u] = append(a[u], v)
		a[v] = append(a[v], u)
	}

	makeLCA()

	for kk := 0; kk < m; kk++ {
		var ds = make([]int, 0)

		var could = false
		var sz int
		var pos = -1

		fmt.Fscanf(reader, "%d", &sz)
		for i := 0; i < sz; i++ {
			var u int
			fmt.Fscanf(reader, "%d", &u)
			ds = append(ds, u)
			if pos == -1 {
				pos = u
			} else if dist[u] > dist[pos] {
					pos = u
				}
		}
		fmt.Fscanf(reader, "\n")

		if check(ds, pos) {
			could = true
		}

		if check(ds, parent[pos][0]) {
			could = true
		}

		if could {
			fmt.Fprintf(writer, "YES\n")
		} else {
			fmt.Fprintf(writer, "NO\n")
		}
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
)

const N  = 200020
var n, m int
var a[N][] int
var dist[N] int
var dd[N] bool
var parent[N] int

func dfs(u int)  {
	dd[u] = true
	for _, v := range a[u] {
		if dd[v] == false {
			dist[v] = dist[u] + 1
			parent[v] = u
			dfs(v)
		}
	}
}

func main()  {
	var reader = bufio.NewReader(os.Stdin)
	var writer = bufio.NewWriter(os.Stdout)
	defer writer.Flush()
	fmt.Fscanf(reader, "%d %d\n", &n, &m)

	for i := 1; i <= n; i++ {
		a[i] = make([]int, 0)
	}

	for i := 1; i < n; i++ {
		var u, v int
		fmt.Fscanf(reader, "%d %d\n", &u, &v)
		a[u] = append(a[u], v)
		a[v] = append(a[v], u)
	}

	dfs(1)

	for kk := 0; kk < m; kk++ {
		var ds = make([]int, 0)

		var could = false

		var pathOne = make([]int, 0)
		var pathTwo = make([]int, 0)

		var sz int
		var pos = -1

		fmt.Fscanf(reader, "%d", &sz)
		for i := 0; i < sz; i++ {
			var u int
			fmt.Fscanf(reader, "%d", &u)
			ds = append(ds, u)
			if pos == -1 {
				pos = u
			} else if dist[u] > dist[pos] {
					pos = u
				}
		}
		fmt.Fscanf(reader, "\n")

		var pos2 = parent[pos]

		if pos == 1 {
			pos2 = 1
		}

		{
			var path[N] bool
			var t = pos
			for true {
				pathOne = append(pathOne, t)
				t = parent[t]
				if t == 0 {
					break
				}
			}
			// mark
			for _, u := range pathOne {
				path[u] = true
			}

			var fall = false
			for _, u := range ds {
				var subNode = u
				var parentNode = parent[u]
				if parentNode == 0 {
					parentNode = 1
				}
				if !path[subNode] && !path[parentNode] {
					fall = true
					break
				}
			}

			if !fall {
				could = true
			}
		}

		if pos2 != pos && !could {
			var path[N] bool
			var t = pos2
			for true {
				pathTwo = append(pathTwo, t)
				t = parent[t]
				if t == 0 {
					break
				}
			}
			// mark
			for _, u := range pathTwo {
				path[u] = true
			}

			var fall = false
			for _, u := range ds {
				var subNode = u
				var parentNode = parent[u]
				if parentNode == 0 {
					parentNode = 1
				}
				if !path[subNode] && !path[parentNode] {
					fall = true
					break
				}
			}
			if fall == false {
				could = true
			}
		}

		if could {
			fmt.Fprintf(writer, "YES\n")
		} else {
			fmt.Fprintf(writer, "NO\n")
		}
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
)

const N  = 200020
var n, m int
var a[N][] int
var dist[N] int
var dd[N] bool
var parent[N] int

func dfs(u int)  {
	dd[u] = true
	for _, v := range a[u] {
		if dd[v] == false {
			dist[v] = dist[u] + 1
			parent[v] = u
			dfs(v)
		}
	}
}

func main()  {
	var reader = bufio.NewReader(os.Stdin)
	var writer = bufio.NewWriter(os.Stdout)
	defer writer.Flush()
	fmt.Fscanf(reader, "%d %d\n", &n, &m)

	for i := 1; i <= n; i++ {
		a[i] = make([]int, 0)
	}

	for i := 1; i < n; i++ {
		var u, v int
		fmt.Fscanf(reader, "%d %d\n", &u, &v)
		a[u] = append(a[u], v)
		a[v] = append(a[v], u)
	}

	dfs(1)

	for kk := 0; kk < m; kk++ {
		var ds = make([]int, 0)

		var could = false

		var pathOne = make([]int, 0)
		var pathTwo = make([]int, 0)

		var path[N] bool

		var sz int
		var pos = -1

		fmt.Fscanf(reader, "%d", &sz)
		for i := 0; i < sz; i++ {
			var u int
			fmt.Fscanf(reader, "%d", &u)
			ds = append(ds, u)
			if pos == -1 {
				pos = u
			} else if dist[u] > dist[pos] {
					pos = u
				}
		}
		fmt.Fscanf(reader, "\n")

		var pos2 = parent[pos]

		if pos == 1 {
			pos2 = 1
		}

		{
			var t = pos
			for true {
				pathOne = append(pathOne, t)
				t = parent[t]
				if t == 0 {
					break
				}
			}
			// mark
			for _, u := range pathOne {
				path[u] = true
			}

			var cnt = 0
			for _, u := range ds {
				var subNode = u
				var parentNode = parent[u]
				if parentNode == 0 {
					parentNode = 1
				}
				if path[subNode] || path[parentNode] {
					cnt++
				}
			}
			if cnt == len(ds) {
				could = true
			}

			for _, u := range pathOne {
				path[u] = false
			}
		}

		{
			var t = pos2
			for true {
				pathTwo = append(pathTwo, t)
				t = parent[t]
				if t == 0 {
					break
				}
			}
			// mark
			for _, u := range pathTwo {
				path[u] = true
			}

			var cnt = 0
			for _, u := range ds {
				var subNode = u
				var parentNode = parent[u]
				if parentNode == 0 {
					parentNode = 1
				}
				if path[subNode] || path[parentNode] {
					cnt++
				}
			}
			if cnt == len(ds) {
				could = true
			}
		}

		if could {
			fmt.Fprintf(writer, "YES\n")
		} else {
			fmt.Fprintf(writer, "NO\n")
		}
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
)

const N  = 200020
var n, m int
var a[N][] int
var dist[N] int
var dd[N] bool
var parent[N] int

func dfs(u int)  {
	dd[u] = true
	for _, v := range a[u] {
		if dd[v] == false {
			dist[v] = dist[u] + 1
			parent[v] = u
			dfs(v)
		}
	}
}

func main()  {
	var reader = bufio.NewReader(os.Stdin)
	var writer = bufio.NewWriter(os.Stdout)
	defer writer.Flush()
	fmt.Fscanf(reader, "%d %d\n", &n, &m)

	for i := 1; i <= n; i++ {
		a[i] = make([]int, 0)
	}

	for i := 1; i < n; i++ {
		var u, v int
		fmt.Fscanf(reader, "%d %d\n", &u, &v)
		a[u] = append(a[u], v)
		a[v] = append(a[v], u)
	}

	dfs(1)

	for kk := 0; kk < m; kk++ {
		var ds = make([]int, 0)

		var could = false

		var pathOne = make([]int, 0)
		var pathTwo = make([]int, 0)

		var sz int
		var pos = -1

		fmt.Fscanf(reader, "%d", &sz)
		for i := 0; i < sz; i++ {
			var u int
			fmt.Fscanf(reader, "%d", &u)
			ds = append(ds, u)
			if pos == -1 {
				pos = u
			} else if dist[u] > dist[pos] {
					pos = u
				}
		}
		fmt.Fscanf(reader, "\n")

		var pos2 = parent[pos]

		if pos == 1 {
			pos2 = 1
		}

		{
			var path[N] bool
			var t = pos
			for true {
				pathOne = append(pathOne, t)
				t = parent[t]
				if t == 0 {
					break
				}
			}
			// mark
			for _, u := range pathOne {
				path[u] = true
			}

			var fall = false
			for _, u := range ds {
				var subNode = u
				var parentNode = parent[u]
				if parentNode == 0 {
					parentNode = 1
				}
				if !path[subNode] && !path[parentNode] {
					fall = true
					break
				}
			}

			if !fall {
				could = true
			}
		}

		if pos2 != pos {
			var path[N] bool
			var t = pos2
			for true {
				pathTwo = append(pathTwo, t)
				t = parent[t]
				if t == 0 {
					break
				}
			}
			// mark
			for _, u := range pathTwo {
				path[u] = true
			}

			var fall = false
			for _, u := range ds {
				var subNode = u
				var parentNode = parent[u]
				if parentNode == 0 {
					parentNode = 1
				}
				if !path[subNode] && !path[parentNode] {
					fall = true
					break
				}
			}
			if fall == false {
				could = true
			}
		}

		if could {
			fmt.Fprintf(writer, "YES\n")
		} else {
			fmt.Fprintf(writer, "NO\n")
		}
	}

}


package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
)

type BufferedWriter interface {
	Printf(format string, a ...interface{})
	Flush()
}

type writerImpl struct {
	*bufio.Writer
}

func NewBufferedWriter(writer io.Writer) BufferedWriter {
	return &writerImpl{Writer: bufio.NewWriter(writer)}
}

func (impl *writerImpl) Printf(f string, a ...interface{}) {
	fmt.Fprintf(impl.Writer, f, a...)
}

func (impl *writerImpl) Flush() {
	impl.Writer.Flush()
}

type WordScanner interface {
	NextInt() int
	NextInt64() int64
	NextString() string
}

type wordScannerImpl struct {
	*bufio.Scanner
}

func NewWordScanner(reader io.Reader) WordScanner {
	s := bufio.NewScanner(reader)
	s.Split(bufio.ScanWords)
	return &wordScannerImpl{Scanner: s}
}

func (impl *wordScannerImpl) NextInt() int {
	impl.Scan()
	bb := impl.Bytes()
	i := 0
	for _, b := range bb {
		i *= 10
		i += int(b - '0')
	}
	return i
}

func (impl *wordScannerImpl) NextInt64() int64 {
	impl.Scan()
	bb := impl.Bytes()
	i := int64(0)
	for _, b := range bb {
		i *= 10
		i += int64(b - '0')
	}
	return i
}

func (impl *wordScannerImpl) NextString() string {
	impl.Scan()
	return impl.Text()
}

var reader = NewWordScanner(os.Stdin)
var writer = NewBufferedWriter(os.Stdout)

type Node struct {
	Val    int64
	Parent *Node
}

func main() {
	defer writer.Flush()
	n, m := reader.NextInt64(), reader.NextInt64()
	nodes := map[int64]*Node{
		1: &Node{
			Val:    1,
			Parent: nil,
		},
	}
	for ; n > 1; n-- {
		u, v := reader.NextInt64(), reader.NextInt64()
		if nodes[u] == nil && nodes[v] == nil {
			panic("no node to attach to")
		}
		if nodes[u] != nil && nodes[v] != nil {
			panic("edge already exists") // should not happen?
		}
		if nodes[v] == nil {
			nodes[v] = &Node{
				Val:    v,
				Parent: nodes[u],
			}
		}
		if nodes[u] == nil {
			nodes[u] = &Node{
				Val:    u,
				Parent: nodes[v],
			}
		}
	}
	for ; m > 0; m-- {
		writer.Printf("%s\n", sol(nodes))
	}
}

func sol(nodes map[int64]*Node) string {
	k := reader.NextInt64()
	tmp := map[int64]bool{1: true}
	tail := int64(1)
	for ; k > 0; k-- {
		v := reader.NextInt64()
		if tmp[v] {
			continue
		}
		curr := nodes[v].Parent // start with parent
		if tmp[curr.Val] {
			continue
		}
		newTail := curr.Val
		for !tmp[curr.Val] {
			tmp[curr.Val] = true
			curr = curr.Parent
		}
		if curr.Val != tail {
			return "NO"
		}
		tail = newTail
	}
	return "YES"
}