#include <bits/stdc++.h>
using namespace std;
const long long N = 5e5 + 36;
const long long M = 11;
const long long INF = 1e18;
const long long MOD = 987654323;
const long long MOD1 = 1e9 + 7;
const long long MOD2 = 1e9 + 9;
const int XK[4] = {-1, 0, 1, 0};
const int YK[4] = {0, -1, 0, 1};
const int X[8] = {1, 1, -1, -1, 2, 2, -2, -2};
const int Y[8] = {2, -2, 2, -2, 1, -1, 1, -1};
int sz[N], n, q, st = 1;
long long otvety[N], jirna[N << 2], t[N << 2];
vector<pair<int, int> > grapth[N];
vector<pair<pair<int, int>, int> > vse[N];
inline void push(int v) {
  t[v << 1] += jirna[v];
  t[(v << 1) + 1] += jirna[v];
  jirna[v << 1] += jirna[v];
  jirna[(v << 1) + 1] += jirna[v];
  jirna[v] = 0;
  return;
}
int rnd() { return (rand() << 16) ^ rand(); }
class treap {
 public:
  int sze, pr, key;
  treap *l, *r;
  treap(int x) {
    sze = 1;
    pr = rnd();
    this->key = x;
    l = r = nullptr;
  }
};
void update(treap* z) {
  if (z == nullptr) return;
  z->sze = 1;
  if (z->l) z->sze += z->l->sze;
  if (z->r) z->sze += z->r->sze;
}
int lsze(treap* z) {
  int aa = 1;
  if (z == nullptr) return 0;
  if (z->l == nullptr) return 1;
  aa += z->l->sze;
  return aa;
}
void split(treap* t, treap*& l, treap*& r, int k) {
  if (t == nullptr) {
    r = l = nullptr;
    return;
  }
  if (lsze(t) <= k) {
    l = t;
    split(t->r, l->r, r, k - lsze(t));
  } else {
    r = t;
    split(t->l, l, r->l, k);
  }
  update(l);
  update(r);
}
void merch(treap* l, treap* r, treap*& t) {
  if (l == nullptr) {
    t = r;
    return;
  }
  if (r == nullptr) {
    t = l;
    return;
  }
  if (l->pr > r->pr) {
    t = l;
    merch(l->r, r, t->r);
  } else {
    t = r;
    merch(l, r->l, t->l);
  }
  update(t);
}
void write(treap* t) {
  if (t == nullptr) {
    return;
  }
  write(t->l);
  cout << t->key << ' ';
  write(t->r);
}
inline void obnovit(int v, int cl, int cr, int l, int r, long long x) {
  if (cl > r || cr < l) return;
  if (cl >= l && cr <= r) {
    t[v] += x;
    jirna[v] += x;
    return;
  }
  push(v);
  int mid = (cl + cr) >> 1;
  obnovit(v << 1, cl, mid, l, r, x);
  obnovit((v << 1) + 1, mid + 1, cr, l, r, x);
  t[v] = min(t[v << 1], t[(v << 1) + 1]);
  return;
}
inline long long query(int v, int cl, int cr, int l, int r) {
  if (cl > r || cr < l) return INF;
  if (cl >= l && cr <= r) return t[v];
  push(v);
  int mid = (cl + cr) >> 1;
  return min(query(v << 1, cl, mid, l, r),
             query((v << 1) + 1, mid + 1, cr, l, r));
}
inline long long query(int l, int r) { return query(1, 0, st - 1, l, r); }
inline void obnovit(int l, int r, long long x) {
  obnovit(1, 0, st - 1, l, r, x);
  return;
}
inline void dfs(int v, int pr, long long cur = 0) {
  sz[v] = 1;
  for (auto to : grapth[v]) {
    if (to.first == pr) {
      continue;
    }
    dfs(to.first, v, cur + to.second);
    sz[v] += sz[to.first];
  }
  if (grapth[v].size() == 1) {
    obnovit(v, v, cur - INF);
  }
  return;
}
inline void dobavit(int x, int y) {
  obnovit(0, x - 1, y);
  obnovit(x + sz[x], N, y);
  obnovit(x, x + sz[x] - 1, -y);
  return;
}
inline void udalit(int x, int y) {
  obnovit(0, x - 1, -y);
  obnovit(x + sz[x], N, -y);
  obnovit(x, x + sz[x] - 1, y);
  return;
}
inline void dfs1(int v, int pr) {
  for (auto x : vse[v]) {
    int l = x.first.first, r = x.first.second, id = x.second;
    otvety[id] = query(l, r);
  }
  for (auto to : grapth[v]) {
    if (to.first == pr) {
      continue;
    }
    dobavit(to.first, to.second);
    dfs1(to.first, v);
    udalit(to.first, to.second);
  }
  return;
}
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> q;
  while (st < n) {
    st <<= 1;
  }
  for (int i(0); i < st * 2; ++i) {
    t[i] = INF;
  }
  int p, w;
  for (int i(0); i < n - 1; ++i) {
    cin >> p >> w;
    grapth[p - 1].push_back({i + 1, w});
    grapth[i + 1].push_back({p - 1, w});
  }
  dfs(0, -1);
  for (int i(0); i < q; ++i) {
    int ask, l, r;
    cin >> ask >> l >> r;
    vse[ask - 1].push_back({{l - 1, r - 1}, i});
  }
  dfs1(0, -1);
  for (int i(0); i < q; ++i) cout << otvety[i] << '\n';
  return 0;
}
