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



using namespace std;

typedef long long int ll;

typedef pair<int, int> P;

typedef pair<ll, ll> Pll;

typedef vector<int> Vi;

typedef tuple<int, int, int> T;

#define FOR(i,s,x) for(int i=s;i<(int)(x);i++)

#define REP(i,x) FOR(i,0,x)

#define ALL(c) c.begin(), c.end()

#define MP make_pair

#define DUMP( x ) cerr << #x << " = " << ( x ) << endl

#define fst first

#define snd second



#define MAX_V 100010

#define MAX_LOG_V 20



vector<int> edge[MAX_V];

int parent[MAX_LOG_V][MAX_V];

int depth[MAX_V];



struct LCA{

  int root;



  LCA(int r): root(r){}



  void add_edge(int a, int b) {

    edge[a].push_back(b);

    edge[b].push_back(a);

  }

  

  void dfs(int v, int par, int dep) {

    parent[0][v] = par;

    depth[v] = dep;

    for (auto child : edge[v]) {

      if (child != par) dfs(child, v, dep + 1);

    }

  }



  void init(int V) {

    dfs(root, -1, 0);

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

      for (int v = 0; v < V; v++) {

	if (parent[k][v] < 0) {

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

	} else {

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

	}

      }

    }

  }



  int lca(int u, int v) {

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

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

      if ((depth[v] - depth[u]) >> k & 1) {

	v = parent[k][v];

      }

    }

    if (u == v) return u;

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

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

	u = parent[k][u];

	v = parent[k][v];

      }

    }

    return parent[0][u];

  }

};



int main() {

  int N;

  LCA lca(0);

  

  scanf("%d", &N);

  REP(i, N) {

    int k;

    cin >> k;

    REP(j, k) {

      int c;

      cin >> c;

      lca.add_edge(i, c);

    }

  }

  lca.init(N);

  int Q;

  cin >> Q;

  REP(i, Q) {

    int u, v;

    cin >> u >> v;

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

  }

  return 0;

}

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



using namespace std;

typedef long long int ll;

typedef pair<int, int> P;

typedef pair<ll, ll> Pll;

typedef vector<int> Vi;

//typedef tuple<int, int, int> T;

#define FOR(i,s,x) for(int i=s;i<(int)(x);i++)

#define REP(i,x) FOR(i,0,x)

#define ALL(c) c.begin(), c.end()

#define DUMP( x ) cerr << #x << " = " << ( x ) << endl



const int dr[4] = {-1, 0, 1, 0};

const int dc[4] = {0, 1, 0, -1};



// graph by adjacency list

template <typename T>

struct Edge {

  int dst; T weight;

  Edge(int dst, T weight) : dst(dst), weight(weight) { }

  bool operator < (const Edge<T> &e) const {

    return weight > e.weight;

  }

};



template <typename T>

struct Graph {

  int V;

  vector<vector<Edge<T>>> E;

  Graph(int V) : V(V) { E.resize(V); }

  void add_edge(int src, int dst, T weight) {

    E[src].emplace_back(dst, weight);

  }

};



template <typename T>

struct HeavyLightDecomposition {

  const Graph<T> g;

  vector<int> vid, head, heavy, parent;

  HeavyLightDecomposition(const Graph<T> g, int root = 0) : g(g), vid(g.V, -1), head(g.V), heavy(g.V, -1), parent(g.V) {

    dfs(root, -1);

    bfs(root);

  }



  int dfs(int v, int par) {

    parent[v] = par;

    int sub = 1, max_sub = 0;

    for (Edge<T> child : g.E[v]) {

      if (child.dst != par) {

        int child_sub = dfs(child.dst, v);

        sub += child_sub;

        if (child_sub > max_sub) {

          max_sub = child_sub;

          heavy[v] = child.dst;

        }

      }

    }

    return sub;

  }



  void bfs(int root = 0) {

    int k = 0;

    queue<int> que({root});

    while (not que.empty()) {

      int r = que.front(); que.pop();

      for (int v = r; v != -1; v = heavy[v]) {

        vid[v] = k++;

        head[v] = r;

        for (Edge<T> child : g.E[v]) {

          if (child.dst != parent[v] and child.dst != heavy[v]) que.push(child.dst);

        }

      }

    }

  }



  int lca(int u, int v) {

    while(head[u] != head[v]) {

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

      v = parent[head[v]];

    }

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

    return u;

  }

};



int main() {

  int N; scanf("%d", &N);

  Graph<int> g(N);

  REP(i, N) {

    int k; scanf("%d", &k);

    REP(_, k) {

      int c; scanf("%d", &c);

      g.add_edge(i, c, 1);

      g.add_edge(c, i, 1);

    }

  }



  HeavyLightDecomposition<int> hld(g);



  int Q; scanf("%d", &Q);

  REP(_, Q) {

    int u, v; scanf("%d %d", &u, &v);

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

  }

  return 0;

}