#include <algorithm>  
#include <iostream>  
#include <sstream>  
#include <string>  
#include <cstring>
#include <vector>  
#include <queue>  
#include <set>  
#include <map>  
#include <cstdio>  
#include <cstdlib>  
#include <cctype>  
#include <cmath>  
#include <list>  
#include <cassert>
#include <ctime>
#include <climits>
using namespace std;  

#define PB push_back  
#define MP make_pair  
#define SZ(v) ((int)(v).size())  
#define FOR(i,a,b) for(int i=(a);i<(b);++i)  
#define REP(i,n) FOR(i,0,n)  
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)  
#define REPE(i,n) FORE(i,0,n)  
#define FORSZ(i,a,v) FOR(i,a,SZ(v))  
#define REPSZ(i,v) REP(i,SZ(v))  
typedef long long ll;
typedef unsigned long long ull;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

const int MAXN=131072;
typedef struct R { ll p,q; } R;

int n;
int par[MAXN],cost[MAXN];
int c[MAXN][2],nc[MAXN];


R tmp[MAXN];
int combine(R* a,int na,int ca,R *b,int nb,int cb,ll mx) {
	if(na>nb) swap(a,b),swap(na,nb),swap(ca,cb);
	int ap=0,aq=na-1,bpp=nb,bpq=-1,bqp=nb,bqq=-1,ret=0;
	while(ap<na||aq>=0) {
		ll pval=LLONG_MAX,qval=LLONG_MAX;
		if(ap<na&&a[ap].p<pval) pval=a[ap].p; if(aq>=0&&a[aq].q<pval) pval=a[aq].q;
		if(ap<na&&a[ap].p==pval) {
			while(bpp-1>=0&&a[ap].q+b[bpp-1].q+ca+cb<=mx) --bpp;
			while(bpq+1<nb&&a[ap].q+b[bpq+1].p+ca+cb<=mx) ++bpq;
			if(bpp<nb&&b[bpp].p<qval) qval=b[bpp].p;
			if(bpq>=0&&b[bpq].q<qval) qval=b[bpq].q;
			++ap;
		}
		if(aq>=0&&a[aq].q==pval) {
			while(bqp-1>=0&&a[aq].p+b[bqp-1].q+ca+cb<=mx) --bqp;
			while(bqq+1<nb&&a[aq].p+b[bqq+1].p+ca+cb<=mx) ++bqq;
			if(bqp<nb&&b[bqp].p<qval) qval=b[bqp].p;
			if(bqq>=0&&b[bqq].q<qval) qval=b[bqq].q;
			--aq;
		}
		if(qval!=LLONG_MAX&&(ret==0||qval+cb<tmp[ret-1].q)) tmp[ret].p=pval+ca,tmp[ret].q=qval+cb,++ret;
	}
	//printf("a="); REP(i,na) printf("(%lld,%lld)",a[i].p,a[i].q); printf(" + %d\n",ca);
	//printf("b="); REP(i,nb) printf("(%lld,%lld)",b[i].p,b[i].q); printf(" + %d\n",cb);
	//REP(i,ret) printf("(%lld,%lld)",tmp[i].p,tmp[i].q); puts("");
	return ret;
}

int go(int at,R* res,ll mx) {
	if(nc[at]==0) { res[0].p=0,res[0].q=0; return 1; }
	int n1=go(c[at][0],res,mx);
	int n2=go(c[at][1],res+n1,mx);
	int n12=combine(res,n1,cost[c[at][0]],res+n1,n2,cost[c[at][1]],mx);
	REP(i,n12) res[i]=tmp[i];
	return n12;
}
R res[MAXN];
bool ok(ll mx) {
	//printf("testing %d\n",mx);
	return go(0,res,mx)>0;
}

void input() {
	scanf("%d",&n);
	par[0]=-1,cost[0]=0;
	FOR(i,1,n) scanf("%d%d",&par[i],&cost[i]),--par[i];
}

void init() {
	memset(nc,0,sizeof(nc)); FOR(i,1,n) c[par[i]][nc[par[i]]++]=i;
}

ll solve() {
	ll l=-1,h=1; while(!ok(h)) l=h,h+=h;
	while(l+1<h) {
		ll m=l+(h-l)/2;
		if(ok(m)) h=m; else l=m;
	}
	return h;
}
/*
ll rec(int at,ll pathmx,ll mx) {
	if(nc[at]==0) return cost[at]<=pathmx?cost[at]:-1;
	ll ret=LLONG_MAX;
	REP(i,2) {
		ll a=rec(c[at][i],pathmx-cost[at],mx);
		if(a==-1) continue;
		ll b=rec(c[at][1-i],mx-a,mx);
		if(b==-1) continue;
		if(b<ret) ret=b;
	}
	//printf("rec(%d,%lld,%lld)=%lld\n",at,pathmx,mx,ret==LLONG_MAX?-1:ret);
	return ret==LLONG_MAX?-1:ret+cost[at];
}
ll bf() {
	ll l=-1,h=1; while(rec(0,LLONG_MAX,h)==-1) l=h,h+=h;
	while(l+1<h) {
		ll m=l+(h-l)/2;
		if(rec(0,LLONG_MAX,m)!=-1) h=m; else l=m;
	}
	return h;
}
int lst[MAXN],nlst;
void test() {
	while(true) {
		n=101;
		cost[0]=0; FOR(i,1,n) cost[i]=rand()%1000;
		nlst=0; par[0]=-1,lst[nlst++]=0; int cnt=1; while(cnt<n) { int i=rand()%nlst,at=lst[i]; swap(lst[i],lst[--nlst]); REP(j,2) par[cnt]=at,lst[nlst++]=cnt,++cnt; }
		init();
		ll ret=solve();
		ll chk=bf(); if(ret!=chk) { fprintf(stderr,"ret=%lld chk=%lld\n",ret,chk); printf("%d\n",n); FOR(i,1,n) printf("%d %d\n",par[i]+1,cost[i]); return; }
		printf("%lld\n",ret);
	}
}
*/
void run() {
	input();
	init();
	ll ret=solve();
	//ll chk=bf(); if(ret!=chk) fprintf(stderr,"ret=%lld chk=%lld\n",ret,chk);
	printf("%lld\n",ret);
}

int main() {
	run();
	//test();
	return 0;
}


Measured memory_bytes: 6912