#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef long double D;
//typedef complex<D> P;
#define F first
#define S second
const ll MOD=1000000007;
//const ll MOD=998244353;

template<typename T,typename U>istream & operator >> (istream &i,pair<T,U> &A){i>>A.F>>A.S; return i;}
template<typename T>istream & operator >> (istream &i,vector<T> &A){for(auto &I:A){i>>I;} return i;}
template<typename T,typename U>ostream & operator << (ostream &o,const pair<T,U> &A){o<<A.F<<" "<<A.S; return o;}
template<typename T>ostream & operator << (ostream &o,const vector<T> &A){int i=A.size(); for(auto &I:A){o<<I<<(--i?" ":"");} return o;}

template<typename F> struct FixPoint : F{
  FixPoint(F&& f):F(forward<F>(f)){}
  template<typename... Args> decltype(auto) operator() (Args&&... args) const {return F::operator()(*this,forward<Args>(args)...);}
};
template<typename F> inline decltype(auto) MFP(F&& f){return FixPoint<F>(forward<F>(f));}

namespace tree_functions{
  using Tree=vector<vector<int>>;

  //A[root]=-1,A[v]=parent(v)
  vector<int> parent(const Tree &edge,int root=0){
    vector<int> A(edge.size(),-1);
    MFP(
        [&](auto dfs,int u,int p)->void{
          A[u]=p;
          for(auto &v:edge[u]){
            if(v!=p){dfs(v,u);}
          }
        }
        )(root,-1);
    return A;
  }

  //A[root]=0,A[v]=A[parent(v)]+1
  vector<int> depth(const Tree &edge,int root=0){
    vector<int> A(edge.size(),-1);
    MFP(
        [&](auto dfs,int u,int p,int d)->void{
          A[u]=d++;
          for(auto &v:edge[u]){
            if(v!=p){dfs(v,u,d);}
          }
        }
        )(root,-1,0);
    return A;
  }

  //A[i]=|{j|j is a descendant of i}|
  vector<int> cnt_dsc(const Tree &edge,int root=0){
    vector<int> A(edge.size(),-1);
    MFP(
        [&](auto dfs,int u,int p)->int{
          A[u]=1;
          for(auto &v:edge[u]){
            if(v!=p){A[u]+=dfs(v,u);}
          }
          return A[u];
        }
        )(root,-1);
    return A;
  }
  
  //sort edges by the number of descendants
  //parent,heavy child,light child (root doesn't have a parent)
  void heavy_sort(Tree &edge,int root=0){
    int N=edge.size();
    vector<int> num=cnt_dsc(edge,root);
    for(int i=0;i<N;i++){
      sort(edge[i].begin(),edge[i].end(),[&](int a,int b){return num[a]>num[b];});
    }
  }

  //A[i]=root of heavy edge
  vector<int> HLD(Tree &edge,int root=0){
    heavy_sort(edge,root);
    vector<int> A(edge.size(),-1);
    MFP(
        [&](auto dfs,int u,int p,int d)->void{
          A[u]=d;
          bool heavy=true;
          for(auto &v:edge[u]){
            if(v!=p){dfs(v,u,heavy?d:v); heavy=false;}
          }
        }
        )(root,-1,root);
    return A;
  }

  vector<int> first_order(const Tree &edge,int root=0){
    vector<int> A(edge.size(),-1);
    int idx=0;
    MFP(
        [&](auto dfs,int u,int p)->void{
          A[idx++]=u;
          for(auto &v:edge[u]){
            if(v!=p){dfs(v,u);}
          }
        }
        )(root,-1);
    return A;
  }

  vector<int> last_order(const Tree &edge,int root=0){
    vector<int> A(edge.size(),-1);
    int idx=0;
    MFP(
        [&](auto dfs,int u,int p)->void{
          for(auto &v:edge[u]){
            if(v!=p){dfs(v,u);}
          }
          A[idx++]=u;
        }
        )(root,-1);
    return A;
  }

  //max(dist(v,from)),argmax(dist(v,from))
  pair<int,int> distant_node(const Tree &edge,int from){
    pair<int,int> ret(0,from);
    MFP(
        [&](auto dfs,int u,int p,int d)->void{
          ret=max(ret,pair<int,int>(d,u));
          for(auto &v:edge[u]){
            if(v!=p){dfs(v,u,d+1);}
          }
        }
        )(0,-1,0);
    return ret;
  }
  
