A little girl loves problems on trees very much. Here's one of them.

A tree is an undirected connected graph, not containing cycles. The degree of node x in the tree is the number of nodes y of the tree, such that each of them is connected with node x by some edge of the tree. 

Let's consider a tree that consists of n nodes. We'll consider the tree's nodes indexed from 1 to n. The cosidered tree has the following property: each node except for node number 1 has the degree of at most 2.

Initially, each node of the tree contains number 0. Your task is to quickly process the requests of two types:

  * Request of form: 0 v x d. In reply to the request you should add x to all numbers that are written in the nodes that are located at the distance of at most d from node v. The distance between two nodes is the number of edges on the shortest path between them. 
  * Request of form: 1 v. In reply to the request you should print the current number that is written in node v. 

Input

The first line contains integers n (2 ≤ n ≤ 105) and q (1 ≤ q ≤ 105) — the number of tree nodes and the number of requests, correspondingly.

Each of the next n - 1 lines contains two integers ui and vi (1 ≤ ui, vi ≤ n, ui ≠ vi), that show that there is an edge between nodes ui and vi. Each edge's description occurs in the input exactly once. It is guaranteed that the given graph is a tree that has the property that is described in the statement.

Next q lines describe the requests.

  * The request to add has the following format: 0 v x d (1 ≤ v ≤ n, 1 ≤ x ≤ 104, 1 ≤ d < n). 
  * The request to print the node value has the following format: 1 v (1 ≤ v ≤ n). 



The numbers in the lines are separated by single spaces.

Output

For each request to print the node value print an integer — the reply to the request.

Examples

Input

3 6
1 2
1 3
0 3 1 2
0 2 3 1
0 1 5 2
1 1
1 2
1 3


Output

9
9
6


Input

6 11
1 2
2 5
5 4
1 6
1 3
0 3 1 3
0 3 4 5
0 2 1 4
0 1 5 5
0 4 6 2
1 1
1 2
1 3
1 4
1 5
1 6


Output

11
17
11
16
17
11
import static java.lang.Math.*;

import java.io.*;
import java.lang.reflect.*;
import java.util.*;

public class E {

	public E () {
		int N = sc.nextInt(), M = N-1;
		int Q = sc.nextInt();
		Integer [][] E = sc.nextInts(M);

		int [][] G = graph(N, E);
		int D = G[0].length;
		
		int [] Z = new int[D];
		int [] K = new int [N], L = new int [N]; K[0] = L[0] = -1;
		for (int i : rep(D)) {
			int V = G[0][i], W = 0;
			for(;;) {
				K[V] = i; L[V] = Z[i]++; 
				if (G[V].length == 1)
					break;
				int j = G[V][0] == W ? 1 : 0;
				W = V; V = G[V][j];  
			}
		}
		
		Node R = new Node(0, N);
		Node [] Y = new Node [D];
		for (int i : rep(D))
			Y[i] = new Node(0, Z[i]);
		
		for (@SuppressWarnings("unused") int q : rep(Q))
			switch(sc.nextInt()) {
			case 0: {
				int v = sc.nextInt() - 1;
				int x = sc.nextInt();
				int d = sc.nextInt();
				
				if (v != 0) {					
					int i = K[v], j = L[v];
					int to = min(Z[i], j + d + 1), from, r;
					if (j - d >= 0) {
						from = j - d; r = 0;
					} else
						r = 1 + (from = d - j - 1);
					
					if (from < to)
						Y[i].add(x, from, to);
					
					if (r > 0)
						R.add(x, 0, r);
				} else
					R.add(x, 0, d + 1);
				
				break;
			}
			case 1: {
				int v = sc.nextInt() - 1; long res;
				if (v != 0) {
					int i = K[v], j = L[v];
					res = Y[i].get(j) + R.get(j+1);
				} else
					res = R.get(0);
				print(res);					
			}
			}
	}
	
	int [][] graph (int N, Integer [][] E) {
		int [] D = new int [N];
		for (Integer [] e : E) {
			int x = e[0] - 1, y = e[1] - 1;
			++D[x]; ++D[y];
		}
		
		int [][] res = new int [N][];
		for (int i = 0; i < N; ++i)
			res[i] = new int [D[i]];
		
		D = new int [N];
		for (Integer [] e : E) {
			int x = e[0] - 1, y = e[1] - 1;
			res[x][D[x]++] = y;
			res[y][D[y]++] = x;
		}
		
		return res;
	}
	
	static class Node {
		final Node L, R;
		final int from, to, m;
		long X = 0;
		
		Node(int from, int to) {
			assert(from < to);
			this.from = from;
			this.to = to;
			m = (from + to) / 2;
			if (m > from) {
				L = new Node(from, m);
				R = new Node(m, to);
			} else
				L = R = null;
		}
		
		void add(int X, int from, int to) {
			assert(from >= this.from && to <= this.to && from < to);
			if (from == this.from && to == this.to)
				this.X += X;
			else {
				if (from < m)
					L.add(X, from, min(to, m));
				if (to > m)
					R.add(X, max(from, m), to);
			}
		}
		
		long get(int V) {
			assert(from <= V && V < to);
			long res = X;
			if (V < m)
				res += L.get(V);
			if (V >= m && m > from)
				res += R.get(V);
			return res;
		}
	}
	
