Link to this code: https://cses.fi/paste/d6aab732b164cb2ad9f7e0/
#include <bits/stdc++.h>
using namespace std;

const int MAX_N = 2e6 + 5;

int downward[MAX_N], upward[MAX_N];
vector<int> tree[MAX_N];  // 1-based

void add_edge(int u, int v) {
    tree[u].push_back(v);
    tree[v].push_back(u);
}

int dfs1(int u, int p = -1) {
    for (int v : tree[u]) {
        if (v == p) continue;
        dfs1(v, u);
        downward[u] = max(downward[u], downward[v] + 1);  // max height of the subtree rooted at `u`
    }
    return 0;
}

int dfs2(int u, int p = -1) {
    vector<int> &nbrs = tree[u];  // neighbors
    int sz = nbrs.size();
    vector<int> pref_mx(sz, 0), suff_mx(sz, 0);
    for (int i = 0, mx = 0; i < sz; ++i) {  // compute prefix
        int v = nbrs[i];
        if (v != p) mx = max(mx, downward[v]);
        if (i) mx = max(mx, pref_mx[i - 1]);
        pref_mx[i] = mx;
    }
    for (int i = sz - 1, mx = 0; i >= 0; --i) {  // compute suffix
        int v = nbrs[i];
        if (v != p) mx = max(mx, downward[v]);
        if (i < sz - 1) mx = max(mx, suff_mx[i + 1]);
        suff_mx[i] = mx;
    }
    for (int i = 0; i < sz; ++i) {  // consider the max
        int v = nbrs[i];
        if (v == p) continue;
        upward[v] = upward[u] + 1;  // do not use `if (p != -1)`
        if (i) upward[v] = max(upward[v], 2 + pref_mx[i - 1]);
        if (i < sz - 1) upward[v] = max(upward[v], 2 + suff_mx[i + 1]);
    }
    for (int v : nbrs) {
        if (v == p) continue;
        dfs2(v, u);
    }
    // for (int i = 0; i < sz; ++i) cout << nbrs[i] << " " << pref_mx[i] << " " << suff_mx[i] <<
    // endl;
    return 0;
}

void solve() {
    int N;
    cin >> N;
    for (int i = 0; i < N - 1; ++i) {
        int u, v;
        cin >> u >> v;
        add_edge(u, v);
    }
    dfs1(1);
    dfs2(1);
    for (int i = 1; i <= N; ++i) cout << max(downward[i], upward[i]) << ' ';
}

int32_t main() {
    solve();
    return 0;
}

/*
the path to the farthest node from each node can exist only in 2 ways
    1. through its subtree (below/downwards)
    2. through its parent (above/upwards)

dfs1 - downwards
    - compute the height of each node
    - this gives the distance of farthest node in subtree

dfs2 - upwards
    - A = upward of parent + 1
    - B = consider the maximum of heights of all the siblings of the current node (in other words
      maximum of all the chidren of the parent of current node except the current node and grand
      parent)
    - upward of current node = max(A, B)

answer is max(upward, downward) for each node
*/