  //middle of wight   one or two
  vector<int> centroid(const Tree &edge){
    vector<int> ret;
    int N=edge.size();
    MFP(
        [&](auto dfs,int u,int p)->int{
          int mx=0,sum=1;
          for(auto &v:edge[u]){
            if(v!=p){
              int tmp=dfs(v,u);
              sum+=tmp;
              mx=max(mx,tmp);
            }
          }
          mx=max(mx,N-sum);
          if(mx*2<=N){ret.push_back(u);}
          return sum;
        }
        )(0,-1);
    sort(ret.begin(),ret.end());
    return ret;
  }

  //middle of distance   one or two
  vector<int> center(const Tree &edge){
    vector<int> ret;
    int N=edge.size();
    int u=distant_node(edge,0).S;
    int v=distant_node(edge,u).S;
    vector<int> d1=depth(edge,u),d2=depth(edge,v);
    int dm=d1[v];
    for(int i=0;i<N;i++){
      if(d1[i]+d2[i]==dm && abs(d1[i]-d2[i])<=1){ret.push_back(i);}
    }
    return ret;
  }
  
  //A[i]=centroid of up-tree
  vector<int> CRD(const Tree &edge){
    vector<int> A(edge.size(),-2);
    int sz,ctr;
    auto size_of_subtree=
      MFP(
          [&](auto dfs,int u,int p)->int{
            int sum=1;
            for(auto &v:edge[u]){
              if(v!=p && A[v]==-2){sum+=dfs(v,u);}
            }
            return sum;
          }
          );
    auto centroid_of_subtree=
      MFP(
          [&](auto dfs,int u,int p)->int{
            int mx=0,sum=1;
            for(auto &v:edge[u]){
              if(v!=p && A[v]==-2){
                int tmp=dfs(v,u);
                mx=max(mx,tmp);
                sum+=tmp;
              }
            }
            mx=max(mx,sz-sum);
            if(mx*2<=sz){ctr=u;}
            return sum;
          }
          );
    MFP(
        [&](auto dfs,int u,int p)->void{
          sz=size_of_subtree(u,-1);
          centroid_of_subtree(u,-1);
          u=ctr;
          A[u]=p;
          for(auto &v:edge[u]){
            if(A[v]==-2){dfs(v,u);}
          }
        }
        )(0,-1);
    return A;
  }
};
using namespace tree_functions;

//BEGIN CUT HERE
template <typename T,typename E>
struct SegmentTree{
  using F = function<T(T,T)>;
  using G = function<T(T,E)>;
  using H = function<E(E,E)>;
  int n,height;
  F f;
  G g;
  H h;
  T ti;
  E ei;
  vector<T> dat;
  vector<E> laz;
  SegmentTree(F f,G g,H h,T ti,E ei):
    f(f),g(g),h(h),ti(ti),ei(ei){}

  void init(int n_){
    n=1;height=0;
    while(n<n_) n<<=1,height++;
    dat.assign(2*n,ti);
    laz.assign(2*n,ei);
  }

  void build(const vector<T> &v){
    int n_=v.size();
    init(n_);
    for(int i=0;i<n_;i++) dat[n+i]=v[i];
    for(int i=n-1;i;i--)
      dat[i]=f(dat[(i<<1)|0],dat[(i<<1)|1]);
  }

  inline T reflect(int k){
    return laz[k]==ei?dat[k]:g(dat[k],laz[k]);
  }

  inline void propagate(int k){
    if(laz[k]==ei) return;
    laz[(k<<1)|0]=h(laz[(k<<1)|0],laz[k]);
    laz[(k<<1)|1]=h(laz[(k<<1)|1],laz[k]);
    dat[k]=reflect(k);
    laz[k]=ei;
  }

  inline void thrust(int k){
    for(int i=height;i;i--) propagate(k>>i);
  }

  inline void recalc(int k){
    while(k>>=1)
      dat[k]=f(reflect((k<<1)|0),reflect((k<<1)|1));
  }

  void update(int a,int b,E x){
    if(a>=b) return;
    thrust(a+=n);
    thrust(b+=n-1);
    for(int l=a,r=b+1;l<r;l>>=1,r>>=1){
      if(l&1) laz[l]=h(laz[l],x),l++;
      if(r&1) --r,laz[r]=h(laz[r],x);
    }
    recalc(a);
    recalc(b);
  }

  void set_val(int a,T x){
    thrust(a+=n);
    dat[a]=x;laz[a]=ei;
    recalc(a);
  }

  T query(int a,int b){
    if(a>=b) return ti;
    thrust(a+=n);
    thrust(b+=n-1);
    T vl=ti,vr=ti;
    for(int l=a,r=b+1;l<r;l>>=1,r>>=1) {
      if(l&1) vl=f(vl,reflect(l++));
      if(r&1) vr=f(reflect(--r),vr);
    }
    return f(vl,vr);
  }

