Problem:
LCA: Lowest Common Ancestor

For a rooted tree, find the lowest common ancestor of two nodes u and v.

The given tree consists of n nodes and every node has a unique ID from 0 to n-1 where 0 is the root.

Input

n
k0 c1 c2 ... ck0
k1 c1 c2 ... ck1
:
kn-1 c1 c2 ... ckn-1
q
u1 v1
u2 v2
:
uq vq

The first line of the input includes an integer n, the number of nodes of the tree.

In the next n lines, the information of node i is given. ki is the number of children of node i, and c1, ... cki are node IDs of 1st, ... kth child of node i.

In the next line, the number of queryies q is given. In the next q lines, pairs of u and v are given as the queries.

Output

For each query, print the LCA of u and v in a line.

Constraints

1 ≤ n ≤ 100000

1 ≤ q ≤ 100000

Sample Input 1

8
3 1 2 3
2 4 5
0
0
0
2 6 7
0
0
4
4 6
4 7
4 3
5 2

Sample Output 1

1
1
0
0

Solution in C++14 (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define int ll
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(c) begin(c), end(c)
#define dump(x) // cerr << __LINE__ << ":\t" #x " = " << x << endl

using Weight = int;
using Capacity = int;
struct Edge {
  int src, dst;
  Weight weight;
  Edge(int s, int d, Weight w) : src(s), dst(d), weight(w) {}
};
using Graph = vector<vector<Edge>>;

class lca {
public:
  int n;
  int log2_n;
  vector<vector<int>> parent;
  vector<int> depth;

  lca() {}

  lca(const Graph &g, int root)
      : n(g.size()), log2_n(log2(n) + 2), parent(log2_n, vector<int>(n)),
        depth(n) {
    dfs(g, root, -1, 0);
    for (int k = 0; k + 1 < log2_n; k++) {
      for (int v = 0; v < (int)g.size(); v++) {
        if (parent[k][v] < 0)
          parent[k + 1][v] = -1;
        else
          parent[k + 1][v] = parent[k][parent[k][v]];
      }
    }
  }

  void dfs(const Graph &g, int v, int p, int d) {
    parent[0][v] = p;
    depth[v] = d;
    for (auto &e : g[v]) {
      if (e.dst != p)
        dfs(g, e.dst, v, d + 1);
    }
  }

  int get(int u, int v) {
    if (depth[u] > depth[v])
      swap(u, v);
    for (int k = 0; k < log2_n; k++) {
      if ((depth[v] - depth[u]) >> k & 1) {
        v = parent[k][v];
      }
    }
    if (u == v)
      return u;
    for (int k = log2_n - 1; k >= 0; k--) {
      if (parent[k][u] != parent[k][v]) {
        u = parent[k][u];
        v = parent[k][v];
      }
    }
    return parent[0][u];
  }
};

const int B = 300;

int N, Q;
Graph g;
vector<tuple<int, int, int, int>> query;

int dist[100010];
vector<pair<int, int>> add_at[100010];
vector<int> stk;

void make_dist(int v, int p, int s) {
  dist[v] = s;
  for (auto &e : g[v]) {
    if (e.dst != p) {
      make_dist(e.dst, v, dist[v] + e.weight);
    }
  }
}

void add_many(int v, int p) {
  for (auto &aq : add_at[v]) {
    int k = aq.first;
    int x = aq.second;
    if (k < (int)stk.size())
      stk.rbegin()[k] += x;
  }

  int add = stk.back();
  stk.pop_back();
  for (auto &e : g[v]) {
    if (e.dst != p) {
      e.weight += add;
      add_many(e.dst, v);
    }
  }
  stk.push_back(add);

  for (auto &aq : add_at[v]) {
    int k = aq.first;
    int x = aq.second;
    if (k < (int)stk.size())
      stk.rbegin()[k] -= x;
  }
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n;
    cin >> n;
    Graph g(n);
    rep(i, n){
        int k;
        cin >> k;
        rep(j, k){
            int c;
            cin >> c;
            g[i].emplace_back(i, c, 1);
        }
    }
    lca l(g, 0);
    int q;
    cin >> q;
    rep(i, q){
        int u, v;
        cin >> u >> v;
        cout << l.get(u, v) << '\n';
    }
}

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

//   cin >> N;
//   g.assign(N, {});
//   for (int i = 0; i < N - 1; i++) {
//     int a, b, c;
//     cin >> a >> b >> c;
//     --a;
//     --b;
//     g[a].emplace_back(a, b, c);
//     g[b].emplace_back(b, a, c);
//   }

//   lca lc(g, 0);

//   cin >> Q;
//   query.resize(Q);
//   for (auto &q : query) {
//     int t;
//     cin >> t;
//     if (t == 1) {
//       int v, k, x;
//       cin >> v >> k >> x;
//       --v;
//       --k;
//       q = make_tuple(t, v, k, x);
//     } else {
//       int u, v;
//       cin >> u >> v;
//       --u;
//       --v;
//       q = make_tuple(t, u, v, -1);
//     }
//   }

//   for (int i = 0; i < Q; i += B) {
//     make_dist(0, -1, 0);

//     int left = i, right = min(Q, i + B);

//     for (int j = left; j < right; ++j) {
//       int t, u, v;
//       tie(t, u, v, ignore) = query[j];
//       if (t == 2) {
//         int add = 0;
//         for (auto &path_v : {u, v}) {
//           for (int jj = left; jj < j; ++jj) {
//             int tt, add_v, k, x;
//             tie(tt, add_v, k, x) = query[jj];
//             if (tt == 1 && lc.get(add_v, path_v) == add_v &&
//                 lc.depth[path_v] > lc.depth[add_v] + k) {
//               add += x;
//             }
//           }
//         }
//         dump(add);
//         int l = lc.get(u, v);
//         cout << dist[u] + dist[v] - 2 * dist[l] + add << '\n';
//       }
//     }

//     for (int j = left; j < right; ++j) {
//       int t, v, k, x;
//       tie(t, v, k, x) = query[j];
//       if (t == 1)
//         add_at[v].push_back(make_pair(k, x));
//     }
//     stk.assign(N, 0);
//     add_many(0, -1);
//   }
// }