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  k 0  c 1  c 2 ... c k 0  k 1  c 1  c 2 ... c k 1 : k n-1  c 1  c 2 ... c k n-1  q  u 1  v 1  u 2  v 2 : u q  v q  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. k i is the number of children of node i , and c 1 , ... c k i are node IDs of 1st, ... k th 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 (Python):
import math
import sys
import resource
MAX_N = 202020
sys.setrecursionlimit(MAX_N)
E = [[] for i in range(MAX_N)]
depth = [0]*MAX_N
K = (int)(math.log2(MAX_N) + 10)



db = [[-1]*(MAX_N) for i in range(K)] 


def dfs(now,parent,d):
    
    db[0][now] = parent
    depth[now] = d
    for to in E[now]:
        if(to != parent):dfs(to,now,d+1)


def doubling():
    for i in range(K-1):
        for j in range(MAX_N):
            if(db[i][j] < 0):
                
                db[i+1][j] = -1
            else:
                
                db[i+1][j] = db[i][db[i][j]]

def LCA(u,v):
    
    if(depth[u] < depth[v]):u,v = v,u
    if(u == v):return u

    

    
    
    
    for i in range(K-1,-1,-1):
        if(db[i][u] == -1):continue
        if(depth[db[i][u]] >= depth[v]):u = db[i][u]
    
    if(u == v):return u

    
    
    for i in range(K-1,-1,-1):
        if(db[i][u] != db[i][v]):
            u = db[i][u]
            v = db[i][v]
    
    return db[0][u]
    



n = int(input())
for i in range(n):
    li = list(map(int,input().split()))
    for j in range(li[0]):E[i].append(li[j+1])

dfs(0,-1,0)
doubling()

q = int(input())
for i in range(q):
    u,v =li = list(map(int,input().split()))
    print(LCA(u,v))

Solution (Python):
import math

def lca(x, y):
    if d[x] < d[y]:
        x,y = y,x
    dy = d[y]
    k = d[x]-dy
    
    while k:
        x = p[x][int(math.log(k,2))]
        k = d[x]-dy

    if x == y:
        return x

    for i in range(h)[::-1]:
        
        if p[x][i] != p[y][i]:
            x = p[x][i]
            y = p[y][i]
    return p[x][0]
  
if __name__ == "__main__":
    n = int(input())
    
    d = [0] * n
    d[0] = 1
    
    p = [[] for i in range(n)]
    p[0].append(0)
    for i in range(n):
        vi = map(int, input().split()[1:])
        nd = d[i] + 1
        for j in vi:
            p[j].append(i)
            d[j] = nd
    
    
    
    
    h = int(math.log(max(d),2)) + 1
    for i in range(h - 1):
        for x in range(n):
            p[x].append(p[p[x][i]][i])
    
    
    q = int(input())
    for _ in range(q):
        x,y = map(int, input().split())
        print(lca(x,y))

Solution (Python):
import sys,queue,math,copy,itertools,bisect,collections,heapq

def main():
    LI = lambda : [int(x) for x in sys.stdin.readline().split()]
    NI = lambda : int(sys.stdin.readline())

    n = NI()
    m = n.bit_length()+1
    root = [[-1] * n for _ in range(m)]
    rev = [0] * n
    depth = [0] * n
    for i in range(n):
        x = LI()
        for a in x[1:]:
            root[0][a] = i
            depth[a] = depth[i] + 1
    for k in range(1,m):
        for i in range(n):
            root[k][i] = root[k-1][root[k-1][i]]

    q = NI()
    for _ in range(q):
        u,v = LI()
        if depth[u] < depth[v] : u,v = v, u
        d = depth[u] - depth[v]
        bit = 1
        for i in range(d.bit_length()):
            if d & bit: u = root[i][u]
            bit <<= 1

        j = depth[u].bit_length() - 1
        while j >= 0:
            if root[j][u] != root[j][v]:
                u = root[j][u]
                v = root[j][v]
            j -= 1
        if u == v:
            print(u)
        else:
            print(root[0][u])

if __name__ == '__main__':
    main()

Solution (Python):
import sys,math
sys.setrecursionlimit(1000000)
INF = float("inf")

N = int(sys.stdin.readline())
c = tuple(tuple(map(int,sys.stdin.readline().rstrip().split()))[1:] for _ in range(N)) 
Q = int(sys.stdin.readline())
uv = tuple(tuple(map(int,sys.stdin.readline().rstrip().split())) for _ in range(Q)) 
G = [list() for _ in range(N)]

for i,children in enumerate(c):
    G[i] = children

square = [i**2 for i in range(i,40)]
import bisect

LN = math.ceil(math.log2(N))+1
depth = [0]*N
parents = [[0]*N for _ in range(LN)]

def dfs(v,p,l):
    parents[0][v] = p
    depth[v] = l
    for i in G[v]:
        if i != p:
            dfs(i,v,l+1)

dfs(0,-1,0)

for k in range(LN-1):
    for v in range(N):
        if parents[k][v] < 0:
            parents[k+1][v] = -1
        else:
            parents[k+1][v] = parents[k][parents[k][v]]

def query(u,v):
    if depth[u] > depth[v]:
        u,v = v,u
    while depth[v] != depth[u]:
        v = parents[int(math.log2(depth[v]-depth[u]))][v]
    
    
    
    assert(depth[u]==depth[v])
    if u == v:
        return u
    for k in range(LN)[::-1]:
        if parents[k][v] != parents[k][u]:
            v = parents[k][v]
            u = parents[k][u]
    return parents[0][u]

ans = []
for u,v in uv:
    print(query(u,v))

Solution (Python):
import sys
sys.setrecursionlimit(10**7)

class LCA:
    def __init__(self,N,G,r):
        self.dist=[-1]*N
        self.K=0
        while(2**self.K<N):
            self.K+=1
        self.doubling=[[-1]*N for i in range(self.K+1)]
        self.dfs(G,r,-1,0)
        for k in range(1,self.K+1):
            for i in range(1,N):
                self.doubling[k][i]=self.doubling[k-1][self.doubling[k-1][i]]
        
    def dfs(self,G,v,p,d):
        self.dist[v]=d
        self.doubling[0][v]=p
        for nv in G[v]:
            if nv==p:
                continue
            self.dfs(G,nv,v,d+1)
        
    def get(self,u,v):
        if self.dist[u]<self.dist[v]:
            u,v=v,u
        for k in range(self.K+1):
            if (self.dist[u]-self.dist[v])>>k&1:
                u=self.doubling[k][u]
        if u==v:
            return u
        for k in reversed(range(self.K+1)):
            if self.doubling[k][u]!=self.doubling[k][v]:
                u=self.doubling[k][u]
                v=self.doubling[k][v]
        return self.doubling[0][u]
    
    def getdist(self,u,v):
        return self.dist[u]+self.dist[v]-2*self.dist[self.get(u,v)]

def main():
    N=int(input())
    G=[[] for i in range(N)]
    for i in range(N):
        k=list(map(int,input().split()))
        for j in range(1,len(k)):
            G[i].append(k[j])
            G[k[j]].append(i)
    lca=LCA(N,G,0)
    Q=int(input())
    for i in range(Q):
        a,b=map(int,input().split())
        print(lca.get(a,b))

if __name__=='__main__':
    main()

Solution (Python):
from math import log2

class LCA:
    N = 0
    depth = []
    table = []
    
    def init(N, par):
        LCA.N = N
        LCA.depth = [-1] * (N+1)
        max_depth = 0
        
        
        for i in range(1, N+1):
            if LCA.depth[i] != -1: continue
        
            q = []
            v = i
            
            while True:
                q.append(v)
                if v == par[v]:
                    d = 1
                    break
                if LCA.depth[v] != -1:
                    d = LCA.depth[v]
                    break
                v = par[v]
                
            for v in q[::-1]:
                LCA.depth[v] = d
                d += 1
            max_depth = max(max_depth, d)
                
        t_size = int(log2(max_depth))+1
        LCA.table = [[i for i in range(N+1)] for j in range(t_size)]
        
        for i in range(N+1):
            LCA.table[0][i] = par[i]
        
        for i in range(1, t_size):
            for j in range(1, N+1):
                LCA.table[i][j] = LCA.table[i-1][LCA.table[i-1][j]]
                
    def move(v, m):
        
        i = 0
        while m:
            if m % 2: v = LCA.table[i][v]
            i += 1
            m //= 2
        return v
    
    def same(v, u):
        
        v_d = LCA.depth[v]
        u_d = LCA.depth[u]
        
        if v_d > u_d:
            v, u = u, v
            v_d, u_d = u_d, v_d
            
        diff = u_d - v_d
        
        u = LCA.move(u, diff)
        
        if v == u: return v
        
        l, r = 1, v_d
        
        while l < r:
            mid = (l+r) // 2
            
            v_p = LCA.move(v, mid)
            u_p = LCA.move(u, mid)
            
            if v_p == u_p: r = mid
            else: l = mid+1
        
        return LCA.move(v, l)
    
    def same2(v, u):
        
        if v == u: return True
        
        v_d = LCA.depth[v]
        u_d = LCA.depth[u]
        
        if v_d <= u_d: return False
        
        if LCA.move(v, v_d-u_d) == u: return True
        else: return False

