//树形DP,求树的最大直径。。。。
#include<stdio.h>
#include<string.h>#include<vector>
using namespace std;
#define Max(x,y) (x>y?x:y)
#define max 10000+5
vector<int> next[max];//存图
int n,cost[max],dp[max],sec[max],up[max],f[max];
//dp[i] 结点i在其子树上的最大直径
//sec[i]结点i在其子树上的次最大直径
//up[i] 结点i通过其父结点可获得的最大直径
//f[i] 结点i在其子树上获得最大直径所通过的子结点
void init(){
for(int i=0;i<=n;i++){
next[i].clear();
}
memset(sec,0,sizeof(sec));
memset(f,0,sizeof(f));
memset(dp,0,sizeof(dp));
memset(up,0,sizeof(up));
memset(cost,0,sizeof(cost));
}
int dfs(int u){
int pre;//记录在子树上获得最大直径所通过的子结点
int& res=dp[u];
for(int i=0;i<next[u].size();i++){
int v=next[u][i];
int temp=dfs(v)+cost[v];
if(res<temp){ //更新最大直径
sec[u]=res;
res=temp; pre=v;
}
else if(temp>sec[u]){//更新次最大直径
sec[u]=temp;
}
}
f[u]=pre;
return res;
}
void DP(int u){
for(int i=0;i<next[u].size();i++){
int v=next[u][i];
if(f[u]==v){ //如果结点u通过其子结点v得到最大直径
up[v]=Max(up[u],sec[u])+cost[v];
}
else{
up[v]=Max(up[u],dp[u])+cost[v];
}
DP(v);
}
}
int main(){
while(~scanf("%d",&n)){
init();
for(int i=2;i<=n;i++){
int a,b;
scanf("%d%d",&a,&b);
next[a].push_back(i);
cost[i]=b;
}
dfs(1); //计算每个结点到其子树上叶结点最大距离
DP(1); //更新最大距离
for(int i=1;i<=n;i++){
printf("%d\n",Max(dp[i],up[i]));//取向下和向上的最大值
}
}
}