  template<typename C>
  int find(int st,C &check,T &acc,int k,int l,int r){
    if(l+1==r){
      acc=f(acc,reflect(k));
      return check(acc)?k-n:-1;
    }
    propagate(k);
    int m=(l+r)>>1;
    if(m<=st) return find(st,check,acc,(k<<1)|1,m,r);
    if(st<=l&&!check(f(acc,dat[k]))){
      acc=f(acc,dat[k]);
      return -1;
    }
    int vl=find(st,check,acc,(k<<1)|0,l,m);
    if(~vl) return vl;
    return find(st,check,acc,(k<<1)|1,m,r);
  }

  template<typename C>
  int find(int st,C &check){
    T acc=ti;
    return find(st,check,acc,1,0,n);
  }
};
//END CUT HERE

vector<int> inv(const vector<int> &A){
  int N=A.size();
  vector<int> ret(N);
  for(int i=0;i<N;i++){ret[A[i]]=i;}
  return ret;
}

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  int N;
  cin>>N;
  if(N==1){cout<<0<<endl; return 0;}
  vector<vector<int>> edge(N);
  vector<ll> D(N,0);
  for(int i=1;i<N;i++){
    int p,d;
    cin>>p>>d;
    p--;
    edge[i].push_back(p);
    edge[p].push_back(i);
    D[i]=d;
  }

  auto leaf=[&](int v){return (v==0 && edge[v].empty()) || (v!=0 && edge[v].size()<2);};
  vector<ll> d=D;
  vector<int> hl=HLD(edge);
  vector<int> fr=first_order(edge);
  vector<int> idx=inv(fr);
  vector<int> ls=last_order(edge);
  vector<int> sub(N,fr.back());
  vector<int> bt(N);
  vector<int> mx(N,fr[1]);
  auto f1=[](int a,int b){return a+b;};
  auto f2=[](ll a,ll b){return a+b;};
  SegmentTree<int,int> seg(f1,f1,f1,0,0);
  SegmentTree<ll,ll> dep(f2,f2,f2,0,0);
  SegmentTree<int,int> num(f1,f1,f1,0,0);
  seg.build(vector<int>(N,0));
  dep.build(vector<ll>(N,0));
  num.build(vector<int>(N,0));
  for(int i=1;i<N;i++){mx[i]=(leaf(i)?-1:edge[i][1]);}
  for(int i=0;i<N;i++){bt[hl[fr[i]]]=i;}
  for(int i=0,tmp=-1;i<N;i++){
    if(leaf(ls[i])){tmp=ls[i];}
    sub[ls[i]]=idx[tmp]+1;
  }
  for(auto &u:fr){for(auto &v:edge[u]){if(idx[v]>idx[u]){D[v]+=D[u];}}}
  
  auto cnt=[&](int a){return seg.query(idx[a],sub[a]);};
  ll sum=0;
  auto query=
    [&](int k){
      ll ans=sum;
      int u=0;
      while(1){
        int lf=idx[u],rg=bt[u]+1;
        while(rg-lf>1){
          int mid=(lf+rg)/2;
          if(cnt(fr[mid])*2>=k){lf=mid;}
          else{rg=mid;}
        }
        lf=fr[lf];
        rg=bt[u]+1;
        ans+=(D[lf]-D[u])*(k-cnt(u));
        ans-=2*dep.query(idx[u],idx[lf])-(D[lf]+D[u])*num.query(idx[u],idx[lf]);        
        ans-=(D[lf]-D[u])*num.query(idx[lf],rg);
        u=lf;        
        if(leaf(u) || cnt(mx[u])*2<=k){break;}
        ans+=(k-2*cnt(mx[u]))*d[mx[u]];
        u=mx[u];
      }
      cout<<ans<<endl;
    };
  auto add=
    [&](int a){
      sum+=D[a];
      seg.update(idx[a],idx[a]+1,1);
      dep.update(idx[a],idx[a]+1,D[a]);
      num.update(idx[a],idx[a]+1,1);
      a=hl[a];
      while(a!=0){
        int v=a;
        a=edge[a][0];
        dep.update(idx[a],idx[a]+1,D[a]);
        num.update(idx[a],idx[a]+1,1);
        if(cnt(mx[a])<cnt(v)){mx[a]=v;}
        a=hl[a];
      }
    };
  for(int i=0;i<N;){add(i); query(++i);}
  
  
  return 0;
}



Measured memory_bytes: 48196