#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/priority_queue.hpp>
#include<unordered_map>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
using namespace std;
const int maxn=500500;
typedef long long ll;
inline void up(ll&x,ll y){if(x<y)x=y;}
inline void down(ll&x,ll y){if(x>y)x=y;}
int n,q;
struct T{
    int to,nxt,v;
}way[maxn<<1];
int h[maxn],num;
int vis[maxn],size[maxn];
inline void adde(int x,int y,int v){
     way[++num]=(T){y,h[x],v},h[x]=num;
     way[++num]=(T){x,h[y],v},h[y]=num;
} 
inline void getsize(int x){
    size[x]=vis[x]=1;
    for(int i=h[x];i;i=way[i].nxt)
        if(!vis[way[i].to])
            getsize(way[i].to),size[x]+=size[way[i].to];
    vis[x]=0;
}
int root,rsz;
inline void getrot(int x,int sumsize){
    vis[x]=1;
    int maxsize=0;
    for(int i=h[x];i;i=way[i].nxt)
        if(!vis[way[i].to]){
            getrot(way[i].to,sumsize);
            maxsize=max(maxsize,size[way[i].to]);
        }
    maxsize=max(maxsize,sumsize-size[x]);
    if(maxsize<rsz)root=x,rsz=maxsize;
    vis[x]=0;
}
inline int getroot(int x){
    getsize(x);root=0;rsz=1e9;getrot(x,size[x]);
    return root;
}
ll tree[maxn<<2];
inline void cls(int cur,int l=1,int r=n){
	if(tree[cur]==1e18)return ;
	tree[cur]=1e18;
	if(l==r)return ;
	int mid=l+r>>1;
	cls(cur<<1,l,mid),cls(cur<<1|1,mid+1,r);
}
inline void modify(int cur,int l,int r,int pos,ll v){
	if(l==r)return down(tree[cur],v);
	int mid=l+r>>1;
	if(pos<=mid)modify(cur<<1,l,mid,pos,v);
	else modify(cur<<1|1,mid+1,r,pos,v);
	tree[cur]=std::min(tree[cur<<1],tree[cur<<1|1]);
}
inline void build(int cur,int l,int r){
	if(l==r)return void(tree[cur]=1e18);
	int mid=l+r>>1;
	build(cur<<1,l,mid),build(cur<<1|1,mid+1,r);
	tree[cur]=std::min(tree[cur<<1],tree[cur<<1|1]);
}
inline ll query(int cur,int L,int R,int l,int r){
	if(L <= l && r <= R)return tree[cur];
	int mid=l+r>>1;ll ans=1e18;
	if(L<=mid)down(ans,query(cur<<1,L,R,l,mid));
	if(mid<R)down(ans,query(cur<<1|1,L,R,mid+1,r));
	return ans;
}
inline void dfs(int x,ll sum=0){
	vis[x]=1;
	int lv=x!=1;
	for(int i=h[x];i;i=way[i].nxt)
		if(!vis[way[i].to])
			dfs(way[i].to,sum+way[i].v),lv=0;
	if(lv)modify(1,1,n,x,sum);
	vis[x]=0;
}
struct Q{
	int l,r,id;
	ll ans;
	inline Q(){l=r=id=0,ans=1e18;}
	inline Q(int L,int R,int ID){l=L,r=R,id=ID,ans=1e18;}
};
std::vector<Q> Qu[maxn];
inline void solq(int x,ll sum=0){
	vis[x]=1;
	for(Q&i:Qu[x]){
		down(i.ans,sum+query(1,i.l,i.r,1,n));
	}
	for(int i=h[x];i;i=way[i].nxt)
		if(!vis[way[i].to])
			solq(way[i].to,sum+way[i].v);
	vis[x]=0;
}
inline void dfz(int x){
    x=getroot(x),cls(1),dfs(x),solq(x),vis[x]=1;
    for(int i=h[x];i;i=way[i].nxt)if(!vis[way[i].to])dfz(way[i].to);
}
ll ans[maxn];
template<typename T>inline istream&operator,(istream&cin,T&x){return cin>>x;}
template<typename T>inline ostream&operator,(ostream&cout,const T&x){return cout<<x;}
istream&in=cin;ostream&out=cout;

int main(){
	std::ios::sync_with_stdio(false),std::cin.tie(0);
	in,n,q;
	for(int i=2,x,y,v;i<=n;++i){
		in,y,v;x=i;
		adde(x,y,v);
	}
	for(int i=1,l,r,v;i<=q;++i){
		in,v,l,r;
		Qu[v].emplace_back(l,r,i);
	}
	build(1,1,n);
	dfz(1);
	for(int i=1;i<=n;++i)
		for(Q&j:Qu[i])
			ans[j.id]=j.ans;
	for(int i=1;i<=q;++i)
		out,ans[i],'\n';
} 
