#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int __SIZE = 1 << 18;
char ibuf[__SIZE], *iS, *iT;

#define ge (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, __SIZE, stdin), (iS == iT ? EOF : *iS++)) : *iS++)
#define ri read_int()
#define rl read_ll()
#define FILE(s) freopen(s"in", "r", stdin), freopen(s"out", "w", stdout)

template<typename T>
inline void read(T &x) {
		char ch, t = 0; x = 0;
		while(!isdigit(ch = ge)) t |= ch == '-';
		while(isdigit(ch)) x = x * 10 + (ch ^ 48), ch = ge;
		x = t ? -x : x;
}
inline int read_int() { int x; return read(x), x; }
inline ll read_ll() { ll x; return read(x), x; }

template<typename T>
inline void chkmin(T&a, T b) { a = a < b ? a : b; }

const int MAXN = 132000;

int tot;
int fi[MAXN];
int ne[MAXN << 1];
int to[MAXN << 1];
int vl[MAXN << 1];

inline void Link(int u, int v, int w) {
	tot++;
	to[tot] = v;
	vl[tot] = w;
	ne[tot] = fi[u];
	fi[u] = tot;
}

struct Node {
	ll a, b;

	Node() {}
	Node(ll a, ll b):a(a), b(b) {}

	friend bool operator < (Node a, Node b) {
		return a.a < b.a;
	}
}A[MAXN * 20], tmp[MAXN * 20];

int L[MAXN];
int R[MAXN];
int n;
int cnt;

inline void gb_Merge(int l1, int r1, int l2, int r2) {
	int l = l1, r = r2, k = l1;
	while(l1 <= r1 && l2 <= r2) {
		if(A[l1] < A[l2]) tmp[k++] = A[l1++];
		else tmp[k++] = A[l2++];
	}
	while(l1 <= r1) tmp[k++] = A[l1++];
	while(l2 <= r2) tmp[k++] = A[l2++];
	while(k > l) --k, A[k] = tmp[k];
}

inline void Merge(int x, int l, int r, ll lim) {
	int pl1 = cnt + 1, pr1 = cnt;
	ll mi = 1LL << 61;
	for(int i = L[l], j = L[r] - 1; i <= R[l]; ++i) {
		while(j < R[r] && A[i].b + A[j + 1].a <= lim) ++j, mi = mi < A[j].b ? mi : A[j].b;
		if(j < L[r]) continue;
		A[++pr1] = Node(A[i].a, mi);
	} cnt = pr1;
	int pl2 = cnt + 1, pr2 = cnt;
	mi = 1LL << 61, swap(l, r);
	for(int i = L[l], j = L[r] - 1; i <= R[l]; ++i) {
		while(j < R[r] && A[i].b + A[j + 1].a <= lim) ++j, mi = mi < A[j].b ? mi : A[j].b;
		if(j < L[r]) continue;
		A[++pr2] = Node(A[i].a, A[j].b);
	} cnt = pr2, L[x] = pl1, R[x] = pr2;
	if(L[x] > R[x]) return ;
	gb_Merge(pl1, pr1, pl2, pr2);
	int Sum = 0;
	for(int i = L[x] + 1; i <= R[x]; ++i) {
		if(A[i].b >= A[L[x] + Sum].b) continue;
		else ++Sum, A[L[x] + Sum] = A[i];
	} cnt = R[x] = L[x] + Sum;
	/*
	cout << lim << endl;
	for(int i = L[x]; i <= R[x]; i++) {
		cout << A[i].a << ' ' << A[i].b << endl;
	}
	cout << endl;
	*/
}

inline void dfs(int x, ll lim) {
	if(!fi[x]) {
		L[x] = R[x] = ++cnt;
		A[cnt] = Node(0, 0);
	}
	else {
		L[x] = cnt + 1, R[x] = cnt;
		int val, Ls = to[fi[x]], Rs = to[ne[fi[x]]];
		
		dfs(Ls, lim), val = vl[fi[x]];
		// cout << L[Ls] << ' ' << R[Ls] << endl;
		if(L[Ls] > R[Ls]) return;
		for(int i = L[Ls]; i <= R[Ls]; i++) A[i].a += val, A[i].b += val; 

		dfs(Rs, lim), val = vl[ne[fi[x]]];
		if(L[Rs] > R[Rs]) return ;
		for(int i = L[Rs]; i <= R[Rs]; i++) A[i].a += val, A[i].b += val; 
		
		Merge(x, Ls, Rs, lim);
	}
}

inline bool chk(ll lim) {
	cnt = 0, dfs(1, lim);
	return L[1] <= R[1];
}

int main() {
	n = ri;
	ll mx = 0;
	for(int i = 2; i <= n; i++) {
		int f = ri, v = ri;
		Link(f, i, v);
		mx += v;
	} ll l = 0, r = mx, res;
	while(l <= r) {
		ll mid = (l + r) >> 1;
		if(chk(mid)) r = mid - 1, res = mid;
		else l = mid + 1;
	} printf("%lld\n", res);
	return 0;
}

Measured memory_bytes: 46208