Problem:
Max Score: 1450 Points

Problem Statement

There are N workers in Atcoder company. Each worker is numbered 0 through N - 1, and the boss for worker i is p_i like a tree structure and the salary is currently a_i. (p_i < i, especially p_0 = -1 because worker 0 is a president)

In atcoder, the boss of boss of boss of ... (repeated k times) worker i called "k-th upper boss", and "k-th lower subordinate" called for vice versa.

You have to process Q queries for Atcoder:

Query 1: You are given v_i, d_i, x_i. Increase the salary of worker v_i, and all j-th (1 ≤ j ≤ d_i) lower subordinates by x_i.

Query 2: You are given v_i, d_i. Calculate the sum of salary of worker v_i and all j-th (1 ≤ j ≤ d_i) lower subordinates.

Query 3: You are given pr_i, ar_i. Now Atcoder has a new worker c! (c is the current number of workers) The boss is pr_i, and the first salary is ar_i.

Process all queries!!!

Input Format

Let the i-th query query_i, the input format is following:

N Q
p_0 a_0
p_1 a_1
: :
p_{N - 1} a_{N - 1}
query_0
query_1
: :
query_{Q - 1}

THe format of query_i is one of the three format:

1 v_i d_i x_i

2 v_i d_i

3 pr_i ar_i

Output Format

Print the result in one line for each query 2.

Constraints

N ≤ 400000

Q ≤ 50000

p_i < i for all valid i.

In each question 1 or 2, worker v_i exists.

d_i ≤ 400000

0 ≤ a_i, x_i ≤ 1000

Scoring

Subtask 1 [170 points]

N, Q ≤ 5000

Subtask 2 [310 points]

p_i + 1 = i for all valid i.

Subtask 3 [380 points]

There are no query 3.

Subtask 4 [590 points]

There are no additional constraints.

Sample Input 1

6 7
-1 6
0 5
0 4
2 3
2 2
1 1
2 0 1
1 0 2 1
2 2 1
3 3 3
2 0 3
3 3 4
2 1 1

Sample Output 1

15
12
30
8

Sample Input 2

7 9
-1 1
0 5
0 7
0 8
1 3
4 1
5 1
2 1 1
2 1 2
1 1 2 3
1 4 1 1
2 3 1
2 0 2
3 6 1
3 7 11
2 0 15

Sample Output 2

8
9
8
31
49

Solution in C# (Mono 4.6.2.0) (judge verdict: Runtime Error)

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Globalization;
using System.Diagnostics;
using static System.Console;
using Pair = System.Collections.Generic.KeyValuePair<int, int>;

class Program
{
    static void Main()
    {
        SetOut(new StreamWriter(OpenStandardOutput()) { AutoFlush = false });
        new Program().Solve();
        Out.Flush();
    }
    Scanner cin = new Scanner();
    Random rnd = new Random();
    Stopwatch sw = new Stopwatch();
    readonly int[] dd = { 0, 1, 0, -1, 0 };
    readonly int mod = 1000000007;
    readonly string alfa = "abcdefghijklmnopqrstuvwxyz";


    List<int>[] G;
    int[] M;
    int N;
    long sum;
    void Solve()
    {
        N = cin.Nextint;
        int Q = cin.Nextint;
        M = new int[N + Q];
        G = Enumerable.Range(0, N + Q).Select(i => new List<int>()).ToArray();
        bool flag = true;
        for (int i = 0; i < N; i++)
        {
            int p = cin.Nextint;
            if (p != i - 1) flag = false;
            int a = cin.Nextint;
            M[i] = a;
            if (p == -1) continue;
            G[p].Add(i);
        }

        if (flag)
        {
            var T = N + Q;
            var E = new int[T];
            for (int i = 0; i < Q; i++)
            {
                int q = cin.Nextint;
                if (q == 1)
                {
                    int v = cin.Nextint;
                    int d = cin.Nextint;
                    int x = cin.Nextint;
                    E[v] += x;
                    E[v + d + 1] -= x;//ここや
                }
                else if (q == 2)
                {
                    int v = cin.Nextint;
                    int d = cin.Nextint;
                    sum = 0;
                    for (int j = 0; j < T; j++)
                    {
                        if (v + d < j) continue;
                        if(j != 0)
                        {
                            E[j] += E[j - 1];
                        }
                        if (v <= j && j <= v + d)
                        {
                            sum += E[j] + M[j];//ここのMが配列外参照しそう
                        }
                    }
                    WriteLine(sum);
                    E = new int[T];
                }
                else
                {
                    int pr = cin.Nextint;
                    int ar = cin.Nextint;
                    M[N] = ar;
                    N++;
                }
            }
            return;
        }


          

        for (int i = 0; i < Q; i++)
        {
            int q = cin.Nextint;
            if (q == 1)
            {
                int v = cin.Nextint;
                int d = cin.Nextint;
                int x = cin.Nextint;
                Dfsmore(0, v, d, x);
            }
            else if (q == 2)
            {
                int v = cin.Nextint;
                int d = cin.Nextint;
                sum = 0;
                Dfssum(0, v, d);
                WriteLine(sum);
            }
            else
            {
                int pr = cin.Nextint;
                int ar = cin.Nextint;
                M[N] = ar;
                G[pr].Add(N);
                N++;
            }
        }
    }
    void Dfsmore(int depth, int u, int d, int x)
    {
        if (depth <= d)
        {
            M[u] += x;
        }
        if (depth == d) return;
        foreach (var v in G[u])
        {
            Dfsmore(depth + 1, v, d, x);
        }
    }
    void Dfssum(int depth, int u, int d)
    {
        if (depth <= d)
        {
            sum += M[u];
        }
        if (depth == d) return;
        foreach (var v in G[u])
        {
            Dfssum(depth + 1, v, d);
        }
    }
}


class Scanner
{
    string[] s; int i;
    char[] cs = new char[] { ' ' };
    public Scanner() { s = new string[0]; i = 0; }
    public string[] Scan { get { return ReadLine().Split(); } }
    public int[] Scanint { get { return Array.ConvertAll(Scan, int.Parse); } }
    public long[] Scanlong { get { return Array.ConvertAll(Scan, long.Parse); } }
    public double[] Scandouble { get { return Array.ConvertAll(Scan, double.Parse); } }
    public string Next
    {
        get
        {
            if (i < s.Length) return s[i++];
            string st = ReadLine();
            while (st == "") st = ReadLine();
            s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 0;
            return Next;
        }
    }
    public int Nextint { get { return int.Parse(Next); } }
    public long Nextlong { get { return long.Parse(Next); } }
    public double Nextdouble { get { return double.Parse(Next); } }
}