#include <bits/stdc++.h>
#pragma GCC optimize("Ofast,unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4")
#pragma GCC target("popcnt,abm,mmx,avx")
using namespace std;
const int N = 5e5 + 2;
const long long oo = 1e18;
const long long MAX = 1e16;
struct SegmentTree {
  long long t[4 * N];
  long long lazy[4 * N];
  long long arr[2 * N];
  int n;
  long long OpId = oo, UpdId = 0;
  long long Op(long long a, long long b) { return min(a, b); }
  void build(int u, int a, int b) {
    if (a + 1 == b) {
      t[u] = arr[a];
      return;
    }
    build(u << 1, a, (a + b) >> 1);
    build(u << 1 | 1, (a + b) >> 1, b);
    t[u] = Op(t[u << 1], t[u << 1 | 1]);
  }
  void push(int u, int a, int b) {
    if (lazy[u] != UpdId) {
      t[u] += lazy[u];
      if (a + 1 != b) {
        lazy[u << 1] += lazy[u];
        lazy[u << 1 | 1] += lazy[u];
      }
      lazy[u] = UpdId;
    }
  }
  void update(int u, int a, int b, int l, int r, long long x) {
    if (lazy[u] != UpdId) push(u, a, b);
    if (b <= l || a >= r) return;
    if (a >= l && b <= r) {
      lazy[u] += x;
      push(u, a, b);
      return;
    }
    update(u << 1, a, (a + b) >> 1, l, r, x);
    update(u << 1 | 1, (a + b) >> 1, b, l, r, x);
    t[u] = Op(t[u << 1], t[u << 1 | 1]);
  }
  long long query(int u, int a, int b, int l, int r) {
    if (lazy[u] != UpdId) push(u, a, b);
    if (b <= l || a >= r) return OpId;
    if (a >= l && b <= r) return t[u];
    long long lch = query(u << 1, a, (a + b) >> 1, l, r);
    long long rch = query(u << 1 | 1, (a + b) >> 1, b, l, r);
    return Op(lch, rch);
  }
  inline void update(int l, int r, long long x) { update(1, 0, n, l, r, x); }
  inline long long query(int l, int r) { return query(1, 0, n, l, r); }
  inline void build() { build(1, 0, n); }
} st;
long long ans[N];
int in[N], out[N];
vector<array<int, 3>> ask[N];
vector<pair<long long, long long>> adj[N];
int pos;
void dfs2(int u, int pai = -1) {
  for (auto qry : ask[u]) {
    int idx = qry[0], l = qry[1], r = qry[2];
    long long ret = st.query(l, r + 1);
    ans[idx] = ret;
  }
  for (pair<long long, long long> vv : adj[u]) {
    long long v = vv.first, w = vv.second;
    if (v == pai) continue;
    int from = in[v], to = out[v];
    st.update(from, to, -w);
    if (from > 0) st.update(0, from, w);
    if (to < st.n) st.update(to, st.n, w);
    dfs2(v, u);
    w *= -1;
    st.update(from, to, -w);
    if (from > 0) st.update(0, from, w);
    if (to < st.n) st.update(to, st.n, w);
  }
}
void dfs(int u, int pai = -1, long long d = 0) {
  in[u] = pos++;
  bool leaf = true;
  for (pair<long long, long long> vv : adj[u]) {
    long long v = vv.first, w = vv.second;
    if (v == pai) continue;
    leaf = false;
    dfs(v, u, d + w);
  }
  st.update(u, u + 1, (leaf ? d : MAX));
  out[u] = pos;
}
int main() {
  int n, q;
  scanf("%d%d", &n, &q);
  for (int i = 1; i < n; ++i) {
    long long p, w;
    scanf("%lld%lld", &p, &w);
    p--;
    adj[i].push_back({p, w});
    adj[p].push_back({i, w});
  }
  st.n = n;
  st.build();
  for (int i = 0; i < q; ++i) {
    long long v, l, r;
    scanf("%lld%lld%lld", &v, &l, &r);
    v--;
    l--;
    r--;
    array<int, 3> x;
    x[0] = i;
    x[1] = l;
    x[2] = r;
    ask[v].push_back(x);
  }
  dfs(0);
  dfs2(0);
  for (int i = 0; i < q; ++i) {
    cout << ans[i] << endl;
  }
  return 0;
}