N = int(input())
par = [i for i in range(N+1)]

for i in range(N):
    c = list(map(int, input().split()))

    for j in c[1:]:
        par[j] = i

LCA.init(N, par)

for i in range(int(input())):
    a, b = list(map(int, input().split()))
    print(LCA.same(a, b))

Solution (Python):
import sys
input=sys.stdin.readline
class LCA:
  def __init__(self,n,s,edge):
    self.logn=n.bit_length()
    self.parent=[n*[-1]for _ in range(self.logn)]
    self.dist=[0]*n
    stack=[s]
    visited={s}
    for i in stack:
      for j in edge[i]:
        if j in visited:continue
        stack.append(j)
        visited.add(j)
        self.parent[0][j]=i
        self.dist[j]=self.dist[i]+1
        for k in range(1,self.logn):self.parent[k][j]=self.parent[k-1][self.parent[k-1][j]]
  def query(self,a,b):
    if self.dist[a]<self.dist[b]:a,b=b,a
    if self.dist[a]>self.dist[b]:
      for i in range(self.logn):
        if (self.dist[a]-self.dist[b])&(1<<i):a=self.parent[i][a]
    if a==b:return a
    for i in range(self.logn-1,-1,-1):
      if self.parent[i][a]!=self.parent[i][b]:
        a=self.parent[i][a]
        b=self.parent[i][b]
    return self.parent[0][a]
  def path_range(self,a,b):return self.dist[a]+self.dist[b]-2*self.dist[self.query(a,b)]
  def x_in_abpath(self,x,a,b):return self.path_range(a,x)+self.path_range(b,x)==self.path_range(a,b)
n=int(input())
edge=[[]for _ in range(n)]
for i in range(n):
  k=list(map(int,input().split()))
  for j in range(k[0]):edge[i].append(k[j+1])
lca=LCA(n,0,edge)
q=int(input())
for u,v in [list(map(int,input().split()))for _ in range(q)]:
  print(lca.query(u,v))

Solution (Python):
import sys
stdin = sys.stdin
inf = 1 << 60
mod = 1000000007
 
ni      = lambda: int(ns())
nin     = lambda y: [ni() for _ in range(y)]
na      = lambda: list(map(int, stdin.readline().split()))
nan     = lambda y: [na() for _ in range(y)]
nf      = lambda: float(ns())
nfn     = lambda y: [nf() for _ in range(y)]
nfa     = lambda: list(map(float, stdin.readline().split()))
nfan    = lambda y: [nfa() for _ in range(y)]
ns      = lambda: stdin.readline().rstrip()
nsn     = lambda y: [ns() for _ in range(y)]
ncl     = lambda y: [list(ns()) for _ in range(y)]
nas     = lambda: stdin.readline().split()

sys.setrecursionlimit(10 ** 7)

class LCA:
    def __init__(self, G, root=0):
        V = len(G)
        K = 1
        while 1 << K < V:
            K += 1
        self.parent = [[-1] * V for _ in range(K)]
        self.dist = [-1] * V
        self.dfs(G, root, -1, 0)
        for k in range(K - 1):
            for v in range(V):
                if self.parent[k][v] < 0:
                    self.parent[k + 1][v] = -1
                else:
                    self.parent[k + 1][v] = self.parent[k][self.parent[k][v]]
    
    def dfs(self, G, v, p, d):
        self.parent[0][v] = p
        self.dist[v] = d
        for nv in G[v]:
            if nv != p:
                self.dfs(G, nv, v, d + 1)
    
    def query(self, u, v):
        if self.dist[u] < self.dist[v]:
            u, v = v, u
        K = len(self.parent)
        for k in range(K):
            if (self.dist[u] - self.dist[v]) >> k & 1:
                u = self.parent[k][u]
        
        if u == v:
            return u
        for k in range(K - 1, -1, -1):
            if self.parent[k][u] != self.parent[k][v]:
                u = self.parent[k][u]
                v = self.parent[k][v]

        return self.parent[0][u]
    
    def get_dist(self, u, v):
        return self.dist[u] + self.dist[v] - 2 * self.dist[self.query(u, v)]
    
    def on_path(self, u, v, a):
        return self.get_dist(u, a) + self.get_dist(a, v) == self.get_dist(u, v)

