#include <bits/stdc++.h>
using namespace std;
inline int nxt() {
  int x;
  scanf("%d", &x);
  return x;
}
struct Edge {
  int to;
  long long w;
};
const int N = 511111;
const int L = 20;
const long long inf = LLONG_MAX / 10;
vector<Edge> a[N];
int tin[N], tout[N];
int par[N][L];
int actual_level[N];
long long level[N];
long long minlevel[N];
vector<int> order;
array<long long, L> ml_lr[N], ml_l[N], ml_r[N];
void dfs(int v) {
  tin[v] = order.size();
  order.push_back(v);
  minlevel[v] = inf;
  if (a[v].empty()) {
    minlevel[v] = level[v];
  }
  for (auto e : a[v]) {
    level[e.to] = level[v] + e.w;
    actual_level[e.to] = actual_level[v] + 1;
    par[e.to][0] = v;
    dfs(e.to);
    minlevel[v] = min(minlevel[v], minlevel[e.to]);
  }
  tout[v] = order.size();
}
bool isPar(int u, int v) { return tin[u] <= tin[v] && tout[u] >= tout[v]; }
int lca(int u, int v) {
  if (isPar(v, u)) {
    return v;
  }
  for (int i = L - 1; i >= 0; --i) {
    if (!isPar(par[v][i], u)) {
      v = par[v][i];
    }
  }
  return par[v][0];
}
int almost(int u, int v) {
  int cnt = actual_level[u] - actual_level[v];
  cnt -= 1;
  for (int i = 0; i < L; ++i) {
    if (cnt & (1 << i)) {
      u = par[u][i];
    }
  }
  return u;
}
long long roflanLevels[N][L];
long long getMin(int l, int r) {
  int len = r - l;
  int idx = 31 - __builtin_clz(len);
  return min(roflanLevels[l][idx], roflanLevels[r - (1 << idx)][idx]);
}
long long getUp(int v, int cnt, array<long long, L>* dp) {
  long long res = inf;
  for (int i = L - 1; i >= 0; --i) {
    if (cnt & (1 << i)) {
      res = min(res, dp[v][i]);
      v = par[v][i];
    }
  }
  return res;
}
int nx_leaf[N], pr_leaf[N];
int main() {
  mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  int n = nxt(), q = nxt();
  for (int i = 0; i < n - 1; ++i) {
    int u = nxt() - 1, v = i + 1;
    a[u].push_back({v, nxt()});
  }
  dfs(0);
  for (int i = 1; i < L; ++i) {
    for (int j = 0; j < n; ++j) {
      par[j][i] = par[par[j][i - 1]][i - 1];
    }
  }
  for (int i = 0; i < n; ++i) {
    if (a[i].empty()) {
      pr_leaf[i] = i;
    } else {
      if (i) {
        pr_leaf[i] = pr_leaf[i - 1];
      }
    }
  }
  for (int i = n - 1; i >= 0; --i) {
    if (a[i].empty()) {
      nx_leaf[i] = i;
    } else {
      nx_leaf[i] = nx_leaf[i + 1];
    }
  }
  for (int i = 0; i < n; ++i) {
    ml_lr[i][0] = minlevel[i] - 2 * level[i];
  }
  vector<int> last_son(n, -1);
  for (int i = 1; i < n; ++i) {
    int son = last_son[par[i][0]];
    last_son[par[i][0]] = i;
    if (son == -1) {
      ml_r[i][0] = inf;
    } else {
      ml_r[i][0] = max(ml_r[son][0], ml_lr[son][0]);
    }
  }
  last_son.assign(n, -1);
  for (int i = n - 1; i > 0; --i) {
    int son = last_son[par[i][0]];
    last_son[par[i][0]] = i;
    if (son == -1) {
      ml_l[i][0] = inf;
    } else {
      ml_l[i][0] = max(ml_l[son][0], ml_lr[son][0]);
    }
  }
  for (int i = 1; i < L; ++i) {
    for (int j = 0; j < n; ++j) {
      ml_lr[j][i] = min(ml_lr[j][i - 1], ml_lr[par[j][i - 1]][i - 1]);
      ml_l[j][i] = min(ml_l[j][i - 1], ml_l[par[j][i - 1]][i - 1]);
      ml_r[j][i] = min(ml_r[j][i - 1], ml_r[par[j][i - 1]][i - 1]);
    }
  }
  for (int i = 0; i < n; ++i) {
    if (a[i].empty()) {
      roflanLevels[i][0] = level[i];
    } else {
      roflanLevels[i][0] = inf;
    }
  }
  for (int i = 1; i < L; ++i) {
    int st = (1 << (i - 1));
    for (int j = 0; j + st * 2 <= n; ++j) {
      roflanLevels[j][i] =
          min(roflanLevels[j][i - 1], roflanLevels[j + st][i - 1]);
    }
  }
  while (q--) {
    int v = order[nxt() - 1];
    int lb = nxt() - 1, rb = nxt() - 1;
    lb = nx_leaf[order[lb]];
    rb = pr_leaf[order[rb]];
    int l = lca(lb, rb);
    int l1 = lca(lb, v);
    int r1 = lca(rb, v);
    long long ans =
        level[v] + getMin(tin[lb], tin[rb] + 1) - 2 * level[lca(l1, l)];
    if (!isPar(l, v)) {
    } else if (l != l1) {
      if (tin[v] >= tin[lb])
        ans = min(ans, level[v] +
                           getUp(v, actual_level[v] - actual_level[l1], ml_lr));
      ans = min(ans, level[v] + getMin(lb, tout[l1]) - 2 * level[l1]);
      ans = min(ans,
                level[v] + getUp(l1, actual_level[l1] - actual_level[l], ml_l));
    } else if (l != r1) {
      if (tin[v] <= tin[rb])
        ans = min(ans, level[v] +
                           getUp(v, actual_level[v] - actual_level[r1], ml_lr));
      ans = min(ans, level[v] + getMin(tin[r1], rb + 1) - 2 * level[r1]);
      ans = min(ans,
                level[v] + getUp(r1, actual_level[r1] - actual_level[l], ml_r));
    } else {
      if (tin[v] >= tin[lb] && tin[v] <= tin[rb])
        ans = min(
            ans, level[v] + getUp(v, actual_level[v] - actual_level[l], ml_lr));
    }
    printf("%lld\n", ans);
  }
  return 0;
}
