#include <bits/stdc++.h>
using namespace std;
#define int long long   // <-----!!!!!!!!!!!!!!!!!!!

#define rep(i,n) for (int i=0;i<(n);i++)
#define rep2(i,a,b) for (int i=(a);i<(b);i++)
#define rrep(i,n) for (int i=(n)-1;i>=0;i--)
#define rrep2(i,a,b) for (int i=(a)-1;i>=b;i--)
#define chmin(a,b) (a)=min((a),(b));
#define chmax(a,b) (a)=max((a),(b));
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define printV(v) cout<<(#v)<<":";for(auto(x):(v)){cout<<" "<<(x);}cout<<endl;
#define printVS(vs) cout<<(#vs)<<":"<<endl;for(auto(s):(vs)){cout<<(s)<< endl;}
#define printVV(vv) cout<<(#vv)<<":"<<endl;for(auto(v):(vv)){for(auto(x):(v)){cout<<" "<<(x);}cout<<endl;}
#define printP(p) cout<<(#p)<<(p).first<<" "<<(p).second<<endl;
#define printVP(vp) cout<<(#vp)<<":"<<endl;for(auto(p):(vp)){cout<<(p).first<<" "<<(p).second<<endl;}

inline void output(){ cerr << endl; }
template<typename First, typename... Rest>
inline void output(const First& first, const Rest&... rest) {
    cerr << first << " "; output(rest...);
}

using ll = long long;
using Pii = pair<int, int>;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
const int inf = 2e9;
const int mod = 1e9 + 7;

struct edge {
    int to, cost;
    edge(){}
    edge(int _to, int _cost) : to(_to), cost(_cost) {}
};
using Graph = vector<vector<edge>>;

class LCA {
private:
    static const int MAX_LOG = 20;
    const int n;
    Graph G;
    vector<vector<int>> par;
    vector<int> depth;
    vector<int> cost;

    bool inited = false;

public:
    void dfs(int v, int p, int d, int c = 0, bool debug = false) {
        par[0][v] = p;
        depth[v] = d;
        cost[v] = c;
        for (auto e : G[v]) {
            if (e.to != p) {
                dfs(e.to, v, d + 1, c + e.cost, debug);
            }
        }
    }
    LCA(int _n) : n(_n), G(_n), par(MAX_LOG, vector<int>(_n)), depth(_n), cost(_n) {}
    void addEdge(int a, int b, int c = 0) {
        G[a].emplace_back(b, c);
        G[b].emplace_back(a, -c);
    }
    void init(bool debug = false) {
        dfs(0, -1, 0, 0, debug);
        rep(i, MAX_LOG - 1) {
            rep(j, n) {
                if (par[i][j] == -1) {
                    par[i + 1][j] = -1;
                } else {
                    par[i + 1][j] = par[i][par[i][j]];
                }
            }
        }
        inited = true;
    }
    int lca(int a, int b) {
        assert(inited);
        if (depth[a] > depth[b]) {
            swap(a, b);
        }
        rep(i, MAX_LOG) {
            if ((depth[b] - depth[a]) >> i & 1) {
                b = par[i][b];
            }
        }
        if (a == b) return a;

        rrep(i, MAX_LOG) {
            if (par[i][a] != par[i][b]) {
                a = par[i][a];
                b = par[i][b];
            }
        }
        return par[0][a];
    }
    int query(int a, int b) {
        int v = lca(a, b);
        return - (cost[a] - cost[v]) + cost[b] - cost[v];
    }

    bool isTree(int v, int p, vector<bool>& visited) {
        if (visited[v]) return false;
        visited[v] = true;
        for (auto e : G[v]) {
            if (e.to == p) continue;
            if (!isTree(e.to, v, visited)) return false;
            visited[e.to] = false;
        }
        return true;
    }
};

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);

    int n;
    cin >> n;
    LCA lca(n);
    rep(i, n) {
        int k;
        cin >> k;
        rep(j, k) {
            int c;
            cin >> c;
            lca.addEdge(i, c);
        }
    }

    lca.init();

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

Measured memory_bytes: 31592