n = ni()
kc = nan(n)
q = ni()
uv = nan(q)

g = [[] for _ in range(n)]
for i in range(n):
    k = kc[i][0]
    c = kc[i][1:]
    for j in range(k):
        g[i].append(c[j])

lca = LCA(g)
for i in range(q):
    u, v = uv[i]
    print(lca.query(u, v))

Solution (Python):

from functools import lru_cache
import sys
buff_readline = sys.stdin.buffer.readline
readline = sys.stdin.readline

INF = 2**60


def read_int():
    return int(buff_readline())


def read_int_n():
    return list(map(int, buff_readline().split()))


class Doubling():
    def __init__(self, a0):
        """
        a0 is an array-like object which contains ai, 0 <= i < N.
        ai is the next value of i.
        """
        N = len(a0)
        self.N = N
        self.nt = [[None] * N for i in range(N.bit_length()+1)]
        for i, a in enumerate(a0):
            self.nt[0][i] = a

        for i in range(1, len(self.nt)):
            for j in range(N):
                if self.nt[i-1][j] is None:
                    self.nt[i][j] = None
                else:
                    self.nt[i][j] = self.nt[i-1][self.nt[i-1][j]]

    def apply(self, i, n):
        """
        Apply n times from i
        """
        j = i
        for k in range(n.bit_length()):
            m = 1 << k
            if m & n:
                j = self.nt[k][j]
            if j is None:
                break
        return j


class LCA():
    def __init__(self, g, root):
        s = [root]
        self.N = len(g)
        self.p = [None] * self.N
        self.d = [INF] * self.N

        self.p[root] = root
        self.d[root] = 0
        while s:
            u = s.pop()
            for v in g[u]:
                if self.d[v] is INF:
                    self.p[v] = u
                    self.d[v] = self.d[u] + 1
                    s.append(v)

        self.doubling = Doubling(self.p)

    def query(self, u, v):
        if self.d[u] > self.d[v]:
            u, v = v, u
        o = self.d[v] - self.d[u]
        v = self.doubling.apply(v, o)

        if u == v:
            return u

        for k in range(len(self.doubling.nt)-1, -1, -1):
            if self.doubling.nt[k][u] != self.doubling.nt[k][v]:
                u = self.doubling.nt[k][u]
                v = self.doubling.nt[k][v]
        return self.doubling.nt[0][u]


def slv(N, KC, Q, UV):
    g = [list() for _ in range(N)]
    for u, (k, *c) in enumerate(KC):
        for v in c:
            g[u].append(v)
            g[v].append(u)

    lca = LCA(g, 0)

    ans = []
    for u, v in UV:
        i = lca.query(u, v)
        ans.append(i)

    return ans


def main():
    N = read_int()
    KC = [read_int_n() for _ in range(N)]
    Q = read_int()
    UV = [read_int_n() for _ in range(Q)]
    print(*slv(N, KC, Q, UV), sep='\n')


if __name__ == '__main__':
    main()

Solution (Python):
import sys
input = sys.stdin.buffer.readline

n = int(input())
li = [list(map(int, input().split()))[1:] for _ in range(n)]


def prepare(n: int, con: list):
	sz = n.bit_length()
	parent = [[0] * n for _ in range(sz)]
	parent[0][0] = -1
	depth = [-1] * n
	depth[0] = 0
	q = [0]
	while q:
		cur = q.pop()
		for nxt in con[cur]:
			if depth[nxt] < 0:
				depth[nxt] = depth[cur] + 1
				parent[0][nxt] = cur
				q.append(nxt)
	for k in range(sz - 1):
		for i in range(n):
			if parent[k][i] < 0:
				parent[k + 1][i] = -1
			else:
				parent[k + 1][i] = parent[k][parent[k][i]]
	return sz, depth, parent


