#include <bits/stdc++.h>
using namespace std;
inline void open(const char *s) {}
namespace IO {
const int S = (1 << 20) + 10;
char buf[S], *H, *T;
inline char Get() {
  if (H == T) T = (H = buf) + fread(buf, 1, S, stdin);
  if (H == T) return -1;
  return *H++;
}
inline int rd() {
  static int x, f;
  x = 0;
  f = 1;
  char ch = Get();
  for (; ch < '0' || ch > '9'; ch = Get())
    if (ch == '-') f = -1;
  for (; ch >= '0' && ch <= '9'; ch = Get()) x = x * 10 + ch - '0';
  return f > 0 ? x : -x;
}
}  // namespace IO
using IO::rd;
const int N = 500010;
struct edge {
  int v, w, next;
  edge(int v = 0, int w = 0, int next = 0) : v(v), w(w), next(next) {}
} e[N << 1];
int n, m, rt = 0, ed[N];
int tot = 0, head[N];
bool isnl[N];
long long dis[N], ans[N];
struct node {
  int l, r, id;
};
vector<node> q[N];
inline void add(int u, int v, int w) {
  e[++tot] = edge(v, w, head[u]);
  head[u] = tot;
}
namespace Seg {
struct tree {
  int ls, rs;
  long long mn, tag;
  tree() {
    ls = rs = tag = 0;
    mn = (long long)1e16;
  }
} tr[N << 1];
int cnt = 0;
inline void pushup(int o) { tr[o].mn = min(tr[tr[o].ls].mn, tr[tr[o].rs].mn); }
inline void pushdown(int o) {
  static int ls, rs;
  if (!tr[o].tag) return;
  ls = tr[o].ls, rs = tr[o].rs;
  if (ls) tr[ls].mn += tr[o].tag, tr[ls].tag += tr[o].tag;
  if (rs) tr[rs].mn += tr[o].tag, tr[rs].tag += tr[o].tag;
  tr[o].tag = 0;
}
void insert(int &o, int l, int r, int x, long long d) {
  if (!o) o = ++cnt;
  if (l == r) return tr[o].mn = d, void();
  pushdown(o);
  int mid = (l + r) >> 1;
  if (x <= mid)
    insert(tr[o].ls, l, mid, x, d);
  else
    insert(tr[o].rs, mid + 1, r, x, d);
  pushup(o);
}
void updata(int o, int l, int r, int L, int R, long long d) {
  if (!o || L > R) return;
  if (l == L && r == R) return tr[o].mn += d, tr[o].tag += d, void();
  pushdown(o);
  int mid = (l + r) >> 1;
  if (L <= mid) updata(tr[o].ls, l, mid, L, min(mid, R), d);
  if (R > mid) updata(tr[o].rs, mid + 1, r, max(mid + 1, L), R, d);
  pushup(o);
}
long long query(int o, int l, int r, int L, int R) {
  if (!o) return (long long)1e16;
  if (l == L && r == R) return tr[o].mn;
  pushdown(o);
  int mid = (l + r) >> 1;
  long long res = (long long)1e16;
  if (L <= mid) res = min(res, query(tr[o].ls, l, mid, L, min(mid, R)));
  if (R > mid) res = min(res, query(tr[o].rs, mid + 1, r, max(mid + 1, L), R));
  return res;
}
}  // namespace Seg
void dfs(int u, int fat) {
  if (!isnl[u]) Seg::insert(rt, 1, n, u, dis[u]);
  ed[u] = u;
  for (int i = head[u]; i; i = e[i].next) {
    int v = e[i].v;
    if (v == fat) continue;
    dis[v] = dis[u] + e[i].w;
    dfs(v, u);
    ed[u] = max(ed[u], ed[v]);
  }
}
void gao(int u, int fat) {
  for (int i = 0; i <= (int)q[u].size() - 1; i++)
    ans[q[u][i].id] = Seg::query(rt, 1, n, q[u][i].l, q[u][i].r);
  for (int i = head[u]; i; i = e[i].next) {
    int v = e[i].v, w = e[i].w;
    if (v == fat) continue;
    Seg::updata(rt, 1, n, v, ed[v], -w);
    Seg::updata(rt, 1, n, 1, v - 1, w);
    Seg::updata(rt, 1, n, ed[v] + 1, n, w);
    gao(v, u);
    Seg::updata(rt, 1, n, v, ed[v], w);
    Seg::updata(rt, 1, n, 1, v - 1, -w);
    Seg::updata(rt, 1, n, ed[v] + 1, n, -w);
  }
}
int main() {
  n = rd();
  m = rd();
  for (int i = 2; i <= n; i++) {
    int x = rd(), y = rd();
    add(x, i, y);
    add(i, x, y);
    isnl[x] = 1;
  }
  dfs(1, 0);
  for (int i = 1; i <= m; i++) {
    int x = rd(), l = rd(), r = rd();
    q[x].push_back(node{l, r, i});
  }
  gao(1, 0);
  for (int i = 1; i <= m; i++) printf("%lld\n", ans[i]);
  return 0;
}
