#include <bits/stdc++.h>

// pbds
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;
// gp_hash_table<int, int> table;

using namespace std;

typedef unsigned long long ull;
typedef unsigned int ui;
typedef long long ll;
typedef long double ld;
typedef pair< int, int > pii;
typedef pair< long long, long long > pll;
typedef pair<long double, long double> pdd;

const int inf = 1000 * 1000 * 1000;
const ll inf64 = 1e18;

mt19937 rnd(179);

struct Node {
    Node *l;
    Node *r;
    int prior;
    ll key;
    ll value;
    ll push;
    ll mn;

    Node(ll _key, ll _value) {
        l = 0;
        r = 0;
        prior = rnd();
        key = _key;
        value = _value;
        push = 0;
        mn = _value;
    }
};

ll get_min_key(Node *& v) {
    return v->l ? get_min_key(v->l) : v->key;
}

ll get_max_key(Node *& v) {
    return v->r ? get_max_key(v->r) : v->key;
}

void update(Node *&v) {
    if(!v) return;
    v->mn = v->value;
    if(v->l) {
        v->mn = min(v->mn, v->l->mn);
    }
    if(v->r) {
        v->mn = min(v->mn, v->r->mn);
    }
}

void inc(Node *& v, ll delt) {
    if(!v) return;
    v->push += delt;
    v->mn += delt;
    v->value += delt;
}

void push(Node *& v) {
    if(!v) return;
    inc(v->l, v->push);
    inc(v->r, v->push);
    v->push = 0;
}

void merge(Node *& v, Node *l, Node *r) {
    if(!l || !r) {
        v = l ? l : r;
        return;
    }
    push(l);
    push(r);
    if(l->prior < r->prior) {
        merge(l->r, l->r, r);
        v = l;
    }else {
        merge(r->l, l, r->l);
        v = r;
    }
    update(v);
}

// < x
void split_by_key(Node *v, Node *& l, Node *& r, ll x) {
    if(!v) {
        l = r = 0;
        return;
    }
    push(v);
    if(v->key < x) {
        split_by_key(v->r, v->r, r, x);
        l = v;
    }else {
        split_by_key(v->l, l, v->l, x);
        r = v;
    }
    update(l);
    update(r);
}

// [l, r]
ll get_min(Node *&v, ll l, ll r) {
    if(!v) return inf64;
    Node *nl = 0;
    Node *nm = 0;
    Node *nr = 0;
    split_by_key(v, nl, nr, l);
    split_by_key(nr, nm, nr, r + 1);
    ll res = nm ? nm->mn : inf64;
    merge(nm, nm, nr);
    merge(v, nl, nm);
    return res;
}

void inner_insert(Node *&glob, Node *loc, int l, int r) {
    Node *nl = 0;
    Node *nm = 0;
    Node *nr = 0;
    split_by_key(glob, nl, nr, l);
    merge(nl, nl, loc);
    merge(glob, nl, nr);
}

void innser_erase(Node *& glob, Node *& loc, int l, int r) {
    Node *nl = 0;
    Node *nm = 0;
    Node *nr = 0;
    split_by_key(glob, nl, nr, l);
    split_by_key(nr, nm, nr, r + 1);
    merge(glob, nl, nr);
    loc = nm;
}

const int N = 5e5 + 5;

int n, q;
int p[N], w[N];

struct Query {
    int v, l, r, id;
};

vector< Query > qs[N];
ll res[N];
int euler[N], cur = 1;
pii seg[N];
vector< pii > g[N];
vector< int > leafs;
ll S[N];

void dfs(int v) {
    if(v > 1) {
        S[v] = S[p[v]] + w[v];
    } else {
        S[v] = 0;
    }
    if(g[v].empty()) {
        seg[v] = {cur, cur};
        leafs.push_back(v);
    } else {
        seg[v] = {inf, -inf};
    }
    euler[v] = cur++;
    for(pii ed : g[v]) {
        int to = ed.first;
        dfs(to);
        seg[v].first = min(seg[v].first, seg[to].first);
        seg[v].second = max(seg[v].second, seg[to].second);
    }
}

void go(int v, Node *down, Node *up) {
    for(Query qi : qs[v]) {
        res[qi.id] = min(
            get_min(down, qi.l, qi.r),
            get_min(up, qi.l, qi.r)
        );
        if(qi.l <= euler[qi.v] && euler[qi.v] <= qi.r && g[qi.v].empty())  {
            res[qi.id] = 0;
        }
    }
    for(pii ed : g[v]) {
        int to = ed.first;
        ll we = ed.second;
        Node *up1, *down1;
        Node *nl, *nm, *nr;
        Node *TO, *OTHER_L, *OTHER_R;

        {
            TO = OTHER_L = OTHER_R = 0;
            nl = nm = nr = 0;

            split_by_key(down, nl, nr, seg[to].first);
            split_by_key(nr, nm, nr, seg[to].second + 1);
            TO = nm;
            OTHER_L = nl;
            OTHER_R = nr;
        }

        bool is_left = OTHER_L ? 1 : 0;
        bool is_right = OTHER_R ? 1 : 0;
        pii seg_left = is_left ? make_pair((int)get_min_key(OTHER_L), (int)get_max_key(OTHER_L)) : make_pair(-1, -1);
        pii seg_right = is_right ? make_pair((int)get_min_key(OTHER_R), (int)get_max_key(OTHER_R)) : make_pair(-1, -1);

        if(is_left) {
            inner_insert(up, OTHER_L, seg_left.first, seg_left.second);
        }

        if(is_right) {
            inner_insert(up, OTHER_R, seg_right.first, seg_right.second);
        }

        inc(TO, we);
        inc(up, we);

        go(to, TO, up);

        inc(TO, -we);
        inc(up, -we);

        if(is_left) {
            innser_erase(up, OTHER_L, seg_left.first, seg_left.second);
        }

        if(is_right) {
            innser_erase(up, OTHER_R, seg_right.first, seg_right.second);
        }

        merge(OTHER_L, OTHER_L, TO);
        merge(down, OTHER_L, OTHER_R);
    }
}

int main() {

#ifdef debug
    freopen("input.txt", "r", stdin);
#endif

    scanf("%d %d", &n, &q);

    for(int i = 2;i <= n;i++) {
        scanf("%d %d", &p[i], &w[i]);
        g[p[i]].push_back({i, w[i]});
    }

    for(int it = 0;it < q;it++) {
        Query qi;
        scanf("%d %d %d", &qi.v, &qi.l, &qi.r);
        qi.id = it;
        qs[qi.v].push_back(qi);
    }

    dfs(1);

//    for(int v = 1;v <= n;v++) {
//        cout << v << " : [" << seg[v].first << " .. " << seg[v].second << "]\n";
//    }

    Node *up = 0;
    Node *down = 0;

    for(int v : leafs) {
        merge(down, down, new Node(euler[v], S[v]));
    }

    go(1, down, up);

    for(int i = 0;i < q;i++) {
        printf("%lld\n", res[i]);
    }

    return 0;
}
