#include "bits/stdc++.h"
#include <sys/timeb.h>
#include <fstream>

using namespace std;

#define repr(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define rep(i,n) repr(i,0,n)
#define reprrev(i,a,b) for(int i=(int)(b)-1;i>=(int)(a);i--)
#define reprev(i,n) reprrev(i,0,n)
#define repi(itr,ds) for(auto itr=ds.begin();itr!=ds.end();itr++)
#define exist(container, item) (lower_bound(container.begin(),container.end(),item)!=container.end())
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define mp make_pair
#define mt make_tuple
#define INF 1050000000
#define INFL 9e18
#define EPS (1e-10)
#define MOD 1000000007
#define PI 3.1415926536
#define RMAX 4294967295

typedef long long ll;
typedef pair<int, int> Pi;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<bool> vb;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<Pi> vPi;
typedef vector<vector<int> > vvi;
typedef vector<vector<bool> > vvb;
typedef vector<vector<ll> > vvll;
typedef vector<vector<char> > vvc;
typedef vector<vector<string> > vvs;
typedef vector<vector<double> > vvd;
typedef vector<vector<Pi> > vvPi;
typedef priority_queue<int, vector<int>, greater<int> > pqli;
typedef priority_queue<ll, vector<ll>, greater<ll> > pqlll;
typedef priority_queue<Pi, vector<Pi>, greater<Pi> > pqlP;
struct Edge {
	int from, to, cost;
	bool operator<(Edge e) {
		return cost < e.cost;
	}
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
template <class T>
using vec = vector<T>;
template<class T>
using pql = priority_queue<T, vector<T>, greater<T>>;
string debug_show(Pi a) {
	return "(" + to_string(a.first) + "," + to_string(a.second) + ")";
}

template<class T>
struct augEdge {
	T from, to;
	int cost;
	bool operator<(augEdge e) { return cost < e.cost; }
	bool operator>(augEdge e) { return cost > e.cost; }
};
template<class T>
using augGraph = vector<augEdge<T>>;

class LCA {
public:
	int N;
	vi depth;
	int maxdepth = 0;
	vvi dblpar;

	LCA(const Graph G) {
		N = G.size();
		depth = vi(N);
		dfs1(G, 0, -1);
		int D = bindigit(maxdepth) + 1;
		dblpar = vvi(D, vi(N));
		rep(i, D) {
			dfs2(G, 0, 0, i);
		}
	}

	void dfs1(const Graph &G, int pos, int par, int d = 0) {
		depth[pos] = d;
		maxdepth = max(maxdepth, d);
		for (auto e : G[pos]) {
			if (e.to == par)continue;
			dfs1(G, e.to, pos, d + 1);
		}
	}

	void dfs2(const Graph &G, int pos, int par, int dbl) {
		if (dbl == 0) {
			dblpar[0][pos] = par;
		}
		else {
			dblpar[dbl][pos] = dblpar[dbl - 1][dblpar[dbl - 1][pos]];
		}
		for (auto e : G[pos]) {
			if (e.to == par)continue;
			dfs2(G, e.to, pos, dbl);
		}
	}

	int parent(int pos, int step) {
		int ret = pos;
		int dbl = 0;
		while (step > 0) {
			if ((step & 1) != 0) {
				ret = dblpar[dbl][ret];
			}
			step >>= 1;
			dbl++;
		}
		return ret;
	}

	int bindigit(int n) {
		int ret = 0;
		while (n > 0) {
			ret++;
			n >>= 1;
		}
		return ret;
	}

	int lca(int u, int v) {
		if (depth[u] < depth[v]) {
			swap(u, v);
		}
		u = parent(u, depth[u] - depth[v]);
		int ng = -1, ok = depth[u];
		while (ok - ng > 1) {
			int mid = (ok + ng) / 2;
			if (parent(u, mid) == parent(v, mid)) {
				ok = mid;
			}
			else {
				ng = mid;
			}
		}
		return parent(u, ok);
	}
};


int main(void) {
	int N;
	cin >> N;
	Graph G(N);
	rep(i, N) {
		int num;
		cin >> num;
		rep(j, num) {
			int ch;
			cin >> ch;
			G[i].push_back(Edge{ i,ch,1 });
			G[ch].push_back(Edge{ ch,i,1 });
		}
	}

	LCA lca(G);

	int Q;
	cin >> Q;
	rep(q, Q) {
		int u, v;
		cin >> u >> v;
		cout << lca.lca(u, v) << endl;
	}

	return 0;
}

Measured memory_bytes: 24528