using
System;
using
System.Collections.Generic;
class
GFG {
static
int
N = 100005;
static
int
[] level =
new
int
[N];
static
int
LG = 20;
static
int
[,] dp =
new
int
[LG, N];
static
int
[,] mx =
new
int
[LG, N];
static
List<List<Tuple<
int
,
int
>>> v =
new
List<List<Tuple<
int
,
int
>>>();
static
int
n = 0;
static
void
dfs_lca(
int
a,
int
par,
int
lev)
{
dp[0,a] = par;
level[a] = lev;
for
(
int
i = 0; i < v[a].Count; i++)
{
if
(v[a][i].Item1 == par)
continue
;
mx[0,v[a][i].Item1] = v[a][i].Item2;
dfs_lca(v[a][i].Item1, a, lev + 1);
}
}
static
void
find_ancestor()
{
for
(
int
i = 1; i < 16; i++)
{
for
(
int
j = 1; j < n + 1; j++)
{
dp[i,j] = dp[i - 1,dp[i - 1,j]];
mx[i,j] = Math.Max(mx[i - 1,j], mx[i - 1,dp[i - 1,j]]);
}
}
}
static
int
getMax(
int
a,
int
b)
{
if
(level[b] < level[a])
{
int
temp = a;
a = b;
b = temp;
}
int
ans = 0;
int
diff = level[b] - level[a];
while
(diff > 0)
{
int
log = (
int
)(Math.Log(diff) / Math.Log(2));
ans = Math.Max(ans, mx[log,b]);
b = dp[log,b];
diff -= (1 << log);
}
while
(a != b)
{
int
i = (
int
)(Math.Log(level[a]) / Math.Log(2));
while
(i > 0 && dp[i,a] == dp[i,b])
{
i-=1;
}
ans = Math.Max(ans, mx[i,a]);
ans = Math.Max(ans, mx[i,b]);
a = dp[i,a];
b = dp[i,b];
}
return
ans;
}
static
void
compute_lca()
{
dfs_lca(1, 0, 0);
find_ancestor();
}
static
void
Main() {
for
(
int
i = 0; i < LG; i++)
{
for
(
int
j = 0; j < N; j++)
{
dp[i,j] = 0;
mx[i,j] = 0;
}
}
for
(
int
i = 0; i < N; i++)
{
v.Add(
new
List<Tuple<
int
,
int
>>());
}
v[1].Add(
new
Tuple<
int
,
int
>(2, 2));
v[2].Add(
new
Tuple<
int
,
int
>(1, 2));
v[1].Add(
new
Tuple<
int
,
int
>(3, 5));
v[3].Add(
new
Tuple<
int
,
int
>(1, 5));
v[3].Add(
new
Tuple<
int
,
int
>(4, 3));
v[4].Add(
new
Tuple<
int
,
int
>(3, 4));
v[3].Add(
new
Tuple<
int
,
int
>(5, 1));
v[5].Add(
new
Tuple<
int
,
int
>(3, 1));
compute_lca();
int
[,] queries
= { { 3, 5 },
{ 2, 3 },
{ 2, 4 } };
int
q = 3;
for
(
int
i = 0; i < q; i++) {
int
max_edge = getMax(queries[i,0],
queries[i,1]);
Console.WriteLine(max_edge);
}
}
}