Link to this code: https://cses.fi/paste/e3fbebb580d9c52fd9fb12/
#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
    // lg1 - first largest, lg2 - second largest, v1 - origin/node of lg1, v2 - origin/node of lg2;
    int lg1 = 0, v1 = -1, lg2 = 0, v2 = -1;
    for (int v : nbrs) {
        if (v == p) continue;
        int x = downward[v];
        if (x >= lg1) {
            lg2 = lg1;
            lg1 = x;
            v2 = v1;
            v1 = v;
        } else if (x > lg2) {
            lg2 = x;
            v2 = v;
        }
    }
    for (int v : nbrs) {
        if (v == p) continue;
        // cout << v << " " << lg1 << " " << v1 << " " << lg2 << endl;
        upward[v] = upward[u] + 1;
        // the following conditions are important for edge cases
        if (v1 != -1 && v != v1) {
            upward[v] = max(upward[v], 2 + lg1);
        } else if (v2 != -1) {
            upward[v] = max(upward[v], 2 + lg2);
        }
    }
    for (int v : nbrs) {
        if (v == p) continue;
        dfs2(v, u);
    }
    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 (bottom up / bottom to top)
    - compute the height of each node
    - this gives the distance of farthest node in subtree

dfs2 - upwards (top down / top to bottom)
    - A = upward of parent + 1
    - B = consider largest 2 values and their origin so that if it came from the current node we can
          ignore it
    - upward of current node = max(A, B)

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