// 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.8995431989828884x):
#include "bits/stdc++.h"

using namespace std;

typedef long long ll;

typedef pair<int, int> pii;

typedef pair<ll, ll> pll;

const int INF = 1e9;

const ll LINF = 1e18;

template<class S,class T> ostream &operator << (ostream& out,const pair<S,T>& o){

    out << "(" << o.first << "," << o.second << ")"; return out;

}





struct edge{

    ll u,v,c;

    edge():u(0),v(0),c(0){}

    edge(ll u,ll v,ll c):u(u),v(v),c(c){}

};

typedef vector<vector<edge>> Graph;

Graph G;

class LCA{

public:

    const ll n = 0;

    const ll log2_n = 0;

    vector<vector<ll>> parent;

    vector<ll> depth;

    LCA();

    LCA(const Graph &g,ll root):n((ll)g.size()),log2_n(log2(n)+1),parent(log2_n,vector<ll>(n)),depth(n){

        dfs(g,root,-1,0);

        for(int k = 0; k+1 < log2_n; k++){

            for(int v = 0; v < (int)g.size();v++){

                if(parent[k][v] < 0) parent[k+1][v] = -1;

                else parent[k+1][v] = parent[k][parent[k][v]];

            }

        }

    }

    

    void dfs(const Graph &g,ll v,ll p,ll d){

        parent[0][v] = p; depth[v] = d;

        for(auto &e :g[v]){

            if(e.v != p) dfs(g, e.v, v, d+1);

        }

    }

    

    ll get(ll u,ll v){

        if(depth[u] > depth[v]) swap(u,v);

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

            if(((depth[v]-depth[u])>>k) & 1) v = parent[k][v];

        }

        if(u == v) return u;

        for(int k = (int)log2_n - 1; k >= 0; k--){

            if(parent[k][u] != parent[k][v]){

                u = parent[k][u]; v = parent[k][v];

            }

        }

        return parent[0][u];

    }

};



// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_5_C&lang=jp

int main(void) {

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

    ll n; cin >> n;

    G.resize(n);

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

        ll k; cin >> k;

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

            ll c; cin >> c;

            G[i].push_back(edge(i,c,0));

            G[c].push_back(edge(c,i,0));

        }

    }

    LCA lca(G,0);

    ll q; cin >> q;

    while(q--){

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

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

    }

    return 0;

}