#ifndef call_from_test
#include <bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
template<typename Vertex, typename Cluster, size_t LIM>
struct TopTree{
  enum Type { Compress, Rake, Edge, None };
  struct Node{
    Vertex* vs[2];
    Cluster dat,inv;
    Node* p;
    Node* q;
    Node* ch[2];
    bool rev,guard;
    Type type;
    Node():p(nullptr),q(nullptr),rev(false),guard(false),type(Type::None){}
  };

  static array<Node, LIM> pool;
  size_t ptr;

  TopTree():ptr(0){}

  inline Node* create(Vertex* u,Cluster w,Vertex* v){
    auto t=&(pool[ptr++]);
    t->vs[0]=u;t->vs[1]=v;t->dat=w;t->type=Type::Edge;
    t->inv=w;t->inv.toggle();
    return pushup(t);
  }

  inline Node* compress(Node* l,Node* r){
    auto t=&(pool[ptr++]);
    t->ch[0]=l;t->ch[1]=r;t->type=Type::Compress;
    return pushup(t);
  }

  inline Node* rake(Node* l,Node* r){
    auto t=&(pool[ptr++]);
    t->ch[0]=l;t->ch[1]=r;t->type=Type::Rake;
    return pushup(t);
  }

  int parent_dir(Node* t){
    Node* p=t->p;
    if(!p) return -1;
    if(p->guard) return -1;
    if(p->ch[0]==t) return 0;
    if(p->ch[1]==t) return 1;
    return -1;
  }

  inline Node* pushup(Node* const t){
    Node* const l=t->ch[0];
    Node* const r=t->ch[1];

    if(t->type==Type::Edge){
      if(!t->p){
	t->vs[0]->handle=t;
	t->vs[1]->handle=t;
      }else if(t->p->type==Type::Compress){
	if(parent_dir(t)==-1)
	  t->vs[0]->handle=t;
      }else if(t->p->type==Type::Rake){
	t->vs[0]->handle=t;
      }
    }else if(t->type==Type::Compress){
      assert(l->vs[1]==r->vs[0]);
      t->vs[0]=l->vs[0];
      t->vs[1]=r->vs[1];

      Cluster lf=l->dat;
      Cluster rg=r->inv;
      if(t->q){
	Node* q=t->q;
	assert(l->vs[1]==q->vs[1]);
	lf=Cluster::rake(l->dat,q->dat,q->vs[0]);
	rg=Cluster::rake(r->inv,q->dat,q->vs[0]);
      }
      t->dat=Cluster::compress(lf,r->vs[0],r->dat);
      t->inv=Cluster::compress(rg,r->vs[0],l->inv);

      l->vs[1]->handle=t;
      if(!t->p){
	t->vs[0]->handle=t;
	t->vs[1]->handle=t;
      }else if(t->p->type==Type::Compress){
	if(parent_dir(t)==-1)
	  t->vs[0]->handle=t;
      }else if(t->p->type==Type::Rake){
	t->vs[0]->handle=t;
      }
    }else if(t->type==Type::Rake){
      propagate(t);
      assert(l->vs[1]==r->vs[1]);
      t->vs[0]=l->vs[0];
      t->vs[1]=l->vs[1];
      t->dat=Cluster::rake(l->dat,r->dat,r->vs[0]);
    }else abort();
    return t;
  }

  void rotate(Node* t,Node* x,size_t dir){
    Node* y=x->p;
    int par=parent_dir_guard(x);
    propagate(t->ch[dir]);
    x->ch[dir^1]=t->ch[dir];
    t->ch[dir]->p=x;
    t->ch[dir]=x;
    x->p=t;
    t->p=y;
    if(~par) y->ch[par]=t;
    else if(y and y->type==Type::Compress) y->q=t;
    pushup(x);pushup(t);
    if(y and !y->guard) pushup(y);
  }

  inline void propagate(Node* t){
    if(t->type==Type::Compress){
      if(t->rev){
	assert(t->ch[0] and t->ch[1]);
	swap(t->ch[0],t->ch[1]);
	toggle(t->ch[0]);
	toggle(t->ch[1]);
	t->rev=false;
      }
    }
  }

  inline void toggle(Node* t){
    if(t->type==Type::Edge){
      swap(t->vs[0],t->vs[1]);
      swap(t->dat,t->inv);
    }else if(t->type==Type::Compress){
      swap(t->vs[0],t->vs[1]);
      swap(t->dat,t->inv);
      t->rev^=true;
    }else if(t->type==Type::Rake){
    }else abort();
  }

  void splay(Node* t){
    assert(t->type!=Type::Edge);
    propagate(t);

    while(~parent_dir(t)){
      Node* q=t->p;
      if(q->type!=t->type) break;
      if(~parent_dir(q) and q->p and q->p->type==q->type){
	Node* r=q->p;
	if(r->p) propagate(r->p);
	propagate(r);propagate(q);propagate(t);
	int qt_dir=parent_dir(t);
	int rq_dir=parent_dir(q);
	if(rq_dir==qt_dir){
	  rotate(q,r,rq_dir^1);
	  rotate(t,q,qt_dir^1);
	}else{
	  rotate(t,q,qt_dir^1);
	  rotate(t,r,rq_dir^1);
	}
      }else{
	if(q->p) propagate(q->p);
	propagate(q);propagate(t);
	int qt_dir=parent_dir(t);
	rotate(t,q,qt_dir^1);
      }
    }
  }

  void pusher(Node* t){
    if(!t) return;
    pusher(t->p);
    propagate(t);
  }

  int parent_dir_guard(Node* t){
    Node* p=t->p;
    if(!p) return -1;
    if(p->ch[0]==t) return 0;
    if(p->ch[1]==t) return 1;
    return -1;
  }

  Node* expose(Node* t){
    pusher(t);
    while(true){
      assert(t->type!=Type::Rake);
      if(t->type==Type::Compress) splay(t);
      Node* n=nullptr;
      {
	Node* p=t->p;
	if(!p) break;
	if(p->type==Type::Rake){
	  propagate(p);
	  splay(p);
	  n=p->p;
	}else if(p->type==Type::Compress){
	  propagate(p);
	  if(p->guard and ~parent_dir_guard(t)) break;
	  n=p;
	}else abort();
      }
      splay(n);
      int dir=parent_dir_guard(n);
      if(dir==-1 or n->p->type==Type::Rake) dir=0;
      if(dir==1){
	toggle(n->ch[dir]);
	propagate(n->ch[dir]);
	toggle(t);
	propagate(t);
      }
      int n_dir=parent_dir(t);
      if(~n_dir){
	Node* c=n->ch[dir];
	propagate(c);
	Node* r=t->p;
	propagate(r);
	r->ch[n_dir]=c;
	c->p=r;
	n->ch[dir]=t;
	t->p=n;
	pushup(c);pushup(r);pushup(t);pushup(n);
	splay(r);
      }else{
	Node* c=n->ch[dir];
	propagate(c);
	n->q=c;
	c->p=n;
	n->ch[dir]=t;
	t->p=n;
	pushup(c);pushup(t);pushup(n);
      }
      if(t->type==Type::Edge) t=n;
    }
    return t;
  }

