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# (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;

class C
{
	static int[] Read() => Console.ReadLine().Split().Select(int.Parse).ToArray();
	static void Main()
	{
		var n = int.Parse(Console.ReadLine());
		map = new int[n].Select(_ => Read().Skip(1).ToArray()).ToArray();
		var q = int.Parse(Console.ReadLine());
		var qs = new int[q].Select(_ => Read()).ToArray();

		tour = new List<int>();
		order = Array.ConvertAll(new int[n], _ => new List<int>());
		minDepth = new ST_Min(2 * n);
		EulerTourDfs(0, 0);

		Console.WriteLine(string.Join("\n", qs.Select(x => Lca(x[0], x[1]))));
	}

	static int[][] map;
	static List<int> tour;
	static List<int>[] order;
	static ST_Min minDepth;
	static void EulerTourDfs(int v, int depth)
	{
		order[v].Add(tour.Count);
		minDepth.SetMin(tour.Count, depth);
		foreach (var nv in map[v])
		{
			tour.Add(v);
			EulerTourDfs(nv, depth + 1);
			tour.Add(-nv);
			order[v].Add(tour.Count);
			minDepth.SetMin(tour.Count, depth);
		}
	}

	static int Lca(int u, int v)
	{
		if (u == v) return u;
		if (order[u][0] > order[v][0]) { var t = u; u = v; v = t; }
		if (order[u].Last() > order[v][0]) return u;
		return tour[minDepth.ArgMin(order[u].Last(), order[v][0])];
	}
}

class ST_Min
{
	struct KI
	{
		public int k, i;
	}

	int kMax;
	List<long[]> vs = new List<long[]> { new long[1] };
	public ST_Min(int n)
	{
		for (int c = 1; c < n; vs.Add(new long[c <<= 1])) ;
		foreach (var a in vs)
			for (int i = 0; i < a.Length; i++)
				a[i] = long.MaxValue;
		kMax = vs.Count - 1;
	}

	KI[] GetLevels(int i)
	{
		var r = new List<KI>();
		for (int k = kMax; k >= 0; --k, i >>= 1) r.Add(new KI { k = k, i = i });
		return r.ToArray();
	}

	KI[] GetRange(int minIn, int maxEx)
	{
		var r = new List<KI>();
		for (int k = kMax, f = 1; k >= 0 && minIn < maxEx; --k, f <<= 1)
		{
			if ((minIn & f) != 0) r.Add(new KI { k = k, i = (minIn += f) / f - 1 });
			if ((maxEx & f) != 0) r.Add(new KI { k = k, i = (maxEx -= f) / f });
		}
		return r.ToArray();
	}

	public long Get(int i) => vs[kMax][i];

	public void SetMin(int i, long v)
	{
		foreach (var x in GetLevels(i)) vs[x.k][x.i] = Math.Min(vs[x.k][x.i], v);
	}

	public long Submin(int minIn, int maxEx) => GetRange(minIn, maxEx).Select(x => vs[x.k][x.i]).Aggregate(Math.Min);

	public int ArgMin(int minIn, int maxEx)
	{
		var m = Submin(minIn, maxEx);
		var ki = GetRange(minIn, maxEx).First(x => vs[x.k][x.i] == m);

		for (int j; ki.k < kMax; ki = new KI { k = ki.k + 1, i = j })
		{
			j = 2 * ki.i;
			if (vs[ki.k + 1][j] > m) j++;
		}
		return ki.i;
	}
}