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
/* Codeforces Template */

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

import static java.lang.Math.*;
import static java.util.Arrays.fill;
import static java.util.Arrays.binarySearch;
import static java.util.Arrays.sort;

public class Main {
	
	static long initTime;
	static final Random rnd = new Random(7777L);
	static boolean writeLog = false;
	
	public static void main(String[] args) throws IOException {
		initTime = System.currentTimeMillis();
		try {
			writeLog = "true".equals(System.getProperty("LOCAL_RUN_7777"));
		} catch (SecurityException e) {}
		new Thread(null, new Runnable() {
			public void run() {
				try {
					try {
						if (new File("input.txt").exists())
							System.setIn(new FileInputStream("input.txt"));
					} catch (SecurityException e) {}
					long prevTime = System.currentTimeMillis();
					new Main().run();
					log("Total time: " + (System.currentTimeMillis() - prevTime) + " ms");
					log("Memory status: " + memoryStatus());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}, "1", 1L << 24).start(); 
	}

	void run() throws IOException {
		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		solve();
		out.close();
		in.close();
	}
	
	/*************************************************************** 
	 * Solution
	 **************************************************************/

	int vNum;
	int qNum;
	
	Tree tree;
	int[] deg;
	
	RSQ potencial;
	RSQ[] rsqs;
	
	int rootSum = 0;
	
	int[] branch;
	int[] index;
	int[] size;
	
	void solve() throws IOException  {
		
		vNum = nextInt();
		qNum = nextInt();
		
		tree = new Tree(vNum);
		deg = new int [vNum];
		
		for (int i = 1; i < vNum; i++) {
			int u = nextInt() - 1;
			int v = nextInt() - 1;
			tree.add(u, v);
			tree.add(v, u);
			deg[u]++;
			deg[v]++;
		}

		rsqs = new RSQ [deg[0]];
		potencial = new RSQ(0, vNum);
		size = new int [deg[0]];
		branch = new int [vNum];
		index = new int [vNum];
		
		for (int branch = 0, idx = tree.head[0]; idx != 0; idx = tree.next[idx]) {
			int nv = tree.vert[idx];
			size[branch] = buildBranch(branch, nv, 0, 0);
			rsqs[branch] = new RSQ(0, size[branch] - 1);
			branch++;
		}
		
		for (int q = 0; q < qNum; q++) {
			
			int qt = nextInt();
			int v = nextInt() - 1;
			
			if (qt == 0) {
				
				int x = nextInt();
				int d = nextInt();
				
				if (v == 0) {
					increaseBranches(d, x, -1);
					rootSum += x;
				} else {
					int pos = index[v];
					
					int l = max(0, pos - d);
					int r = min(size[branch[v]] - 1, pos + d);
					rsqs[branch[v]].add(l, r, x);
					
					if (pos < d) {
						increaseBranches(d - pos - 1, x, branch[v]);
						rootSum += x;
					}
					
				}
				
			} else {
				
				if (v == 0) {
					out.println(rootSum);
				} else {
					int pos = index[v];
					out.println(rsqs[branch[v]].sum(pos, pos) + potencial.sum(pos, pos));
				}
				
			}
		}
		
	}
	
	void increaseBranches(int d, int x, int exception) {
		
		int l = 0;
		int rr = d - 1;

		if (l <= rr) {
			int r = min(rr, vNum - 1);
			potencial.add(l, r, x);
			
			if (exception != -1) {
				rsqs[exception].add(l, min(r, size[exception] - 1), -x);
			}
		}
		
	}

	int buildBranch(int branchIdx, int v, int p, int pos) {
		
		branch[v] = branchIdx;
		index[v] = pos;
		
		int size = 1;
		
		for (int idx = tree.head[v]; idx != 0; idx = tree.next[idx]) {
			
			int nv = tree.vert[idx];
			if (nv == p) continue;
			size += buildBranch(branchIdx, nv, v, pos + 1);
		}
		
		return size;
	}

	class Tree {
		int vNum;
		int[] head;
		int[] next;
		int[] vert;
		int cnt = 1;
		
		Tree(int vNum) {
			head = new int [vNum];
			next = new int [2 * vNum - 1];
			vert = new int [2 * vNum - 1];
		}
		
		void add(int u, int v) {
			next[cnt] = head[u];
			vert[cnt] = v;
			head[u] = cnt++;
		}
	}
	
	class RSQ {
		int NEYTRAL = 0, size = 1;
		int[] val, pot, left, right;
		
		RSQ(int l, int r) {
			for (int ln = (r - l + 1); size < ln; size <<= 1);
			val = new int [2 * size];
			pot = new int [2 * size];
			left = new int [2 * size];
			right = new int [2 * size];
			build(1, l, r);
		}

		void build(int v, int l, int r) {
			left[v] = l; right[v] = r;
			if (l != r) {
				build(v << 1, l, (l + r) >> 1);
				build((v << 1) + 1, ((l + r) >> 1) + 1, r);
			}
		}
		
		void add(int l, int r, int v) {
			add(1, l, r, v);
		}
		
		int add(int v, int l, int r, int x) {
			if (l <= left[v] && right[v] <= r)
				pot[v] += x;
			else if (l <= right[v] && left[v] <= r)
				val[v] = add(v << 1, l, r, x) + add((v << 1) + 1, l, r, x);
			return val(v);
		}
		
		int sum(int l, int r) {
			return sum(1, l, r);
		}

		int sum(int v, int l, int r) {
			if (l <= left[v] && right[v] <= r)
				return val(v);
			if (l <= right[v] && left[v] <= r)
				return sum(v << 1, l, r) + sum((v << 1) + 1, l, r) + pot[v] * (min(r, right[v]) - max(l, left[v]) + 1);
			return NEYTRAL;
		}
		
		int val(int v) {
			return val[v] + pot[v] * (right[v] - left[v] + 1);
		}
	}
	
	/*************************************************************** 
	 * Input 
	 **************************************************************/
	BufferedReader in;
	PrintWriter out;
	StringTokenizer st = new StringTokenizer("");
	
	String nextToken() throws IOException {
		while (!st.hasMoreTokens())
			st = new StringTokenizer(in.readLine());
		return st.nextToken();
	}
	
	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}
	
	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}
	
	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}
	
	int[] nextIntArray(int size) throws IOException {
		int[] ret = new int [size];
		for (int i = 0; i < size; i++)
			ret[i] = nextInt();
		return ret;
	}
	
	long[] nextLongArray(int size) throws IOException {
		long[] ret = new long [size];
		for (int i = 0; i < size; i++)
			ret[i] = nextLong();
		return ret;
	}
	
	double[] nextDoubleArray(int size) throws IOException {
		double[] ret = new double [size];
		for (int i = 0; i < size; i++)
			ret[i] = nextDouble();
		return ret;
	}
	
	String nextLine() throws IOException {
		st = new StringTokenizer("");
		return in.readLine();
	}
	
	boolean EOF() throws IOException {
		while (!st.hasMoreTokens()) {
			String s = in.readLine();
			if (s == null)
				return true;
			st = new StringTokenizer(s);
		}
		return false;
	}
	
	/*************************************************************** 
	 * Output 
	 **************************************************************/
	void printRepeat(String s, int count) {
		for (int i = 0; i < count; i++)
			out.print(s);
	}
	
	void printArray(int[] array) {
		if (array == null || array.length == 0)
			return;
		for (int i = 0; i < array.length; i++) {
			if (i > 0) out.print(' ');
			out.print(array[i]);
		}
		out.println();
	}
	
	void printArray(long[] array) {
		if (array == null || array.length == 0)
			return;
		for (int i = 0; i < array.length; i++) {
			if (i > 0) out.print(' ');
			out.print(array[i]);
		}
		out.println();
	}
	
	void printArray(double[] array) {
		if (array == null || array.length == 0)
			return;
		for (int i = 0; i < array.length; i++) {
			if (i > 0) out.print(' ');
			out.print(array[i]);
		}
		out.println();
	}
	
	void printArray(double[] array, String spec) {
		if (array == null || array.length == 0)
			return;
		for (int i = 0; i < array.length; i++) {
			if (i > 0) out.print(' ');
			out.printf(Locale.US, spec, array[i]);
		}
		out.println();
	}
	
	void printArray(Object[] array) {
		if (array == null || array.length == 0)
			return;
		boolean blank = false;
		for (Object x : array) {
			if (blank) out.print(' '); else blank = true;
			out.print(x);
		}
		out.println();
	}
	
	@SuppressWarnings("rawtypes")
	void printCollection(Collection collection) {
		if (collection == null || collection.isEmpty())
			return;
		boolean blank = false;
		for (Object x : collection) {
			if (blank) out.print(' '); else blank = true;
			out.print(x);
		}
		out.println();
	}
	
	/*************************************************************** 
	 * Utility
	 **************************************************************/
	static String memoryStatus() {
		return (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory() >> 20) + "/" + (Runtime.getRuntime().totalMemory() >> 20) + " MB";
	}
	
	static void checkMemory() {
		System.err.println(memoryStatus());
	}
	
	static long prevTimeStamp = Long.MIN_VALUE;
	
	static void updateTimer() {
		prevTimeStamp = System.currentTimeMillis();
	}
	
	static long elapsedTime() {
		return (System.currentTimeMillis() - prevTimeStamp);
	}
	
	static void checkTimer() {
		System.err.println(elapsedTime() + " ms");
	}
	
	static void chk(boolean f) {
		if (!f) throw new RuntimeException("Assert failed");
	}
	
	static void chk(boolean f, String format, Object ... args) {
		if (!f) throw new RuntimeException(String.format(format, args));
	}
	
	static void log(String format, Object ... args) {
		if (writeLog) System.err.println(String.format(Locale.US, format, args));
	}
}
