#include<vector>
#include<algorithm>
#include<iostream>
#include<utility>
#include<climits>
using namespace std;


class SparseTableRMQ{
	int maxlog;
	std::vector<int> a;
	std::vector<char> log;
	std::vector<int> M;
public:
	SparseTableRMQ(){}
	void build(const std::vector<int> &a){
		this->a=a;
		int n=a.size();
		log.resize(n+1);
		log[0]=0;
		for(int i=1,a=0;i<=n;i++){
			if((1<<a+1)<i)a++;
			log[i]=a;
		}
		maxlog=log[n]+1;
		M.resize(n*maxlog);
		for(int i=0;i<n;i++)M[i*maxlog]=i;
		for(int j=1;1<<j<=n;j++){
			for(int i=0;i+(1<<j)-1<n;i++){
				int n=M[i*maxlog+j-1];
				int m=M[(i+(1<<j-1))*maxlog+j-1];
				M[i*maxlog+j] = a[n]<a[m]?n:m;
			}
		}
	}
	int query(int i,int j)const{//[i,j)の最小値
		int k=log[j-i];
		int n=M[i*maxlog+k];
		int m=M[(j-(1<<k))*maxlog+k];
		return a[n]<a[m]?n:m;
	}
};



class RMQsub1{
	std::vector<int> pattern;
	std::vector<std::vector<int> > minpos;
	std::vector<int> depth;
	SparseTableRMQ rmq;
	int blocksize;
	int n;
public:
	RMQsub1(){}
	void build(std::vector<int> &a){
		depth=a;
		std::vector<int> B;
		int n=a.size();
		int k=1;
		while((1<<k)<a.size())k++;
		blocksize=k>>1;//log(n)/2
		if(blocksize==0)blocksize=1;
		int m=(n+blocksize-1)/blocksize;//num node
		while(m&m-1)m+=m&-m;
		this->n=m;
		pattern.resize(n,-1);
		minpos.resize(1<<blocksize-1);
		B.resize((n+blocksize-1)/blocksize);
		for(int i=0;i<(n+blocksize-1)/blocksize;i++){
			int s=i*blocksize;
			int p=0;
			for(int j=1;j<blocksize&&s+j<n;j++){
				if(a[s+j-1]>a[s+j])p|=1<<j-1;
			}
			pattern[i]=p;
			int b=(i+1)*blocksize<=n?blocksize:n-i*blocksize;
			if(minpos[p].empty()){
				minpos[p].resize(blocksize*blocksize);
				for(int j=0;j<blocksize;j++){
					int d=0,pos=j,mind=0;
					minpos[p][j*blocksize+j]=pos;
					for(int k=j+1;k<blocksize;k++){	
						if(p>>k-1&1)d--;
						else d++;
						if(d<mind){
							mind=d;
							pos=k;
						}
						minpos[p][j*blocksize+k]=pos;
					}
				}
			}
			B[i]=depth[s+minpos[p][0+b-1]];
		}
		rmq.build(B);
	}
	int query(int a,int b)const{//[a,b)の最小値
		b--;
		int ab=a/blocksize,bb=b/blocksize;
		if(ab==bb)return ab*blocksize + minpos[pattern[ab]][(a%blocksize)*blocksize+b%blocksize];
		int i,j;
		i=ab*blocksize + minpos[pattern[ab]][(a%blocksize)*blocksize+blocksize-1];
		j=bb*blocksize + minpos[pattern[bb]][0+b%blocksize];
		if(depth[i]>depth[j])i=j;
		if(ab+1==bb)return i;
		j=rmq.query(ab+1,bb);
		j=j*blocksize + minpos[pattern[j]][0+blocksize-1];
		if(depth[i]>depth[j])i=j;
		return i;
	}
};


class LCA{
	vector<int> eulertour;
	vector<int> vertex;
	//SparseTableRMQ rmq;
	//RMQ rmq;
	RMQsub1 rmq;
	void dfs(const vector<int> edge[],int n,vector<int> &depth,int d,int u){
		eulertour[u]=vertex.size();	
		vertex.push_back(u);
		depth.push_back(d);
		for(int i=0;i<edge[u].size();i++){
			dfs(edge,n,depth,d+1,edge[u][i]);
			vertex.push_back(u);
			depth.push_back(d);
		}
	}
public:
	LCA(const vector<int> edge[],int n,int root):eulertour(n){
		vector<int> depth;
		dfs(edge,n,depth,1,root);
		vertex.push_back(root);
		depth.push_back(0);
		rmq.build(depth);
	}
	int query(int u,int v)const{
		if(u==v)return u;
		if(eulertour[u]>eulertour[v])swap(u,v);
		return vertex[rmq.query(eulertour[u], eulertour[v])];
	}
};



vector<int> edge[100000];
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		int k,v;
		cin>>k;
		for(int j=0;j<k;j++){
			cin>>v;
			edge[i].push_back(v);
		}
	}
	LCA lca(edge,n,0);
	int q,u,v;
	cin>>q;
	for(int i=0;i<q;i++){
		cin>>u>>v;
		cout<<lca.query(u,v)<<endl;
	}
	return 0;
}

Measured memory_bytes: 14248