#include <bits/stdc++.h>
using namespace std;
const long long MAXN = 1000 * 1000;
const long long MAXLIST = MAXN * 2;
const long long LOG_MAXLIST = 121;
const long long SQRT_MAXLIST = 1100;
const long long MAXBLOCKS = MAXLIST / ((LOG_MAXLIST + 1) / 2) + 1;
long long n, root;
vector<long long> g[MAXN];
long long h[MAXN];
vector<long long> a;
long long a_pos[MAXN];
long long block;
long long bt[MAXBLOCKS][LOG_MAXLIST + 1];
long long bhash[MAXBLOCKS];
long long brmq[SQRT_MAXLIST][LOG_MAXLIST / 2][LOG_MAXLIST / 2];
long long sosos[2 * MAXN];
void dfs(long long v, long long curh) {
  h[v] = curh;
  a_pos[v] = (long long)a.size();
  a.push_back(v);
  for (size_t i = 0; i < g[v].size(); ++i)
    if (h[g[v][i]] == -1) {
      dfs(g[v][i], curh + 1);
      a.push_back(v);
    }
}
long long log(long long n) {
  long long res = 1;
  while (1 << res < n) ++res;
  return res;
}
inline long long min_h(long long i, long long j) {
  return h[a[i]] < h[a[j]] ? i : j;
}
void build_lca() {
  long long sz = (long long)a.size();
  block = (log(sz) + 1) / 2;
  long long blocks = sz / block + (sz % block ? 1 : 0);
  memset(bt, 255, sizeof bt);
  for (long long i = 0, bl = 0, j = 0; i < sz; ++i, ++j) {
    if (j == block) j = 0, ++bl;
    if (bt[bl][0] == -1 || min_h(i, bt[bl][0]) == i) bt[bl][0] = i;
  }
  for (long long j = 1; j <= log(sz); ++j)
    for (long long i = 0; i < blocks; ++i) {
      long long ni = i + (1 << (j - 1));
      if (ni >= blocks)
        bt[i][j] = bt[i][j - 1];
      else
        bt[i][j] = min_h(bt[i][j - 1], bt[ni][j - 1]);
    }
  memset(bhash, 0, sizeof bhash);
  for (long long i = 0, bl = 0, j = 0; i < sz || j < block; ++i, ++j) {
    if (j == block) j = 0, ++bl;
    if (j > 0 && (i >= sz || min_h(i - 1, i) == i - 1))
      bhash[bl] += 1 << (j - 1);
  }
  memset(brmq, 255, sizeof brmq);
  for (long long i = 0; i < blocks; ++i) {
    long long id = bhash[i];
    if (brmq[id][0][0] != -1) continue;
    for (long long l = 0; l < block; ++l) {
      brmq[id][l][l] = l;
      for (long long r = l + 1; r < block; ++r) {
        brmq[id][l][r] = brmq[id][l][r - 1];
        if (i * block + r < sz)
          brmq[id][l][r] =
              min_h(i * block + brmq[id][l][r], i * block + r) - i * block;
      }
    }
  }
  for (long long i = 0, j = 0; i < sz; ++i) {
    if (1 << (j + 1) <= i) ++j;
    sosos[i] = j;
  }
}
inline long long lca_in_block(long long bl, long long l, long long r) {
  return brmq[bhash[bl]][l][r] + bl * block;
}
long long lca(long long v1, long long v2) {
  long long l = a_pos[v1], r = a_pos[v2];
  if (l > r) swap(l, r);
  long long bl = l / block, br = r / block;
  if (bl == br) return a[lca_in_block(bl, l % block, r % block)];
  long long ans1 = lca_in_block(bl, l % block, block - 1);
  long long ans2 = lca_in_block(br, 0, r % block);
  long long ans = min_h(ans1, ans2);
  if (bl < br - 1) {
    long long pw2 = sosos[br - bl - 1];
    long long ans3 = bt[bl + 1][pw2];
    long long ans4 = bt[br - (1 << pw2)][pw2];
    ans = min_h(ans, min_h(ans3, ans4));
  }
  return a[ans];
}
long long height[500000];
bool is_leaf[500000];
long long dist(long long u, long long v) {
  long long L = lca(u, v);
  return height[u] + height[v] - 2 * height[L];
}
vector<long long> pref_rmq[2000000], suff_rmq[2000000];
long long sparse_table[20][500000];
long long min_leaf[500000], max_leaf[500000];
void build_sparces() {
  for (long long i = 0; i < 20; i++) {
    long long S = (1LL << i);
    for (long long j = 0; j + S <= n; j++) {
      long long T = 1e18;
      if (is_leaf[j]) T = height[j];
      if (i == 0)
        sparse_table[i][j] = T;
      else
        sparse_table[i][j] =
            min(sparse_table[i - 1][j], sparse_table[i - 1][j + S / 2]);
    }
  }
}
long long query(long long l, long long r) {
  if (l > r) return 1e18;
  long long kek = sosos[r - l + 1];
  long long res =
      min(sparse_table[kek][l], sparse_table[kek][r + 1 - (1 << kek)]);
  return res;
}
long long Down(long long i, long long l, long long r, long long l1,
               long long r1, long long tp, long long vertex) {
  if (l1 >= r1) return 1e18;
  if (l == l1 && r == r1) {
    if (tp == 0) {
      long long L = lca(vertex, l);
      long long D = dist(vertex, L);
      long long rgt = min(r - 1, max_leaf[L]);
      long long res = query(l, rgt) - height[L] + D;
      if (rgt == r - 1) return res;
      long long index = r - 1 - rgt;
      res = min(res, suff_rmq[i][index] + D - dist(L, l));
      return res;
    }
    long long R = lca(vertex, r - 1);
    long long D = dist(vertex, R);
    long long lgt = max(l, min_leaf[R]);
    long long res = query(lgt, r - 1) - height[R] + D;
    if (lgt == l) return res;
    long long index = lgt - 1 - l;
    res = min(res, pref_rmq[i][index] + D - dist(R, r - 1));
    return res;
  }
  long long mid = (l + r) / 2;
  long long A = Down(2 * i + 1, l, mid, l1, min(r1, mid), tp, vertex);
  long long B = Down(2 * i + 2, mid, r, max(l1, mid), r1, tp, vertex);
  return min(A, B);
}
long long solve(long long vertex, long long l, long long r) {
  if (vertex < r)
    return Down(0, 0, n, l, r + 1, 0, vertex);
  else
    return Down(0, 0, n, l, r + 1, 1, vertex);
}
long long get(long long vertex, long long l, long long r) {
  long long L = max(l, min_leaf[vertex]);
  long long R = min(r, max_leaf[vertex]);
  long long tet = query(L, R) - height[vertex];
  if (L > l) tet = min(tet, solve(vertex, l, min(L - 1, r)));
  if (R < r) tet = min(tet, solve(vertex, max(R + 1, l), r));
  return tet;
}
vector<pair<long long, long long> > data[500000];
void dfs2(long long vertex, long long last) {
  height[vertex] = last;
  for (long long i = 0; i < data[vertex].size(); i++) {
    long long to = data[vertex][i].first;
    dfs2(to, last + data[vertex][i].second);
    max_leaf[vertex] = max(max_leaf[vertex], max_leaf[to]);
  }
  if (data[vertex].size() > 0)
    is_leaf[vertex] = false;
  else {
    max_leaf[vertex] = vertex;
    is_leaf[vertex] = true;
  }
  min_leaf[vertex] = vertex;
}
void construct(long long i, long long l, long long r) {
  long long cur = 1e18;
  for (long long j = r - 1; j >= l; j--) {
    if (is_leaf[j]) cur = min(cur, dist(l, j));
    suff_rmq[i].push_back(cur);
  }
  cur = 1e18;
  for (long long j = l; j < r; j++) {
    if (is_leaf[j]) cur = min(cur, dist(j, r - 1));
    pref_rmq[i].push_back(cur);
  }
  if (r - l == 1) return;
  long long mid = (l + r) / 2;
  construct(2 * i + 1, l, mid);
  construct(2 * i + 2, mid, r);
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  for (long long i = 0; i < MAXN; i++) h[i] = -1;
  for (long long i = 1; i < MAXN; i++) {
    long long lg = 0, now = 1;
    while (now <= i) {
      now *= 2, lg++;
    }
    sosos[i] = lg;
  }
  long long q;
  cin >> n >> q;
  for (long long i = 0; i < n - 1; i++) {
    long long u, v;
    cin >> u >> v;
    g[u - 1].push_back(i + 1);
    data[u - 1].push_back({i + 1, v});
  }
  dfs(0, 0);
  build_lca();
  dfs2(0, 0);
  build_sparces();
  construct(0, 0, n);
  for (long long i = 0; i < q; i++) {
    long long V, L, R;
    cin >> V >> L >> R;
    cout << get(V - 1, L - 1, R - 1) << "\n";
  }
}
