/* Author haleyk10198 */
/* �@��:  haleyk10198 */
/* CF handle: haleyk100198*/
/* FOR ACM-ICPC WF*/
#include <bits/stdc++.h>

using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using pii = pair<int, int>;

#define pb push_back

constexpr auto MOD = 1000000007LL;
constexpr auto LINF = (1LL << 60);
constexpr auto INF = 2147483647LL;
constexpr auto PI = 3.1415926535897932384626433;
constexpr auto EPS = 1E-9;

template<typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> p) {
    out << p.first << ' ' << p.second;
    return out;
}

template<typename T1, typename T2>
istream &operator>>(istream &in, pair<T1, T2> &p) {
    in >> p.first >> p.second;
    return in;
}

template<typename T>
istream &operator>>(istream &in, vector<T> &v) {
    for (auto &x: v)
        in >> x;
    return in;
}

template<typename T>
ostream &operator<<(ostream &out, vector<T> v) {
    for (int i = 0; i < v.size(); i++)
        out << v[i] << (i + 1 == v.size() ? '\n' : ' ');
    out.flush();
    return out;
}

#if __cplusplus < 201703L
#define mp make_pair
#endif

#define MAXN 500010

int n, q;
vector<pii> e[MAXN];
vi ee[MAXN];

int na[MAXN], sz[MAXN], cfa[MAXN], croot;
//assume vi e[MAXN] exists

vi ce[MAXN];
vi cst;

void runCen(int);

int mib, center;

void dfssz(int now, int prv){
    sz[now] = 1;
    for(auto x: ee[now])
        if(x-prv && not na[x]){
            dfssz(x, now), sz[now] += sz[x];
        }
    return;
}

void choose(int now){
    if(cst.size())
        cfa[now] = cst.back(), ce[cst.back()].pb(now);
    else
        croot = now;
    cst.pb(now);
    na[now] = 1;
    for(auto x: ee[now])
        if(not na[x])
            runCen(x);
    cst.pop_back();
}

void pickCen(int now, int prv, int tot = -1){
    int mx = 0, id = -1;
    if(tot == -1) tot = sz[now];
    for(auto x: ee[now])
        if(not na[x] && x-prv){
            pickCen(x, now, tot);
            if(sz[x] > mx){
                mx = sz[x];
            }
        }

    mx = max(mx, tot-sz[now]);
    if(mx < mib){
        mib = mx;
        center = now;
    }
    return;
}

void runCen(int root = 1){
    mib = INF;
    dfssz(root, root);
    pickCen(root, root);
    choose(center);
    return;
}

class SegmentTree {
public:
    vector<ll> T;
    vi nums;

    SegmentTree(){}

    SegmentTree(vi nums): nums(nums){
        T = vector<ll>(2*nums.size(), LINF);
    }

    ll ask(int x, int y){
        int l = lower_bound(nums.begin(), nums.end(), x)-nums.begin();
        int r = upper_bound(nums.begin(), nums.end(), y)-nums.begin();

        ll ret = LINF;
        for(l += nums.size(), r += nums.size(); l < r; l>>=1, r>>=1){
            if(l&1) ret = min(ret, T[l++]);
            if(r&1) ret = min(ret, T[--r]);
        }

        return ret;
    }

    void update(int x, ll v){
        x = lower_bound(nums.begin(), nums.end(), x)-nums.begin();
        for(T[x+=nums.size()] = v; x > 1; x>>=1)
            T[x>>1] = min(T[x], T[x^1]);
    }
};

vi contains[MAXN];
SegmentTree T[MAXN];

struct Node{
    Node *l, *r, *par;
    bool rev;
    int val, sum;
    Node(){
        l = r = par = NULL;
        rev = false;
        val = sum = 0;
    }
}LCT[MAXN<<1];

inline void maintain(Node* x){
    if(x){
        x->sum = x->val;
        if(x->l) x->sum += x->l->sum;
        if(x->r) x->sum += x->r->sum;
    }
    return;
}

inline bool isroot(Node *x){
    if(not x->par) return true;
    return x->par->l != x && x->par->r != x;
}

inline void reverse(Node *x){
    if(x){
        x->rev ^= 1;
        swap(x->l, x->r);
    }
}

