#include <bits/stdc++.h>
using namespace std;
template <typename T>
using V = vector<T>;
template <typename T>
struct SegTree {
  vector<int> sz;
  vector<T> st;
  vector<T> lz;
  T e = 0;
  T lze = 0;
  int n;
  SegTree(int _sz) {
    n = _sz;
    sz.resize(4 * n), st.resize(4 * n), lz.resize(4 * n);
    build(n);
  }
  void push(int p, int L, int R) {
    if (lz[p] != lze) {
      st[p] += lz[p];
      if (L < R) {
        lz[p << 1] += lz[p];
        lz[p << 1 | 1] += lz[p];
      }
      lz[p] = lze;
    }
  }
  void pull(int p) {
    sz[p] = sz[p << 1] + sz[p << 1 | 1];
    st[p] = min(st[p << 1], st[p << 1 | 1]);
  }
  void build(int siz) {
    for (int i = 0; i < (n << 2); i++) {
      lz[i] = lze, st[i] = e;
    }
    build(1, 0, siz - 1);
  }
  void build(int p, int L, int R) {
    if (L == R) {
      sz[p] = 1;
      return;
    }
    build(p << 1, L, (L + R) >> 1);
    build(p << 1 | 1, ((L + R) >> 1) + 1, R);
    pull(p);
  }
  void upd(int l, int r, long long val) { upd(1, l, r, 0, n - 1, val); }
  void upd(int p, int l, int r, int L, int R, T val) {
    push(p, L, R);
    if (l > R || r < L) return;
    if (l <= L && r >= R) {
      lz[p] += val;
      push(p, L, R);
      return;
    }
    upd(p << 1, l, r, L, (L + R) >> 1, val);
    upd(p << 1 | 1, l, r, ((L + R) >> 1) + 1, R, val);
    pull(p);
  }
  T query(int l, int r) { return query(1, l, r, 0, n - 1); }
  T query(int p, int l, int r, int L, int R) {
    push(p, L, R);
    if (l > R || r < L) return 1e17;
    if (l <= L && r >= R) return st[p];
    return min(query(p << 1, l, r, L, (L + R) >> 1),
               query(p << 1 | 1, l, r, ((L + R) >> 1) + 1, R));
  }
};
vector<vector<pair<int, int> > > T;
vector<long long> d;
vector<int> in, out;
int t = 0;
void dfs(int u, long long dis) {
  in[u] = t;
  if (T[u].empty()) {
    d[in[u]] = dis;
  }
  t++;
  for (auto v : T[u]) {
    dfs(v.first, dis + v.second);
  }
  out[u] = t - 1;
}
struct query {
  int lt, rt, ind;
  long long ans;
  query(int l, int r, int _it) { lt = l, rt = r, ind = _it; }
};
vector<vector<query> > Q;
int n;
void dfs2(int u, SegTree<long long> &seg) {
  for (auto &q : Q[u]) {
    q.ans = seg.query(q.lt, q.rt);
  }
  for (auto v : T[u]) {
    seg.upd(0, n - 1, +v.second);
    seg.upd(in[v.first], out[v.first], -2 * v.second);
    dfs2(v.first, seg);
    seg.upd(in[v.first], out[v.first], +2 * v.second);
    seg.upd(0, n - 1, -v.second);
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int q;
  cin >> n >> q;
  SegTree<long long> seg(n);
  in.resize(n), out.resize(n), d.resize(n, 1e17), T.resize(n);
  for (int i = 0; i < n - 1; i++) {
    int u, w;
    cin >> u >> w;
    T[u - 1].push_back({i + 1, w});
  }
  dfs(0, 0);
  Q.resize(n);
  for (int i = 0; i < n; i++) {
    seg.upd(in[i], in[i], d[in[i]]);
  }
  for (int i = 0; i < q; i++) {
    int l, r, v;
    cin >> v >> l >> r;
    l--;
    r--;
    v--;
    Q[v].push_back(query(l, r, i));
  }
  dfs2(0, seg);
  vector<long long> A(q);
  for (int i = 0; i < n; i++) {
    for (auto &qu : Q[i]) {
      A[qu.ind] = qu.ans;
    }
  }
  for (int i = 0; i < q; i++) {
    cout << A[i] << endl;
  }
  return 0;
}
