// Original C++ solution (slower):
#include <cstdio>

#include <cstring>

#include <vector>

#include <algorithm>

const int MaxN = 131172;

int N;

int Point[MaxN], Next[MaxN], To[MaxN], W[MaxN], q;

long long d[MaxN];

void Add(int u, int v, int w){ Next[++q] = Point[u]; Point[u] = q; To[q] = v; W[q] = w; }

void dfs(int u, long long tmp)

{

	d[u] = tmp;

	for(int j = Point[u]; j; j = Next[j])

		dfs(To[j], tmp + W[j]);

}

struct pair{ int fir, sec; };

typedef std::vector<pair>::iterator iter;

std::vector<pair> S[MaxN], t;

bool cmp1(pair i, pair j){ return d[i.fir] < d[j.fir]; }

bool cmp2(pair i, pair j){ return d[i.sec] > d[j.sec]; }

bool cmp3(pair i, pair j){ return d[i.fir] > d[j.fir]; }

bool cmp4(pair i, pair j){ return d[i.sec] < d[j.sec]; }

bool dfs1(int u, long long v)

{

	S[u].clear();

	for(int j = Point[u]; j; j = Next[j])

	{

		if(dfs1(To[j], v)) return 1;

		if(S[u].empty()) std::swap(S[u], S[To[j]]);

		else

		{

			if(S[u].size() > S[To[j]].size()) std::swap(S[u], S[To[j]]);

			std::sort(S[u].begin(), S[u].end(), cmp2);

			std::sort(S[To[j]].begin(), S[To[j]].end(), cmp1);

			t.clear();

			iter k = S[To[j]].begin(); int sec = 0;

			for(iter i = S[u].begin(); i != S[u].end(); ++i)

			{	

				while(k != S[To[j]].end() && d[i->sec] + d[k->fir] <= v + (d[u] << 1))

				{

					if(d[k->sec] < d[sec]) sec = k->sec;

					++k;

				}

			/*	for(iter k = S[To[j]].begin(); k != S[To[j]].end(); ++k)

					if(d[i->sec] + d[k->fir] <= v + (d[u] << 1) && d[sec] > d[k->sec]) 

						sec = k->sec;*/

				if(sec) t.push_back((pair){i->fir, sec});

			}

			std::sort(S[u].begin(), S[u].end(), cmp3);

			std::sort(S[To[j]].begin(), S[To[j]].end(), cmp4);

			k = S[To[j]].begin(); int fir = 0;

			for(iter i = S[u].begin(); i != S[u].end(); ++i)

			{	

				while(k != S[To[j]].end() && d[k->sec] + d[i->fir] <= v + (d[u] << 1))

				{

					if(d[k->fir] < d[fir]) fir = k->fir;

					++k;

				}

				/*for(iter k = S[To[j]].begin(); k != S[To[j]].end(); ++k)

					if(d[k->sec] + d[i->fir] <= v + (d[u] << 1) && d[fir] > d[k->fir]) 

						fir = k->fir;*/

				if(fir) t.push_back((pair){fir, i->sec});

			}		

			std::swap(t, S[u]);

		}

	}

	if(!Point[u]) S[u].push_back((pair){u, u});

	return S[u].empty();

}

int main()

{

	scanf("%d", &N);

	for(int i = 2; i <= N; ++i)

	{

		int a, v;

		scanf("%d %d", &a, &v);

		Add(a, i, v);

	}

	d[0] = 1ll << 60;

	dfs(1, 0);

	//for(int i = 1; i <= N; ++i) printf("%d ", d[i]); puts("");

	long long l = -1, r = 1ll << 35;

	while(r - l > 1)

	{

		long long mid = l + r >> 1;

	//	printf("%lld\n", mid);

		if(dfs1(1, mid)) l = mid;

		else r = mid;

	}

	printf("%lld\n", r);

	return 0;

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<vector>

const int MaxN=1<<17|10;

int N,ch[MaxN][2],v[MaxN];

long long dep[MaxN];

struct Point{long long x,y;};

void ins(std::vector<Point>&v,long long x,long long y){

	if(!v.size()||y<v[v.size()-1].y)v.push_back((Point){x,y});

}

void find(std::vector<Point>&v,int&p,long long M){

	while(p<v.size()&&v[p].x<=M)p++;

}

std::vector<Point>chk(int i,long long M){

	std::vector<Point>f;

	if(!*ch[i]){

		f.push_back((Point){dep[i],dep[i]});

		return f;

	}

	std::vector<Point>fl=chk(ch[i][0],M),fr=chk(ch[i][1],M);

	for(int pl=0,pr=0,ql=0,qr=0;;pl++){

		for(;pr<fr.size()&&(pl>=fl.size()||fr[pr].x<fl[pl].x);pr++){

			find(fl,ql,M+2*dep[i]-fr[pr].y);

			if(ql)ins(f,fr[pr].x,fl[ql-1].y);

		}

		if(pl>=fl.size())break;

		find(fr,qr,M+2*dep[i]-fl[pl].y);

		if(qr)ins(f,fl[pl].x,fr[qr-1].y);

	}

	return f;

}

int main(){

	scanf("%d",&N);

	for(int i=2,f;i<=N;i++){

		scanf("%d%d",&f,v+i);

		if(*ch[f])ch[f][1]=i;

		else ch[f][0]=i;

		dep[i]=dep[f]+v[i];

	}

	long long l=-1,r=1ll<<34,mid;

	while(r-l>1)chk(1,mid=l+r>>1).size()?r=mid:l=mid;

	printf("%lld\n",r);

}

// Fastest known solution for this problem: