// Slower C++ solution:
#include <bits/stdc++.h>

#define MAX 100000

using namespace std;

using pi = pair<int, int>;



template <typename T>

class SegmentTree {

	using func_t = function<T(T, T)>;

	const int n;

	const T id;

	func_t merge;

	vector<T> data;

	int size(int n) {

		int res;

		for (res = 1; res < n; res <<= 1);

		return res;

	}

	T sub(int l, int r, int node, int lb, int ub) const {

		if (ub <= l || r <= lb) return id;

		if (l <= lb && ub <= r) return data[node];

		return merge(sub(l, r, node * 2, lb, (lb + ub) / 2), sub(l, r, node * 2 + 1, (lb + ub) / 2, ub));

	}

public:

	SegmentTree(int n_, T id_, func_t merge_) :

		n(size(n_)), id(id_), merge(merge_), data(size(n_) * 2, id_) {}

	SegmentTree(const vector<T>& data_, T id_, func_t merge_) :

		n(size(data_.size())), id(id_), merge(merge_), data(size(data_.size()) * 2, id_) {

		for (int i = 0; i < (int)data_.size(); i++)

			data[i + n] = data_[i];

		for (int i = n - 1; i >= 0; i--)

			data[i] = merge(data[i * 2], data[i * 2 + 1]);

	}

	void Update(int p, T val) {

		p += n;

		data[p] = val;

		while (p >>= 1) data[p] = merge(data[p * 2], data[p * 2 + 1]);

	}

	void Add(int p, T val) {

		p += n;

		data[p] += val;

		while (p >>= 1) data[p] = merge(data[p * 2], data[p * 2 + 1]);

	}

	T Find(int l, int r) const {

		return sub(l, r + 1, 1, 0, n);

	}

	T operator[](int i) const {

		return data[i + n];

	}

};



int N, rt;

vector<int> G[MAX];

int depth[MAX], used[MAX], id[MAX];

vector<int> vs, de;



void Add(int a, int b) {

	G[a].push_back(b);

	G[b].push_back(a);

}



void dfs(int s, int d) {

	used[s] = 1;



	vs.push_back(s);

	de.push_back(d);

	for (int v : G[s]) {

		if (!used[v]) {

			dfs(v, d + 1);



			vs.push_back(s);

			de.push_back(d);

		}

	}

}



SegmentTree<pi> Init() {

	fill(used, used + N, 0);

	fill(id, id + N, -1);

	dfs(rt, 0);

	for (int i = 0; i < (int)vs.size(); i++) {

		if (id[vs[i]] == -1) {

			id[vs[i]] = i;

		}

	}

	vector<pi> r((int)vs.size());

	for (int i = 0; i < (int)vs.size(); i++) {

		r[i] = pi(de[i], vs[i]);

	}

	SegmentTree<pi> res(r, pi(N, -1), [](pi a, pi b) { return a.first <= b.first ? a : b; });

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

		depth[i] = res[id[i]].first;

	}

	return res;

}



int LCA(const SegmentTree<pi>& st, int a, int b) {

	return st.Find(min(id[a], id[b]), max(id[a], id[b])).second;

}



int main()

{

	cin >> N;

	for (int i = 0, k; i < N; i++) {

		cin >> k;

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

			cin >> c;

			Add(i, c);

		}

	}

	int Q, a, b;

	auto st = Init();

	cin >> Q;

	while (Q--) {

		cin >> a >> b;

		cout << LCA(st, a, b) << endl;

	}

	return 0;

}

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

using namespace std;

using graph = vector<vector<int>>;



template <typename T>

class SparseTable {

	const int n, h;

	vector<vector<T>> t;

public:

	SparseTable(const vector<T>& b)

		: n(b.size()), h(31 - __builtin_clz(n)), t(h + 1, vector<T>(b.size())) {

		t[0] = b;

		for (int i = 0; i < h; i++)

			for (int k = 0; k + (1 << i) < n; k++)

				t[i + 1][k] = min(t[i][k], t[i][k + (1 << i)]);

	}

	T find(int l, int r) {

		int b = 31 - __builtin_clz(r - l);

		return min(t[b][l], t[b][r - (1 << b)]);

	}

	T operator[](int id) {

		return t[0][id];

	}

};



class LCA {

	using pii = pair<int, int>;

	vector<int> depth, id;

	SparseTable<pii> st;

	void dfs(int v, int prev, const graph& G, vector<pii>& res) {

		depth[v] = prev != -1 ? depth[prev] + 1 : 0;

		id[v] = res.size();

		res.emplace_back(depth[v], v);

		for (auto to : G[v]) if (to != prev) {

			dfs(to, v, G, res);

			res.emplace_back(depth[v], v);

		}

	}

	vector<pii> init(const graph& G, int rt) {

		vector<pii> res;

		res.reserve(G.size() * 2 - 1);

		dfs(rt, -1, G, res);

		return res;

	}

public:

	LCA(const graph& G, int rt = 0) : depth(G.size()), id(G.size()), st(init(G, rt)) {}

	int calc(int a, int b) {

		if (id[a] > id[b]) swap(a, b);

		return st.find(id[a], id[b] + 1).second;

	}

	int dist(int a, int b) {

		return depth[a] + depth[b] - depth[calc(a, b)] * 2;

	}

};



int main()

{

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

	int n;

	cin >> n;

	graph G(n);

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

		int k;

		cin >> k;

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

			int c;

			cin >> c;

			G[i].push_back(c);

			G[c].push_back(i);

		}

	}

	LCA lca(G);

	int q;

	cin >> q;

	while (q--) {

		int u, v;

		cin >> u >> v;

		printf("%d\n", lca.calc(u, v));

	}

	return 0;

}