#include <bits/stdc++.h>
using namespace std;
const int MaxN = 5e5;
const long long inf = 0x3f3f3f3f3f3f3f3f;
int x, t, idx, l[MaxN + 5], r[MaxN + 5], head[MaxN + 5], cnt, n, q;
long long d[MaxN + 5], b[MaxN + 5], ans[MaxN + 5];
struct Edge {
  int to;
  long long w;
};
vector<Edge> G[MaxN + 5];
struct qe {
  int id, u, l, r;
  friend bool operator<(qe a, qe b) { return a.u < b.u; }
} Q[MaxN + 5];
struct node {
  int l, r;
  long long sum, lazy;
} T[(MaxN << 2) + 5];
inline void PushUp(int rt) {
  T[rt].sum = min(T[rt << 1].sum, T[rt << 1 | 1].sum);
}
inline void PushDown(int rt) {
  if (T[rt].lazy) {
    T[rt << 1].sum += T[rt].lazy;
    T[rt << 1].lazy += T[rt].lazy;
    T[rt << 1 | 1].sum += T[rt].lazy;
    T[rt << 1 | 1].lazy += T[rt].lazy;
    T[rt].lazy = 0LL;
  }
}
void Build(int l, int r, int rt) {
  T[rt].l = l, T[rt].r = r;
  if (l == r) {
    T[rt].sum = b[l];
    return;
  }
  int mid = l + r >> 1;
  Build(l, mid, rt << 1);
  Build(mid + 1, r, rt << 1 | 1);
  PushUp(rt);
}
void update(int l, int r, int rt, long long val) {
  if (l <= T[rt].l && T[rt].r <= r) {
    T[rt].sum += val;
    T[rt].lazy += val;
    return;
  }
  PushDown(rt);
  int mid = T[rt].l + T[rt].r >> 1;
  if (r <= mid)
    update(l, r, rt << 1, val);
  else if (l > mid)
    update(l, r, rt << 1 | 1, val);
  else {
    update(l, r, rt << 1, val);
    update(l, r, rt << 1 | 1, val);
  }
  PushUp(rt);
}
long long query(int l, int r, int rt) {
  if (l <= T[rt].l && T[rt].r <= r) return T[rt].sum;
  PushDown(rt);
  int mid = T[rt].l + T[rt].r >> 1;
  if (r <= mid)
    return query(l, r, rt << 1);
  else if (l > mid)
    return query(l, r, rt << 1 | 1);
  else
    return min(query(l, r, rt << 1), query(l, r, rt << 1 | 1));
}
void dfs(int u) {
  l[u] = ++idx;
  int Size = G[u].size();
  for (int i = 0; i < Size; ++i) {
    int v = G[u][i].to;
    d[v] = d[u] + G[u][i].w;
    dfs(v);
  }
  r[u] = idx;
}
int p = 1;
void Dfs(int u) {
  while (p <= q && Q[p].u == u) {
    ans[Q[p].id] = query(Q[p].l, Q[p].r, 1);
    ++p;
  }
  int Size = G[u].size();
  for (int i = 0; i < Size; ++i) {
    int v = G[u][i].to;
    update(1, n, 1, G[u][i].w);
    update(l[v], r[v], 1, -2LL * G[u][i].w);
    Dfs(v);
    update(1, n, 1, -G[u][i].w);
    update(l[v], r[v], 1, 2LL * G[u][i].w);
  }
}
int main() {
  scanf("%d %d", &n, &q);
  for (int i = 1; i <= n; ++i) head[i] = -1;
  for (int i = 2; i <= n; ++i) {
    int f;
    long long w;
    scanf("%d %lld", &f, &w);
    G[f].push_back((Edge){i, w});
  }
  for (int i = 1; i <= q; ++i) {
    scanf("%d %d %d", &Q[i].u, &Q[i].l, &Q[i].r);
    Q[i].id = i;
  }
  sort(Q + 1, Q + 1 + q);
  dfs(1);
  b[1] = inf;
  for (int i = 2; i <= n; ++i) {
    if ((int)G[i].size() == 0)
      b[i] = d[i];
    else
      b[i] = inf;
  }
  Build(1, n, 1);
  Dfs(1);
  for (int i = 1; i <= q; ++i) printf("%lld\n", ans[i]);
  return 0;
}
