#include <bits/stdc++.h>
using namespace std;
const long long int inf = 1e18;
const long long int mod = 1e9 + 7;
inline long long int add(long long int x, long long int y) {
  x += y;
  if (x >= mod) x -= mod;
  return x;
}
inline long long int sub(long long int x, long long int y) {
  x -= y;
  if (x < 0) x += mod;
  return x;
}
inline long long int mul(long long int x, long long int y) {
  return ((x % mod) * (y % mod)) % mod;
}
inline long long int power(long long int a, long long int b) {
  long long int x = 1;
  while (b) {
    if (b & 1) x = mul(x, a);
    a = mul(a, a);
    b >>= 1;
  }
  return x;
}
inline long long int inv(long long int a) { return power(a, mod - 2); }
const long long int N = 5e5 + 5;
struct query_node {
  long long int l, r, idx;
};
vector<pair<long long int, long long int> > g[N];
vector<query_node> queries[N];
long long int height[N], tree[4 * N], lazy[4 * N], tin[N], tout[N], ans[N], n,
    q;
void update(long long int node, long long int start, long long int end,
            long long int l, long long int r, long long int val) {
  if (lazy[node]) {
    tree[node] += lazy[node];
    if (start != end) {
      lazy[2 * node] += lazy[node];
      lazy[2 * node + 1] += lazy[node];
    }
    lazy[node] = 0;
  }
  if (start > end or start > r or end < l) return;
  if (l <= start and r >= end) {
    tree[node] += val;
    if (start != end) {
      lazy[2 * node] += val;
      lazy[2 * node + 1] += val;
    }
    return;
  }
  long long int mid = (start + end) / 2;
  update(2 * node, start, mid, l, r, val);
  update(2 * node + 1, mid + 1, end, l, r, val);
  tree[node] = min(tree[2 * node], tree[2 * node + 1]);
}
void dfs1(long long int u) {
  tin[u] = tout[u] = u;
  for (auto edge : g[u]) {
    long long int v = edge.first, w = edge.second;
    height[v] = w + height[u];
    dfs1(v);
    tin[u] = min(tin[u], tin[v]);
    tout[u] = max(tout[u], tout[v]);
  }
  if (g[u].empty()) {
    update(1, 1, n, u, u, height[u]);
  } else {
    update(1, 1, n, u, u, inf);
  }
}
long long int query(long long int node, long long int start, long long int end,
                    long long int l, long long int r) {
  if (start > end or start > r or end < l) return inf;
  if (lazy[node]) {
    tree[node] += lazy[node];
    if (start != end) {
      lazy[2 * node] += lazy[node];
      lazy[2 * node + 1] += lazy[node];
    }
    lazy[node] = 0;
  }
  if (l <= start and r >= end) return tree[node];
  long long int mid = (start + end) / 2;
  long long int ret1 = query(2 * node, start, mid, l, r);
  long long int ret2 = query(2 * node + 1, mid + 1, end, l, r);
  return min(ret1, ret2);
}
void dfs2(long long int u) {
  for (query_node node : queries[u]) {
    long long int l = node.l, r = node.r;
    ans[node.idx] = query(1, 1, n, l, r);
  }
  for (auto edge : g[u]) {
    long long int v = edge.first, w = edge.second;
    update(1, 1, n, 1, n, w);
    update(1, 1, n, tin[v], tout[v], -2 * w);
    dfs2(v);
    update(1, 1, n, tin[v], tout[v], 2 * w);
    update(1, 1, n, 1, n, -w);
  }
}
int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> q;
  for (long long int i = 2; i <= n; i++) {
    long long int p, w;
    cin >> p >> w;
    g[p].push_back({i, w});
  }
  dfs1(1);
  for (long long int i = 1; i <= q; i++) {
    query_node node;
    long long int v;
    cin >> v;
    cin >> node.l >> node.r;
    node.idx = i;
    queries[v].push_back(node);
  }
  dfs2(1);
  for (long long int i = 1; i <= q; i++) cout << ans[i] << endl;
  return 0;
}
