#include <bits/stdc++.h>
using namespace std;
std::ostream& operator<<(std::ostream& os, pair<int, int> p) {
  os << p.first << ", " << p.second;
  return os;
}
struct data {
  int indis, l, r;
  data(int a, int c, int d) {
    indis = a;
    l = c;
    r = d;
  }
  data() {}
};
vector<vector<pair<long long int, long long int> > > adj;
const int MAXN = 5 * 1e5 + 5;
const int MAXQ = 5 * 1e5 + 5;
vector<long long int> dist(MAXN);
long long int segmentTree[4 * MAXN], lazy[4 * MAXN];
vector<long long int> segs(MAXN), sege(MAXN);
void dfs(int node, int parent, int len, int* ml, int* mxl) {
  dist[node] = len;
  for (auto item : adj[node]) {
    if (item.first == parent) continue;
    int m1l, m2l;
    if (adj[item.first].size() == 1)
      m1l = item.first;
    else
      m1l = 1e7;
    m2l = (int)(item.first);
    dfs(item.first, node, len + item.second, &m1l, &m2l);
    *ml = (int)min(m1l, *ml);
    *mxl = (int)max(*mxl, m2l);
  }
  segs[node] = *ml;
  sege[node] = *mxl;
}
void buildTree(int node, int a, int b) {
  if (a > b) return;
  if (a == b) {
    segmentTree[node] = dist[a];
    if (adj[a].size() > 1 || a == 1) {
      segmentTree[node] = 1e16;
    }
  } else {
    buildTree(node * 2, a, (a + b) / 2);
    buildTree(node * 2 + 1, (a + b) / 2 + 1, b);
    segmentTree[node] = min(segmentTree[node * 2], segmentTree[node * 2 + 1]);
  }
}
void push(int node, int a, int b) {
  if (lazy[node] != 0) {
    segmentTree[node] += lazy[node];
    if (a != b) {
      lazy[node * 2] += lazy[node];
      lazy[node * 2 + 1] += lazy[node];
    }
    lazy[node] = 0;
  }
}
void update(int node, int a, int b, int l, int r, long long int x) {
  push(node, a, b);
  if (a > b || a > r || b < l) return;
  if (a >= l && b <= r) {
    segmentTree[node] += x;
    if (a != b) {
      lazy[node * 2] += x;
      lazy[node * 2 + 1] += x;
    }
    return;
  }
  update(node * 2, a, (a + b) / 2, l, r, x);
  update(node * 2 + 1, (a + b) / 2 + 1, b, l, r, x);
  segmentTree[node] = min(segmentTree[node * 2], segmentTree[node * 2 + 1]);
}
long long int query(int node, int a, int b, int l, int r) {
  if (a > b || a > r || b < l) return 1e16;
  push(node, a, b);
  if (a >= l && b <= r) {
    return segmentTree[node];
  }
  long long int l1 = query(node * 2, a, (a + b) / 2, l, r);
  long long int l2 = query(node * 2 + 1, (a + b) / 2 + 1, b, l, r);
  return min(l1, l2);
}
int n, q;
vector<vector<data> > queries(MAXN);
vector<long long int> ans(MAXQ);
void solveDfs(int node, int parent, int dlen) {
  update(1, 1, n, segs[node], sege[node], -2 * dlen);
  update(1, 1, n, 1, n, dlen);
  for (auto item : queries[node]) {
    ans[item.indis] = query(1, 1, n, item.l, item.r);
  }
  for (auto item : adj[node]) {
    if (item.first == parent) continue;
    solveDfs(item.first, node, item.second);
  }
  update(1, 1, n, segs[node], sege[node], 2 * dlen);
  update(1, 1, n, 1, n, -dlen);
}
int main() {
  cin >> n >> q;
  adj = vector<vector<pair<long long int, long long int> > >(n + 1);
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    cin >> a >> b;
    adj[i + 2].push_back(pair<long long int, long long int>(a, b));
    adj[a].push_back(pair<long long int, long long int>(i + 2, b));
  }
  int r1 = 1000000, r2 = 0;
  dfs(1, -1, 0, &r1, &r2);
  buildTree(1, 1, n);
  for (int i = 0; i < q; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    queries[a].push_back(data(i + 1, b, c));
  }
  solveDfs(1, 0, 0);
  for (int i = 1; i <= q; i++) {
    cout << ans[i] << "\n";
  }
  return 0;
}
