#include <bits/stdc++.h>
using namespace std;
const long long INF = 1e18 + 7;
vector<vector<pair<long long, long long>>> g;
vector<pair<long long, long long>> otr;
vector<long long> used;
long long t = 0;
vector<long long> glub;
vector<long long> leafs;
vector<long long> rast;
vector<long long> zapl, zapr;
vector<long long> isleaf;
vector<long long> ans;
struct zapros {
  long long l, r, i;
  zapros() {}
  zapros(long long l1, long long r1, long long i1) {
    l = l1;
    r = r1;
    i = i1;
  }
};
vector<vector<zapros>> zap;
struct node {
  long long x;
  node() {}
  node(long long x1) { x = x1; }
};
struct segment_tree {
  vector<node> tree;
  vector<long long> d;
  long long n;
  node e;
  node operation(node a, node b) { return node(min(a.x, b.x)); }
  node get_e() { return INF; }
  void build(vector<long long> &a, long long v, long long l, long long r) {
    if (l + 1 == r) {
      tree[v] = node(a[l]);
      return;
    }
    long long m = (l + r) / 2;
    build(a, 2 * v + 1, l, m);
    build(a, 2 * v + 2, m, r);
    tree[v] = operation(tree[2 * v + 1], tree[2 * v + 2]);
  }
  segment_tree() { e = get_e(); }
  segment_tree(long long n1) {
    n = n1;
    tree.assign(4 * n, node(INF));
    d.assign(4 * n, 0);
    e = get_e();
  }
  segment_tree(vector<long long> &a) {
    n = a.size();
    tree.assign(4 * n, node(INF));
    d.assign(4 * n, 0);
    e = get_e();
    build(a, 0, 0, n);
  }
  void push(long long v, long long l, long long r) {
    if (d[v] == 0) return;
    tree[v].x += d[v];
    if (l + 1 != r) {
      d[2 * v + 1] += d[v];
      d[2 * v + 2] += d[v];
    }
    d[v] = 0;
  }
  void local_update(long long v, long long l, long long r, long long ql,
                    long long qr, long long qx) {
    push(v, l, r);
    if (ql <= l && r <= qr) {
      d[v] += qx;
      push(v, l, r);
      return;
    }
    if (r <= ql || qr <= l) {
      return;
    }
    long long m = (l + r) / 2;
    local_update(2 * v + 1, l, m, ql, qr, qx);
    local_update(2 * v + 2, m, r, ql, qr, qx);
    tree[v] = operation(tree[2 * v + 1], tree[2 * v + 2]);
  }
  void update(long long l, long long r, long long x) {
    local_update(0, 0, n, l, r, x);
  }
  node local_get_ans(long long v, long long l, long long r, long long ql,
                     long long qr) {
    push(v, l, r);
    if (ql <= l && r <= qr) {
      return tree[v];
    }
    if (r <= ql || qr <= l) {
      return e;
    }
    long long m = (l + r) / 2;
    node t1 = local_get_ans(2 * v + 1, l, m, ql, qr);
    node t2 = local_get_ans(2 * v + 2, m, r, ql, qr);
    return operation(t1, t2);
  }
  long long get_ans(long long l, long long r) {
    node ans = local_get_ans(0, 0, n, l, r);
    return ans.x;
  }
};
pair<long long, long long> dfs1(long long v, long long gl) {
  used[v] = 1;
  glub[v] = gl;
  long long l = -1, r = -1;
  for (auto it : g[v]) {
    if (!used[it.first]) {
      auto e = dfs1(it.first, gl + it.second);
      if (l == -1 && r == -1) {
        l = e.first;
        r = e.second;
      } else {
        l = min(e.first, l);
        r = max(e.second, r);
      }
    }
  }
  if (g[v].size() == 1) {
    otr[v] = {t, t};
    t++;
    leafs.push_back(v);
    return otr[v];
  } else {
    return otr[v] = {l, r};
  }
}
void dfs2(long long v, segment_tree &seg) {
  used[v] = 1;
  for (auto it : zap[v]) {
    ans[it.i] = seg.get_ans(it.l, it.r + 1);
  }
  for (auto it : g[v]) {
    if (!used[it.first]) {
      seg.update(otr[it.first].first, otr[it.first].second + 1, -it.second);
      if (otr[it.first].first > 0)
        seg.update(0, otr[it.first].first, it.second);
      if (otr[it.first].second < (long long)leafs.size() - 1)
        seg.update(otr[it.first].second + 1, leafs.size(), it.second);
      dfs2(it.first, seg);
      seg.update(otr[it.first].first, otr[it.first].second + 1, it.second);
      if (otr[it.first].first > 0)
        seg.update(0, otr[it.first].first, -it.second);
      if (otr[it.first].second < (long long)leafs.size() - 1)
        seg.update(otr[it.first].second + 1, leafs.size(), -it.second);
    }
  }
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  long long n, q;
  cin >> n >> q;
  g.resize(n);
  otr.resize(n);
  used.assign(n, 0);
  glub.assign(n, 0);
  zapl.assign(n, 0);
  zapr.assign(n, 0);
  zap.resize(n);
  isleaf.assign(n, 0);
  ans.assign(q, 0);
  for (long long i = 0; i < n - 1; ++i) {
    long long p, w;
    cin >> p >> w;
    p--;
    g[i + 1].push_back({p, w});
    g[p].push_back({i + 1, w});
  }
  dfs1(0, 0);
  for (auto it : leafs) {
    isleaf[it] = 1;
    rast.push_back(glub[it]);
  }
  long long ll = leafs.size(), rr = -1;
  for (long long i = 0; i < n; ++i) {
    if (isleaf[i]) rr++;
    zapr[i] = rr;
  }
  for (long long i = n - 1; i >= 0; --i) {
    if (isleaf[i]) ll--;
    zapl[i] = ll;
  }
  for (long long i = 0; i < q; ++i) {
    long long v, l, r;
    cin >> v >> l >> r;
    v--;
    l--;
    r--;
    zap[v].push_back(zapros(zapl[l], zapr[r], i));
  }
  used.assign(n, 0);
  segment_tree seg(rast);
  dfs2(0, seg);
  for (auto it : ans) cout << it << endl;
  return 0;
}
