#include <bits/stdc++.h>
#include <ext/pb_ds/detail/standard_policies.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pb push_back
#define F first
#define S second
#define ll long long
#define FILE "meetings"
#define ld long double
#define endl '\n'
#define pii pair <int, int>
#define last fedgfre
#define ull unsigned long long
//#define int long long

//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")

using namespace std;
using namespace __gnu_pbds;

typedef tree <pii,null_type,less<pii>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;

const int N = 5e5 + 5;
const int mod = 1e9 + 7;
const int rx[8] = {1, -1, 0, 0, 1, 1, -1, -1 };
const int ry[8] = {0, 0, 1, -1, 1, -1, 1, -1 };
const ld pi = acos(-1.0);
//const int B = 9e3;
const ld eps = 1e-11;
const ll INF = 1e18;

const int kx[8] = {1, 1, -1, -1, 2, 2, -2, -2};
const int ky[8] = {2, -2, 2, -2, 1, -1, 1, -1};

mt19937_64 gen(chrono::high_resolution_clock::now().time_since_epoch().count());


ll t[N << 2];
ll lazy[N << 2];

void push(int v){
   t[v << 1] += lazy[v];
   t[v << 1 | 1] += lazy[v];
   lazy[v << 1] += lazy[v];
   lazy[v << 1 | 1] += lazy[v];
   lazy[v] = 0;
}

void update(int v, int cl, int cr, int l, int r, ll x){
    if (cl > r || cr < l) return;
    if (cl >= l && cr <= r){
        t[v] += x;
        lazy[v] += x;
        return;
    }
    push(v);
    int mid = (cl + cr) >> 1;
    update(v << 1, cl, mid, l, r, x);
    update(v << 1 | 1, mid + 1, cr, l, r, x);
    t[v] = min(t[v << 1], t[v << 1 | 1]);
}

ll query(int v, int cl, int cr, int l, int r){
    if (cl > r || cr < l) return 1e18;
    if (cl >= l && cr <= r) return t[v];
    push(v);
    int mid = (cl + cr) >> 1;
    return min(query(v << 1, cl, mid, l, r), query(v << 1 | 1, mid + 1, cr, l, r));
}


int n, q;
int st = 1;

ll query(int l, int r){
   return query(1, 0, st - 1, l, r);
}

void update(int l, int r, ll x){
    if (l > r) return;
   update(1, 0, st - 1,  l, r, x);
}

int sz[N];
vector <pii> g[N];
ll res[N];
vector <pair <pii, int>> all[N];

void dfs(int v, int pr, int cur = 0) {
    sz[v] = 1;
    for (auto to : g[v]) {
        if (to.F == pr) continue;
        dfs(to.F, v, cur + to.S);
        sz[v] += sz[to.F];
    }
    if (g[v].size() == 1) {
        update(v, v, cur - INF);
    }
}

void add(int x, int y) {
    update(0, x - 1, y);
    update(x + sz[x], n, y);
    update(x, x + sz[x] - 1, -y);
}

void del(int x, int y) {
    update(0, x - 1, -y);
    update(x + sz[x], n, -y);
    update(x, x + sz[x] - 1, y);
}

void dfs1(int v, int pr) {
    for (auto x : all[v]) {
        int l = x.F.F;
        int r = x.F.S;
        int id = x.S;
        res[id] = query(l, r);
    }
    for (auto to : g[v]) {
        if (to.F == pr) continue;
        add(to.F, to.S);
        dfs1(to.F, v);
        del(to.F, to.S);
    }
}

main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
    // freopen(FILE".in", "r", stdin);
    //  freopen(FILE".out", "w", stdout);
#endif // LOCAL
    cin >> n >> q;
    while (st < n) st <<= 1;
    for (int i = 0; i < st * 2; i++) t[i] = 1e18;
    for (int i = 0; i < n - 1; i++) {
        int p, w;
        cin >> p >> w;
        g[i + 1].pb({p - 1, w});
        g[p - 1].pb({i + 1, w});
    }
    dfs(0, -1);
    for (int i = 0; i < q; i++) {
        int u, l, r;
        cin >> u >> l >> r;
        all[u - 1].pb({{l - 1, r - 1}, i});
    }
    dfs1(0, -1);
    for (int i = 0; i < q; i++) cout << res[i] << endl;
    return 0;
}
