#include<bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
using namespace std;
typedef vector<int> vi;

vi MSB;
void initMSB(int n){
  MSB = vi(n+1,0);
  int k = 2;
  rep(i,n){
    if(i+1==k)MSB[i+1] = MSB[i] + 1, k<<=1;
    else MSB[i+1] = MSB[i];
  }
}

struct SparseTable{
  vi val;
  vector<vi> table;

  SparseTable(void){}
  SparseTable(const vi a):val(a){
    int n = a.size();
    initMSB(n);
    table = vector<vi>(n,vi(MSB[n]+1,0));
    rep(i,n)table[i][0] = i;

    int k = 1;
    rep(j,MSB[n]){
      rep(i,n){
	int id1 = table[i][j], id2 = (i+k<n)?table[i+k][j]:id1;
	table[i][j+1] = (val[id1]<=val[id2])?id1:id2;
      }
      k <<= 1;
    }
  }

  int rmqi(int l, int r){
    int ln = MSB[r-l];
    int id1 = table[l][ln], id2 = table[r-(1<<ln)][ln];
    return (val[id1]<=val[id2])?id1:id2;
  }

  int rmq(int l, int r){ return val[rmqi(l,r)]; }
};

struct dif1RMQ{
  int s;
  vi val, subval, subid, bit;
  SparseTable st;
  vector< vector<vi> > lookup_table;

  dif1RMQ(void){}
  dif1RMQ(const vi a):val(a){
    int n = a.size();
    initMSB(n);
    s = max(1,MSB[n]/2);
    int m = (n+s-1)/s;

    subval.resize(m); subid.resize(m); bit.resize(m);
    rep(i,m){
      subval[i] = val[s*i]; subid[i] = s*i;
      int lim = min(s*(i+1),n);
      for(int j=s*i;j<lim;j++){
	if(subval[i] > val[j]){ subval[i] = val[j]; subid[i] = j; }
      }
      bit[i] = 0;
      for(int j=s*i;j<lim-1;j++){
	if(val[j]<val[j+1])bit[i] |= 1<<(j-s*i+1);
      }
    }
    st = SparseTable(subval);

    lookup_table.resize(1<<s);
    rep(i,1<<s)lookup_table[i] = vector<vi>(s, vi(s,0));
      
    rep(i,1<<s)rep(j,s){
      int cur = 0, minv = 0, minid = j;
      lookup_table[i][j][j] = j;
      for(int k=j+1;k<s;k++){
	if( (i>>k)&1 )cur++;
	else cur--;
	if(minv > cur){ minv = cur; minid = k; }
	lookup_table[i][j][k] = minid;
      }
    }
  }

  int rmqi(int l, int r){
    //cerr << l << " " << r << endl;
    r--;
    int bl = l/s, br = r/s;
    if(bl == br)return lookup_table[bit[bl]][l-bl*s][r-br*s] + bl*s;
    else{
      //cerr << bit[bl] << " "<< bl << " " << s << endl;
      //cerr << bit[br] << " "<< br << " " << s << endl;
      int res = lookup_table[bit[bl]][l-bl*s][s-1] + bl*s;
      int tmp = lookup_table[bit[br]][0][r-br*s] + br*s;

      //cerr << res << " " << tmp << endl;
      if(val[res] > val[tmp])res = tmp;
      if(br-bl>1){
	tmp = subid[st.rmqi(bl+1,br)];
	if(val[res] > val[tmp])res = tmp;
      }
      return res;
    }
  }

  int rmq(int l, int r){ return val[rmqi(l,r)]; }
};

struct LCA{
  vi tour, depth, id;
  dif1RMQ dr;
  
  LCA(void){}
  LCA(const vector<vi> t,int root){
    int n = t.size(), k = 0;
    tour.resize(2*n-1); depth.resize(2*n-1); id.resize(n);
    dfs(root,-1,0,k,t);
    /*
    rep(i,2*n-1)cerr << tour[i] << " "; cerr << endl;
    rep(i,2*n-1)cerr << depth[i] << " "; cerr << endl;
    rep(i,n)cerr << id[i] << " "; cerr << endl;
    */
    dr = dif1RMQ(depth);
  }

  void dfs(int v,int p, int d, int &k, const vector<vi> &t){
    id[v] = k; tour[k] = v;
    depth[k++] = d;
    for(int u : t[v]){
      if(u != p){
	dfs(u,v,d+1,k,t);
	tour[k] = v;
	depth[k++] = d;
      }
    }
  }

  int lca(int u, int v){
    int a = min(id[u],id[v]), b = max(id[u],id[v]);
    //cerr << dr.rmqi(a,b+1) << endl;
    return tour[dr.rmqi(a,b+1)];
  }
  int dep(int v){ return depth[id[v]]; }
};

int main(){
  int n;
  cin >> n;
  vector<vi> g(n);
  rep(i,n){
    int k;
    cin >> k;
    rep(j,k){
      int c;
      cin >> c;
      g[i].push_back(c);
    }
  }
  LCA lca(g,0);
  
  int q;
  cin >> q;
  rep(i,q){
    int a,b;
    cin >> a >> b;
    int x = lca.lca(a,b);
    cout << x << endl;
  }
}

Measured memory_bytes: 21524