#include <bits/stdc++.h>
using namespace std;
struct query {
  int i, l, r;
};
struct Node {
  long long int mx, prop;
} tree[500003];
int n, q, p, w, id, L[500003], ML[500003];
long long int dis[500003], ans[500003];
vector<pair<int, int> > G[500003];
vector<query> Q[500003];
bool vis[500003];
void dfs(int u, long long int d) {
  vis[u] = 1;
  L[u] = ML[u] = ++id;
  dis[L[u]] = G[u].size() == 1 ? d : 1e18;
  for (int i = 0; i < G[u].size(); i++) {
    if (!vis[G[u][i].first]) {
      dfs(G[u][i].first, d + G[u][i].second);
      ML[u] = max(ML[u], ML[G[u][i].first]);
    }
  }
}
void build(int v, int l, int r) {
  if (r < l) {
    return;
  }
  if (l == r) {
    tree[v].mx = dis[l];
    return;
  }
  int left = 2 * v;
  int right = left + 1;
  int mid = (l + r) / 2;
  build(left, l, mid);
  build(right, mid + 1, r);
  tree[v].mx = min(tree[left].mx, tree[right].mx);
}
void update(int v, int tl, int tr, int l, int r, long long int val) {
  if (r < l) {
    return;
  }
  if (tl == l && tr == r) {
    tree[v].mx += val;
    tree[v].prop += val;
    return;
  }
  int left = 2 * v;
  int right = left + 1;
  int mid = (tl + tr) / 2;
  tree[left].prop += tree[v].prop;
  tree[left].mx += tree[v].prop;
  tree[right].prop += tree[v].prop;
  tree[right].mx += tree[v].prop;
  tree[v].prop = 0;
  if (r <= mid) {
    update(left, tl, mid, l, r, val);
  } else if (l > mid) {
    update(right, mid + 1, tr, l, r, val);
  } else {
    update(left, tl, mid, l, min(r, mid), val);
    update(right, mid + 1, tr, max(l, mid + 1), r, val);
  }
  tree[v].mx = min(tree[left].mx, tree[right].mx);
}
long long int read(int v, int tl, int tr, int l, int r) {
  if (r < l) {
    return 1e18;
  }
  if (tl == l && tr == r) {
    return tree[v].mx;
  }
  int left = 2 * v;
  int right = left + 1;
  int mid = (tl + tr) / 2;
  tree[left].prop += tree[v].prop;
  tree[left].mx += tree[v].prop;
  tree[right].prop += tree[v].prop;
  tree[right].mx += tree[v].prop;
  tree[v].prop = 0;
  if (r <= mid) {
    return read(left, tl, mid, l, r);
  } else if (l > mid) {
    return read(right, mid + 1, tr, l, r);
  }
  return min(read(left, l, mid, l, min(r, mid)),
             read(right, mid + 1, r, max(l, mid + 1), r));
}
void print() {
  puts("Tree");
  for (int i = 1; i <= 5; i++) {
    cout << i << ' ' << read(1, 1, n, i, i) << endl;
  }
  puts("=====");
}
void dfs1(int u, int d) {
  vis[u] = 1;
  for (int i = 0; i < G[u].size(); i++) {
    if (!vis[G[u][i].first]) {
      update(1, 1, n, 1, n, G[u][i].second);
      update(1, 1, n, L[G[u][i].first], ML[G[u][i].first], -2 * G[u][i].second);
      for (int j = 0; j < Q[G[u][i].first].size(); j++) {
        ans[Q[G[u][i].first][j].i] =
            read(1, 1, n, Q[G[u][i].first][j].l, Q[G[u][i].first][j].r);
      }
      dfs1(G[u][i].first, d + G[u][i].second);
      update(1, 1, n, 1, n, -G[u][i].second);
      update(1, 1, n, L[G[u][i].first], ML[G[u][i].first], 2 * G[u][i].second);
    }
  }
}
int main() {
  scanf("%d%d", &n, &q);
  for (int i = 1; i < n; i++) {
    scanf("%d%d", &p, &w);
    G[p].push_back({i + 1, w});
    G[i + 1].push_back({p, w});
  }
  for (int i = 1; i <= n; i++) {
  }
  for (int i = 0; i < 500003; i++) {
    sort(G[i].begin(), G[i].end());
  }
  int v;
  query a;
  for (int i = 0; i < q; i++) {
    a.i = i;
    scanf("%d%d%d", &v, &a.l, &a.r);
    Q[v].push_back(a);
  }
  dfs(1, 0);
  for (int i = 1; i <= n; i++) {
  }
  for (int i = 0; i < 500003; i++) {
    tree[i].mx = tree[i].prop = 0;
  }
  build(1, 1, n);
  for (int j = 0; j < Q[1].size(); j++) {
    ans[Q[1][j].i] = read(1, 1, n, Q[1][j].l, Q[1][j].r);
  }
  memset(vis, 0, sizeof vis);
  dfs1(1, 0);
  for (int i = 0; i < q; i++) {
    cout << ans[i] << endl;
  }
}
