#include <bits/stdc++.h>
using namespace std;
const long long maxn = 500100, inf = 1e18;
struct Segment_tree {
  long long addv[maxn << 2], minv[maxn << 2];
  inline void pushup(long long p) {
    minv[p] = min(minv[(p << 1)], minv[(p << 1 | 1)]);
  }
  inline void setadd(long long p, long long v) {
    addv[p] += v;
    minv[p] += v;
  }
  inline void pushdown(long long p) {
    if (addv[p])
      setadd((p << 1), addv[p]), setadd((p << 1 | 1), addv[p]), addv[p] = 0;
  }
  inline void Add(long long p, long long l, long long r, long long ql,
                  long long qr, long long v) {
    if (ql <= l && qr >= r) return (void)setadd(p, v);
    long long mid = (l + r) >> 1;
    pushdown(p);
    if (ql <= mid) Add((p << 1), l, mid, ql, qr, v);
    if (qr > mid) Add((p << 1 | 1), mid + 1, r, ql, qr, v);
    pushup(p);
  }
  inline long long Qmin(long long p, long long l, long long r, long long ql,
                        long long qr) {
    if (ql <= l && qr >= r) return minv[p];
    long long mid = (l + r) >> 1;
    pushdown(p);
    if (qr <= mid) return Qmin((p << 1), l, mid, ql, qr);
    if (ql > mid) return Qmin((p << 1 | 1), mid + 1, r, ql, qr);
    return min(Qmin((p << 1), l, mid, ql, qr),
               Qmin((p << 1 | 1), mid + 1, r, ql, qr));
  }
} seg;
long long head[maxn], nxt[maxn << 1], ver[maxn << 1], val[maxn << 1], tot, n, m;
inline void addedge(long long a, long long b, long long c) {
  nxt[++tot] = head[a];
  ver[tot] = b;
  val[tot] = c;
  head[a] = tot;
  nxt[++tot] = head[b];
  ver[tot] = a;
  val[tot] = c;
  head[b] = tot;
}
long long size[maxn], ans[maxn], dep[maxn], scnt[maxn];
inline void dfs(long long x, long long fa) {
  size[x] = 1;
  scnt[x] = 0;
  for (long long i = head[x]; i; i = nxt[i]) {
    long long y = ver[i];
    if (y == fa) continue;
    dep[y] = dep[x] + val[i];
    scnt[x]++;
    dfs(y, x);
    size[x] += size[y];
  }
}
struct Query {
  long long id, l, r;
};
vector<Query> v[maxn];
inline void getans(long long x, long long fa) {
  for (long long i = 0; i < (long long)v[x].size(); i++)
    ans[v[x][i].id] = seg.Qmin(1, 1, n, v[x][i].l, v[x][i].r);
  for (long long i = head[x]; i; i = nxt[i]) {
    long long y = ver[i];
    if (y == fa) continue;
    seg.Add(1, 1, n, y, y + size[y] - 1, -val[i]);
    if (y > 1) seg.Add(1, 1, n, 1, y - 1, val[i]);
    if (y + size[y] - 1 < n) seg.Add(1, 1, n, y + size[y], n, val[i]);
    getans(y, x);
    seg.Add(1, 1, n, y, y + size[y] - 1, val[i]);
    if (y > 1) seg.Add(1, 1, n, 1, y - 1, -val[i]);
    if (y + size[y] - 1 < n) seg.Add(1, 1, n, y + size[y], n, -val[i]);
  }
}
inline void init() {
  scanf("%lld%lld", &n, &m);
  for (long long i = 2; i <= n; i++) {
    long long f, v;
    scanf("%lld%lld", &f, &v);
    addedge(f, i, v);
  }
  dfs(1, 0);
  for (long long i = 1; i <= n; i++)
    seg.Add(1, 1, n, i, i, scnt[i] ? inf : dep[i]);
  for (long long i = 1; i <= m; i++) {
    Query nxt;
    long long x;
    scanf("%lld%lld%lld", &x, &nxt.l, &nxt.r);
    nxt.id = i;
    v[x].push_back(nxt);
  }
}
signed main() {
  init();
  getans(1, 0);
  for (long long i = 1; i <= m; i++) printf("%lld\n", ans[i]);
  return 0;
}