sz, depth, parent = prepare(n, li)


def lca(u, v):
	if depth[u] > depth[v]:
		u, v = v, u
	for k in range(sz):
		if ((depth[v] - depth[u]) >> k & 1):
			v = parent[k][v]
	if u == v:
		return u
	for k in range(sz - 1, -1, -1):
		if parent[k][u] != parent[k][v]:
			u, v = parent[k][u], parent[k][v]
	return parent[0][u]


ans = []
for _ in range(int(input())):
	u, v = map(int, input().split())
	ans.append(lca(u, v))
print("\n".join(map(str, ans)))

Solution (Python):
import sys
input = sys.stdin.readline
sys.setrecursionlimit(100000000)
dy = (-1,0,1,0)
dx = (0,1,0,-1)

class LCA():

    def __init__(self,G,root = 0): 
        self.n = len(G)
        self.G = G
        self.root = root
        self.K = 1 
        while (1<<self.K) <= self.n:
            self.K += 1
        self.parents = [[-1] * self.n for _ in range(self.K)]
        self.dist = [0] * self.n
        
        self._dfs(root,0,-1)
        for k in range(self.K - 1):
            for v in range(self.n):
                if self.parents[k][v] >= 0:
                    self.parents[k + 1][v] = self.parents[k][self.parents[k][v]]
    
    def _dfs(self,i,d,p):
        self.parents[0][i] = p
        self.dist[i] = d
        for e in self.G[i]:
            if e != p:
                self._dfs(e,d + 1,i)
    
    def qry(self,u,v): 
        if self.dist[u] < self.dist[v]:
            u,v = v,u
        
        dif = self.dist[u] - self.dist[v]
        for k in range(self.K):
            if dif >> k & 1:
                u = self.parents[k][u]
        
        if u == v:
            return u
        
        for k in range(self.K - 1,-1,-1):
            if self.parents[k][u] != self.parents[k][v]:
                u = self.parents[k][u]
                v = self.parents[k][v]
        
        return self.parents[0][u]

def main():
    n = int(input())
    G = [[] for _ in range(n)]
    for i in range(n):
        a = list(map(int,input().split()))
        k = a[0]
        for e in a[1:]:
            G[e].append(i)
            G[i].append(e)

    lca = LCA(G)
    q = int(input())
    for _ in range(q):
        u,v = map(int,input().split())
        print(lca.qry(u,v))

if __name__ == '__main__':
    main()

Solution (Python):
import math

def lca(x, y):
    if d[x] < d[y]:
        x,y = y,x
    dy = d[y]
    k = d[x]-dy
    while k:
        x = p[x][int(math.log(k,2))]
        k = d[x]-dy

    if x == y:
        return x

    for i in range(h)[::-1]:
        if p[x][i] != p[y][i]:
            x = p[x][i]
            y = p[y][i]
    return p[x][0]
if __name__ == "__main__":
    n = int(input())
    d = [0]*n
    d[0] = 1
    p = [[] for i in range(n)]
    p[0].append(0)
    for i in range(n):
        vi = map(int, input().split()[1:])
        nd = d[i]+1
        for j in vi:
            p[j].append(i)
            d[j] = nd
    h = int(math.log(max(d),2))+1
    for i in range(h-1):
        for x in range(n):
            p[x].append(p[p[x][i]][i])
    q = int(input())
    for _ in range(q):
        x,y = map(int, input().split())
        print(lca(x,y))

Solution (Python):

import sys, math, itertools, collections, bisect
input = lambda: sys.stdin.buffer.readline().rstrip().decode('utf-8')
inf = float('inf') ;mod = 10**9+7
mans = inf ;ans = 0 ;count = 0 ;pro = 1
sys.setrecursionlimit(10**6)









n=int(input())
G = [[] for i in range(n)]
for i in range(n):
  data = list(map(int,input().split()))
  for j in range(1,len(data)):
    G[i].append(data[j])

depth = [0] * n
parent = [[0] * n for i in range(20)]
def setdepth(node,pre,d):
  depth[node] = d
  parent[0][node] = pre
  for vi in G[node]:
    if vi == pre: continue
    setdepth(vi,node,d + 1)

setdepth(0,-1,0)

for k in range(19):
  for v in range(n):
    if parent[k][v] < 0: parent[k+1][v] = -1
    else: parent[k+1][v] = parent[k][parent[k][v]]

