#include <bits/stdc++.h>
using namespace std;
const long long INF = 0x3f3f3f3f3f3f3f3f;
int fa[500010];
vector<pair<int, int> > from[500010];
vector<pair<pair<int, int>, int> > q[500010];
long long ans[500010];
int size[500010];
long long dist[500010];
int n, m;
struct Segment_tree {
  struct Node {
    long long minj, lazy;
  } T[2000000];
  void pushdown(int now) {
    if (!T[now].lazy) return;
    long long v = T[now].lazy;
    T[now].lazy = 0;
    T[now << 1].minj += v, T[now << 1].lazy += v;
    T[now << 1 | 1].minj += v, T[now << 1 | 1].lazy += v;
  }
  void pushup(int now) {
    T[now].minj = min(T[now << 1].minj, T[now << 1 | 1].minj);
  }
  void Build(int now, int l, int r) {
    T[now].lazy = 0;
    if (l == r) {
      T[now].minj = INF;
      return;
    }
    int mid = l + r >> 1;
    Build(now << 1, l, mid), Build(now << 1 | 1, mid + 1, r);
    pushup(now);
  }
  void Update(int now, int l, int r, int L, int R, long long v) {
    if (l == L && r == R) {
      T[now].minj += v, T[now].lazy += v;
      return;
    }
    pushdown(now);
    int mid = l + r >> 1;
    if (R <= mid)
      Update(now << 1, l, mid, L, R, v);
    else if (L > mid)
      Update(now << 1 | 1, mid + 1, r, L, R, v);
    else
      Update(now << 1, l, mid, L, mid, v),
          Update(now << 1 | 1, mid + 1, r, mid + 1, R, v);
    pushup(now);
  }
  long long Query(int now, int l, int r, int L, int R) {
    if (l == L && r == R) return T[now].minj;
    pushdown(now);
    int mid = l + r >> 1;
    if (R <= mid) return Query(now << 1, l, mid, L, R);
    if (L > mid) return Query(now << 1 | 1, mid + 1, r, L, R);
    return min(Query(now << 1, l, mid, L, mid),
               Query(now << 1 | 1, mid + 1, r, mid + 1, R));
  }
} seg;
void dfs(int x) {
  if (!from[x].size()) seg.Update(1, 1, n, x, x, -INF + dist[x]);
  size[x] = 1;
  for (int i = 0; i < from[x].size(); i++) {
    int v = from[x][i].first, w = from[x][i].second;
    dist[v] = dist[x] + w, dfs(v), size[x] += size[v];
  }
}
void get_ans(int x) {
  for (int i = 0; i < q[x].size(); i++) {
    int l = q[x][i].first.first, r = q[x][i].first.second, id = q[x][i].second;
    ans[id] = seg.Query(1, 1, n, l, r);
  }
  for (int i = 0; i < from[x].size(); i++) {
    int v = from[x][i].first, w = from[x][i].second;
    seg.Update(1, 1, n, 1, n, w),
        seg.Update(1, 1, n, v, v + size[v] - 1, -2 * w);
    get_ans(v);
    seg.Update(1, 1, n, v, v + size[v] - 1, 2 * w),
        seg.Update(1, 1, n, 1, n, -w);
  }
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 2; i <= n; i++) {
    scanf("%d", &fa[i]);
    int w;
    scanf("%d", &w);
    from[fa[i]].push_back(pair<int, int>(i, w));
  }
  for (int i = 0; i < m; i++) {
    int x, l, r;
    scanf("%d%d%d", &x, &l, &r);
    q[x].push_back(make_pair(make_pair(l, r), i));
  }
  seg.Build(1, 1, n);
  dfs(1), get_ans(1);
  for (int i = 0; i < m; i++) {
    printf("%I64d\n", ans[i]);
  }
  return 0;
}
