const int N = ${1:5e5} + 5;
int siz[N], ms[N], dep[N], top[N], p[N];
void dfs1(int now, int fa) {
for (auto t : adj[now]) {
if (ms[now] == -1 || siz[t] > siz[ms[now]]) ms[now] = t;
void dfs(int now, int fa, int tag) {
for (auto t : adj[now]) {
if (t == fa || t == ms[now]) continue;
while (top[a] != top[b]) {
if (dep[top[a]] < dep[top[b]]) {
return dep[a] > dep[b] ? b : a;
vector d(n + 1, vector<pair<int, int>>(20));
auto dfs = [&](auto self, int u, int fa) -> void {
for (auto [v, w] : adj[u]) {
for (int i = 1; i < 20; i++) {
for (int j = 1; j <= n; j++) {
d[j][i] = {d[d[j][i - 1].first][i - 1].first, max(d[j][i - 1].second, d[d[j][i - 1].first][i - 1].second)};
auto dis = [&](int u, int v) {
if (dep[u] < dep[v]) swap(u, v);
for (int i = 19; i >= 0; i--) {
if (dep[d[u][i].first] >= dep[v]) {
res = max(res, d[u][i].second);
assert(dep[u] == dep[v]);
for (int i = 19; i >= 0; i--) {
if (d[u][i].first != d[v][i].first) {
res = max(res, d[u][i].second);
res = max(res, d[v][i].second);
res = max(res, d[u][0].second);
res = max(res, d[v][0].second);