#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <iomanip>
#include <fstream>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <string>
#include <tuple>
#include <vector>
#include <map>
#include <unordered_map>
#include <list>
#include <set>
#include <stack>
#include <queue>
#include <cstdlib>
#include <algorithm>
#include <random>
#include <cassert>
using namespace std;
#define LL long long
#define MP(a, b) make_pair(a, b)
#define POWER9 1000000000
#define MOD POWER9+7
#undef INT_MIN
#undef INT_MAX
#define INT_MIN -2147483647
#define INT_MAX 2147483647
#define LL_MIN (LL)-9223372036854775807
#define LL_MAX (LL)9223372036854775807
#define PI 3.14159265359
#define LLONG_MAX 9223372036854775807LL

//RMQ セグメント木
struct SegmentTree{
private:
	int n;
	vector<long long> nodes;
public:
	void init(int N){ //初期化する O(N)
		nodes.clear();
		n = 1;
		while(n < N) n *= 2;
		n = 2 * n -1;
		for(int i=0; i<n; i++) nodes.push_back(LLONG_MAX);
	}
	void update(int i, long long x){ //値を変更する O(log N)
		i += n / 2;
		nodes[i] = x;
		while(i > 0){
			i = (i-1)/2; //親の取得は(i-1)/2
			nodes[i] = min(nodes[i*2+1], nodes[i*2+2]); //子の取得はi*2+1,i*2+2
		}
	}
	long long minimum(int a, int b){ //[a,b)の最小値を求める O(log N)
		return query(a, b, 0, 0, n/2+1);
	}
	long long query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l) return LLONG_MAX; //交差する場合
		if(a <= l && r <= b) return nodes[k]; //完全に含む場合
		long long valueL = query(a, b, k*2+1, l, (l+r)/2);
		long long valueR = query(a, b, k*2+2, (l+r)/2, r);
		return min(valueL, valueR);
	}
	long long m;
	long long find(int a, int b, int k=0, int l=0, int r=-1){
		if(r == -1){
			m = minimum(a, b);
			r = (n+1)/2;
		}
		if(r <= a || b <= l) return LLONG_MAX; //交差する場合
		if(r-l == 1){
			if(nodes[k] == m) return l;
			else return LLONG_MAX;
		}
		if(a <= l && r <= b){ //完全に含む場合
			long long valueL = query(a, b, k*2+1, l, (l+r)/2);
			long long valueR = query(a, b, k*2+2, (l+r)/2, r);
			if(valueL <= valueR) return find(a, b, k*2+1, l, (l+r)/2);
			else return find(a, b, k*2+2, (l+r)/2, r);
		}
		long long valueL = find(a, b, k*2+1, l, (l+r)/2);
		long long valueR = find(a, b, k*2+2, (l+r)/2, r);
		return min(valueL, valueR);
	}
};

int n;
vector<int> c[100000];
int par[100000];
int q;

int d[100000] = {};
int depth(int now){
	if(par[now] == now) return 0;
	if(d[now] != 0) return d[now];
	return d[now] = 1 + depth(par[now]);
}

vector<int> order;
bool already[100000] = {};
int pre[100000];
void dfs(int now){
	pre[now] = order.size();
	order.push_back(now);
	for(int i=0; i<c[now].size(); i++){
		if(already[c[now][i]]) continue;
		already[c[now][i]] = true;
		dfs(c[now][i]);
		order.push_back(now);
	}
}

SegmentTree st;

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	cout << setprecision(9);

	cin >> n;
	for(int i=0; i<n; i++) par[i] = i;
	for(int i=0; i<n; i++){
		int k;
		cin >> k;
		for(int j=0; j<k; j++){
			int tmp;
			cin >> tmp;
			c[i].push_back(tmp);
			par[tmp] = i;
		}
	}
	for(int i=0; i<n; i++) depth(i);
	for(int i=0; i<n; i++){
		if(already[i]) continue;
		already[i] = true;
		dfs(i);
	}

	/*for(int i=0; i<n; i++) cout << d[i] << " ";
	cout << endl;
	for(int i=0; i<order.size(); i++) cout << order[i] << " ";
	cout << endl;
	for(int i=0; i<n; i++) cout << pre[i] << " ";
	cout << endl;*/

	st.init(order.size());
	for(int i=0; i<order.size(); i++) st.update(i, d[order[i]]);
	cin >> q;
	for(int i=0; i<q; i++){
		int a,b;
		cin >> a >> b;
		if(pre[b] < pre[a]) swap(a, b);
		//cout << st.find(pre[a],pre[b]+1) << endl;
		cout << order[st.find(pre[a],pre[b]+1)] << endl;
	}

	return 0;
}


Measured memory_bytes: 17680