#include <bits/stdc++.h>
using namespace std;
inline long long mod(long long n, long long m) {
  long long ret = n % m;
  if (ret < 0) ret += m;
  return ret;
}
long long gcd(long long a, long long b) { return (b == 0 ? a : gcd(b, a % b)); }
long long exp(long long a, long long b, long long m) {
  if (b == 0) return 1;
  if (b == 1) return mod(a, m);
  long long k = mod(exp(a, b / 2, m), m);
  if (b & 1) {
    return mod(a * mod(k * k, m), m);
  } else
    return mod(k * k, m);
}
long long n, q;
vector<pair<long long, long long> > adj[500100];
long long t = 0;
long long tin[500100];
long long tout[500100];
long long A[500100];
void dfs(long long v, long long d, long long p = -1) {
  tin[v] = ++t;
  tout[v] = t;
  for (long long i = 0; i < (long long)adj[v].size(); i++) {
    long long to = adj[v][i].first;
    if (to != p) dfs(to, d + adj[v][i].second, v);
    if (to != p) tout[v] = max(tout[v], tout[to]);
  }
  if (adj[v].size() == 1)
    A[tin[v]] = d;
  else
    A[tin[v]] = 1e15;
}
long long tree[500100];
long long lazy[500100];
void build(long long no, long long i, long long j) {
  lazy[no] = 0;
  if (i == j) {
    tree[no] = A[i];
  } else {
    long long mid = (i + j) / 2;
    long long l = 2 * no, r = 2 * no + 1;
    build(l, i, mid);
    build(r, mid + 1, j);
    tree[no] = min(tree[l], tree[r]);
  }
}
void flush(long long no, long long i, long long j) {
  if (lazy[no] == 0) return;
  tree[no] += lazy[no];
  if (i != j) {
    lazy[2 * no] += lazy[no];
    lazy[2 * no + 1] += lazy[no];
  }
  lazy[no] = 0;
}
long long query(long long no, long long i, long long j, long long a,
                long long b) {
  if (i > j || i > b || j < a) return 1e17;
  flush(no, i, j);
  if (a <= i && j <= b) return tree[no];
  long long mid = (i + j) / 2;
  long long l = 2 * no, r = 2 * no + 1;
  return min(query(l, i, mid, a, b), query(r, mid + 1, j, a, b));
}
void update(long long no, long long i, long long j, long long a, long long b,
            long long v) {
  flush(no, i, j);
  if (i > j || i > b || j < a) return;
  if (a <= i && j <= b) {
    tree[no] += v;
    if (i != j) {
      lazy[2 * no] += v;
      lazy[2 * no + 1] += v;
    }
    return;
  }
  long long mid = (i + j) / 2;
  long long l = 2 * no, r = 2 * no + 1;
  update(l, i, mid, a, b, v);
  update(r, mid + 1, j, a, b, v);
  tree[no] = min(tree[l], tree[r]);
}
struct Q {
  long long l, r, i;
  Q() {}
  Q(long long a, long long b, long long c) {
    l = a;
    r = b;
    i = c;
  }
};
vector<Q> qry[500100];
long long res[500100];
void dfs2(long long v, long long p) {
  for (long long i = 0; i < (long long)qry[v].size(); i++) {
    long long l = qry[v][i].l;
    long long r = qry[v][i].r;
    res[qry[v][i].i] = query(1, 1, n, l, r);
  }
  for (long long i = 0; i < (long long)adj[v].size(); i++) {
    long long to = adj[v][i].first;
    if (to != p) {
      long long w = adj[v][i].second;
      update(1, 1, n, 1, n, w);
      update(1, 1, n, tin[to], tout[to], -2LL * w);
      dfs2(to, v);
      update(1, 1, n, 1, n, -w);
      update(1, 1, n, tin[to], tout[to], 2LL * w);
    }
  }
}
int32_t main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  ;
  cin >> n >> q;
  for (long long i = 2; i <= n; i++) {
    long long p, w;
    cin >> p >> w;
    adj[p].push_back(pair<long long, long long>(i, w));
    adj[i].push_back(pair<long long, long long>(p, w));
  }
  for (long long i = 1; i <= n; i++) {
    sort(adj[i].begin(), adj[i].end());
  }
  dfs(1, 0);
  for (long long i = 0; i < q; i++) {
    long long v, l, r;
    cin >> v >> l >> r;
    qry[v].push_back(Q(l, r, i));
  }
  build(1, 1, n);
  dfs2(1, -1);
  for (long long i = 0; i < q; i++) {
    cout << res[i] << "\n";
  }
}
