# Python code to find LCA of given
# two nodes in a tree
 
maxn = 100005
 
# the graph
g = [[] for i in range(maxn)]
 
# level of each node
level = [0] * maxn
 
e = []
l = []
h = [0] * maxn
 
# the segment tree
st = [0] * (5 * maxn)
 
# adding edges to the graph(tree)
def add_edge(u: int, v: int):
    g[u].append(v)
    g[v].append(u)
 
# assigning level to nodes
def levelling(src: int):
    for i in range(len(g[src])):
        des = g[src][i]
        if not level[des]:
            level[des] = level[src] + 1
            leveling(des)
 
visited = [False] * maxn
 
# storing the dfs traversal
# in the array e
def dfs(src: int):
    e.append(src)
    visited[src] = True
    for i in range(len(g[src])):
        des = g[src][i]
        if not visited[des]:
            dfs(des)
            e.append(src)
 
# making the array l
def setting_l(n: int):
    for i in range(len(e)):
        l.append(level[e[i]])
 
# making the array h
def setting_h(n: int):
    for i in range(n + 1):
        h[i] = -1
    for i in range(len(e)):
 
        # if is already stored
        if h[e[i]] == -1:
            h[e[i]] = i
 
# Range minimum query to return the index
# of minimum in the subarray L[qs:qe]
def RMQ(ss: int, se: int, qs: int, qe: int, i: int) -> int:
    global st
    if ss > se:
        return -1
 
    # out of range
    if se < qs or qe < ss:
        return -1
 
    # in the range
    if qs <= ss and se <= qe:
        return st[i]
 
    mid = (se + ss) >> 1
    stt = RMQ(ss, mid, qs, qe, 2 * i + 1)
    en = RMQ(mid + 1, se, qs, qe, 2 * i + 2)
 
    if stt != -1 and en != -1:
        if l[stt] < l[en]:
            return stt
        return en
    elif stt != -1:
        return stt
    elif en != -1:
        return en
 
# constructs the segment tree
def segmentTreeConstruction(ss: int, se: int, i: int):
    if ss > se:
        return
    if ss == se: # leaf
        st[i] = ss
        return
 
    mid = (ss + se) >> 1
    segmentTreeConstruction(ss, mid, 2 * i + 1)
    segmentTreeConstruction(mid + 1, se, 2 * i + 2)
 
    if l[st[2 * i + 1]] < l[st[2 * i + 2]]:
        st[i] = st[2 * i + 1]
    else:
        st[i] = st[2 * i + 2]
 
# Function to get LCA
def LCA(x: int, y: int) -> int:
    if h[x] > h[y]:
        x, y = y, x
    return e[RMQ(0, len(l) - 1, h[x], h[y], 0)]
 
# Driver Code
if __name__ == "__main__":
 
    # n=number of nodes in the tree
    # q=number of queries to answer
    n = 15
    q = 5
 
    # making the tree
    # /*
    #         1
    #     / | \
    #     2 3 4
    #         | \
    #         5 6
    #     / | \
    #     8 7 9 (right of 5)
    #     / | \ | \
    #     10 11 12 13 14
    #             |
    #             15
    # */
    add_edge(1, 2)
    add_edge(1, 3)
    add_edge(1, 4)
    add_edge(3, 5)
    add_edge(4, 6)
    add_edge(5, 7)
    add_edge(5, 8)
    add_edge(5, 9)
    add_edge(7, 10)
    add_edge(7, 11)
    add_edge(7, 12)
    add_edge(9, 13)
    add_edge(9, 14)
    add_edge(12, 15)
 
    level[1] = 1
    leveling(1)
    dfs(1)
    setting_l(n)
    setting_h(n)
 
    segmentTreeConstruction(0, len(l) - 1, 0)
 
    print(LCA(10, 15))
    print(LCA(11, 14))
 
# This code is contributed by
# sanjeev2552

Time complexity: nlogn
Space complexity: linear