#include <bits/stdc++.h>
using namespace std;
const int N = 500 * 1000 + 20;
const long long inf = 1e18;
long long n, m, par_w[N], par[N], dis[N];
long long res, ans[N];
vector<int> leaf;
vector<pair<int, long long>> gr[N];
pair<int, int> baze[N];
vector<pair<pair<int, int>, int>> query[N];
void dfs(int v, int p) {
  if (gr[v].size() == 1) {
    leaf.push_back(v), baze[v] = {leaf.size() - 1, leaf.size() - 1};
    return;
  }
  sort(gr[v].begin(), gr[v].end());
  for (auto u : gr[v])
    if (u.first != p)
      par[u.first] = v, par_w[u.first] = u.second,
      dis[u.first] = dis[v] + u.second, dfs(u.first, v);
  int l = n, r = 0;
  for (auto u : gr[v])
    if (u.first != p)
      l = min(baze[u.first].first, l), r = max(baze[u.first].second, r);
  baze[v] = {l, r};
}
struct node {
  int l, r;
  long long mn, lazy;
  int size() { return r - l; }
  bool leaf() { return size() == 1; }
  int unity(int ql, int qr) { return max(0, min(qr, r) - max(ql, l)); }
  bool init(int ql, int qr) { return size() == unity(ql, qr); }
  void merge(node lc, node rc) { mn = min(rc.mn, lc.mn); }
} seg[4 * N];
void shift(int v) {
  seg[v].mn += seg[v].lazy;
  if (!seg[v].leaf())
    seg[2 * v].lazy += seg[v].lazy, seg[2 * v + 1].lazy += seg[v].lazy;
  seg[v].lazy = 0;
}
void build(int v, int l, int r) {
  seg[v].l = l, seg[v].r = r;
  if (seg[v].leaf()) {
    seg[v].mn = dis[leaf[l]];
    return;
  }
  int mid = (l + r) / 2;
  build(2 * v, l, mid), build(2 * v + 1, mid, r);
  seg[v].merge(seg[2 * v], seg[2 * v + 1]);
}
void add(int v, int l, int r, int x) {
  shift(v);
  if (!seg[v].unity(l, r)) return;
  if (seg[v].init(l, r)) {
    seg[v].lazy += x, shift(v);
    return;
  }
  add(2 * v, l, r, x), add(2 * v + 1, l, r, x);
  seg[v].merge(seg[2 * v], seg[2 * v + 1]);
}
void get(int v, int l, int r) {
  shift(v);
  if (!seg[v].unity(l, r)) return;
  if (seg[v].init(l, r)) {
    res = min(res, seg[v].mn);
    return;
  }
  return get(2 * v, l, r), get(2 * v + 1, l, r);
}
void dfs_ans(int v, int p) {
  for (auto u : query[v]) {
    int l = lower_bound(leaf.begin(), leaf.end(), u.first.first) - leaf.begin();
    int r =
        upper_bound(leaf.begin(), leaf.end(), u.first.second) - leaf.begin();
    res = inf;
    get(1, l, r);
    ans[u.second] = res;
  }
  for (auto u : gr[v])
    if (u.first != p) {
      if (baze[u.first].first != 0) add(1, 0, baze[u.first].first, u.second);
      add(1, baze[u.first].first, baze[u.first].second + 1, -u.second);
      if (baze[u.first].second != leaf.size())
        add(1, baze[u.first].second + 1, leaf.size(), u.second);
      dfs_ans(u.first, v);
    }
  if (baze[v].first != 0) add(1, 0, baze[v].first, -par_w[v]);
  add(1, baze[v].first, baze[v].second + 1, par_w[v]);
  if (baze[v].second != leaf.size())
    add(1, baze[v].second + 1, leaf.size(), -par_w[v]);
}
int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  cin >> n >> m;
  for (int i = 2; i <= n; i++) {
    int v, w;
    cin >> v >> w;
    gr[i].push_back({v, w}), gr[v].push_back({i, w});
  }
  dfs(1, -1);
  for (int i = 0; i < m; i++) {
    int v, l, r;
    cin >> v >> l >> r;
    query[v].push_back({{l, r}, i});
  }
  build(1, 0, leaf.size());
  dfs_ans(1, -1);
  for (int i = 0; i < m; i++) cout << ans[i] << '\n';
  return 0;
}