	////////////////////////////////////////////////////////////////////////////////////

	static int [] rep(int N) { return rep(0, N); }
	static int [] rep(int S, int T) { int [] res = new int [T-S]; for (int i = S; i < T; ++i) res[i-S] = i; return res; }
	static int [] req(int S, int T) { return rep(S, T+1); }	
	
	////////////////////////////////////////////////////////////////////////////////////

	/* Dear hacker, don't bother reading below this line, unless you want to help me debug my I/O routines :-) */
	
	static MyScanner sc = new MyScanner();
	
	static class MyScanner {
		public String next() {
			newLine();
			return line[index++];
		}
		
		public char nextChar() {
			return next().charAt(0);
		}
				
		public int nextInt() {
			return Integer.parseInt(next());
		}
		
		public long nextLong() {
			return Long.parseLong(next());
		}
		
		public double nextDouble() {
			return Double.parseDouble(next());
		}
		
		public String nextLine() {
			line = null;
			return readLine();
		}
		
		public String [] nextStrings() {
			line = null;
			return readLine().split(" ");
		}
		
		public char [] nextChars() {
			return next().toCharArray();
		}

		public Integer [] nextInts() {
			String [] L = nextStrings();
			Integer [] res = new Integer [L.length];
			for (int i = 0; i < L.length; ++i)
				res[i] = Integer.parseInt(L[i]);
			return res;
		}	
		
		public Long [] nextLongs() {
			String [] L = nextStrings();
			Long [] res = new Long [L.length];
			for (int i = 0; i < L.length; ++i)
				res[i] = Long.parseLong(L[i]);
			return res;
		}

		public Double [] nextDoubles() {
			String [] L = nextStrings();
			Double [] res = new Double [L.length];
			for (int i = 0; i < L.length; ++i)
				res[i] = Double.parseDouble(L[i]);
			return res;
		}

		public String [] next (int N) {
			String [] res = new String [N];
			for (int i = 0; i < N; ++i)
				res[i] = sc.next();
			return res;
		}
		
		public Integer [] nextInt (int N) {
			Integer [] res = new Integer [N];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextInt();
			return res;
		}		
		
		public Long [] nextLong (int N) {
			Long [] res = new Long [N];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextLong();
			return res;
		}		
		
		public Double [] nextDouble (int N) {
			Double [] res = new Double [N];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextDouble();
			return res;
		}		
		
		public String [][] nextStrings (int N) {
			String [][] res = new String [N][];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextStrings();
			return res;
		}
		
		public Integer [][] nextInts (int N) {
			Integer [][] res = new Integer [N][];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextInts();
			return res;
		}
		
		public Long [][] nextLongs (int N) {
			Long [][] res = new Long [N][];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextLongs();
			return res;
		}
		
		public Double [][] nextDoubles (int N) {
			Double [][] res = new Double [N][];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextDoubles();
			return res;
		}
		
		//////////////////////////////////////////////
		
		private boolean eol() {
			return index == line.length;
		}

		private String readLine() {
			try {
				return r.readLine();
			} catch (Exception e) {
				throw new Error(e);
			}
		}
		private final BufferedReader r;

		MyScanner () {
			this(new BufferedReader(new InputStreamReader(System.in)));
		}
		
		MyScanner(BufferedReader r) {
			try {
				this.r = r;
				while (!r.ready())
					Thread.sleep(1);
				start();
			} catch (Exception e) {
				throw new Error(e);
			}
		}
		
		private String [] line;
		private int index;

		private void newLine() {
			if (line == null || eol()) {
				line = readLine().split(" ");
				index = 0;
			}
		}		
	}
	
	static void print(Object o, Object... a) {
		printDelim(" ", o, a);
	}
	
	static void cprint(Object o, Object... a) {
		printDelim("", o, a);
	}
	
	static void printDelim (String delim, Object o, Object... a) {
		pw.println(build(delim, o, a));
	}

	static void exit (Object o, Object... a) {
		print(o, a);
		exit();
	}

	static void exit () {
		pw.close();
		System.out.flush();
		System.err.println("------------------");
		System.err.println("Time: " + ((millis() - t) / 1000.0));
		System.exit(0);
	}
	
	void NO() {
		throw new Error("NO!");
	}
	
	////////////////////////////////////////////////////////////////////////////////////
	
	static String build(String delim, Object o, Object... a) {
		StringBuilder b = new StringBuilder();
		append(b, o, delim);
		for (Object p : a)
			append(b, p, delim);
		return b.toString().trim();		
	}
	
	static void append(StringBuilder b, Object o, String delim) {
		if (o.getClass().isArray()) {
			int L = Array.getLength(o);
			for (int i = 0; i < L; ++i)
				append(b, Array.get(o, i), delim);
		} else if (o instanceof Iterable<?>) {
			for (Object p : (Iterable<?>)o)
				append(b, p, delim);
		} else
			b.append(delim).append(o);		
	}
	
	////////////////////////////////////////////////////////////////////////////////////
	
	public static void main(String[] args) {
		new E();
		exit();
	}

	static void start() {
		t = millis();
	}

	static PrintWriter pw = new PrintWriter(System.out);
	
	static long t;
	
	static long millis() {
		return System.currentTimeMillis();
	}	
}