def lca(u,v):
  
  if depth[u] > depth[v]: u,v = v,u
  for k in range(20):
    if (depth[v] - depth[u]) >> k & 1:
      v = parent[k][v]
  
  if u == v:
    return u
  for k in range(19,-1,-1):
    if parent[k][u] != parent[k][v]:
      u = parent[k][u]
      v = parent[k][v]
  return parent[0][u]

Q = int(input())
for _ in range(Q):
  x,y = map(int,input().split())
  
  print(lca(x,y))

Solution (Python):
import math
from collections import deque

def create_table(N, A):
    num_block = int(-(-math.log2(N)//1)) + 1
    dp = [[-1]*num_block for i in range(N)]
    for i in range(N):
        dp[i][0] = i
    for k in range(1, num_block):
        for i in range(N):
            e = min(N-1, i + (1 << (k - 1)))
            former = dp[i][k-1]
            later = dp[e][k-1]
            if A[former] > A[later]:
                dp[i][k] = later
            else:
                dp[i][k] = former
            if e == N-1:
                break
    return dp

def query(i, j, dp, A):
    if i == j:
      return i
    length = int(math.log2(abs(i-j)))
    former = dp[i][length]
    later = dp[j-(1<<length)+1][length]
    if A[former] > A[later]:
        return later
    return former
      
def run():
  N = int(input())
  g = {}
  for n in range(N):
    kc = list(map(int, input().split()))
    g[n] = kc[1:]
  Q = int(input())
  uv = [tuple(map(int, input().split())) for q in range(Q)]
  euler = []
  depths = []
  order = [-1]*N
  def dfs(now, pred, d):
    stacks = deque([(now, pred, d)])
    while stacks:
      now, pred, d = stacks.pop()
      euler.append(now)
      depths.append(d)
      if order[now] != -1:
        continue
      if order[now] == -1:
        order[now] = len(euler) - 1
      for nxt in g[now]:
        if nxt == pred:
          continue
        stacks.append((now, pred, d))
        stacks.append((nxt, now, d+1))
  dfs(0, -1, 0)
  
  len_li = len(depths)
  dp = create_table(len_li, depths)
  
  for u, v in uv:
    o1, o2 = order[u], order[v]
    o1, o2 = min([o1, o2]), max([o1, o2])
    o = query(o1, o2, dp, depths)
    print(euler[o])
    if len(uv) == 1:
      exit()
  
if __name__ == '__main__':
  run()

Solution (Python):
import sys
sys.setrecursionlimit(1000000)
input=sys.stdin.readline


class SegTree():
    def __init__(self, l, INF):
        self.inf = INF

        N = len(l)
        v = 1
        while v<N:
            v *= 2

        self.size = v
        self.node = [self.inf] * (2*self.size-1)
        for i in range(N): 
            self.node[i+self.size-1] = l[i]
        for i in range(self.size-1)[::-1]:
            self.node[i] = min(self.node[2*i+1], self.node[2*i+2]) 

    def get(self, left, right, k=0, l=0, r=-1):
        if r < 0:
            r = self.size

        if (r <= left or right <= l):
            return self.inf
        if (left <= l and r <= right):
            return self.node[k]

        vl = self.get(left, right, 2*k+1, l, (l+r)//2)
        vr = self.get(left, right, 2*k+2, (l+r)//2, r)
        return min(vl, vr)

    def update(self, x, v):
        x += self.size-1
        self.node[x] = v

        while x>0:
            x = (x-1)//2
            self.node[x] = min(self.node[2*x+1], self.node[2*x+2])


class LCA():
    def __init__(self, N, G):
        self.depth = [0] * (N+1)
        self.euler_tour = []
        self.G = G
    
        self.idx = {}
        self._currentIndex = 0

        self._dfs(0, 0, 0)
        self.tree = SegTree(self.euler_tour, (2**31-1, 2**31-1))
    
    def _dfs(self, v, p, d):
        self.euler_tour.append((d, v))
        self.idx[v] = self._currentIndex
        self._currentIndex += 1

        self.depth[v] = d
        for u in self.G[v]:
            if u==p:continue
            self._dfs(u, v, d+1)
            self.euler_tour.append((d, v))
            self._currentIndex += 1
    
    def get(self, u, v):
        a, b = self.idx[u], self.idx[v]
        a, b = (a, b) if a<b else (b, a)
        return self.tree.get(a, b+1)[1]


if __name__ == "__main__":
    n = int(input())
    G = {i:[] for i in range(n)}
    for i in range(n):
        k, *l = map(int, input().split())
        G[i] = l
        for j in l:
            G[j].append(i)
    lca = LCA(n, G)
    q = int(input())
    for _ in range(q):
        u, v = map(int, input().split())
        print(lca.get(u, v))

Solution (Python):
import sys
input = sys.stdin.readline

class Tree():
    def __init__(self,n,edge):
        self.n = n
        self.tree = [[] for _ in range(n)]
        for e in edge:
            self.tree[e[0]-1].append(e[1]-1)
            self.tree[e[1]-1].append(e[0]-1)

    def setroot(self,root):
        self.root = root
        self.parent = [None for _ in range(self.n)]
        self.parent[root] = -1
        self.depth = [None for _ in range(self.n)]
        self.depth[root] = 0
        stack = [root]
        while stack:
            node = stack.pop()
            for adj in self.tree[node]:
                if self.parent[adj] is None:
                    self.parent[adj] = node
                    self.depth[adj] = self.depth[node]+1
                    stack.append(adj)

    def construct_lca(self):
        L = (self.n-1).bit_length()
        self.k_parent = [self.parent]
        prev = self.parent
        for k in range(L):
            array = [0 for _ in range(self.n)]
            for i in range(self.n):
                if prev[i] == -1:
                    continue
                array[i] = prev[prev[i]]
            self.k_parent.append(array)
            prev = array

    def lca(self,u,v):
        d = self.depth[v]-self.depth[u]
        if d < 0: u,v,d = v,u,-d
        for k in self.k_parent:
            if d & 1: v = k[v]
            d >>= 1
        if u == v:
            return u
        for k in reversed(self.k_parent):
            pu,pv = k[u],k[v]
            if pu != pv: u,v = pu,pv
        return self.k_parent[0][u]

N = int(input())
E = []

for i in range(N):
    raw_input = list(map(int,input().split()))
    for j in range(raw_input[0]):
        E.append((i+1,raw_input[j+1]+1))

t = Tree(N,E)
t.setroot(0)
t.construct_lca()

Q = int(input())
A = []

for _ in range(Q):
    u,v = map(int,input().split())
    A.append(t.lca(u,v))

print(*A,sep='\n')

Solution (Python):





import sys
sys.setrecursionlimit(10**7)

N = int(input())
G = [[] for _ in range(N)]
for v in range(N):
    for j, nv in enumerate(map(int, input().split())):
        if j == 0:
            continue
        G[v].append(nv)  


S = []
F = [0]*N
depth = [0]*N
def dfs(v, d):
    F[v] = len(S)
    depth[v] = d
    S.append(v)
    for w in G[v]:
        dfs(w, d+1)
        S.append(v)
dfs(0, 0)


INF = (N, None)


M = 2*N
M0 = 2**(M-1).bit_length()
data = [INF]*(2*M0)
for i, v in enumerate(S):
    data[M0-1+i] = (depth[v], i)
for i in range(M0-2, -1, -1):
    data[i] = min(data[2*i+1], data[2*i+2])


def _query(a, b):
    yield INF
    a += M0; b += M0
    while a < b:
        if b & 1:
            b -= 1
            yield data[b-1]
        if a & 1:
            yield data[a-1]
            a += 1
        a >>= 1; b >>= 1


def query(u, v):
    fu = F[u]; fv = F[v]
    if fu > fv:
        fu, fv = fv, fu
    return S[min(_query(fu, fv + 1))[1]]

ans_list = []

q = int(input())
for _ in range(q):
    u, v = map(int, input().split())
    ans = query(u, v)
    ans_list.append(ans)

print(*ans_list, sep="\n")

Solution (Python):









import sys
input = sys.stdin.readline

N = int(input())
Log_N = (N-1).bit_length()

prev = [[-1]*(Log_N+1) for _ in range(N)]
graph = [[] for _ in range(N)]
for i in range(N):
    K, *A = map(int, input().split())
    graph[i] = A
    for a in A:
        prev[a][0] = i

Q = int(input())
Query = [list(map(int, input().split())) for _ in range(Q)]



Depth = [-1]*N
q = [0]
Depth[0] = 0
d = 0
while q:
    qq = []
    d += 1
    for p in q:
        for np in graph[p]:
            if Depth[np] == -1:
                Depth[np] = d
                qq.append(np)
    q = qq



for k in range(Log_N):
    for i in range(N):
        if prev[i][k] == -1:
            prev[i][k+1] = -1
        else:
            prev[i][k+1] = prev[prev[i][k]][k]


def LCA(u, v):
    dd = Depth[v] - Depth[u]
    if dd < 0:
        u, v = v, u
        dd = -dd
    
    
    for k in range(Log_N+1):
        if dd & 1:
            v = prev[v][k]
        dd >>= 1
    
    if u == v:
        return u
    
    for k in reversed(range(Log_N)):
        pu = prev[u][k]
        pv = prev[v][k]
        if pu != pv:
            u, v = pu, pv
    
    return prev[u][0]


for a, b in Query:
    print(LCA(a, b))

Solution (Python):
from collections import deque
import sys
input = sys.stdin.readline

def bfs():
    depth[0] = 0
    queue = deque([])
    queue.append(0)
    
    while queue:
        current_node = queue.popleft()
        
        for next_node in adj_list[current_node]:
            if depth[next_node] == -1:
                parent[0][next_node] = current_node
                depth[next_node] = depth[current_node] + 1
                queue.append(next_node)
    
def init():
    bfs() 
    
    for k in range(1, log_size):
        for v in range(N):
            if parent[k-1][v] < 0:
                parent[k][v] = -1
            else:
                parent[k][v] = parent[k-1][parent[k-1][v]]

def lca(u, v): 
    if depth[u] > depth[v]:
        u, v = v, u
    
    for k in range(log_size):
        if (depth[v]-depth[u])>>k & 1:
            v = parent[k][v]
    
    if u == v:
        return u
    
    for k in range(log_size-1, -1, -1):
        if parent[k][u] != parent[k][v]:
            u = parent[k][u]
            v = parent[k][v]
    
    return parent[0][u]
    
N = int(input())
log_size = N.bit_length() 
depth = [-1] * N
parent = [[-1] * N for _ in range(log_size)]
adj_list = [[] for _ in range(N)]

for i in range(N):
    kc = list(map(int, input().split()))
    
    for ci in kc[1:]:
        adj_list[i].append(ci)
        adj_list[ci].append(i)

init()
q = int(input())

for _ in range(q):
    ui, vi = map(int, input().split())
    print(lca(ui, vi))

Solution (Python):
from collections import deque


class LowestCommonAncestor():
    """根付き木に対して、二頂点の共通の祖先で最も近いところにある頂点を求める
    初期化(ダブリング配列parent[k][v]の構築): O(NlogN)
    lcaを求めるクエリ: O(logN)
    """
    
    def __init__(self, tree, root):
        self.n = len(tree)
        self.depth = [0] * self.n
        self.log_size = (self.n).bit_length()
        self.parent = [[-1] * self.n for i in range(self.log_size)]

        
        
        q = deque([(root, -1, 0)]) 
        while q:
            v, par, dist = q.pop()
            self.parent[0][v] = par
            self.depth[v] = dist
            for child_v in tree[v]:
                if child_v != par:
                    self.depth[child_v] = dist + 1
                    q.append((child_v, v, dist + 1))

        
        for k in range(1, self.log_size):
            for v in range(self.n):
                self.parent[k][v] = self.parent[k-1][self.parent[k-1][v]]
            
    def lca(self, u, v):
        
        if self.depth[u] > self.depth[v]:
            u, v = v, u
        for k in range(self.log_size):
            if (self.depth[v] - self.depth[u] >> k) & 1:
                v = self.parent[k][v]
        if u == v:
            return u
          
        
        for k in reversed(range(self.log_size)):
            if self.parent[k][u] != self.parent[k][v]:
                u = self.parent[k][u]
                v = self.parent[k][v]
        return self.parent[0][u]


n = int(input())
info = [list(map(int, input().split())) for i in range(n)]
tree = [[] for i in range(n)]
for i in range(n):
    for j in info[i][1:]:
        tree[i].append(j)
        tree[j].append(i)

lca = LowestCommonAncestor(tree, 0)

q = int(input())
query = [list(map(int, input().split())) for i in range(q)]
for i in range(q):
    u, v = query[i]
    print(lca.lca(u, v))