#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
const int tinf = (int)1e9 + 7;
const long long inf = (long long)1e18 + 7;
const int N = 7e5 + 5;
const long long M = 1e9 + 7;
const int rx[4] = {1, 0, -1, 0};
const int ry[4] = {0, 1, 0, -1};
struct T {
  int l, r, num;
};
vector<pair<int, int> > g[N];
bool used[N], need[N * 4];
long long depth[N], n;
long long t[N * 4], add[N * 4];
vector<T> queary[N];
long long ans[N];
int par[N];
inline void push(int v, int tl, int tr) {
  if (need[v]) {
    t[v] += add[v];
    if (tl != tr) {
      add[v * 2] += add[v];
      add[v * 2 + 1] += add[v];
      need[v * 2] = 1;
      need[v * 2 + 1] = 1;
    }
    need[v] = 0;
    add[v] = 0;
  }
}
inline void update(int v, int tl, int tr, int l, int r, int val) {
  push(v, tl, tr);
  if (l > r) return;
  if (tl == l && tr == r) {
    add[v] += val;
    need[v] = 1;
    push(v, tl, tr);
    return;
  }
  int tm = (tl + tr) >> 1;
  update(v * 2, tl, tm, l, min(tm, r), val);
  update(v * 2 + 1, tm + 1, tr, max(tm + 1, l), r, val);
  t[v] = min(t[v * 2], t[v * 2 + 1]);
}
inline long long Min(int v, int tl, int tr, int l, int r) {
  push(v, tl, tr);
  if (l > r) return inf;
  if (tl == l && tr == r) {
    return t[v];
  }
  int tm = (tl + tr) >> 1;
  return min(Min(v * 2, tl, tm, l, min(tm, r)),
             Min(v * 2 + 1, tm + 1, tr, max(tm + 1, l), r));
}
inline int dfs(int v, int d) {
  used[v] = true;
  depth[v] = d;
  bool leaf = 1;
  int Max = v;
  for (auto j : g[v]) {
    int to = j.first, len = j.second;
    if (!used[to]) {
      Max = max(Max, dfs(to, d + len));
      leaf = 0;
    }
  }
  if (leaf) {
    update(1, 0, n - 1, v, v, -inf + depth[v]);
  }
  par[v] = Max;
  return Max;
}
inline void dfs_new(int v, int w) {
  used[v] = true;
  update(1, 0, n - 1, v, par[v], -w);
  if (v) update(1, 0, n - 1, 0, v - 1, w);
  if (par[v] + 1 <= n - 1) update(1, 0, n - 1, par[v] + 1, n - 1, w);
  for (auto j : queary[v]) {
    int num = j.num, l = j.l, r = j.r;
    ans[num] = Min(1, 0, n - 1, l, r);
  }
  for (auto j : g[v]) {
    int to = j.first, len = j.second;
    if (!used[to]) {
      dfs_new(to, len);
    }
  }
  update(1, 0, n - 1, v, par[v], w);
  if (v) update(1, 0, n - 1, 0, v - 1, -w);
  if (par[v] + 1 <= n - 1) update(1, 0, n - 1, par[v] + 1, n - 1, -w);
}
signed main() {
  {
    ios ::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
  }
  fill(t, t + N * 4, inf);
  int q;
  cin >> n >> q;
  for (int i = 1; i < n; i++) {
    int p, w;
    cin >> p >> w;
    p--;
    g[p].push_back({i, w});
    g[i].push_back({p, w});
  }
  dfs(0, 0);
  for (int i = 0; i < q; i++) {
    int v, l, r;
    cin >> v >> l >> r;
    v--;
    l--;
    r--;
    queary[v].push_back({l, r, i});
  }
  fill(used, used + N, false);
  dfs_new(0, 0);
  for (int i = 0; i < q; i++) {
    cout << ans[i] << endl;
  }
}
