import java.io.*;
import java.math.BigInteger;
import java.util.*;

/*
Прокрастинирую
*/

public class Main {

    static FastReader in;
    static PrintWriter out;
    static Random rand = new Random();
    static final int INF = (int) (1e9 + 10), MOD = (int) (1e9 + 7), LOGN = 20;
    static final long IINF = (long) (2e18 + 10);
    static ArrayList<Edge>[] g;
    static int[] tin, tout;
    static long[] d;
    static ArrayList<Integer> leafs;

    static SegTree st;
    static class SegTree {
        int t_sz;
        long[] t_min, t_add;

        void push(int v) {
            if (t_add[v] != 0) {
                t_min[v * 2 + 1] += t_add[v];
                t_add[v * 2 + 1] += t_add[v];
                t_min[v * 2 + 2] += t_add[v];
                t_add[v * 2 + 2] += t_add[v];
                t_add[v] = 0;
            }
        }
        void pull(int v) {
            t_min[v] = Math.min(t_min[v * 2 + 1], t_min[v * 2 + 2]);
        }

        void build(int v, int tl, int tr) {
            if (tl == tr) {
                t_min[v] = d[leafs.get(tl)];
                return;
            }
            int tm = (tl + tr) / 2;
            build(v * 2 + 1, tl, tm);
            build(v * 2 + 2, tm + 1, tr);
            pull(v);
        }
        void build() {
            t_sz = leafs.size();
            t_min = new long[t_sz * 4];
            t_add = new long[t_sz * 4];
            build(0, 0, t_sz - 1);
        }

        long minOn(int v, int tl, int tr, int l, int r) {
            if (r < tl || l > tr) return IINF;
            if (l <= tl && tr <= r) {
                return t_min[v];
            }
            int tm = (tl + tr) / 2;
            push(v);
            return Math.min(minOn(v * 2 + 1, tl, tm, l, r),
                    minOn(v * 2 + 2, tm + 1, tr, l, r));
        }
        long minOn(int l, int r) {
            return minOn(0, 0, t_sz - 1, l, r);
        }

        void addOn(int v, int tl, int tr, int l, int r, long val) {
            if (r < tl || l > tr) return;
            if (l <= tl && tr <= r) {
                t_min[v] += val;
                t_add[v] += val;
                return;
            }
            int tm = (tl + tr) / 2;
            push(v);
            addOn(v * 2 + 1, tl, tm, l, r, val);
            addOn(v * 2 + 2, tm + 1, tr, l, r, val);
            pull(v);
        }
        void addOn(int l, int r, long val) {
            addOn(0, 0, t_sz - 1, l, r, val);
        }
    }

    static int timer = 0;
    static void dfs1(int v) {
        tin[v] = timer;
        if (g[v].size() == 0) {
            leafs.add(v);
            timer++;
        } else {
            for (Edge e : g[v]) {
                d[e.v] = d[v] + e.w;
                dfs1(e.v);
            }
        }
        tout[v] = timer - 1;
    }

    static void dfs2(int v, long w) {
        st.addOn(0, leafs.size() - 1, w);
        st.addOn(tin[v], tout[v], -w * 2);

        for (Query query : queries[v]) {
            query.ans = st.minOn(query.l, query.r);
        }

        for (Edge e : g[v]) {
            dfs2(e.v, e.w);
        }

        st.addOn(0, leafs.size() - 1, -w);
        st.addOn(tin[v], tout[v], w * 2);
    }

    static int lowerBound(int x) {
        int lb = 0, rb = leafs.size();
        while (lb < rb) {
            int mb = (lb + rb) / 2;
            if (leafs.get(mb) < x) {
                lb = mb + 1;
            } else {
                rb = mb;
            }
        }
        return lb;
    }

    static class Edge {
        int v, w;

        Edge(int v, int w) {
            this.v = v;
            this.w = w;
        }
    }

    static ArrayList<Query>[] queries;
    static class Query {
        int l, r, i;
        long ans;

        Query(int l, int r, int i) {
            this.l = l;
            this.r = r;
            this.i = i;
        }
    }

    static void solve() {
        int n = in.nextInt();
        int q = in.nextInt();

        g = new ArrayList[n];
        Arrays.setAll(g, gg -> new ArrayList<>());
        for (int i = 1; i < n; i++) {
            int p = in.nextInt() - 1;
            int w = in.nextInt();
            g[p].add(new Edge(i, w));
        }

        tin = new int[n];
        tout = new int[n];
        d = new long[n];
        leafs = new ArrayList<>();
        dfs1(0);

        st = new SegTree();
        st.build();

        queries = new ArrayList[n];
        Arrays.setAll(queries, qq -> new ArrayList<>());
        for (int i = 0; i < q; i++) {
            int v = in.nextInt() - 1;
            int l = in.nextInt() - 1;
            int r = in.nextInt() - 1;
            queries[v].add(new Query(lowerBound(l), lowerBound(r + 1) - 1, i));
        }

        dfs2(0, 0);

        long[] ans = new long[q];
        for (int v = 0; v < n; v++) {
            for (Query query : queries[v]) {
                ans[query.i] = query.ans;
            }
        }

        for (int i = 0; i < q; i++) {
            out.println(ans[i]);
        }
    }

    public static void main(String[] args) throws FileNotFoundException, InterruptedException {
        in = new FastReader(System.in);
//        in = new FastReader(new FileInputStream("sometext.txt"));
        out = new PrintWriter(System.out);
//        out = new PrintWriter(new FileOutputStream("sometext.txt"));

        int tests = 1;
//        tests = in.nextInt();

        while (tests-- > 0) {
            Thread thread = new Thread(null, () -> solve(), "Main", 1 << 28);
            thread.start();
            thread.join();
        }

        out.flush();
        out.close();
    }

    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        FastReader(InputStream is) {
            br = new BufferedReader(new InputStreamReader(is));
        }

        Integer nextInt() {
            return Integer.parseInt(next());
        }

        Long nextLong() {
            return Long.parseLong(next());
        }

        Double nextDouble() {
            return Double.parseDouble(next());
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                st = new StringTokenizer(nextLine());
            }
            return st.nextToken();
        }

        String nextLine() {
            String s = "";
            try {
                s = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return s;
        }
    }
}