#include <iostream>
#include <vector>
#include <stdio.h>
#include <bits/stdc++.h>
 
using namespace std;
#define ll long long
#define ld long double
#define  P pair<ll,ll>
#define FOR(i,n,m) for(ll i=n; i<(ll)m;i++)
#define FORa(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define FORr(i,m,n) for(ll i=n; i>=(ll)m; i--)
#define FORm(i,m) for(auto i=m.begin();i!=m.end();i++)
#define FORs(i,st) for(auto i : st)
#define REP(i,n) for(int i=0;i<(int)n;++i)
#define ALL(c) (c).begin(), (c).end()
#define VEC2(x,a,b) vector<vector<ll>> x = vector<vector<ll>>(a,vector<ll>(b,0))
#define sortAl(v) sort(v.begin(),v.end())
#define sortAlr(v) sort(v.begin(),v.end()); reverse(v.begin(),v.end())
#define cinv(v,n,m) FOR(i,n,m) cin>>v.at(i)
#define coutv(v,n,m) FOR(i,n,m) cout<<v.at(i) <<" "; cout<<endl
#define cout(n) cout<<fixed<<setprecision(n)
 
# define FORq(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
typedef int Weight;
struct Edge {
  int src, dst;
  Weight weight;
  Edge(int src, int dst, Weight weight) :
    src(src), dst(dst), weight(weight) { }
};
bool operator < (const Edge &e, const Edge &f) {
  return e.weight != f.weight ? e.weight > f.weight : // !!INVERSE!!
    e.src != f.src ? e.src < f.src : e.dst < f.dst;
}
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
 
typedef vector<Weight> Array;
typedef vector<Array> Matrix;
 
struct UnionFind {
  vector<int> data;
  UnionFind(int size) : data(size, -1) { }
  bool unionSet(int x, int y) {
    x = root(x); y = root(y);
    if (x != y) {
      if (data[y] < data[x]) swap(x, y);
      data[x] += data[y]; data[y] = x;
    }
    return x != y;
  }
  bool findSet(int x, int y) {
    return root(x) == root(y);
  }
  int root(int x) {
    return data[x] < 0 ? x : data[x] = root(data[x]);
  }
  int size(int x) {
    return -data[root(x)];
  }
};
 
 
struct Query {
  int v, id; // 相手の頂点とクエリ id
  Query(int v, int i) : v(v), id(i) { }
};
void visit(const Graph &g, int u, int w,
    vector<vector<Query>> &qs, vector<int> &color,
    vector<int> &ancestor, UnionFind &uf, vector<int>& ans) {
  ancestor[ uf.root(u) ] = u;
  FORq(e, g[u]) if (e->dst != w) {
    visit(g, e->dst, u, qs, color, ancestor, uf, ans);
    uf.unionSet( e->src, e->dst );
    ancestor[ uf.root(u) ] = u;
  }
  color[u] = 1;
  for(auto const& q : qs[u]) {
    if (q.v >= 0 && color[q.v]) ans[q.id] = ancestor[ uf.root(q.v) ];
  }
}
void leastCommonAncestor(const Graph &g, int r, vector<vector<Query>> &qs, vector<int>& ans) {
  UnionFind uf(g.size());
  vector<int> color(g.size()), ancestor(g.size());
  visit(g, r, -1, qs, color, ancestor, uf, ans);
}
 
int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
 
    ll n;
    cin>>n;
    Graph g(n);
    FOR(i,0,n){
      ll round;
      cin>>round;
      FOR(j,0,round){
        ll t1 = i;
        ll t2;
        cin>>t2;
        g[t1].push_back(Edge(t1,t2,1));
      }
    }
 
    int q;
    cin>>q;
    vector<vector<Query>> qs(n);
 
    FOR(i,0,q){
      int in1,in2;
      cin>>in1>>in2;
      qs[in1].emplace_back(in2, i);
      qs[in2].emplace_back(in1, i);
    }
    vector<int> ans(q);
    leastCommonAncestor(g,0,qs, ans);
 
    FOR(i,0,q){
      cout<< ans[i] <<endl;
    }
}


Measured memory_bytes: 34896