#include <bits/stdc++.h>
using namespace std;

struct Benri { Benri() { std::cin.tie(0); ios::sync_with_stdio(false); cout << fixed << setprecision(12);}} benri;

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using pii = pair<int, int>;
using vll = vector<long long>;
using vvll = vector<vll>;
using pll = pair<ll, ll>;
using ull = unsigned long long;

template <typename T> using PQ = priority_queue<T>;
template <typename T> using minPQ = priority_queue<T, vector<T>, greater<T>>;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define mp make_pair
#define F first
#define S second

template<class T>bool chmax(T &a, const T &b) { if (a < b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b < a) { a = b; return 1; } return 0; }

constexpr long long MOD = 1000000007;
//constexpr long long MOD = 998244353;
constexpr int INF = 1001001001;
//constexpr ll INF = 1001001001001001001ll;
constexpr double EPS = 1e-10;
using number = long long;


struct inRMQ {
    int n;
    vector<int> dat;
    vector<int> ind;

    inRMQ() {}
    inRMQ(int N, const vector<int> &vec) { init(N, vec); }

    inline void init(int N, const vector<int> &vec) {
        n = 1; while (n < N) n *= 2;
        dat.assign(2 * n - 1, INF);
        ind.assign(2 * n - 1, -1);

        rep(k, N) {
            dat[k + n - 1] = vec[k];
            ind[k + n - 1] = k;
        }

        int tmp = n;
        while (tmp > 1) {
            tmp /= 2;
            for (int k = tmp - 1 ; k < 2 * tmp - 1; k++) {
                if (dat[k * 2 + 1] > dat[k * 2 + 2]) {
                    dat[k] = dat[k * 2 + 2]; ind[k] = ind[k * 2 + 2];
                }
                else {
                    dat[k] = dat[k * 2 + 1]; ind[k] = ind[k * 2 + 1];
                }
            }
        }
    }

    inline void update(int k, int a) {
        k += n - 1;
        dat[k] = a;
        while (k > 0) {
            k = (k - 1) / 2;
            if (dat[k * 2 + 1] > dat[k * 2 + 2]) {
                dat[k] = dat[k * 2 + 2]; ind[k] = ind[k * 2 + 2];
            }
            else {
                dat[k] = dat[k * 2 + 1]; ind[k] = ind[k * 2 + 1];
            }
        }
    }

    inline pii QUERY(int a, int b, int k, int l, int r) {
        if (r <= a || b <= l) return pii(INF, -1);
        if (a <= l && r <= b) return pii(dat[k], ind[k]);
        else {
            pii vl = QUERY(a, b, k * 2 + 1, l, (l + r) / 2);
            pii vr = QUERY(a, b, k * 2 + 2, (l + r) / 2, r);
            if (vl.first > vr.first) return vr;
            else return vl;
        }
    }

    inline int query(int a, int b) {
        return QUERY(a, b, 0, 0, n).second;
    }

};


using Graph = vector<vector<int>>;

struct segmentLCA {
    int root;
    vector<int> vs;
    vector<int> dept; //オイラーツアーの途上におけるdepth
    vector<int> id;
    inRMQ rmq;

    segmentLCA(int V, int r, const Graph &G) {init(V, r, G);}

    void init(int V, int r, const Graph &G) {
        root = r;
        vs.assign(V * 2 - 1, 0);
        dept.assign(V * 2 - 1, 0);
        id.assign(V, 0);
        int k = 0;
        DFS(root, -1, 0, k, G);
        rmq.init(2 * V - 1, dept);
    }

    void DFS(int v, int p, int d, int &k, const Graph &G) {
        id[v] = k;
        vs[k] = v;
        dept[k++] = d;
        for (auto x : G[v]) {
            if (x == p) continue;
            DFS(x, v, d + 1, k, G);
            vs[k] = v;
            dept[k++] = d;
        }
    }

    int calcLCA(int u, int v) {
        return vs[rmq.query(min(id[u], id[v]), max(id[u], id[v]) + 1)];
    }

};



int main() {
    int n; cin >> n;
    Graph G(n);
    int k, c;
    rep(i, n) {
        cin >> k;
        rep(j, k) {
            cin >> c;
            G[i].pb(c);
            G[c].pb(i);
        }
    }

    segmentLCA lca(n, 0, G);

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


Measured memory_bytes: 17248