  Node* link(Vertex* u,Cluster w,Vertex* v){
    if(!u->handle and !v->handle) return create(u,w,v);

    Node* nnu=(Node*)u->handle;
    Node* nnv=(Node*)v->handle;
    Node* ee=create(u,w,v);
    Node* ll=nullptr;

    if(!nnv) ll=ee;
    else{
      Node* vv=expose(nnv);
      propagate(vv);
      if(vv->vs[1]==v){
	toggle(vv);
	propagate(vv);
      }
      if(vv->vs[0]==v){
	Node* nv=compress(ee,vv);
	ee->p=nv;
	pushup(ee);
	vv->p=nv;
	pushup(vv);pushup(nv);
	ll=nv;
      }else{
	Node* nv=vv;
	Node* ch=nv->ch[0];
	propagate(ch);
	nv->ch[0]=ee;
	ee->p=nv;
	pushup(ee);

	Node* bt=nv->q;
	Node* rk=nullptr;
	if(bt){
	  propagate(bt);
	  rk=rake(bt,ch);
	  bt->p=rk;
	  ch->p=rk;
	  pushup(bt);pushup(ch);
	}else{
	  rk=ch;
	}
	nv->q=rk;
	rk->p=nv;
	pushup(rk);pushup(nv);
	ll=nv;
      }
    }

    if(nnu){
      Node* uu=expose(nnu);
      propagate(uu);
      if(uu->vs[0]==u){
	toggle(uu);
	propagate(uu);
      }
      if(uu->vs[1]==u){
	Node* tp=compress(uu,ll);
	uu->p=tp;
	ll->p=tp;
	pushup(uu);pushup(ll);pushup(tp);
      }else{
	Node* nu=uu;
	Node* ch=nu->ch[1];
	toggle(ch);
	propagate(ch);

	nu->ch[1]=ll;
	ll->p=nu;
	pushup(ll);

	Node* al=nu->q;
	Node* rk=nullptr;
	if(al){
	  propagate(al);
	  rk=rake(al,ch);
	  al->p=rk;
	  ch->p=rk;
	  pushup(al);pushup(ch);
	}else{
	  rk=ch;
	}
	nu->q=rk;
	rk->p=nu;
	pushup(rk);pushup(nu);
      }
    }
    return ee;
  }

  void set_toggle(Node* v){
    toggle(v);propagate(v);pushup(v);
  }

  void soft_expose(Vertex* u,Vertex* v){
    pusher((Node*)u->handle);
    pusher((Node*)v->handle);
    Node* root=expose((Node*)u->handle);

    if(u->handle==v->handle){
      if(root->vs[1]==u or root->vs[0]==v){
	set_toggle(root);
      }
      return;
    }

    root->guard=true;
    Node* soft=expose((Node*)v->handle);
    root->guard=false;

    pushup(root);
    if(parent_dir(soft)==0) set_toggle(root);
  }

  Cluster query(Vertex* u,Vertex* v){
    soft_expose(u,v);
    Node* root=(Node*)u->handle;
    propagate(root);

    if(root->vs[0]==u and root->vs[1]==v) return root->dat;
    if(root->vs[0]==u) return root->ch[0]->dat;
    if(root->vs[1]==v) return root->ch[1]->dat;
    propagate(root->ch[1]);
    return root->ch[1]->ch[0]->dat;
  }

  Cluster leaf(Vertex* v){
    Node* root=expose((Node*)v->handle);
    assert(root->vs[0]==v or root->vs[1]==v);
    assert(!root->p);
    if(root->vs[0]==v) set_toggle(root);
    return root->dat;
  }

  void print(){
    string name[]={"Compress", "Rake", "Edge", "None"};
    for(int i=0;i<(int)ptr;i++){
      auto t=&pool[i];
      cout<<i<<":"<<name[t->type]<<" "<<t->rev<<endl;
      cout<<(t->vs[0]->idx+1)<<" "<<(t->vs[1]->idx+1)<<endl;
      cout<<(t->ch[0]-(&pool[0]))<<" "<<(t->ch[1]-(&pool[0]))<<endl;
      cout<<":"<<t->dat.v<<endl;
      cout<<endl;
    }
  }

};
template<typename Vertex, typename Cluster, size_t LIM>
array<typename TopTree<Vertex, Cluster, LIM>::Node, LIM>
TopTree<Vertex, Cluster, LIM>::pool;

