#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const int maxn = 10000 + 20;
struct node {
int u, v, w, tonext;
}e[maxn * 2];
int first[maxn];
int num;
int n;
int dp[maxn][2], vis[maxn], id[maxn], DFN;
void add(int u, int v, int w) {
++num;
e[num].u = u;
e[num].v = v;
e[num].w = w;
e[num].tonext = first[u];
first[u] = num;
}
int dfsone(int cur) {
if (vis[cur] == DFN) return dp[cur][0];
vis[cur] = DFN;
int mx = 0, mxid = -inf;
for (int i = first[cur]; i; i = e[i].tonext) {
int v = e[i].v;
int t = dfsone(v) + e[i].w;
if (t > mx) {
mx = t;
mxid = i;
}
}
dp[cur][0] = mx; //子树的是0
id[cur] = mxid;
//求second大
int sec = 0;
for (int i = first[cur]; i; i = e[i].tonext) {
int v = e[i].v;
if (i == id[cur]) continue;
int t = dfsone(v) + e[i].w;
if (t > sec) sec = t;
}
dp[cur][1] = sec;
return dp[cur][0];
}
int ans[maxn]; //依靠爸爸能得到的最大值,然后最后dfstwo完后更新自己
int dfstwo(int cur) {
for (int i = first[cur]; i; i = e[i].tonext) {
int v = e[i].v;
if (id[cur] == i) {
ans[v] = max(ans[cur], dp[cur][1]) + e[i].w;
} else {
ans[v] = max(ans[cur], dp[cur][0]) + e[i].w;
}
dfstwo(v);
ans[v] = max(ans[v], dp[v][0]); //更新真实值
}
}
void work() {
memset(first, 0, sizeof first);
memset(ans, 0, sizeof ans);
num = 0;
++DFN;
for (int i = 2; i <= n; ++i) {
int u, w;
scanf("%d%d", &u, &w);
add(u, i, w);
}
dfsone(1);
ans[1] = 0;
dfstwo(1);
ans[1] = dp[1][0];
for (int i = 1; i <= n; ++i) {
printf("%d\n", ans[i]);
}
// printf("\n");
}
int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
while (scanf("%d", &n) != EOF) work();
return 0;
}