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.InputStreamReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.math.BigDecimal;
import java.util.Arrays;
import java.io.BufferedWriter;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.io.Writer;
import java.util.StringTokenizer;
import java.math.BigInteger;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		TaskE solver = new TaskE();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskE {
	public void solve(int testNumber, InputReader in, OutputWriter out) {
        n = in.nextInt();
        int q = in.nextInt();
        g = new ArrayList[n];
        qu = new ArrayList[n];
        int i,j,k;
        for(i=0;i<n;++i) g[i] = new ArrayList<Integer>();
        for(i=0;i<n;++i) qu[i] = new ArrayList<Integer>();
        for(k=0;k<n-1;++k){
            i = in.nextInt()-1;
            j = in.nextInt()-1;
            g[i].add(j);
            g[j].add(i);
        }
        
        tin = new int[n];
        Arrays.fill(tin, -1);
        tout = new int[n];
        tm = 0;
        t = new int[n*2];
        
        dfs(0);
        //for(i=0;i<n*2;++i) out.write(t[i]+1,' '); out.writeln();
        
        a = new int[q];
        b = new int[q];
        for(k=0;k<q;++k){
            a[k] = in.nextInt()-1;
            b[k] = in.nextInt()-1;
            qu[a[k]].add(k);
            qu[b[k]].add(k);
        }
        s = new DataStruct.SegmentTreeMinSegAdd(new int[n*2]);
        w = new boolean[n];
        ans = new int[n];
        
        go(0);
        
        for(i=0;i<n;++i) out.write(ans[i]==0 ? 0 : ans[i]/2-1,' '); out.writeln();
	}
    
    DataStruct.SegmentTreeMinSegAdd s;
    int ans[];
    boolean w[];
    void go(int v){
        w[v] = true;
        for(int x : qu[v]){
            s.addRange(tin[a[x]], tout[a[x]], 1);
            s.addRange(tin[b[x]], tout[b[x]], 1);
        }
        
        int call[] = s.getMinimum(0, n*2-1);
        if(call[0]==0) ans[v] = n*2 - call[1]; else ans[v] = n*2;
       // System.out.println((v+1)+": "); for(int i=0;i<n*2;++i) System.out.print(z.getSum(i,i)+" "); System.out.println();
        
        for(int u : g[v]) if(!w[u]){
            go(u);
        }

        for(int x : qu[v]){
            s.addRange(tin[a[x]], tout[a[x]], -1);
            s.addRange(tin[b[x]], tout[b[x]], -1);
        }
    }
    
    ArrayList<Integer> qu[];
    
    int a[], b[];
    int tm, tin[], tout[], t[];
    int n;
    ArrayList<Integer> g[];
    
    void dfs(int v){
        t[tm] = v;
        tin[v] = tm++;
        for(int u : g[v]){
            if(tin[u]==-1) dfs(u);
        }
        t[tm] = v;
        tout[v] = tm++;
    }
}

class InputReader{
    private BufferedReader reader;
    private StringTokenizer tokenizer;

    public InputReader(InputStream stream){
        reader = new BufferedReader(new InputStreamReader(stream));
        tokenizer = null;
    }
    
    public String next(){
        while (tokenizer == null || !tokenizer.hasMoreTokens()){
            try{
                tokenizer = new StringTokenizer(reader.readLine());
            }catch (IOException e){
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }
    
    public int nextInt(){
        return Integer.parseInt(next());
    }

    }

class OutputWriter{
    private PrintWriter out;

    public OutputWriter(Writer out){
        this.out = new PrintWriter(out);
    }

    public OutputWriter(OutputStream out){
        this.out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(out)));
    }

    public void write(Object ... o){
        for(Object x : o) out.print(x);
    }

    public void writeln(Object ... o){
        write(o);
        out.println();
    }

    public void close(){
        out.close();
    }
}

class DataStruct {
    
    
    

    public static class SegmentTreeMinSegAdd{
        private int t[];
        private int cnt[];
        private int add[];
        int d;

        public SegmentTreeMinSegAdd(int[] array){
            int n = array.length, i;
            for(d=1; d<n; d<<=1);
            t = new int[d<<1];
            add = new int[d<<1];
            cnt = new int[d<<1];
            for(i=d; i<n+d; ++i){ t[i] = array[i-d]; cnt[i] = 1; }
            for(i=n+d; i<d+d; ++i){ t[i] = Integer.MAX_VALUE; cnt[i] = 1; }
            for(i=d-1; i>0; --i){
                if(t[i*2]<t[i*2+1]){
                    t[i] = t[i*2];
                    cnt[i] = cnt[i*2] + (t[i*2]==t[i*2+1] ? cnt[i*2+1] : 0);
                }else{
                    t[i] = t[i*2+1];
                    cnt[i] = cnt[i*2+1] + (t[i*2]==t[i*2+1] ? cnt[i*2] : 0);
                }
            }
        }

        private void add(int i, int j, int value, int left, int right, int node){
            if(i==left && j==right){
                add[node] += value;
                t[node] += value;
            }else{
                int middle = (left+right)>>1;
                if(i<=middle) add(i, Math.min(j,middle), value, left, middle, node*2);
                if(j>middle) add(Math.max(i, middle + 1), j, value, middle+1, right, node*2+1);
                if(t[node*2]<t[node*2+1]){
                    t[node] = t[node*2];
                    cnt[node] = cnt[node*2] + (t[node*2]==t[node*2+1] ? cnt[node*2+1] : 0);
                }else{
                    t[node] = t[node*2+1];
                    cnt[node] = cnt[node*2+1] + (t[node*2]==t[node*2+1] ? cnt[node*2] : 0);
                }
                t[node] += add[node];
            }
        }

        public void addRange(int left, int right, int value){
            if(left<=right && 0<=left && right<d)
                add(left, right, value, 0, d-1, 1);
        }

        private int[] getMinimum(int i, int j, int left, int right, int node){
            if(i>j || left>right || left>i || j>right) return new int[]{Integer.MAX_VALUE, j-i+1};
            if(i==left && j==right){
                return new int[]{t[node], cnt[node]};
            }else{
                int middle = (left+right)>>1;
                int[] getLeft = {Integer.MAX_VALUE, -1}, getRight = {Integer.MAX_VALUE, -1};
                if(i<=middle) getLeft = getMinimum(i, Math.min(j, middle), left, middle, node * 2);
                if(j>middle) getRight = getMinimum(Math.max(i, middle + 1), j, middle + 1, right, node * 2 + 1);
                int[] res = new int[2];
                if(getLeft[0]<getRight[0]){
                    res[0] = getLeft[0];
                    res[1] = getLeft[1] + (getLeft[0]==getRight[0] ? getRight[1] : 0);
                }else{
                    res[0] = getRight[0];
                    res[1] = getRight[1] + (getLeft[0]==getRight[0] ? getLeft[1] : 0);
                }
                res[0] += add[node];
                return res;
            }
        }

        public int[] getMinimum(int left, int right){
            return getMinimum(left, right, 0, d-1, 1);
        }
    }



    }