struct Vertex{
  void* handle;
  int idx;
  Vertex(int idx=-1):handle(nullptr),idx(idx){}
};

struct Cluster{
  int v;
  Cluster(int v=0):v(v){}
  void toggle(){}
  static Cluster compress(Cluster x,Vertex*,Cluster y){
    return Cluster(x.v+y.v);
  }
  static Cluster rake(Cluster x,Cluster y,Vertex*){
    return x;
    return Cluster(max(x.v,y.v));
  }
};
//END CUT HERE
#ifndef call_from_test

struct LowestCommonAncestor{
  int n,h;
  vector< vector<int> > G,par;
  vector<int> dep;
  LowestCommonAncestor(){}
  LowestCommonAncestor(int n):n(n),G(n),dep(n){
    h=1;
    while((1<<h)<=n) h++;
    par.assign(h,vector<int>(n,-1));
  }

  void add_edge(int u,int v){
    G[u].emplace_back(v);
    G[v].emplace_back(u);
  }

  void dfs(int v,int p,int d){
    par[0][v]=p;
    dep[v]=d;
    for(int u:G[v])
      if(u!=p) dfs(u,v,d+1);
  }

  void build(int r=0){
    dfs(r,-1,0);
    for(int k=0;k+1<h;k++)
      for(int v=0;v<n;v++)
        if(~par[k][v])
          par[k+1][v]=par[k][par[k][v]];
  }

  int lca(int u,int v){
    if(dep[u]>dep[v]) swap(u,v);
    for(int k=0;k<h;k++)
      if((dep[v]-dep[u])>>k&1)
        v=par[k][v];

    if(u==v) return u;

    for(int k=h-1;k>=0;k--)
      if(par[k][u]!=par[k][v])
        u=par[k][u],v=par[k][v];

    return par[0][u];
  }

  int distance(int u,int v){
    return dep[u]+dep[v]-dep[lca(u,v)]*2;
  }
};

//INSERT ABOVE HERE
const size_t LIM = 1e6;
TopTree<Vertex, Cluster, LIM> T;
using Node = TopTree<Vertex, Cluster, LIM>::Node;

Vertex vs[LIM];
signed AOJ_1595(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n;
  cin>>n;
  for(int i=0;i<n;i++){
    vs[i]=Vertex(i);
    vs[n+i]=Vertex(-(i+1)-1);
    T.link(vs+i,Cluster(0),vs+n+i);
  }

  for(int i=1;i<n;i++){
    int u,v;
    cin>>u>>v;
    u--;v--;
    T.link(vs+u,Cluster(1),vs+v);
  }

  for(int i=0;i<n;i++)
    cout<<(n-1)*2-T.leaf(vs+n+i).v<<"\n";

  return 0;
}

signed AOJ_GRL_5_C(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n;
  cin>>n;
  for(int i=0;i<n;i++){
    vs[i]=Vertex(i);
    vs[n+i]=Vertex(-(i+1)-1);
    T.link(vs+i,Cluster(0),vs+n+i);
  }

  LowestCommonAncestor lca(n);
  for(int i=0;i<n;i++){
    int k;
    cin>>k;
    for(int j=0;j<k;j++){
      int c;
      cin>>c;
      lca.add_edge(i,c);
      T.link(vs+i,Cluster(1),vs+c);
    }
  }
  lca.build();

  int q;
  cin>>q;
  for(int i=0;i<q;i++){
    int u,v;
    cin>>u>>v;
    cout<<lca.lca(u,v)<<"\n";
    if(u==v) continue;
    // cout<<u<<" "<<v<<":"<<lca.distance(u,v)<<" "<<T.query(vs+u,vs+v).v<<endl;
    assert(lca.distance(u,v)==T.query(vs+u,vs+v).v);
  }

  return 0;
}

signed main(){
  //AOJ_1595();
  AOJ_GRL_5_C();
  return 0;
}
#endif



Measured memory_bytes: 96488