// Slower C++ solution:
#include <iostream>

#include <vector>

#include <map>

#include <string.h>

#include <algorithm>

#define P pair<int,int>

#define INF (1<<30)

using namespace std;



vector<int> Ind(100010);		//Ind[n]  ??\???n???euler tour??¨??§???????????°?????????

vector<bool> f(100010, false);	//

vector<vector<int>> T(100010);	//??°??????

vector<P> ET;                   //????????¢?´¢??¨



void dfs(int n,int dep) {

	f[n] = true;

	ET.emplace_back(make_pair(dep,n));

	Ind[n] = ET.size() - 1;

	for (int next : T[n]) {

		if (f[next] == true) continue;

		dfs(next,dep + 1);

		ET.emplace_back(make_pair(dep,n));

	}

}



P RMQ(int a, int b, int k, int l, int r, vector<P>& node) {

	if (r <= a || b <= l) {return P(INF, INF); }

	if (a <= l && r <= b) return node[k];



	P vl = RMQ(a, b, 2 * k + 1, l, (l + r) / 2,node);

	P vr = RMQ(a, b, 2 * k + 2, (l + r) / 2, r, node);

	return min(vl, vr);

}



int main() {

	cin.tie(0); ios::sync_with_stdio(false);

	//Graph initialize

	int n_; cin >> n_;

	for (int i = 0; i < n_; i++) {

		int k; cin >> k;

		for (int j = 0; j < k; j++) {

			int c; cin >> c;

			T[i].emplace_back(c);

			T[c].emplace_back(i);

		}

	}

	//ET??¨?????????

	dfs(0,0);



	//RMQ initialize

	n_ = ET.size();



	int n = 1;

	while (n < n_) n *= 2;

	vector<P> node(2 * n - 1, P(INF, INF));



	for (int i = 0; i < n_;i++) { node[n - 1 + i] = ET[i]; }

	for (int i = n - 2; i >= 0; i--) { node[i] = min(node[2 * i + 1], node[2 * i + 2]); }



	//Answer

	int q; cin >> q;

	for (int i = 0; i < q; i++) {

		int u, v; cin >> u >> v;

		int a = Ind[u], b = Ind[v];

		if (a > b) { swap(a, b); }

		if (a == b) { cout << u << endl; continue; }

		cout << RMQ(a,b, 0, 0, n, node).second << endl;

	}

}

// Faster C++ solution for the same problem (measured speedup: 3.8909046898004647x):
#include "bits/stdc++.h"

using namespace std;

typedef long long ll;

typedef pair<int, int> pii;

typedef pair<ll, ll> pll;

#define INF 1<<30

#define LINF 1LL<<60



class LCA{

public:

    ll V; // ????????°

    vector<vector<ll>> T; // Tree

    vector<pll> ET; // Euler Tour ET(dep, n)

    vector<int> visited;

    vector<ll> Ind; // ????????????????????????ET???index?????????

    

    ll N; // SegTree???????´???°

    vector<pll> node; // SegTree

    

    LCA(ll V):V(V){

        T.resize(V); Ind.resize(V);

    }

    

    void add_edge(ll u,ll v){

        T[u].emplace_back(v);

        T[v].emplace_back(u);

    }

    

    void fit(){

        visited.clear(); visited.assign(V,0);

        dfs(0,0);

        ll N_ = ET.size();

        N = 1;

        while(N < N_) N*=2;

        node.clear(); node.assign(2*N - 1,make_pair(INF,INF));

        for(int i = 0; i < N_;i++) node[N-1+i] = ET[i];

        for(int k = N - 2; k>=0;k--) node[k] = min(node[2*k+1],node[2*k+2]);

    }

    

    void dfs(ll n,ll dep){

        visited[n] = 1;

        ET.emplace_back(make_pair(dep, n));

        Ind[n] = (int)ET.size() - 1;

        for(auto next:T[n]){

            if(visited[next] == 1)continue;

            dfs(next,dep +1);

            ET.emplace_back(make_pair(dep,n));

        }

    }

    

    

    pll RMQ(ll a,ll b){ return RMQ(a,b,0,0,N); }

    pll RMQ(ll a,ll b,ll k,ll l, ll r){

        if(r <= a || b <= l)return make_pair(INF,INF);

        if(a <= l && r <= b)return node[k];

        auto vl = RMQ(a,b,2*k+1,l,(l+r)/2);

        auto vr = RMQ(a,b,2*k+2,(l+r)/2,r);

        return min(vl,vr);

    }

    

    ll solve(ll s,ll t){

        ll idx1 = Ind[s],idx2 = Ind[t];

        if(idx1 > idx2) swap(idx1,idx2);

        

        return RMQ(idx1,idx2+1).second;

    }

};



int main(void) {

    cin.tie(0); ios::sync_with_stdio(false);

    ll n; cin >> n;

    

    LCA lca(n);

    

    for(int i = 0; i < n;i++){

        ll k; cin >> k;

        for(int j = 0; j < k;j++){

            ll c; cin >> c;

            lca.add_edge(i, c);

        }

    }

    

    lca.fit();

    

    ll q; cin >> q;

    for(int i = 0; i < q;i++){

        ll u, v; cin >> u >> v;

        cout << lca.solve(u,v) << endl;

    }

    return 0;

}