use std::io::*;
use std::str::FromStr;
use std::clone::Clone;
use std::collections::VecDeque;

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

struct LowestCommonAncestor {
    root: usize, 
    n: usize, 
    log_n_max: usize, 
    graph: Vec<Vec<usize>>, 
    depth: Vec<i64>, 
    parent: Vec<Vec<i64>>
}

impl LowestCommonAncestor {
    fn new(graph: Vec<Vec<usize>>, root: usize, n: usize, log_n_max: usize) -> Self {
        let mut depth = vec![-1; n];
        let mut parent: Vec<Vec<i64>> = vec![vec![-1; log_n_max]; n];

        let mut stack = VecDeque::<usize>::new();
        stack.push_front(root);
        parent[root][0] = -1;
        depth[root] = 0;
        let mut used = vec![false; n];
        used[root] = true;
        while !stack.is_empty() {
            let node = stack.pop_front().unwrap();
            stack.push_front(node);
            for &child in &graph[node] {
                if used[child] {
                    continue;
                }
                parent[child][0] = node as i64;
                depth[child] = depth[node] + 1;
                used[child] = true;
                stack.push_front(child);
            }

            let head = stack.pop_front().unwrap();
            if head != node {
                stack.push_front(head);
            }
        }

        for k in 0..(log_n_max-1) {
            for i in 0..n {
                if parent[i][k] != -1 {
                    parent[i][k+1] = parent[parent[i][k] as usize][k];
                }
            }
        }

        LowestCommonAncestor {
            root: root, 
            n: n, 
            log_n_max: log_n_max, 
            graph: graph, 
            depth: depth, 
            parent: parent, 
        }
    }

    fn get_lca(&self, u: usize, v: usize) -> usize {
        let (mut u, mut v) = if self.depth[u] > self.depth[v] {
            (v, u)
        } else {
            (u, v)   
        };

        for k in 0..self.log_n_max {
            if (self.depth[v] - self.depth[u]) & (1 << k) != 0 {
                v = self.parent[v][k] as usize;
            }
        }
        if u == v {
            return u;
        }

        for k in (0..self.log_n_max).rev() {
            if self.parent[u][k] != self.parent[v][k] {
                u = self.parent[u][k] as usize;
                v = self.parent[v][k] as usize;
            }
        }
        self.parent[u][0] as usize
    }
}

fn main() {
    let n: usize = read();
    let mut graph = vec![Vec::new(); n];
    for k in 0..n {
        let m: usize = read();
        for i in 0..m {
            let c: usize = read();
            graph[k].push(c);
        }
    }

    let mut lca = LowestCommonAncestor::new(graph, 0, n, 30);

    let q: usize  = read();
    for _ in 0..q {
        let u: usize = read();
        let v: usize = read();
        println!("{}", lca.get_lca(u, v));
    }
}


Measured memory_bytes: 43840