/+ dub.sdl:
    name "A"
    dependency "dcomp" version=">=0.0.2"
+/

import std.algorithm, std.range, std.stdio, std.math, std.conv, core.bitop;

// import dcomp.scanner;
// import dcomp.algorithm;
// import dcomp.array;
int n;
struct Edge {
    int to;
    long dist;
}
Edge[][] g;
long[2][][] memo;
long md;
 
T[N] toS(T, int N)(T[N] data){ return data; }
long[2][] dfs(int p) {
    if (g[p].empty) {
        static auto leaf = [[0L, 0L].toS];
        return leaf;
    }
    Edge le = g[p][0], re = g[p][1];
    auto lt = dfs(le.to);
    auto rt = dfs(re.to);
    if (lt.length > rt.length) {
        swap(le, re);
        swap(lt, rt);
    }
    long ld = le.dist, rd = re.dist;
    auto buf = FastAppender!(long[2][])(&memo[p]);
    buf.clear();
    buf.reserve(lt.length * 2);
    foreach (co; lt) {
        //co[1] + ld + rd + rco[0] <= md
        int idx = binSearch!((i){return co[1]+ld+rd+rt[i][0] > md;})(-1, rt.length.to!int)-1;
        if (idx == -1) continue;
        buf ~= [co[0]+ld, rt[idx][1]+rd];
        buf ~= [rt[idx][1]+rd, co[0]+ld];
    }
    memo[p] = buf.data;
    auto ans = memo[p];
    sort(ans);
    if (ans.empty) return ans;
    long ma = 10L^^15;
    int co = 0;
    foreach (ref e; ans) {
        if (ma <= e[1]) {
            continue;
        }
        ma = min(ma, e[1]);
        ans[co] = e;
        co++;
    }
 
    return ans[0..co];
}
 
//md以下にできるか？
bool solve(long _md) {
    md = _md;
    return !dfs(0).empty;
}
 
int main(string[] argv) {
    auto sc = new Scanner();
    int n;
    sc.read(n);
    g = new Edge[][](n);
    memo = new long[2][][](n);
    foreach (i; 1..n) {
        int a; long b;
        sc.read(a, b); a--;
        g[a] ~= Edge(i, b);
    }
    writeln(binSearch!solve(-1L, 10L^^12));
    return 0;
}
/* IMPORT /Users/yosupo/Program/dcomp/source/dcomp/array.d */
// module dcomp.array;

struct FastAppender(A) {
    import std.algorithm : max;
    import std.range.primitives : ElementEncodingType;
    import core.stdc.string : memcpy;

    private alias T = ElementEncodingType!A;
    private T* _data;
    private size_t len, cap;

    @disable this();
    @disable this(this);
    this(T[]* arr) {
        _data = (*arr).ptr;
        len = (*arr).length;
        cap = (*arr).length;
    }
    void reserve(size_t nlen) {
        import core.memory : GC;
        if (nlen <= cap) return;

        auto bi = GC.qalloc(nlen * T.sizeof, GC.BlkAttr.NO_SCAN | GC.BlkAttr.APPENDABLE);
        cap = bi.size / T.sizeof;
        if (len) memcpy(bi.base, _data, len * T.sizeof);
        _data = cast(T*)(bi.base);       
    }
    void opOpAssign(string op : "~")(T item) {
        if (len == cap) {
            reserve(max(4, cap*2));
        }
        _data[len++] = item;
    }
    void clear() {
        len = 0;
    }
    T[] data() {
        return _data[0..len];
    }
}
/* IMPORT /Users/yosupo/Program/dcomp/source/dcomp/scanner.d */
// module dcomp.scanner;

class Scanner {
    import std.stdio : File, stdin;
    import std.conv : to;
    import std.range : front, popFront, array, ElementType;
    import std.array : split;
    import std.traits : isSomeString, isDynamicArray;
    import std.algorithm : map;
    File f;
    this(File f = stdin) {
        this.f = f;
    }
    string[] buf;
    bool succ() {
        while (!buf.length) {
            if (f.eof) return false;
            buf = f.readln.split;
        }
        return true;
    }
    int read(Args...)(auto ref Args args) {
        foreach (i, ref v; args) {
            if (!succ()) return i;
            alias VT = typeof(v);
            static if (!isSomeString!VT && isDynamicArray!VT) {
                v = buf.map!(to!(ElementType!VT)).array;
                buf.length = 0;
            } else {
                v = buf.front.to!VT;
                buf.popFront();
            }
        }
        return args.length;
    }
}
/* IMPORT /Users/yosupo/Program/dcomp/source/dcomp/algorithm.d */
// module dcomp.algorithm;

//[0,0,0,...,1,1,1]で、初めて1となる場所を探す。pred(l) == 0, pred(r) == 1と仮定
T binSearch(alias pred, T)(T l, T r) {
    while (r-l > 1) {
        T md = (l+r)/2;
        if (!pred(md)) l = md;
        else r = md;
    }
    return r;
}


Measured memory_bytes: 53372