inline void push(Node* x){
    if(x){
        if(x->rev) reverse(x->l), reverse(x->r);
        x->rev = false;
    }
    return;
}

inline void getpushed(Node* x){
    if(not isroot(x)) getpushed(x->par);
    push(x);
}

inline void rotate(Node* x){
    Node *y = x->par;
    Node *z = y->par;

    if(not isroot(y)){
        if(z->l == y) z->l = x;
        if(z->r == y) z->r = x;
    }
    x->par = z;

    if(y->r == x){
        if(y->r = x->l) y->r->par = y;
        y->par = x;
        x->l = y;
    }
    else{
        if(y->l = x->r) y->l->par = y;
        y->par = x;
        x->r = y;
    }

    maintain(y), maintain(x), maintain(z);
    //ORDER IS IMPORTANT, ALWAYS UPDATE LOWER NODES FIRST
    return;
}

inline void splay(Node* x){
    getpushed(x);
    while(not isroot(x)){
        Node *y = x->par;
        if(not isroot(y)){
            Node *z = y->par;
            if((z->l == y)^(y->l == x)) rotate(x);
            else rotate(y);
        }
        rotate(x);
    }
    return;
}

inline Node* access(Node* x){
    Node *ret = NULL;
    while(x){
        splay(x);
        x->r = ret;
        maintain(x);
        ret = x;
        x = x->par;
    }
    //while(ret && ret->l) ret = ret->l; //depends if intended to return root
    return ret;
}

inline void makeroot(Node* x){
    access(x);
    splay(x);
    reverse(x);
    return;
}

inline void link(Node* x, Node* y){
    makeroot(x);
    x->par = y;
    return;
}

ll dist(int x, int y){
    makeroot(LCT+x);
    access(LCT+y);
    splay(LCT+y);
    return LCT[y].sum;
}

int main() {
#ifdef LOCAL
    freopen("../input.txt", "r", stdin);
//		freopen("output.txt","w",stdout);
    freopen("../debug.txt", "w", stderr);
#endif
    ios_base::sync_with_stdio(false);

    cin >> n >> q;
    for(int i = 2, p, w; i <= n; i++){
        cin >> p >> w;
        LCT[i+n].val = LCT[i+n].sum = w;
        link(LCT+p, LCT+i+n);
        link(LCT+i, LCT+i+n);
        e[p].push_back(pair(i, w));
        ee[p].push_back(i);
        ee[i].push_back(p);
    }

    for(int i = 1; i <= n; i++){
        sort(e[i].begin(), e[i].end());
    }

    runCen();
    for(int i = 1; i <= n; i++){
        if(e[i].empty()){
            for(int pos = i; pos; pos = cfa[pos]){
                contains[pos].push_back(i);
            }
        }
    }

    for(int i = 1; i <= n; i++){
        if(not contains[i].empty()){
            T[i] = SegmentTree(contains[i]);
        }
    }

    for(int i = 1; i <= n; i++){
        if(e[i].empty()){
            for(int pos = i; pos; pos = cfa[pos]){
                T[pos].update(i, dist(i, pos));
            }
        }
    }

    while(q--){
        int v, l, r; cin >> v >> l >> r;
        ll res = LINF;

        if(e[v].empty() && l <= v && v <= r){
            cout << 0 << endl;
            continue;
        }

        pii used = pair(n+1, -n);
        for(int pos = v; pos; pos = cfa[pos]){
            if(contains[pos].empty()) continue;
            ll now = dist(pos, v);

            if(l <= used.first){
                if(r >= used.first){
                    ll ret = T[pos].ask(l, used.first);
                    res = min(now+ret, res);

                    if(used.second < r){
                        ret = T[pos].ask(used.second+1, r);
                        res = min(now+ret, res);
                    }
                }
                else{
                    ll ret = T[pos].ask(l, r);
                    res = min(now+ret, res);
                }
            }
            else{
                ll ret = T[pos].ask(max(used.second+1, l), r);
                res = min(now+ret, res);
            }

            used.first = min(contains[pos].front(), used.first);
            used.second = max(contains[pos].back(), used.second);
        }

        cout << res << endl;

    }

    return 0;
}
