The Little Elephant loves trees very much, he especially loves root trees.

He's got a tree consisting of n nodes (the nodes are numbered from 1 to n), with root at node number 1. Each node of the tree contains some list of numbers which initially is empty. 

The Little Elephant wants to apply m operations. On the i-th operation (1 ≤ i ≤ m) he first adds number i to lists of all nodes of a subtree with the root in node number ai, and then he adds number i to lists of all nodes of the subtree with root in node bi.

After applying all operations the Little Elephant wants to count for each node i number ci — the number of integers j (1 ≤ j ≤ n; j ≠ i), such that the lists of the i-th and the j-th nodes contain at least one common number.

Help the Little Elephant, count numbers ci for him.

Input

The first line contains two integers n and m (1 ≤ n, m ≤ 105) — the number of the tree nodes and the number of operations. 

Each of the following n - 1 lines contains two space-separated integers, ui and vi (1 ≤ ui, vi ≤ n, ui ≠ vi), that mean that there is an edge between nodes number ui and vi. 

Each of the following m lines contains two space-separated integers, ai and bi (1 ≤ ai, bi ≤ n, ai ≠ bi), that stand for the indexes of the nodes in the i-th operation.

It is guaranteed that the given graph is an undirected tree.

Output

In a single line print n space-separated integers — c1, c2, ..., cn.

Examples

Input

5 1
1 2
1 3
3 5
3 4
2 3


Output

0 3 3 3 3 

Input

11 3
1 2
2 3
2 4
1 5
5 6
5 7
5 8
6 9
8 10
8 11
2 9
3 6
2 8


Output

0 6 7 6 0 2 0 5 4 5 5 
import java.io.*;
import java.util.*;

public class CF157DIV1 {
	FastScanner in;
	PrintWriter out;

	ArrayList<Integer>[] g;
	int[] first, last;
	boolean[] was;
	int it;

	void go(int v) {
		was[v] = true;
		first[v] = it++;
		for (int to = 0; to < g[v].size(); to++)
			if (!was[g[v].get(to)])
				go(g[v].get(to));
		last[v] = it++;
	}

	class SegmentTree {
		int n;
		int[] sum;
		int[] addSongs;

		public SegmentTree(int n) {
			this.n = n;
			sum = new int[4 * n];
			addSongs = new int[4 * n];
		}

		void add(int v, int left, int right, int needL, int needR, int add) {
			if (needL > needR)
				return;
			if (left == needL && right == needR) {
				addSongs[v] += add;
			} else {
				int m = (left + right) / 2;
				add(v * 2 + 1, left, m, needL, Math.min(needR, m), add);
				add(v * 2 + 2, m + 1, right, Math.max(needL, m + 1), needR, add);
			}
			updateSum(v, left, right);
		}

		int get(int v, int left, int right, int needL, int needR) {
			if (needL > needR)
				return 0;
			if (left == needL && right == needR)
				return sum[v];
			if (addSongs[v] > 0)
				return (needR - needL + 1);
			int m = (left + right) / 2;
			return get(v * 2 + 1, left, m, needL, Math.min(needR, m))
					+ get(v * 2 + 2, m + 1, right, Math.max(needL, m + 1),
							needR);
		}

		void updateSum(int v, int l, int r) {
			if (addSongs[v] > 0) {
				sum[v] = r - l + 1;
			} else {
				if (r != l) {
					sum[v] = sum[v * 2 + 1] + sum[v * 2 + 2];
				} else {
					sum[v] = 0;
				}
			}
		}
	}

	ArrayList<Integer>[] another;
	SegmentTree st;
	int[] ans;

	void go2(int v) {
		was[v] = true;
		for (int i = 0; i < another[v].size(); i++) {
			int to = another[v].get(i);
			st.add(0, 0, it - 1, first[to], last[to], 1);
		}
		ans[v] += st.get(0, 0, it - 1, 0, it - 1) / 2 - st.get(0, 0, it - 1, first[v], first[v]);
		for (int i = 0; i < g[v].size(); i++) {
			if (!was[g[v].get(i)])
				go2(g[v].get(i));
		}
		for (int i = 0; i < another[v].size(); i++) {
			int to = another[v].get(i);
			st.add(0, 0, it - 1, first[to], last[to], -1);
		}
	}

	void solve() {
		int n = in.nextInt();
		int m = in.nextInt();
		g = new ArrayList[n];
		for (int i = 0; i < n; i++)
			g[i] = new ArrayList<Integer>();
		for (int i = 0; i < n - 1; i++) {
			int fr = in.nextInt() - 1;
			int to = in.nextInt() - 1;
			g[fr].add(to);
			g[to].add(fr);
		}
		was = new boolean[n];
		first = new int[n];
		last = new int[n];
		go(0);
		st = new SegmentTree(it);
		another = new ArrayList[n];
		for (int i = 0; i < n; i++)
			another[i] = new ArrayList<Integer>();
		for (int i = 0; i < m; i++) {
			int ai = in.nextInt() - 1;
			int bi = in.nextInt() - 1;
			another[ai].add(bi);
			another[bi].add(ai);
			another[ai].add(ai);
			another[bi].add(bi);
		}
		ans = new int[n];
		Arrays.fill(was, false);
		go2(0);
		for (int i = 0; i < n; i++)
			out.print(ans[i] + " ");
	}

	void run() {
		try {
			in = new FastScanner(new File("object.in"));
			out = new PrintWriter(new File("object.out"));

			solve();

			out.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	void runIO() {

		in = new FastScanner(System.in);
		out = new PrintWriter(System.out);

		solve();

		out.close();
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		public FastScanner(File f) {
			try {
				br = new BufferedReader(new FileReader(f));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		public FastScanner(InputStream f) {
			br = new BufferedReader(new InputStreamReader(f));
		}

		String next() {
			while (st == null || !st.hasMoreTokens()) {
				String s = null;
				try {
					s = br.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (s == null)
					return null;
				st = new StringTokenizer(s);
			}
			return st.nextToken();
		}

		boolean hasMoreTokens() {
			while (st == null || !st.hasMoreTokens()) {
				String s = null;
				try {
					s = br.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (s == null)
					return false;
				st = new StringTokenizer(s);
			}
			return true;
		}

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

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

	public static void main(String[] args) {
		new CF157DIV1().runIO();
	}
}