#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
const long long INFLL = 1e18 + 1;
const int MAX = 200001;
const long long MOD = 1000000007;
const int SZ = 300100;
const double PI = 3.14159265358979323846264338327;
long long inq(long long k, long long q, long long mod) {
  if (q == 0) return 1;
  long long l = inq(k, q / 2, mod);
  if (q % 2 == 0)
    return l * l % mod;
  else
    return l * l % mod * k % mod;
}
long long gcd(long long a, long long b) {
  if (a < b) swap(a, b);
  if (b == 0) return a;
  return gcd(b, a % b);
}
long long cubr(long long a) {
  long long l = -1, r = 1e6 + 2;
  while (l < r - 1) {
    long long mid = (l + r) / 2;
    if (mid * mid * mid > a)
      r = mid;
    else
      l = mid;
  }
  return l;
}
long long max(long long a, long long b) {
  if (a > b) return a;
  return b;
}
long long min(long long a, long long b) { return -1 * max(-a, -b); }
long long possible(long long q) {
  if (q == INF) return -1;
  return q;
}
bool correct(int x, int xx) {
  if (x < 0) return 0;
  if (x >= xx) return 0;
  return 1;
}
long long dsumm(long long x, long long k) {
  long long y = 1;
  long long z = 0;
  for (int i = 0; y < 1e18; i++) {
    z += x / y % k;
    y *= k;
  }
  return z;
}
long long dcount(long long x) {
  long long y = 1;
  long long z = 0;
  int c[100];
  for (int i = 0; i < 10; i++) c[i] = 0;
  for (int i = 0; x > 0; i++) {
    if (c[x / y % 10] == 0) z++;
    c[x / y % 10] = 1;
    x /= 10;
  }
  return z;
}
long long lg10(long long x) {
  if (10000 <= x && x < 100000) return 5;
  if (x == 0) return 0;
  return lg10(x / 10) + 1;
}
long long g(long long x, long long mod) {
  if (x == 0) return 0;
  return x / mod + g(x / mod, mod);
}
bool is_digit(char c) { return ('0' <= c && c <= '9'); }
long long n, m;
struct Node {
  long long L, R;
  long long res;
  long long upd;
};
vector<Node> segment(2010000);
long long tourist;
void build(long long L, long long R, long long v) {
  segment[v].L = L;
  segment[v].R = R;
  long long M = (L + R) / 2;
  if (L + 1 >= R) {
    return;
  }
  build(L, M, 2 * v + 1);
  build(M, R, 2 * v + 2);
}
void push(long long v) {
  segment[2 * v + 1].res += segment[v].upd;
  segment[2 * v + 2].res += segment[v].upd;
  segment[2 * v + 1].upd += segment[v].upd;
  segment[2 * v + 2].upd += segment[v].upd;
  segment[v].upd = 0;
}
void add(long long l, long long r, long long v, long long w) {
  if (l >= r) return;
  long long L = segment[v].L;
  long long R = segment[v].R;
  if (r <= L || R <= l) return;
  if (l <= L && R <= r) {
    segment[v].res += w;
    segment[v].upd += w;
    return;
  }
  push(v);
  add(l, r, 2 * v + 1, w);
  add(l, r, 2 * v + 2, w);
  push(v);
  segment[v].res = min(segment[2 * v + 1].res, segment[2 * v + 2].res);
}
long long get(long long l, long long r, long long v) {
  long long L = segment[v].L;
  long long R = segment[v].R;
  if (r <= L || R <= l) return INFLL;
  if (l <= L && R <= r) return segment[v].res;
  push(v);
  return min(get(l, r, 2 * v + 1), get(l, r, 2 * v + 2));
}
struct query {
  long long v, l, r, num;
};
bool comp(query a1, query a2) { return a1.v < a2.v; }
long long ans[900000];
long long p[501000], w[501000];
vector<pair<long long, long long> > graph[501000];
vector<query> s;
long long std_tree[501000];
long long ukaz[501000];
void dp(long long v, long long value) {
  std_tree[v] = value;
  for (long long i = 0; i < graph[v].size(); i++) {
    dp(graph[v][i].first, graph[v][i].second + value);
  }
  return;
}
long long VERTEX = 1;
long long last_[501000];
void dp2(long long v) {
  last_[v] = v;
  for (long long i = 0; i < graph[v].size(); i++) {
    dp2(graph[v][i].first);
    last_[v] = last_[graph[v][i].first];
  }
}
void go(long long v) {
  long long l = VERTEX + 1;
  long long r = last_[VERTEX];
  if (v == VERTEX) return;
  if (l <= v && v <= r) {
    long long ww = graph[VERTEX][ukaz[VERTEX]].second;
    VERTEX = graph[VERTEX][ukaz[VERTEX]].first;
    add(VERTEX, last_[VERTEX] + 1, 0, -2 * ww);
    tourist += ww;
    ukaz[p[VERTEX]]++;
  } else {
    add(VERTEX, last_[VERTEX] + 1, 0, 2 * w[VERTEX]);
    tourist -= w[VERTEX];
    VERTEX = p[VERTEX];
  }
  go(v);
}
void solve() {
  dp(1, 0);
  dp2(1);
  for (long long i = 1; i <= n; i++) {
    if (graph[i].size() == 0) {
      add(i, i + 1, 0, std_tree[i]);
    } else {
      add(i, i + 1, 0, INFLL);
    }
  }
  for (long long i = 0; i < m; i++) {
    go(s[i].v);
    ans[s[i].num] = tourist + get(s[i].l, s[i].r + 1, 0);
  }
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  build(0, 500000, 0);
  cin >> n >> m;
  for (long long i = 2; i <= n; i++) {
    cin >> p[i] >> w[i];
    graph[p[i]].push_back({i, w[i]});
  }
  for (long long i = 0; i < m; i++) {
    long long v, l, r;
    cin >> v >> l >> r;
    s.push_back({v, l, r, i});
  }
  sort((s).begin(), (s).end(), comp);
  solve();
  for (long long i = 0; i < m; i++) {
    cout << ans[i] << " ";
  }
}
