<|instruction|>
Solve the below problem. The solution should start with an abridged problem statement. Then key observations. Then full solution based on the observations. Then C++ and Python implementations with comments.

149. Computer Network
time limit per test: 0.25 sec.
memory limit per test: 4096 KB
input: standard input
output: standard output



A school bought the first computer some time ago. During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of school are anxious about slow functioning of the net and want to know for each computer number Si - maximum distance, for which i-th computer needs to send signal (i.e. length of cable to the most distant computer). You need to provide this information.

Input
There is natural number N (N<=10000) in the first line of input, followed by (N-1) lines with descriptions of computers. i-th line contains two natural numbers - number of computer, to which i-th computer is connected and length of cable used for connection. Total length of cable does not exceed 10^9. Numbers in lines of input are separated by a space.

Output
Write N lines in output file. i-th line must contain number Si for i-th computer (1<=i<=N).

Sample test(s)

Input
3
1 1
1 2

Output
2
3
3
Author:	Andrew V. Lazarev, Michael R. Mirzayanov
Resource:	Saratov Subregional School Team Contest, 2002
Date:	Fall, 2002

<|response|>
1. Abridged problem statement  
You are given a tree of N computers (numbered 1 through N). Computer 1 is the root, and each computer i (2 ≤ i ≤ N) is connected to exactly one earlier computer by a cable of given length. For each computer i, compute Si, the maximum total cable length on a path from i to any other computer in the network.

2. Key observations  
- The network is a weighted tree, so there is exactly one simple path between any two nodes.  
- The “eccentricity” of a node is the greatest distance from that node to any other node in the tree.  
- In a tree, all farthest distances from an arbitrary node lie on the tree’s diameter (the longest path between any two nodes).  
- If U and V are the two ends of the diameter, then for every node i, its eccentricity is max(distance(i, U), distance(i, V)).  

3. Full solution approach  
a. Build an undirected weighted adjacency list of the tree.  
b. Run a DFS (or BFS) from node 1 (or any arbitrary node) to compute distances dist0[]. Find the farthest node U from 1.  
c. Run a second DFS from U to compute distU[], and identify the farthest node V from U. The path U–V is a diameter.  
d. Run a third DFS from V to compute distV[].  
e. For each node i, the answer Si = max(distU[i], distV[i]).  
All three DFS traversals take O(N) time, which is efficient for N up to 10 000.

4. C++ Solution
```cpp
#include <bits/stdc++.h>

using namespace std;

template<typename T1, typename T2>
ostream& operator<<(ostream &out, const pair<T1, T2>& x) {
    return out << x.first << ' ' << x.second;
}

template<typename T1, typename T2>
istream& operator>>(istream &in, pair<T1, T2>& x) {
    return in >> x.first >> x.second;
}

template<typename T>
istream& operator>>(istream &in, vector<T>& a) {
    for(auto& x: a) {
        in >> x;
    }
    return in;
};

template<typename T>
ostream& operator<<(ostream &out, const vector<T>& a) {
    for(auto x: a) {
        out << x << ' ';
    }
    return out;
};

int n;
vector<vector<pair<int, int>>> adj;

void read() {
    cin >> n;
    adj.assign(n, {});
    for(int i = 1; i < n; i++) {
        int u, w;
        cin >> u >> w;
        u--;
        adj[i].push_back({u, w});
        adj[u].push_back({i, w});
    }
}

vector<int> get_distances(int src) {
    vector<int> dist(n, -1);

    function<void(int, int)> dfs = [&](int u, int p) {
        for(auto [v, w]: adj[u]) {
            if(v == p) {
                continue;
            }
            dist[v] = dist[u] + w;
            dfs(v, u);
        }
    };

    dist[src] = 0;
    dfs(src, -1);
    return dist;
}

void solve() {
    // For each node we need the eccentricity: the distance to its farthest
    // node in the tree. The farthest node from any vertex is always one of the
    // two endpoints of the tree's diameter. We find the diameter with the
    // classic two passes: a DFS from node 0 gives the first endpoint (the
    // farthest from 0), a DFS from there gives the second endpoint, and a DFS
    // from that second endpoint gives the third distance array. For every node
    // the answer is the larger of its distances to the two diameter endpoints.

    vector<int> dist0 = get_distances(0);
    int diam_end_1 = max_element(dist0.begin(), dist0.end()) - dist0.begin();
    vector<int> dist1 = get_distances(diam_end_1);
    int diam_end_2 = max_element(dist1.begin(), dist1.end()) - dist1.begin();
    vector<int> dist2 = get_distances(diam_end_2);

    for(int i = 0; i < n; i++) {
        cout << max(dist1[i], dist2[i]) << '\n';
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int T = 1;
    // cin >> T;
    for(int test = 1; test <= T; test++) {
        read();
        // cout << "Case #" << test << ": ";
        solve();
    }

    return 0;
}
```

5. Python implementation with detailed comments  
```python
import sys
sys.setrecursionlimit(20000)

def read_tree():
    data = sys.stdin.read().split()
    it = iter(data)
    n = int(next(it))
    # adjacency list: for each node, list of (neighbor, weight)
    adj = [[] for _ in range(n)]
    for i in range(1, n):
        u = int(next(it)) - 1
        w = int(next(it))
        adj[i].append((u, w))
        adj[u].append((i, w))
    return n, adj

def dfs_distances(adj, src):
    n = len(adj)
    dist = [-1] * n
    dist[src] = 0
    # recursive DFS to fill dist[]
    def dfs(u, parent):
        for v, w in adj[u]:
            if v == parent:
                continue
            dist[v] = dist[u] + w
            dfs(v, u)
    dfs(src, -1)
    return dist

def main():
    n, adj = read_tree()
    # 1) DFS from node 0
    dist0 = dfs_distances(adj, 0)
    # find farthest node U
    U = max(range(n), key=lambda i: dist0[i])
    # 2) DFS from U
    distU = dfs_distances(adj, U)
    V = max(range(n), key=lambda i: distU[i])
    # 3) DFS from V
    distV = dfs_distances(adj, V)
    # 4) output max(distU[i], distV[i]) for each i
    out = [str(max(distU[i], distV[i])) for i in range(n)]
    print("\n".join(out))

if __name__ == "__main__":
    main()
```