#include <bits/stdc++.h>
using namespace std;
const long long inf = (long long)1e15;
long long n, q;
vector<vector<pair<long long, long long> > > g;
vector<long long> lv;
map<long long, long long> btos;
map<long long, long long> stob;
long long cntlv = 0;
struct segtree {
  vector<long long> t;
  vector<long long> p;
  long long n;
  segtree() {}
  segtree(long long _n) {
    n = _n;
    t.resize(4 * n);
    p.resize(4 * n);
  }
  inline void push(long long v, long long tl, long long tr) {
    if (p[v] == 0) return;
    t[v] += p[v];
    if (tl != tr) {
      p[v * 2 + 1] += p[v];
      p[v * 2 + 2] += p[v];
    }
    p[v] = 0;
  }
  inline void update(long long v, long long tl, long long tr, long long l,
                     long long r, long long add) {
    push(v, tl, tr);
    if (tl > r || tr < l) return;
    if (l <= tl && tr <= r) {
      p[v] += add;
      push(v, tl, tr);
    } else {
      long long tm = (tl + tr) / 2;
      update(v * 2 + 1, tl, tm, l, r, add);
      update(v * 2 + 2, tm + 1, tr, l, r, add);
      t[v] = min(t[v * 2 + 1], t[v * 2 + 2]);
    }
  }
  inline void update_single(long long v, long long tl, long long tr,
                            long long pos, long long x) {
    if (tl == tr) {
      t[v] = x;
    } else {
      long long tm = (tl + tr) / 2;
      if (pos <= tm) {
        update_single(v * 2 + 1, tl, tm, pos, x);
      } else {
        update_single(v * 2 + 2, tm + 1, tr, pos, x);
      }
      t[v] = min(t[v * 2 + 1], t[v * 2 + 2]);
    }
  }
  inline long long get(long long v, long long tl, long long tr, long long l,
                       long long r) {
    push(v, tl, tr);
    if (tl > r || tr < l) return inf;
    if (l <= tl && tr <= r) {
      return t[v];
    }
    long long tm = (tl + tr) / 2;
    long long v1 = get(v * 2 + 1, tl, tm, l, r);
    long long v2 = get(v * 2 + 2, tm + 1, tr, l, r);
    return min(v1, v2);
  }
  inline void update_single(long long pos, long long x) {
    update_single(0, 0, n - 1, pos, x);
  }
  inline void update(long long l, long long r, long long add) {
    if (l > r) return;
    update(0, 0, n - 1, l, r, add);
  }
  inline long long get(long long l, long long r) {
    return get(0, 0, n - 1, l, r);
  }
};
struct query {
  long long id, l, r;
  query() {}
  query(long long id, long long l, long long r) : id(id), l(l), r(r) {}
};
vector<vector<query> > qv;
segtree tree;
vector<long long> lftv, rhtv;
vector<long long> initdst;
vector<long long> ans;
set<long long> nxt, prv;
void dfs1(long long v, long long p, long long dst) {
  initdst[v] = dst;
  for (auto cu : g[v]) {
    long long u = cu.first;
    long long cost = cu.second;
    if (u == p) continue;
    dfs1(u, v, dst + cost);
  }
}
void dfs0(long long v, long long p) {
  if (v == 0) {
    dfs1(v, -1, 0);
  }
  for (auto cu : g[v]) {
    long long u = cu.first;
    long long cost = cu.second;
    if (u == p) continue;
    dfs0(u, v);
    lftv[v] = min(lftv[v], lftv[u]);
    rhtv[v] = max(rhtv[v], rhtv[u]);
  }
  if (lftv[v] == inf) {
    lftv[v] = rhtv[v] = cntlv;
    btos[v] = cntlv;
    stob[cntlv] = v;
    cntlv++;
  }
}
void dfs2(long long v, long long p) {
  for (auto cur : qv[v]) {
    ans[cur.id] = tree.get(cur.l, cur.r);
  }
  for (auto cu : g[v]) {
    long long u = cu.first;
    long long cost = cu.second;
    if (u == p) continue;
    tree.update(0, cntlv - 1, cost);
    tree.update(lftv[u], rhtv[u], -2 * cost);
    dfs2(u, v);
    tree.update(0, cntlv - 1, -cost);
    tree.update(lftv[u], rhtv[u], 2 * cost);
  }
}
void solve() {
  cin >> n >> q;
  g.resize(n);
  ans.resize(q);
  lftv.resize(n, inf), rhtv.resize(n, -inf);
  initdst.resize(n);
  qv.resize(n);
  for (long long i = 1; i < n; ++i) {
    long long t, w;
    cin >> t >> w;
    t--;
    g[t].push_back({i, w});
    g[i].push_back({t, w});
  }
  for (long long i = 0; i < n; ++i) {
    sort(g[i].begin(), g[i].end());
  }
  dfs0(0, -1);
  tree = segtree(cntlv);
  for (auto c : stob) {
    long long s = c.first;
    long long b = c.second;
    nxt.insert(b);
    prv.insert(-b);
    tree.update_single(s, initdst[b]);
  }
  for (long long i = 0; i < q; ++i) {
    long long v, l, r;
    cin >> v >> l >> r;
    --v, --l, --r;
    long long cl = *nxt.lower_bound(l);
    long long cr = -(*prv.lower_bound(-r));
    qv[v].push_back({i, btos[cl], btos[cr]});
  }
  dfs2(0, -1);
  for (long long i = 0; i < q; ++i) {
    cout << ans[i] << "\n";
  }
}
signed main() {
  long long t = 1;
  srand(time(0));
  cout << fixed << setprecision(20);
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  while (t--) {
    solve();
  }
}
