
import java.io.*;
import java.util.*;

public class C{

	static int n;
	static long INF=(long)1e18;
	static ArrayList<int[]>[]queries,adj;
	static long []ans;
	static int []tin,tout;
	static int timer;
	static SegmentTree tree;
	static void dfsPre(int u,long w) {
		
		tin[u]=timer++;
		
		
		for(int []edge:adj[u]) {
			int v=edge[0];
			dfsPre(v,w+edge[1]);
		}
		tout[u]=timer-1;
		
		tree.init(tin[u], adj[u].size()>0?INF:w);
		
	}
	static void dfs(int u,int w) {
		
		tree.update(tin[u],tout[u],-w);
		tree.update(0, tin[u]-1, w);
		tree.update(tout[u]+1, n-1, w);
		
		for(int []query:queries[u]) {
			int l=query[0],r=query[1],idx=query[2];
			ans[idx]=tree.query(l,r);
		}
		for(int []edge:adj[u]) {
			dfs(edge[0],edge[1]);
		}
	
		tree.update(tin[u],tout[u],w);
		tree.update(0, tin[u]-1, -w);
		tree.update(tout[u]+1, n-1, -w);
		
	}
	
	
	public static void main(String[] args) throws Exception {
		Scanner sc=new Scanner();
		PrintWriter out=new PrintWriter(System.out);
		n=sc.nextInt();
		int q=sc.nextInt();
		queries=new ArrayList[n];
		adj=new ArrayList[n];
		tree=new SegmentTree();
		tin=new int [n];
		tout=new int [n];
		ans=new long [q];
		for(int i=0;i<n;i++) {
			adj[i]=new ArrayList();
			queries[i]=new ArrayList();
		}
		for(int i=1;i<n;i++) {
			adj[sc.nextInt()-1].add(new int [] {i,sc.nextInt()});
		}
		for(int i=0;i<q;i++) {
			queries[sc.nextInt()-1].add(new int [] {sc.nextInt()-1,sc.nextInt()-1,i});
		}
		
		for(int u=0;u<n;u++) {
			for(int []edge:adj[u]) {
				
			}
		}
			
		dfsPre(0, 0);
		dfs(0, 0);
		for(long x:ans)
			out.println(x);
		out.close();

	}
	static class SegmentTree{

		long []min,lazy;
		SegmentTree(){
			min=new long [4*n];
			lazy=new long [4*n];
			Arrays.fill(min, INF);
		}
		public long query(int l, int r) {
			return query(1,0,n-1,l,r);
		}
		long query(int node,int tl,int tr,int l,int r) {
			if(tr<l || r<tl)
				return INF;
			if(tl>=l && tr<=r)
				return min[node];
			int mid=tl+tr>>1,left=node<<1,right=left|1;
			propagate(node);
			return Math.min(query(left,tl,mid,l,r), query(right,mid+1,tr,l,r));
		}
		void propagate(int node) {
			long x=lazy[node];
			int left=node<<1,right=left|1;
			min[left]+=x;
			min[right]+=x;
			lazy[left]+=x;
			lazy[right]+=x;
			lazy[node]=0;
		}
		

		public void update(int l, int r, long v) {
			
			update(1,0,n-1,l,r,v,false);
			
		}
		void init(int l,long v){
			update(1,0,n-1,l,l,v,true);
		}
		void update(int node,int tl,int tr,int l,int r,long v,boolean build){
			if(tr<l || r<tl)
				return;
			if(tl>=l && tr<=r)
			{
				if(build) {
					min[node]=v;
				}
				else
				{
					min[node]+=v;
					lazy[node]+=v;
				}
				
				return;
			}
			int mid=tl+tr>>1,left=node<<1,right=left|1;
			propagate(node);
			update(left,tl,mid,l,r,v,build);
			update(right,mid+1,tr,l,r,v,build);
			min[node]=Math.min(min[left], min[right]);
		}
		
	}
	static class Scanner
	{
		BufferedReader br;
		StringTokenizer st;
		Scanner(){
			br=new BufferedReader(new InputStreamReader(System.in));
		}
		Scanner(String fileName) throws FileNotFoundException{
			br=new BufferedReader(new FileReader(fileName));
		}
		String next() throws IOException {
			while(st==null || !st.hasMoreTokens())
				st=new StringTokenizer(br.readLine());
			return st.nextToken();
		}
		String nextLine() throws IOException {
			return br.readLine();
		}
		int nextInt() throws IOException{
			return Integer.parseInt(next());
		}
		long nextLong()  throws NumberFormatException, IOException {
			return Long.parseLong(next());
		}
		double nextDouble() throws NumberFormatException, IOException {
			return Double.parseDouble(next());
		}
	}
}