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.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;


public class TaskD implements Runnable {
    
    Edge first[];

    class Edge
    {
        int to, w;
        Edge next;
        
        public Edge(int from, int to) {
            // TODO Auto-generated constructor stub
            this.to = to;
            this.w = 0;
            this.next = first[from];
            first[from] = this;
        }
    }
    
    int begin[];
    int end[];
    int current;
    
    private void dfs(int u, int fa) {
        begin[u] = current++;
        for (Edge e = first[u]; e != null; e = e.next) {
            if (e.to != fa) {
                dfs(e.to, u);
            }
        }
        end[u] = current - 1;
    }
    
    int query1[][];
    
    IntervalTree tree;
    
    int ans[];
    
    void count(int u, int fa) {
        
        tree.insert(begin[u], begin[u]);
        if (query1[u].length > 0) {
            tree.insert(begin[u], end[u]);
            for (int x : query1[u]) {
                tree.insert(begin[x], end[x]);
            }
        }
        
        ans[u] = tree.getLength(1) - 1;
        tree.delete(begin[u], begin[u]);

        for (Edge e = first[u]; e != null; e = e.next) {
            if (e.to != fa) {
                count(e.to, u);
            }
        }
        
        if (query1[u].length > 0) {
            tree.delete(begin[u], end[u]);
            for (int x : query1[u]) {
                tree.delete(begin[x], end[x]);
            }
        }
    }

    private void solve() throws IOException {
        int n = nextInt();
        int m = nextInt();
        first = new Edge[n];
        for (int u, v, i = 0; i < n - 1; ++i) {
            u = nextInt();
            v = nextInt();
            --u;
            --v;
            new Edge(u, v);
            new Edge(v, u);
        }
        
        current = 0;
        begin = new int[n];
        end = new int[n];
        dfs(0, -1);
        
        tree = new IntervalTree(n);
        int left[] = new int[m];
        int right[] = new int[m];
        
        int totalEvents[] = new int[n];
        for (int i = 0; i < m; ++i) {
            left[i] = nextInt();
            right[i] = nextInt();
            --left[i];
            --right[i];
            ++totalEvents[left[i]];
            ++totalEvents[right[i]];
        }
        
        query1 = new int[n][];
        for (int i = 0; i < n; ++i) {
            query1[i] = new int[totalEvents[i]];
        }
        
        Arrays.fill(totalEvents, 0);
        for (int i = 0; i < m; ++i) {
            query1[left[i]][totalEvents[left[i]]++] = right[i];
            query1[right[i]][totalEvents[right[i]]++] = left[i];
        }
        
        ans = new int[n];
        count(0, -1);
        
        for (int i = 0; i < n; ++i) {
            if (i > 0) {
                writer.print(" ");
            }
            writer.print(ans[i]);
        }
        
        writer.println();
        
    }

    public static void main(String[] args) {
        new TaskD().run();
    }

    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter writer;

    public void run() {
        try {
            reader = new BufferedReader(new InputStreamReader(System.in));
            tokenizer = null;
            writer = new PrintWriter(System.out);
            solve();
            reader.close();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    String nextToken() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }
}

class IntervalTree {
    
    int cover[];
    int number[];
    int length[];
    final int n;
    
    IntervalTree(int n) {
        this.n = n;
        cover = new int[4 * n + 100];
        number = new int[4 * n + 100];
        length = new int[4 * n + 100];
        buildTree(0, n - 1, 1);
    }
    
    void buildTree(int left, int right, int x) {
        length[x] = right - left + 1;
        if (left < right) {
            int mid = (left + right) >> 1;
            buildTree(left, mid, x * 2);
            buildTree(mid + 1, right, x * 2 + 1);
        }
    }
    
    int getLength(int node) {
        if (cover[node] != 0) {
            return length[node];
        }
        
        return number[node];
    }
    
    void push_up(int x) {
        int least = Math.min(cover[x * 2], cover[x * 2 + 1]);
        cover[x] = least;
        cover[x * 2] -= least;
        cover[x * 2 + 1] -= least;
        number[x] = getLength(x * 2) + getLength(x * 2 + 1);
    }
    
    void push_down(int x) {
        
        if (0 == cover[x]) {
            return;
        }
        
        cover[x * 2] += cover[x];
        cover[x * 2 + 1] += cover[x];
        cover[x] = 0;
    }
    
    void insert(int left, int right, int l, int r, int x) {
        if (l <= left && r >= right) {
            ++cover[x];
            return;
        }
        
        push_down(x);
        int mid = (left + right) >> 1;
        if (l <= mid) insert(left, mid, l, r, x * 2);
        if (r > mid)  insert(mid + 1, right, l, r, x * 2 + 1);
        push_up(x);
    }
    
    void insert(int l, int r) {
        insert(0, n - 1, l, r, 1);
    }
    
    void delete(int l, int r) {
        delete(0, n - 1, l, r, 1);
    }

    void delete(int left, int right, int l, int r, int x) {
        if (l <= left && r >= right) {
            if (cover[x] <= 0) {
                System.err.println("BAD!");
            }
            --cover[x];
            return;
        }
        
        push_down(x);
        int mid = (left + right) >> 1;
        if (l <= mid) delete(left, mid, l, r, x * 2);
        if (r > mid)  delete(mid + 1, right, l, r, x * 2 + 1);
        push_up(x);
    }
}