#include <algorithm>
#include <vector>

template <typename T>
struct RMQ {
  using Index = int;
  using BitIndex = int;

  const std::vector<T>& A;
  const int N, S, L;

  std::vector<int> lg;
  std::vector<BitIndex> small;
  std::vector<std::vector<Index>> large;

  bool f(Index a, Index b) const {
    if (A[a] != A[b]) return A[a] < A[b];
    return a < b;
  }
  RMQ(const std::vector<T>& A) : RMQ(A, A.size()) {}
  Index query(Index l, Index r) const {
    const int a = l / S, b = r / S;
    if (a == b) return query_small(l, r);

    Index ans = F(query_small(l, a * S + (S - 1)), query_small(b * S, r));
    if (a + 1 <= b - 1) ans = F(ans, query_large(a + 1, b - 1));
    return ans;
  }

private:
  Index F(Index a, Index b) const { return f(a, b) ? a : b; }

  RMQ(const std::vector<T>& A, int N) : RMQ(A, N, std::__lg(N) + 1) {}
  RMQ(const std::vector<T>& A, int N, int S) : RMQ(A, N, S, (N + S - 1) / S) {}
  RMQ(const std::vector<T>& A, int N, int S, int L) : RMQ(A, N, S, L, std::__lg(L) + 1) {}
  RMQ(const std::vector<T>& A, int N, int S, int L, int LG_L)
      : A(A), N(N), S(S), L(L), lg(1 << S), small(N), large(L, std::vector<Index>(LG_L)) {
    for (int i = 1, sz = lg.size(); i < sz; i++) {
      lg[i] = std::__lg(i);
    }
    for (int li = 0; li < L; li++) {
      int i = li * S;
      large[li][0] = i;
      for (int si = 0; si < S && i + si < N; si++) {
        large[li][0] = F(large[li][0], i + si);
      }
    }
    for (int x = 0; x < LG_L - 1; x++) {
      for (int li = 0; li + (1 << x) < L; li++) {
        large[li][x + 1] = F(large[li][x], large[li + (1 << x)][x]);
      }
    }
    std::vector<Index> st;
    for (int li = 0; li < L; li++) {
      int i = li * S;
      st.clear();
      for (int si = 0; si < S && i + si < N; si++) {
        while (!st.empty() && f(i + si, st.back())) st.pop_back();
        small[i + si] |= 1 << si;
        if (!st.empty()) small[i + si] |= small[st.back()];
        st.push_back(i + si);
      }
    }
  }
  int ntz(int x) const { return lg[x & -x]; }
  int bitmask(int l, int r) const { return ((1 << (r - l + 1)) - 1) << l; }
  Index query_small(Index l, Index r) const { return (l - l % S) + ntz(small[r] & bitmask(l % S, r % S)); }
  Index query_large(Index l, Index r) const {
    int x = lg[r - l + 1];
    return F(large[l][x], large[r - (1 << x) + 1][x]);
  }
};
#include <vector>
#include <unordered_map>

struct EulerTour {
  using tree_type = std::vector<std::vector<int>>;
  tree_type T;
  std::vector<int> id, depth;
  std::vector<int> ord;

  EulerTour(int N) : T(N), ord(N) {}

  void add_edge(int s, int t) {
    T[s].push_back(t);
    T[t].push_back(s);
  }

  void build(int root) {
    id.reserve(T.size() * 3);
    depth.reserve(T.size() * 3);
    traverse(root);
    id.shrink_to_fit();
    depth.shrink_to_fit();
  }

  void traverse(int u, int p=-1, int d=0) {
    ord[u] = id.size();
    id.push_back(u);
    depth.push_back(d);
    for (int v : T[u]) {
      if (v == p) continue;
      traverse(v, u, d + 1);
      id.push_back(u);
      depth.push_back(d);
    }
  }
};
#include <vector>

struct LCA {
  EulerTour& euler_tour;
  const RMQ<int> rmq;

  LCA(EulerTour& euler_tour) : euler_tour(euler_tour), rmq(euler_tour.depth) {}

  int query(int u, int v) const {
    int l = euler_tour.ord[u];
    int r = euler_tour.ord[v];
    if (r < l) std::swap(r, l);
    int x = rmq.query(l, r);
    return euler_tour.id[x];
  }
};

#include <bits/stdc++.h>
using namespace std;

inline int in(){ int x; scanf("%d", &x); return x; }
inline void pr(int x) { printf("%d\n", x); }

int main() {
  // std::freopen("in31.txt", "r", stdin);
  int N = in();
  EulerTour et(N);
  for (int i = 0; i < N; i++) {
    int k = in();
    for (int j = 0; j < k; j++) {
      et.add_edge(i, in());
    }
  }
  et.build(0);
  LCA lca(et);
  int Q = in();
  for (int i = 0; i < Q; i++) {
    int u = in(), v = in();
    pr(lca.query(u, v));
  }
  return 0;
}

Measured memory_bytes: 16692