#define _CRT_SECURE_NO_DEPRECATE
/************************
*创建时间：2019 02 08
*文件类型：源代码文件
*题目来源：CodeForces
*当前状态：已通过
*备忘录：数据结构 可持久化线段树
*作者：HtBest
************************/
#include <stdio.h>
#include <iostream>
#include <string>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <bitset>
// #include <sys/wait.h>
// #include <sys/types.h>
// #include <unistd.h>
using namespace std;
#define MAXN 500010

int n,m,fa[MAXN],son[MAXN],bro[MAXN],fav[MAXN],num[MAXN];
struct NODE 
{
	int lson,rson,lazy;
	long long v;
	void clear(){lson=rson=v=lazy=0;}
	void merge(NODE &a,NODE &b)
	{
		v=min(a.v,b.v);
	}
	void addl(long long x)
	{
		v+=x;
		lazy+=x;
	}
}o[40*MAXN];
struct SegmentTree
{
	int root[MAXN],cnt;
	void clear(){o[root[0]=cnt=0].clear();}
	int copy(NODE &x){o[++cnt]=x;return cnt;}
	void downl(NODE &x)
	{
		if(x.lazy)
		{
			o[x.lson=copy(o[x.lson])].addl(x.lazy);
			o[x.rson=copy(o[x.rson])].addl(x.lazy);
			x.lazy=0;
		}
	}
	void build(int &x,int l,int r)
	{
		o[x=++cnt].clear();
		if(l==r)o[x].v=1e15;
		else 
		{
			int m=(l+r)>>1;
			build(o[x].lson,l,m);
			build(o[x].rson,m+1,r);
			o[x].merge(o[o[x].lson],o[o[x].rson]);
		}
	}
	void update(int &x,int l,int r,int ul,int ur,long long v,int type)
	{
		if(type)x=copy(o[x]);
		if(l>=ul&&r<=ur)o[x].addl(v);
		else 
		{
			int m=(l+r)>>1;
			downl(o[x]);
			if(ul<=m)update(o[x].lson,l,m,ul,ur,v,type);
			if(ur>m)update(o[x].rson,m+1,r,ul,ur,v,type);
			o[x].merge(o[o[x].lson],o[o[x].rson]);
		}
	}
	void query(int &x,int l,int r,int ql,int qr,NODE &q)
	{
		if(l>=ql&&r<=qr)q=o[x];
		else 
		{
			int m=(l+r)>>1;
			downl(o[x]);
			if(qr<=m)query(o[x].lson,l,m,ql,qr,q);
			else if(ql>m)query(o[x].rson,m+1,r,ql,qr,q);
			else 
			{
				NODE a,b;
				query(o[x].lson,l,m,ql,qr,a);
				query(o[x].rson,m+1,r,ql,qr,b);
				q.merge(a,b);
			}
			o[x].merge(o[o[x].lson],o[o[x].rson]);
		}
	}

	
	void build(){clear();build(root[0],1,n);}
	void update(int a,int b,int l,int r,long long v,int type)
	{
		if(l>r)swap(l,r);
		if(type)root[b]=copy(o[root[a]]);
		update(root[b],1,n,l,r,v,type);
	}
	long long query(int version,int l,int r)
	{
		if(l>r)swap(l,r);
		// printf("%d %d\n",l,r);
		NODE ans=NODE();
		query(root[version],1,n,l,r,ans);
		return ans.v;
	}

}seg;
/* Variable explain:
id[i]:dfs序为i的节点标号
*/
void addt(int a,int b,int v)
{
	fa[b]=a;
	bro[b]=son[a];
	son[a]=b;
	fav[b]=v;
}
void read()
{
	int ls1,ls2;
	scanf("%d%d",&n,&m);
	for(int i=2;i<=n;++i)scanf("%d%d",&ls1,&ls2),addt(ls1,i,ls2);
	return;
}
void dfs(int a,int v)
{
	num[a]=1;
	for(int b=son[a];b;b=bro[b])
	{
		dfs(b,v+fav[b]);
		num[a]+=num[b];
	}
	if(!son[a])seg.update(1,1,a,a,-1e15+v,0);
}
void dfs(int a)
{
	seg.update(fa[a],a,1,n,fav[a],1);
	seg.update(a,a,a,a+num[a]-1,-2*fav[a],0);
	for(int b=son[a];b;b=bro[b])
	{
		dfs(b);
	}
}
int main()
{
	// freopen(".in","r",stdin);
	// freopen(".out","w",stdout);
	read();
	seg.build();
	seg.update(0,1,1,1,0,1);
	dfs(1,0);
	dfs(1);
		for(int i=1;i<=n;++i)
		{
			for(int j=1;j<=n;++j)seg.query(i,j,j);
			// puts("");
		}
	while(m--)
	{
		int ls1,ls2,ls3;
		scanf("%d%d%d",&ls1,&ls2,&ls3);
		printf("%I64d\n",seg.query(ls1,ls2,ls3));
	}

		// for(int i=0;i<=1;++i)
		// {
		// 	for(int j=1;j<=n;++j)printf("%d ",seg.query(i,j,j));
		// 	puts("");
		// }
	return 0;
}