#include <bits/stdc++.h>
using namespace std;
long long int INF = 9223372036854775807;
const long long int mod = 1000000007;
long long int MOD(long long int a, long long int b) {
  if (a > b)
    return a - b;
  else
    return b - a;
}
long long int max3(long long int a, long long int b, long long int c) {
  return max(c, max(a, b));
}
long long int min3(long long int a, long long int b, long long int c) {
  return min(a, min(b, c));
}
long long int power(long long int x, long long int y) {
  long long int res = 1;
  while (y > 0) {
    if (y & 1) res = (res * x);
    y = y >> 1;
    x = (x * x);
  }
  return res;
}
long long int power1(long long int x, long long int y) {
  long long int res = 1;
  while (y > 0) {
    if (y & 1) res = (res * x) % mod;
    y = y >> 1;
    x = (x * x) % mod;
  }
  return res % mod;
}
long long int logg(long long int a) {
  long long int x = 0;
  while (a > 1) {
    x++;
    a /= 2;
  }
  return x;
}
long long int gcd(long long int a, long long int b) {
  if (a == 0) return b;
  return gcd(b % a, a);
}
long long int abso(long long int x) {
  if (x < 0) {
    return -x;
  }
  return x;
}
long long int ceiling(long long int a, long long int b) {
  if (a % b == 0) {
    return a / b;
  } else {
    return a / b + 1;
  }
}
long long int modinv(long long int x) { return power1(x, mod - 2); }
int n, q;
vector<vector<pair<int, long long int>>> adj;
vector<long long int> dist;
vector<int> visited;
vector<bool> isleaf;
vector<vector<pair<int, pair<int, int>>>> queries;
vector<long long int> ans;
vector<int> fin;
void dfs(int i) {
  visited[i] = 1;
  int num = 0;
  fin[i] = i;
  for (int j = 0; j < adj[i].size(); j++) {
    if (!visited[adj[i][j].first]) {
      dist[adj[i][j].first] = dist[i] + adj[i][j].second;
      dfs(adj[i][j].first);
      fin[i] = max(fin[i], fin[adj[i][j].first]);
      num++;
    }
  }
  if (num == 0) {
    isleaf[i] = true;
  }
}
vector<long long int> tree(4 * n + 200, INF);
vector<long long int> lazy(4 * n + 200, INF);
void build(int node, int start, int end) {
  if (start == end) {
    tree[node] = dist[start];
  } else {
    int mid = (start + end) / 2;
    build(2 * node, start, mid);
    build(2 * node + 1, mid + 1, end);
    tree[node] = min(tree[2 * node], tree[2 * node + 1]);
  }
}
long long int range_query(int node, int start, int end, int l, int r) {
  if (start > end || start > r || end < l) {
    return INF;
  }
  if (lazy[node] != 0) {
    if (tree[node] != INF) {
      tree[node] += lazy[node];
    }
    if (start != end) {
      lazy[2 * node] += lazy[node];
      lazy[2 * node + 1] += lazy[node];
    }
    lazy[node] = 0;
  }
  if (start >= l && end <= r) {
    return tree[node];
  }
  int mid = (start + end) / 2;
  long long int left = range_query(2 * node, start, mid, l, r);
  long long int right = range_query(2 * node + 1, mid + 1, end, l, r);
  return min(left, right);
}
void range_update(int node, int start, int end, int l, int r, long long int w) {
  if (lazy[node] != 0) {
    if (tree[node] != INF) {
      tree[node] += lazy[node];
    }
    if (start != end) {
      lazy[2 * node] += lazy[node];
      lazy[2 * node + 1] += lazy[node];
    }
    lazy[node] = 0;
  }
  if (start > end || start > r || end < l) {
    return;
  }
  if (start >= l && end <= r) {
    if (tree[node] != INF) {
      tree[node] += w;
    }
    if (start != end) {
      lazy[2 * node] += w;
      lazy[2 * node + 1] += w;
    }
    return;
  }
  int mid = (start + end) / 2;
  range_update(2 * node, start, mid, l, r, w);
  range_update(2 * node + 1, mid + 1, end, l, r, w);
  tree[node] = min(tree[2 * node], tree[2 * node + 1]);
  return;
}
void solve(int i) {
  visited[i] = 1;
  for (int j = 0; j < queries[i].size(); j++) {
    ans[queries[i][j].first] = range_query(1, 1, n, queries[i][j].second.first,
                                           queries[i][j].second.second);
  }
  for (int j = 0; j < adj[i].size(); j++) {
    if (!visited[adj[i][j].first]) {
      int x = adj[i][j].first;
      range_update(1, 1, n, x, fin[x], -adj[i][j].second);
      if (x != 1) {
        range_update(1, 1, n, 1, x - 1, adj[i][j].second);
      }
      if (fin[x] != n) {
        range_update(1, 1, n, fin[x] + 1, n, adj[i][j].second);
      }
      solve(adj[i][j].first);
      if (fin[x] != n) {
        range_update(1, 1, n, fin[x] + 1, n, -adj[i][j].second);
      }
      if (x != 1) {
        range_update(1, 1, n, 1, x - 1, -adj[i][j].second);
      }
      range_update(1, 1, n, x, fin[x], adj[i][j].second);
    }
  }
}
int main() {
  INF = power(10, 15) + 1;
  cin >> n >> q;
  adj.resize(n + 1);
  dist.resize(n + 1);
  visited.resize(n + 1, 0);
  ans.resize(q);
  isleaf.resize(n + 1);
  queries.resize(n + 1);
  fin.resize(n + 1);
  for (int i = 2; i <= n; i++) {
    int x;
    long long int w;
    cin >> x >> w;
    adj[x].push_back(make_pair(i, w));
    adj[i].push_back(make_pair(x, w));
  }
  dfs(1);
  for (int i = 1; i <= n; i++) {
    if (!isleaf[i]) {
      dist[i] = INF;
    }
  }
  build(1, 1, n);
  for (int j = 0; j < q; j++) {
    int v, l, r;
    cin >> v >> l >> r;
    queries[v].push_back(make_pair(j, make_pair(l, r)));
  }
  for (int i = 0; i <= n; i++) {
    visited[i] = 0;
  }
  solve(1);
  for (int i = 0; i < q; i++) {
    cout << ans[i] << endl;
  }
}
