#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;

int n, m, x, y, a[maxn], b[maxn];
vector<int> op_em[maxn];
vector<int> adj[maxn];
int marc[maxn];
int resp[maxn];

//seg de intervalos
int seg_min[8*maxn];
int seg_quant[8*maxn];
int lazy[8*maxn];
void refresh(int u){
	seg_min[u]+=lazy[u];
	lazy[2*u]+=lazy[u];
	lazy[2*u+1]+=lazy[u];
	lazy[u]=0;
	return;
}
pair<int, int>  update(int u, int l, int r, int l_u, int r_u, int v){
//	fprintf(stderr, "u=%d, l=%d, r=%d\n", u, l, r);
	refresh(u);
	if(l>r_u || r<l_u) return make_pair(seg_min[u], seg_quant[u]);
	if(l>=l_u && r<=r_u){
		lazy[u]+=v;
		refresh(u);
		return make_pair(seg_min[u], seg_quant[u]);
	}
	else{
		int m=(l+r)/2;
		pair<int, int> p1=update(2*u, l, m, l_u, r_u, v);
		pair<int, int> p2=update(2*u+1, m+1, r, l_u, r_u, v);

		if(p1.first>p2.first){
	//		printf("1");
			seg_min[u]=p2.first;
			seg_quant[u]=p2.second;
		}
		else if(p1.first<p2.first){
	//		printf("2");
			seg_min[u]=p1.first;
			seg_quant[u]=p1.second;
		}
		else if(p1.first==p2.first){
	//		printf("3");
			seg_min[u]=p1.first;
			seg_quant[u]=p1.second+p2.second;
		}
	//	printf("  (%d %d), (%d %d) -> (%d %d) ", p1.first, p1.second, p2.first, p2.second, seg_min[u], seg_quant[u]);
		return make_pair(seg_min[u], seg_quant[u]);
	}
}
void ini(int u, int l, int r){
	seg_quant[u]=r-l+1;
	if(l==r) return;
	int m=(l+r)/2;
	ini(2*u, l, m);
	ini(2*u+1, m+1, r);
	return;
}
void debug(int u, int l, int r){
	refresh(u);
//	printf("u=%d, l=%d, r=%d, seg_min[u]=%d, seg_quant[u]=%d\n", u, l, r, seg_min[u], seg_quant[u]);
	if(l==r) return;
	int m=(l+r)/2;
	debug(2*u, l, m);
	debug(2*u+1, m+1, r);
	return;
}

//lineariza arvore
int cont[maxn];
int at;
int fin_sub_arv[maxn];

int dfs_build(int u){
	if(cont[u]==0){
		at++;
		cont[u]=at;
	}
	for(int i=0; i<adj[u].size(); i++){
		int v=adj[u][i];
		if(cont[v]==0){
			fin_sub_arv[u]=dfs_build(v);
	//		printf("fin_sub_arv[%d]=%d\n", u, fin_sub_arv[u]);
		}
	}
	if(fin_sub_arv[u]==0) fin_sub_arv[u]=cont[u];
//	printf("fin_sub_arv[%d]=%d\n", u, fin_sub_arv[u]);
	return fin_sub_arv[u];
}

//dfs normal
void dfs(int u){
//	printf("entrando em %d:\n", u);
	marc[u]=1;

	//coloca os intervalos do vertice
	for(int i=0; i<op_em[u].size(); i++){
		int ind=op_em[u][i];
	//	fprintf(stderr, "%d, %d:\n", cont[a[ind]], fin_sub_arv[a[ind]]);
		update(1, 1, n, cont[a[ind]], fin_sub_arv[a[ind]], 1);
	//	fprintf(stderr, "%d, %d:\n", cont[b[ind]], fin_sub_arv[b[ind]]);
		update(1, 1, n, cont[b[ind]], fin_sub_arv[b[ind]], 1);
	//	fprintf(stderr, "\n\n");

	//	printf("\n\n");
	//	debug(1, 1, n);
	//	printf("\n\n");
	}

	//vai pros filhos
	for(int i=0; i<adj[u].size(); i++){
		int v=adj[u][i];
		if(marc[v]==0){
			dfs(v);
		}
	}

	//faz a query pro cara
	if(seg_min[1]>0) resp[u]=n-1;
	else resp[u]=max(n-seg_quant[1]-1, 0);

	//tira os intervalos do vertice
	for(int i=0; i<op_em[u].size(); i++){
		int ind=op_em[u][i];
	//	fprintf(stderr, "%d, %d:\n", cont[a[ind]], fin_sub_arv[a[ind]]);
		update(1, 1, n, cont[a[ind]], fin_sub_arv[a[ind]], -1);
	//	fprintf(stderr, "\n\n");
	//	fprintf(stderr, "%d, %d:\n", cont[b[ind]], fin_sub_arv[b[ind]]);
		update(1, 1, n, cont[b[ind]], fin_sub_arv[b[ind]], -1);
	//	fprintf(stderr, "\n\n");
	}

	return;
}

int main(){
	//le
	scanf("%d %d", &n, &m);
	for(int i=1; i<n; i++){
		scanf("%d %d", &x, &y);
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	for(int i=1; i<=m; i++){
		scanf("%d %d", &x, &y);
		a[i]=x;
		b[i]=y;
		op_em[x].push_back(i);
		op_em[y].push_back(i);
	}
	//lineariza
	dfs_build(1);
	//inicia seg
	ini(1, 1, n);
	//dfs
	dfs(1);
//	printf("\n");
	for(int i=1; i<=n; i++){
	//	printf("%d ",cont[i]);
	}
//	printf("\n");
	for(int i=1; i<=n; i++){
	//	printf("%d ", fin_sub_arv[i]);
	}
//	printf("\n");
	for(int i=1; i<=n; i++){
		printf("%d ", resp[i]);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;

int n, m, x, y, a[maxn], b[maxn];
vector<int> op_em[maxn];
vector<int> adj[maxn];
int marc[maxn];
int resp[maxn];

//seg de intervalos
int seg_min[4*maxn];
int seg_quant[4*maxn];
int lazy[4*maxn];
void refresh(int u){
	seg_min[u]+=lazy[u];
	lazy[2*u]+=lazy[u];
	lazy[2*u+1]+=lazy[u];
	lazy[u]=0;
	return;
}
pair<int, int>  update(int u, int l, int r, int l_u, int r_u, int v){
//	fprintf(stderr, "u=%d, l=%d, r=%d\n", u, l, r);
	refresh(u);
	if(l>r_u || r<l_u) return make_pair(seg_min[u], seg_quant[u]);
	if(l>=l_u && r<=r_u){
		lazy[u]+=v;
		refresh(u);
		return make_pair(seg_min[u], seg_quant[u]);
	}
	else{
		int m=(l+r)/2;
		pair<int, int> p1=update(2*u, l, m, l_u, r_u, v);
		pair<int, int> p2=update(2*u+1, m+1, r, l_u, r_u, v);

		if(p1.first>p2.first){
	//		printf("1");
			seg_min[u]=p2.first;
			seg_quant[u]=p2.second;
		}
		else if(p1.first<p2.first){
	//		printf("2");
			seg_min[u]=p1.first;
			seg_quant[u]=p1.second;
		}
		else if(p1.first==p2.first){
	//		printf("3");
			seg_min[u]=p1.first;
			seg_quant[u]=p1.second+p2.second;
		}
	//	printf("  (%d %d), (%d %d) -> (%d %d) ", p1.first, p1.second, p2.first, p2.second, seg_min[u], seg_quant[u]);
		return make_pair(seg_min[u], seg_quant[u]);
	}
}
void ini(int u, int l, int r){
	seg_quant[u]=r-l+1;
	if(l==r) return;
	int m=(l+r)/2;
	ini(2*u, l, m);
	ini(2*u+1, m+1, r);
	return;
}
void debug(int u, int l, int r){
	refresh(u);
//	printf("u=%d, l=%d, r=%d, seg_min[u]=%d, seg_quant[u]=%d\n", u, l, r, seg_min[u], seg_quant[u]);
	if(l==r) return;
	int m=(l+r)/2;
	debug(2*u, l, m);
	debug(2*u+1, m+1, r);
	return;
}

//lineariza arvore
int cont[maxn];
int at;
int fin_sub_arv[maxn];

int dfs_build(int u){
	if(cont[u]==0){
		at++;
		cont[u]=at;
	}
	for(int i=0; i<adj[u].size(); i++){
		int v=adj[u][i];
		if(cont[v]==0){
			fin_sub_arv[u]=dfs_build(v);
	//		printf("fin_sub_arv[%d]=%d\n", u, fin_sub_arv[u]);
		}
	}
	if(fin_sub_arv[u]==0) fin_sub_arv[u]=cont[u];
//	printf("fin_sub_arv[%d]=%d\n", u, fin_sub_arv[u]);
	return fin_sub_arv[u];
}

//dfs normal
void dfs(int u){
//	printf("entrando em %d:\n", u);
	marc[u]=1;

	//coloca os intervalos do vertice
	for(int i=0; i<op_em[u].size(); i++){
		int ind=op_em[u][i];
	//	fprintf(stderr, "%d, %d:\n", cont[a[ind]], fin_sub_arv[a[ind]]);
		update(1, 1, n, cont[a[ind]], fin_sub_arv[a[ind]], 1);

	//	printf("\n\n");
//		debug(1, 1, n);
	//	printf("\n\n");

	//	fprintf(stderr, "%d, %d:\n", cont[b[ind]], fin_sub_arv[b[ind]]);
		update(1, 1, n, cont[b[ind]], fin_sub_arv[b[ind]], 1);
	//	fprintf(stderr, "\n\n");

	//	printf("\n\n");
	//	debug(1, 1, n);
	//	printf("\n\n");
	}

	//vai pros filhos
	for(int i=0; i<adj[u].size(); i++){
		int v=adj[u][i];
		if(marc[v]==0){
			dfs(v);
		}
	}

	//faz a query pro cara
	if(seg_min[1]>0) resp[u]=n-1;
	else resp[u]=max(n-seg_quant[1]-1, 0);

	//tira os intervalos do vertice
	for(int i=0; i<op_em[u].size(); i++){
		int ind=op_em[u][i];
	//	fprintf(stderr, "%d, %d:\n", cont[a[ind]], fin_sub_arv[a[ind]]);
		update(1, 1, n, cont[a[ind]], fin_sub_arv[a[ind]], -1);
	//	fprintf(stderr, "\n\n");
	//	fprintf(stderr, "%d, %d:\n", cont[b[ind]], fin_sub_arv[b[ind]]);
		update(1, 1, n, cont[b[ind]], fin_sub_arv[b[ind]], -1);
	//	fprintf(stderr, "\n\n");
	}

	return;
}

int main(){
	//le
	scanf("%d %d", &n, &m);
	for(int i=1; i<n; i++){
		scanf("%d %d", &x, &y);
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	for(int i=1; i<=m; i++){
		scanf("%d %d", &x, &y);
		a[i]=x;
		b[i]=y;
		op_em[x].push_back(i);
		op_em[y].push_back(i);
	}
	//lineariza
	dfs_build(1);
	//inicia seg
	ini(1, 1, n);
	//dfs
	dfs(1);
//	printf("\n");
	for(int i=1; i<=n; i++){
	//	printf("%d ",cont[i]);
	}
//	printf("\n");
	for(int i=1; i<=n; i++){
	//	printf("%d ", fin_sub_arv[i]);
	}
//	printf("\n");
	for(int i=1; i<=n; i++){
		printf("%d ", resp[i]);
	}
	return 0;
}


#include <iostream>
#include <vector>
using namespace std;
struct node {
    int val, add;
    node() { val = 0; add = 0; }
}it[1<<20];
int ls[1<<18], rs[1<<18], dfsInd, n, q, par[1<<18], k = 19, ans[1<<18];
vector < int > qs[1<<18], chs[1<<18];

void dfs( int x ) {
    //cout << x << ": " << par[x] << "\n";
    ls[x] = dfsInd++;
    for ( int i = 0 ; i < chs[x].size() ; i ++ ) {
        if ( chs[x][i] == par[x] ) { swap( chs[x][i], chs[x][ chs[x].size() -1 ] ); }
        if ( chs[x][i] == par[x] ) { break; }
        par [ chs[x][i] ] = x;
        dfs( chs[x][i] );
    }
    if ( chs[x].back() == par[x] ) {
        chs[x].pop_back();
    }
    rs[x] = dfsInd;
}

void add ( int ind, int l, int r, int ll, int rr, int v ) {
    //cout << ind << " :" << l << " " << r << "\n";
    if ( ll <= l && r <= rr ) {
        it[ind].add += v;
        if ( it[ind].add ) { it[ind].val = r-l; }
        else if ( l == r-1 ) {  it[ind].val = 0; }
        else { it[ind].val = it[ind*2].val + it[ind*2+1].val; }
        return;
    }
    if ( r <= ll || rr <= l ) { return; }

    add( ind*2,   l, (l+r)/2, ll, rr, v );
    add( ind*2+1, (l+r)/2, r, ll, rr, v );

    if ( it[ind].add) { it[ind].val = r-l; }
    else { it[ind].val = it[ind*2].val + it[ind*2+1].val; }
}

void dfs2( int x ) {
    if ( qs[x].size() ) { add( 1, 0, (1<<k), ls[x], rs[x], 1 ); }
    for ( int i = 0 ; i < qs[x].size() ; i ++ ) {
        add( 1, 0, (1<<k), ls[ qs[x][i] ], rs[ qs[x][i] ], 1 );
    }
    ans[x] = it[1].val;
    if ( ans[x] ){ ans[x]--; }
    for ( int i = 0 ; i < chs[x].size() ; i ++ ) {
        dfs2( chs[x][i] );
    }

    for ( int i = 0 ; i < qs[x].size() ; i ++ ) {
        add( 1, 0, (1<<k), ls[ qs[x][i] ], rs[ qs[x][i] ], -1 );
    }
    if ( qs[x].size() ) { add( 1, 0, (1<<k), ls[x], rs[x], -1 ); }

}

int main () {
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n >> q;
    for ( int i = 0 ; i < n-1 ; i ++ ) {
        int a, b;
        cin >> a >> b;
        chs[a].push_back(b);
        chs[b].push_back(a);
    }
    dfs(1);
    for ( int i = 0 ; i < q ; i ++ ) {
        int a, b;
        cin >> a >> b;
        qs[a].push_back(b);
        qs[b].push_back(a);
    }
    dfs2( 1 );
    for ( int i = 1; i <= n ; i ++ ) {
        cout << ans[i] << " ";
    }
    cout << "\n";

    return 0;
}


#include <iostream>
#include <vector>
using namespace std;
struct node {
    int val, add;
    node() { val = 0; add = 0; }
}it[1<<20];
int ls[1<<18], rs[1<<18], dfsInd, n, q, par[1<<18], k = 18, ans[1<<18];
vector < int > qs[1<<18], chs[1<<18];

void dfs( int x ) {
    //cout << x << ": " << par[x] << "\n";
    ls[x] = dfsInd++;
    for ( int i = 0 ; i < chs[x].size() ; i ++ ) {
        if ( chs[x][i] == par[x] ) { swap( chs[x][i], chs[x][ chs[x].size() -1 ] ); }
        if ( chs[x][i] == par[x] ) { break; }
        par [ chs[x][i] ] = x;
        dfs( chs[x][i] );
    }
    if ( chs[x].back() == par[x] ) {
        chs[x].pop_back();
    }
    rs[x] = dfsInd;
}

void add ( int ind, int l, int r, int ll, int rr, int v ) {
    //cout << ind << " :" << l << " " << r << "\n";
    if ( ll <= l && r <= rr ) {
        it[ind].add += v;
        if ( it[ind].add ) { it[ind].val = r-l; }
        else if ( l == r-1 ) {  it[ind].val = 0; }
        else { it[ind].val = it[ind*2].val + it[ind*2].val; }
        return;
    }
    if ( r <= ll || rr <= l ) { return; }

    add( ind*2,   l, (l+r)/2, ll, rr, v );
    add( ind*2+1, (l+r)/2, r, ll, rr, v );

    if ( it[ind].add) { it[ind].val = r-l; }
    else { it[ind].val = it[ind*2].val + it[ind*2+1].val; }
}

void dfs2( int x ) {
    if ( qs[x].size() ) { add( 1, 0, (1<<k), ls[x], rs[x], 1 ); }
    for ( int i = 0 ; i < qs[x].size() ; i ++ ) {
        add( 1, 0, (1<<k), ls[ qs[x][i] ], rs[ qs[x][i] ], 1 );
    }
    ans[x] = it[1].val;
    if ( ans[x] ){ ans[x]--; }
    for ( int i = 0 ; i < chs[x].size() ; i ++ ) {
        dfs2( chs[x][i] );
    }

    for ( int i = 0 ; i < qs[x].size() ; i ++ ) {
        add( 1, 0, (1<<k), ls[ qs[x][i] ], rs[ qs[x][i] ], -1 );
    }
    if ( qs[x].size() ) { add( 1, 0, (1<<k), ls[x], rs[x], -1 ); }

}

int main () {
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n >> q;
    for ( int i = 0 ; i < n-1 ; i ++ ) {
        int a, b;
        cin >> a >> b;
        chs[a].push_back(b);
        chs[b].push_back(a);
    }
    dfs(1);
    for ( int i = 0 ; i < q ; i ++ ) {
        int a, b;
        cin >> a >> b;
        qs[a].push_back(b);
        qs[b].push_back(a);
    }
    dfs2( 1 );
    for ( int i = 1; i <= n ; i ++ ) {
        cout << ans[i] << " ";
    }
    cout << "\n";

    return 0;
}


#include<bits/stdc++.h>
#define vi vector<int>
#define pb push_back
using namespace std;
const int N=1e5+5;
struct segmentree{
	int mi,num,add;
}tree[N*16];int n,m;
inline void pushup(int id)
{
	tree[id].mi=min(tree[id<<1].mi,tree[id<<1|1].mi);tree[id].num=0;
	if(tree[id].mi==tree[id<<1].mi)tree[id].num+=tree[id<<1].num;
	if(tree[id].mi==tree[id<<1|1].mi)tree[id].num+=tree[id<<1|1].num;
}
inline void pushdown(int id)
{
	tree[id].mi+=tree[id].add;
	tree[id<<1].add+=tree[id].add;
	tree[id<<1|1].add+=tree[id].add;
	tree[id].add=0;
}
void update(int l,int r,int x,int y,int add,int id)
{
	pushdown(id);
	pushdown(id<<1);
	pushdown(id<<1|1);
	if(x<=l&&r<=y)
	{
		tree[id].add+=add;
		pushdown(id);
		return;
	}
	int mid=(l+r)>>1;
	if(mid>=x)update(l,mid,x,y,add,id<<1);
	if(mid<y)update(mid+1,r,x,y,add,id<<1|1);
	pushup(id);
}
void build(int l,int r,int id)
{
	tree[id].num=r-l+1;
	if(l==r)return;
	int mid=(l+r)>>1;
	build(l,mid,id<<1);
	build(mid+1,r,id<<1|1);
}vi v[N],e[N];int ans[N],pos[N],nxt[N],cnt;
void dfs(int now,int fa)
{
	pos[now]=++cnt;
	for(int i=0;i<v[now].size();i++)
	{
		int to=v[now][i];
		if(to!=fa)
			dfs(to,now);
	}
	nxt[now]=cnt;
}
int query(int l,int r,int v,int id)
{
	pushdown(id);
	if(l==r)return tree[id].mi;
	int mid=(l+r)>>1;//////////
	if(mid>=v)return query(l,mid,v,id<<1);
	else return query(mid+1,r,v,id<<1|1);
}
void dfs2(int now,int fa)
{
//	cout<<now<<"_supercheck: ";
	for(int i=0;i<e[now].size();i++)
		update(1,n,pos[e[now][i]],nxt[e[now][i]],1,1);
	pushdown(1);
	ans[now]=n-(tree[1].mi==0?tree[1].num:0)-(query(1,n,pos[now],1)!=0);
//	for(int i=1;i<=n;i++)cout<<query(1,n,i,1)<<" ";cout<<"\n";
	for(int i=0;i<v[now].size();i++)
	{
		int to=v[now][i];
		if(to!=fa)dfs2(to,now);
	}
	for(int i=0;i<e[now].size();i++)
		update(1,n,pos[e[now][i]],nxt[e[now][i]],-1,1);
}
int main()
{
	cin>>n>>m;
	for(int i=0;i<n-1;i++)
	{
		int a,b;
		cin>>a>>b;
		a--,b--;
		v[a].pb(b);
		v[b].pb(a);
	}
	build(1,n,1);
	dfs(0,-1);
	for(int i=0;i<m;i++)
	{
		int a,b;
		cin>>a>>b;
		a--,b--;
		e[a].pb(b);
		e[a].pb(a);
		e[b].pb(b);
		e[b].pb(a);
	}
	dfs2(0,-1);
	for(int i=0;i<n;i++)
		cout<<ans[i]<<" ";
	return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <cmath>
#define rank krevedka
#define left trulala
#define next ttrulala
#define rigth trulalo
#define ran rank
using namespace std;

int t = 1;
int a[100500];
int b[100500];
int res[100500];
vector<int> e[100500];
vector<int> d[100500];

void dfs(int u)
{
    a[u] = t++;
    for(int i=0;i<e[u].size();i++)
    if(a[e[u][i]] == 0 ) dfs(e[u][i]);
    b[u] = t++;
}

int curr = 0;

const int z =1<<17;
int sum[2*z + 3];
int total[2*z + 3];

int get_value(int pos)
{
    return sum[pos+z];
}

void update(int * arr,int pos,int value)
{
    pos+=z;
    arr[pos] = value;
    pos/=2;
    while(pos)
    {
        arr[pos] = arr[2*pos] + arr[2*pos+1];
        pos/=2;
    }
}
int get(int *arr,int pos)
{
    int l = z;
    int r = z+pos;
    int res = 0;
    while(l<=r)
    {
        if(l&1){ res+=arr[l]; l++; continue;}
        if(r%2==0){ res+=arr[r]; r--; continue;}
        l/=2;
        r/=2;
    }
    return res;
    return 0;
}

void dfs2(int u)
{
    for(int i=0;i<d[u].size();i++)
    {
        int v = d[u][i];
        int s =  get(sum, a[ v ]);
        if(s) {d[u][i] = -1; continue;}
        s = get(total,b[ v ]) - get(total,a[v] );
        s = (b[v]-a[v]+1)/2 - s;
        curr+=s;
        update(sum,a[v],s);
        update(sum,b[v],-s);
        update(total,a[v],s);
    }
    if(get(sum,a[u])) res[u]=-1; else res[u] = 0;
    res[u] += curr;
    for(int i=0;i<e[u].size();i++)
    {
        int v = e[u][i];
        if(a[v]>a[u]) dfs2(v);
    }
    for(int i=0;i<d[u].size();i++)
    {
        int v = d[u][i];
        if(v==-1) continue;
        curr -=get_value(a[v]);
        update(sum,a[v],0);
        update(sum,b[v],0);
        update(total,a[v],0);
    }
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<n;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v); u--;v--;
        e[u].push_back(v);
        e[v].push_back(u);
    }
    dfs(0);
    while(m--)
    {
        int u,v;
        scanf("%d%d",&u,&v); u--;v--;
        d[u].push_back(v);
        d[u].push_back(u);
        d[v].push_back(u);
        d[v].push_back(v);
    }
    dfs2(0);
    for(int i=0;i<n;i++)
        printf("%d ",res[i]);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <cmath>
#define rank krevedka
#define left trulala
#define next ttrulala
#define rigth trulalo
#define ran rank
using namespace std;

int t = 1;
int a[100500];
int b[100500];
int res[100500];
vector<int> e[100500];
vector<int> d[100500];

void dfs(int u)
{
    a[u] = t++;
    for(int i=0;i<e[u].size();i++)
    if(a[e[u][i]] == 0 ) dfs(e[u][i]);
    b[u] = t++;
}

int curr = 0;

const int z =1<<18;
int sum[2*z + 3];
int total[2*z + 3];

int get_value(int pos)
{
    return sum[pos+z];
}

void update(int * arr,int pos,int value)
{
    pos+=z;
    arr[pos] = value;
    pos/=2;
    while(pos)
    {
        arr[pos] = arr[2*pos] + arr[2*pos+1];
        pos/=2;
    }
}
int get(int *arr,int pos)
{
    int l = z;
    int r = z+pos;
    int res = 0;
    while(l<=r)
    {
        if(l&1){ res+=arr[l]; l++; continue;}
        if(r%2==0){ res+=arr[r]; r--; continue;}
        l/=2;
        r/=2;
    }
    return res;
    return 0;
}

void dfs2(int u)
{
    for(int i=0;i<d[u].size();i++)
    {
        int v = d[u][i];
        int s =  get(sum, a[ v ]);
        if(s) {d[u][i] = -1; continue;}
        s = get(total,b[ v ]) - get(total,a[v] );
        s = (b[v]-a[v]+1)/2 - s;
        curr+=s;
        update(sum,a[v],s);
        update(sum,b[v],-s);
        update(total,a[v],s);
    }
    if(get(sum,a[u])) res[u]=-1; else res[u] = 0;
    res[u] += curr;
    for(int i=0;i<e[u].size();i++)
    {
        int v = e[u][i];
        if(a[v]>a[u]) dfs2(v);
    }
    for(int i=0;i<d[u].size();i++)
    {
        int v = d[u][i];
        if(v==-1) continue;
        curr -=get_value(a[v]);
        update(sum,a[v],0);
        update(sum,b[v],0);
        update(total,a[v],0);
    }
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<n;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v); u--;v--;
        e[u].push_back(v);
        e[v].push_back(u);
    }
    dfs(0);
    while(m--)
    {
        int u,v;
        scanf("%d%d",&u,&v); u--;v--;
        d[u].push_back(v);
        d[u].push_back(u);
        d[v].push_back(u);
        d[v].push_back(v);
    }
    dfs2(0);
    for(int i=0;i<n;i++)
        printf("%d ",res[i]);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int MAX=1e5+10;
int n,a,b,q,c,m[MAX];
vector<int> g[MAX];
void dfs(int v,int p)
{

}
int main()
{
	ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	cin>>n;
	for (int i=0;i<n-1;i++) cin>>a>>b,a--,b--,g[a].push_back(b),g[b].push_back(a);
	dfs(0,-1);
}


#include<bits/stdc++.h>
using namespace std;
const int MAX=1e5+9;
int a,cnt,b,n,q,s[MAX],f[MAX],ans[MAX],x[MAX*4],lazy[MAX*4],ted[MAX*4];
vector<int> g[MAX],r[MAX];
void pre(int v,int p=-1){s[v]=cnt++; for (auto u:g[v]) if (u!=p) pre(u,v); f[v]=cnt;}
void shift(int id){x[id*2+1]+=lazy[id],x[id*2+2]+=lazy[id],lazy[id*2+1]+=lazy[id],lazy[id*2+2]+=lazy[id],lazy[id]=0;}
void add(int l,int r,int val,int s=0,int e=n,int id=0)
{
	if (r<=s || e<=l) return ;
	if (l<=s && e<=r){x[id]+=val,lazy[id]+=val; return ;}
	int mid=s+e>>1;
	shift(id),add(l,r,val,s,mid,id*2+1),add(l,r,val,mid,e,id*2+2);
	x[id]=min(x[id*2+1],x[id*2+2]),ted[id]=ted[id*2+1]*(x[id]==x[id*2+1])+ted[id*2+2]*(x[id]==x[id*2+2]);
}
void build(int s=0,int e=n,int id=0){if (e-s==1) {ted[id]=1; return ;} int mid=s+e>>1; build(s,mid,id*2+1),build(mid,e,id*2+2),ted[id]=ted[id*2+1]+ted[id*2+2]; }
int get(int p,int s=0,int e=n,int id=0)
{
	if (e-s==1) return x[id];
	int mid=s+e>>1;
	shift(id); if (p<mid) return get(p,s,mid,id*2+1); else return get(p,mid,e,id*2+2);
}
void dfs(int v,int p=-1)
{
	for (auto u:r[v]) add(s[v],f[v],+1),add(s[u],f[u],+1);
	if (get(s[v])) ans[v]=n-(!x[0])*ted[0]-1; else ans[v]=0;
	for (auto u:g[v]) if (u!=p) dfs(u,v);
	for (auto u:r[v]) add(s[v],f[v],-1),add(s[u],f[u],-1);
}
int main()
{
	cin>>n>>q;
	for (int i=0;i<n-1;i++) cin>>a>>b,a--,b--,g[a].push_back(b),g[b].push_back(a);
	while (q--) cin>>a>>b,a--,b--,r[a].push_back(b),r[b].push_back(a);
	build(),pre(0),dfs(0);
	for (int i=0;i<n;i++) cout<<ans[i]<<" ";
}


#include <bits/stdc++.h>
using namespace std;

int n,m;
int dis[100000];
int ve[100000];
int t[600000];
int c[600000];
int k[600000];
int lazy[6000000];
int ans[1000000];
vector <int> q[100005];
vector <int> p[100005];

int op;

void down(int l,int r,int id)
{
    int mid=(l+r)/2;
    lazy[id*2]+=lazy[id];
    lazy[id*2+1]+=lazy[id];
    t[id*2]+=(mid-l+1)*lazy[id];
    t[id*2+1]+=(r-mid)*lazy[id];
    c[id*2]+=c[id];
    c[id*2+1]+=c[id];
    lazy[id]=0;
}

int cck(int l,int r,int x,int id)
{
    if(l==r&&l==x)
    {
        if(t[id]>0)
            return 1;
        else
            return 0;
    }
    down(l,r,id);
    int mid=(l+r)/2;
    if(mid>=x)return cck(l,mid,x,id*2);
    else return cck(mid+1,r,x,id*2+1);
}

void update(int l,int r,int z,int y,int v,int id)
{
    if(l==z&&r==y)
    {
        t[id]+=(r-l+1)*v;
        lazy[id]+=v;
        c[id]+=v;
        if(c[id]>0)
            k[id]=(r-l+1);
        else
            k[id]=k[id*2]+k[id*2+1];
        return ;
    }
    down(l,r,id);
    int mid=(l+r)/2;
    if(mid>=y)update(l,mid,z,y,v,id*2);
    else if(mid<z)update(mid+1,r,z,y,v,id*2+1);
    else
    {
        update(l,mid,z,mid,v,id*2);
        update(mid+1,r,mid+1,y,v,id*2+1);
    }
    c[id]=c[id*2]&c[id*2+1];
    t[id]=t[id*2]+t[id*2+1];
    k[id]=k[id*2]+k[id*2+1];
    //cout<<l<<" "<<r<<" "<<k[id]<<endl;
}

void dfs(int x,int last)
{
    op++;
    dis[x]=op;
    for(int i=0;i<q[x].size();i++)
    {
        int nx=q[x][i];
        if(nx==last)continue;
        dfs(nx,x);
        ve[x]+=ve[nx];
    }
    ve[x]+=1;
}

void di(int x,int last)
{
    //cout<<x<<endl;
    for(int i=0;i<p[x].size();i++)
    {
        int nx=p[x][i];
        int ny=x;
        update(1,op,dis[nx],dis[nx]+ve[nx]-1,1,1);
        update(1,op,dis[ny],dis[ny]+ve[ny]-1,1,1);
        //cout<<k[1]<<endl;
    }
    ans[x]=k[1]-cck(1,op,dis[x],1);
    //cout<<k[1]<<" "<<ans[x]<<" "<<x<<endl;
    for(int i=0;i<q[x].size();i++)
    {
        int nx=q[x][i];
        if(nx==last)continue;
        di(nx,x);
    }
    for(int i=0;i<p[x].size();i++)
    {
        int nx=p[x][i];
        int ny=x;
        update(1,op,dis[nx],dis[nx]+ve[nx]-1,-1,1);
        update(1,op,dis[ny],dis[ny]+ve[ny]-1,-1,1);
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        q[x].push_back(y);
        q[y].push_back(x);
    }
    dfs(1,1);
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        p[x].push_back(y);
        p[y].push_back(x);
    }
    di(1,1);
    for(int i=1;i<=n;i++)
    {
        printf("%d ",ans[i]);
    }
    printf("\n");
    return 0;
}


#pragma GCC optimize(2)

#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++i)
#define per(i, a, b) for (int i = (a), i##end = (b); i >= i##end; --i)

template <typename T>
inline void chkmax(T &x, T y) { if (x < y) x = y; }

template <typename T>
inline void chkmin(T &x, T y) { if (x > y) x = y; }

inline int read() {
  #define nc getchar()
  int x = 0;
  char c = nc;
  while (c < 48) c = nc;
  while (c > 47) x = x * 10 + (c ^ 48), c = nc;
  return x;
  #undef nc
}

typedef long long ll;
typedef pair <int, int> pii;
const int maxn = 1e5 + 10;
int n, m, ans[maxn];

int h[maxn];

struct edges {
  int nxt, to;
} E[maxn << 1];

void addline(int u, int v) {
  static int ecnt;
  ecnt++, E[ecnt].nxt = h[u], E[ecnt].to = v, h[u] = ecnt;
}

vector <int> Q[maxn];

int tid[maxn], sz[maxn];

void dfs(int u, int f) {
  static int now;
  sz[u] = 1, tid[u] = ++now;
  for (int i = h[u]; i; i = E[i].nxt) {
    int v = E[i].to;
    if (v != f) {
      dfs(v, u), sz[u] += sz[v];
    }
  }
}

#define mid ((l + r) >> 1)

int tot, rt[maxn];
int ls[maxn * 60], rs[maxn * 60], sum[maxn * 60];

void build(int &k, int l, int r, int v) {
  sum[k = ++tot] = v * (r - l + 1);
  if (l == r) return;
  build(ls[k], l, mid, v), build(rs[k], mid + 1, r, v);
}

void upd(int &k, int rt, int o, int l, int r, int ql, int qr) {
  if (l == r) return sum[k = ++tot] = 1, void();
  k = ++tot, ls[k] = ls[rt], rs[k] = rs[rt], sum[k] = sum[rt];
  if (sum[k] == r - l + 1) return;
  if (ql <= l && r <= qr && sum[k] == 0) {
    return ls[k] = ls[o], rs[k] = rs[o], sum[k] = r - l + 1, void();
  }
  if (ql <= mid) upd(ls[k], ls[rt], ls[o], l, mid, ql, qr);
  if (qr > mid) upd(rs[k], rs[rt], rs[o], mid + 1, r, ql, qr);
  sum[k] = sum[ls[k]] + sum[rs[k]];
}

int query(int k, int l, int r, int x) {
  if (l == r) return sum[k];
  return x <= mid ? query(ls[k], l, mid, x) : query(rs[k], mid + 1, r, x);
}

void print(int k, int l, int r) {
  if (l == r) return printf("%d%c", sum[k], "\n "[r < n]), void();
  print(ls[k], l, mid), print(rs[k], mid + 1, r);
}

#undef mid

void DFS(int u, int f) {
  rt[u] = rt[f];
  if (!Q[u].empty()) {
    upd(rt[u], rt[u], rt[n + 1], 1, n, tid[u], tid[u] + sz[u] - 1);
  }
  rep(i, 0, Q[u].size() - 1) {
    int x = Q[u][i];
    upd(rt[u], rt[u], rt[n + 1], 1, n, tid[x], tid[x] + sz[x] - 1);
  }
//  printf("(%d) : ", u);
//  print(rt[u], 1, n);
  ans[u] = sum[rt[u]] - query(rt[u], 1, n, tid[u]);
  for (int i = h[u]; i; i = E[i].nxt) {
    int v = E[i].to;
    if (v != f) {
      DFS(v, u);
    }
  }
}

void solve() {
  cin >> n >> m;
  rep(i, 2, n) {
    int u = read(), v = read();
    addline(u, v), addline(v, u);
  }
  rep(i, 1, m) {
    int x = read(), y = read();
    Q[x].push_back(y), Q[y].push_back(x);
  }
  dfs(1, 0);
  build(rt[0], 1, n, 0);
  build(rt[n + 1], 1, n, 1);
  DFS(1, 0);
  rep(i, 1, n) printf("%d ", ans[i]);
}

signed main() {
//  int T = read();
//  while (T--) solve();
  solve();
  return 0;
}


#include<bits/stdc++.h>
#define vi vector<int>
#define pb push_back
using namespace std;
const int N=1e5+5;
struct segmentree{
	int mi,num,add;
}tree[N*8];int n,m;
inline void pushup(int id)
{
	tree[id].mi=min(tree[id<<1].mi,tree[id<<1|1].mi);tree[id].num=0;
	if(tree[id].mi==tree[id<<1].mi)tree[id].num+=tree[id<<1].num;
	if(tree[id].mi==tree[id<<1|1].mi)tree[id].num+=tree[id<<1|1].num;
}
inline void pushdown(int id)
{
	tree[id].mi+=tree[id].add;
	tree[id<<1].add+=tree[id].add;
	tree[id<<1|1].add+=tree[id].add;
	tree[id].add=0;
}
void update(int l,int r,int x,int y,int add,int id)
{
	pushdown(id);
	pushdown(id<<1);
	pushdown(id<<1|1);
	if(x<=l&&r<=y)
	{
		tree[id].add+=add;
		pushdown(id);
		return;
	}
	int mid=(l+r)>>1;
	if(mid>=x)update(l,mid,x,y,add,id<<1);
	if(mid<y)update(mid+1,r,x,y,add,id<<1|1);
	pushup(id);
}
void build(int l,int r,int id)
{
	tree[id].num=r-l+1;
	if(l==r)return;
	int mid=(l+r)>>1;
	build(l,mid,id<<1);
	build(mid+1,r,id<<1|1);
}vi v[N],e[N];int ans[N],pos[N],nxt[N],cnt;
void dfs(int now,int fa)
{
	pos[now]=++cnt;
	for(int i=0;i<v[now].size();i++)
	{
		int to=v[now][i];
		if(to!=fa)
			dfs(to,now);
	}
	nxt[now]=cnt;
}
int query(int l,int r,int v,int id)
{
	pushdown(id);
	if(l==r)return tree[id].mi;
	int mid=(l+r)>>1;//////////
	if(mid>=v)return query(l,mid,v,id<<1);
	else return query(mid+1,r,v,id<<1|1);
}
void dfs2(int now,int fa)
{
//	cout<<now<<"_supercheck: ";
	for(int i=0;i<e[now].size();i++)
		update(1,n,pos[e[now][i]],nxt[e[now][i]],1,1);
	pushdown(1);
	ans[now]=n-(tree[1].mi==0?tree[1].num:0)-(query(1,n,pos[now],1)!=0);
//	for(int i=1;i<=n;i++)cout<<query(1,n,i,1)<<" ";cout<<"\n";
	for(int i=0;i<v[now].size();i++)
	{
		int to=v[now][i];
		if(to!=fa)dfs2(to,now);
	}
	for(int i=0;i<e[now].size();i++)
		update(1,n,pos[e[now][i]],nxt[e[now][i]],-1,1);
}
int main()
{
	cin>>n>>m;
	for(int i=0;i<n-1;i++)
	{
		int a,b;
		cin>>a>>b;
		a--,b--;
		v[a].pb(b);
		v[b].pb(a);
	}
	build(1,n,1);
	dfs(0,-1);
	for(int i=0;i<m;i++)
	{
		int a,b;
		cin>>a>>b;
		a--,b--;
		e[a].pb(b);
		e[a].pb(a);
		e[b].pb(b);
		e[b].pb(a);
	}
	dfs2(0,-1);
	for(int i=0;i<n;i++)
		cout<<ans[i]<<" ";
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int n,m;
int dis[200000];
int ve[200000];
int t[800000];
int c[800000];
int k[800000];
int lazy[6000000];
int ans[2000000];
vector <int> q[200005];
vector <int> p[200005];

int op;

void down(int l,int r,int id)
{
    int mid=(l+r)/2;
    lazy[id*2]+=lazy[id];
    lazy[id*2+1]+=lazy[id];
    t[id*2]+=(mid-l+1)*lazy[id];
    t[id*2+1]+=(r-mid)*lazy[id];
    c[id*2]+=c[id];
    c[id*2+1]+=c[id];
    lazy[id]=0;
}

int cck(int l,int r,int x,int id)
{
    if(l==r&&l==x)
    {
        if(t[id]>0)
            return 1;
        else
            return 0;
    }
    down(l,r,id);
    int mid=(l+r)/2;
    if(mid>=x)return cck(l,mid,x,id*2);
    else return cck(mid+1,r,x,id*2+1);
}

void update(int l,int r,int z,int y,int v,int id)
{
    if(l==z&&r==y)
    {
        t[id]+=(r-l+1)*v;
        lazy[id]+=v;
        c[id]+=v;
        if(c[id]>0)
            k[id]=(r-l+1);
        else
            k[id]=k[id*2]+k[id*2+1];
        return ;
    }
    down(l,r,id);
    int mid=(l+r)/2;
    if(mid>=y)update(l,mid,z,y,v,id*2);
    else if(mid<z)update(mid+1,r,z,y,v,id*2+1);
    else
    {
        update(l,mid,z,mid,v,id*2);
        update(mid+1,r,mid+1,y,v,id*2+1);
    }
    //c[id]=c[id*2]&c[id*2+1];
    t[id]=t[id*2]+t[id*2+1];
    if(c[id]==0)k[id]=k[id*2]+k[id*2+1];
    //cout<<l<<" "<<r<<" "<<k[id]<<endl;
}

void dfs(int x,int last)
{
    op++;
    dis[x]=op;
    for(int i=0;i<q[x].size();i++)
    {
        int nx=q[x][i];
        if(nx==last)continue;
        dfs(nx,x);
        ve[x]+=ve[nx];
    }
    ve[x]+=1;
}

void di(int x,int last)
{
    //cout<<x<<endl;
    for(int i=0;i<p[x].size();i++)
    {
        int nx=p[x][i];
        int ny=x;
        update(1,op,dis[nx],dis[nx]+ve[nx]-1,1,1);
        update(1,op,dis[ny],dis[ny]+ve[ny]-1,1,1);
        //cout<<k[1]<<endl;
    }
    //cout<<k[1]<<" "<<ans[x]<<" "<<x<<endl;
    for(int i=0;i<q[x].size();i++)
    {
        int nx=q[x][i];
        if(nx==last)continue;
        di(nx,x);
    }
    ans[x]=k[1]-cck(1,op,dis[x],1);
    for(int i=0;i<p[x].size();i++)
    {
        int nx=p[x][i];
        int ny=x;
        update(1,op,dis[nx],dis[nx]+ve[nx]-1,-1,1);
        update(1,op,dis[ny],dis[ny]+ve[ny]-1,-1,1);
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        q[x].push_back(y);
        q[y].push_back(x);
    }
    dfs(1,1);
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        p[x].push_back(y);
        p[y].push_back(x);
    }
    di(1,1);
    for(int i=1;i<=n;i++)
    {
        printf("%d ",ans[i]);
    }
    printf("\n");
    return 0;
}


#include <iostream>
#include <cstdio>

#include <vector>
#include <set>
#include <functional>
#include <utility>
#include <algorithm>

#include <cassert>

using namespace std;

const int MN = 1e5 + 100;

int N, M;
using vi = vector<int>;
#define pb push_back
#define ALL(X) X.begin(),X.end()

vi a[MN];

int o[MN][2];
int p[MN], s[MN];
int dfs(int n = 1, int * c = new int(0))
{
	o[n][0] = (*c)++;
	s[n] = 1;
	for(int x : a[n])
		if(x != p[n])
			p[x] = n, s[n] += dfs(x, c);
	o[n][1] = *c;
	return s[n];
}
bool anc(int x, int y)
{
	return o[x][0] <= o[y][0] && o[x][1] >= o[y][1];
}
bool self[MN];
vi other[MN];
int f[MN];
using comp = function<bool(int, int)>;
const comp cmpo = [](int a, int b){return o[a][0] < o[b][0];};
template<int MS = MN*3> struct C
{
public:
	int s;
	int v[MS], c[MS];
	int z[MS];
	void init(int n, int l, int r)
	{
		if(r-l>1)
		{
			int m = l + (r-l>>1);
			init(n<<1, l, m), init(n<<1|1, m, r);
		}
		v[n] = 0, c[n] = r-l;
		z[n] = 0;
	}
	void init(int s)
	{
		this->s = s;
		init(1, 0, s);
	}
	void addv(int n, int l, int r, int q)
	{
		v[n] += q;
		z[n] += q;
	}
	void down(int n, int l, int r)
	{
		if(!z[n])
			return;
		if(r-l>1)
		{
			int m = l + (r-l>>1);
			addv(n<<1, l, m, z[n]), addv(n<<1|1, m, r, z[n]);
		}
		z[n] = 0;
	}
	void up(int n)
	{
		if(v[n<<1] < v[n<<1|1])
			v[n] = v[n<<1], c[n] = c[n<<1];
		else if(v[n<<1|1] < v[n<<1])
			v[n] = v[n<<1|1], c[n] = c[n<<1|1];
		else
			v[n] = v[n<<1], c[n] = c[n<<1|1] + c[n<<1];
	}
	void add(int n, int l, int r, int ql, int qr)
	{
		if(ql <= l&&r <= qr)
			return addv(n, l, r, 1);
		int m = l + (r-l>>1);
		down(n, l, r);
		if(ql < m) add(n<<1, l, m, ql, qr);
		if(m < qr) add(n<<1|1, m, r, ql, qr);
		up(n);
	}
	void sub(int n, int l, int r, int ql, int qr)
	{
		if(ql <= l&&r <= qr)
			return addv(n, l, r, -1);
		int m = l + (r-l>>1);
		down(n, l, r);
		if(ql < m) sub(n<<1, l, m, ql, qr);
		if(m < qr) sub(n<<1|1, m, r, ql, qr);
		up(n);
	}
	int qry(void)
	{
		if(v[1])
			return s;
		return s - c[1];
	}
	void add(int x)
	{
		add(1, 0, s, o[x][0], o[x][1]);
	}
	void rem(int x)
	{
		sub(1, 0, s, o[x][0], o[x][1]);
	}
};
C<> c;
vi temp;
void dfsf(int n = 1)
{
	for(int x : other[n])
		c.add(x);
	f[n] = c.qry();
	for(int x : a[n])
		if(x != p[n])
			dfsf(x);
	for(int x : other[n])
		c.rem(x);
}
int main(void)
{
	scanf("%d%d", &N, &M);
	for(int i = 0, u, v;i < N-1;i++)
		scanf("%d%d", &u, &v), a[u].pb(v), a[v].pb(u);
	dfs();
	c.init(N);
	for(int i = 0, a, b;i < M;i++)
	{
		scanf("%d%d", &a, &b);
		if(anc(a, b))
			self[a] = 1;
		else if(anc(b, a))
			self[b] = 1;
		else
			self[a] = self[b] = 1, other[a].pb(b), other[b].pb(a);
	}
	for(int i = 1;i <= N;i++)
	{
		if(self[i])
			other[i].pb(i);
		sort(ALL(other[i]), cmpo);
		for(int j = 0, k;j < other[i].size();j=k)
		{
			temp.pb(other[i][j]);
			for(k=j+1;k < other[i].size()&&o[other[i][j]][1] >= o[other[i][k]][1];k++);
		}
		other[i].assign(temp.begin(), temp.end());
		temp.clear();
	}
	dfsf();
	for(int i = 1;i <= N;i++)
		printf("%d%c", f[i]-!!f[i], " \n"[i==N]);
	return 0;
}


#include <iostream>
#include <cstdio>

#include <vector>
#include <set>
#include <functional>
#include <utility>

#include <cassert>

using namespace std;

const int MN = 1e5 + 100;

int N, M;
using vi = vector<int>;
#define pb push_back
#define ALL(X) X.begin(),X.end()

vi a[MN];

int o[MN][2];
int p[MN], s[MN];
int dfs(int n = 1, int * c = new int(0))
{
	o[n][0] = (*c)++;
	s[n] = 1;
	for(int x : a[n])
		if(x != p[n])
			p[x] = n, s[n] += dfs(x, c);
	o[n][1] = *c;
	return s[n];
}
bool anc(int x, int y)
{
	return o[x][0] <= o[y][0] && o[x][1] >= o[y][1];
}
bool self[MN];
vi other[MN];
int f[MN];
using comp = function<bool(int, int)>;
const comp cmpo = [](int a, int b){return o[a][0] < o[b][0];};
using si = set<int, comp>;
#define IT iterator
struct C : public si
{
public:
	int c;
	C() : si(cmpo) {c = 0;}
	bool upd(IT a, IT b)
	{
		if(b == end()) return 0;
		return (o[*a][1] >= o[*b][1]);
	}
	bool add(int x, vi& erased)
	{
		auto v = insert(x);
		if(!v.second) return 0;
		IT n = v.first, p = n;
		if(p != begin()&&upd(--p, n))
			return erase(v.first), 0;
		c += s[x];
		for(p = n;upd(p, ++n);)
			c -= s[*n], erased.pb(*n), n = erase(n);
		return 1;
	}
	void ers(int x)
	{
		c -= s[x];
		erase(x);
	}
};
C c;
vi erased[MN];
vi to_erase[MN];
vi temp;
void dfsf(int n = 1)
{
	if(self[n])
		other[n].pb(n);
	for(int x : other[n])
		if(c.add(x, erased[n]))
			to_erase[n].pb(x);
	f[n] = c.c;
	for(int x : a[n])
		if(x != p[n])
			dfsf(x);
	for(int x : to_erase[n])
		c.ers(x);
	for(int x : erased[n])
		c.add(x, temp);
	//assert(temp.empty());
}
int main(void)
{
	scanf("%d%d", &N, &M);
	for(int i = 0, u, v;i < N-1;i++)
		scanf("%d%d", &u, &v), a[u].pb(v), a[v].pb(u);
	dfs();
	for(int i = 0, a, b;i < M;i++)
	{
		scanf("%d%d", &a, &b);
		if(anc(a, b))
			self[a] = 1;
		else if(anc(b, a))
			self[b] = 1;
		else
			self[a] = self[b] = 1, other[a].pb(b), other[b].pb(a);
	}
	for(int i = 1;i <= N;i++)
	{
		sort(ALL(other[i]), cmpo);
		vi other2(0, 0);
		for(int j = 0, k;j < other[i].size();j=k)
		{
			other2.pb(other[i][j]);
			for(k=j+1;k < other[i].size()&&o[other[i][j]][1] >= o[other[i][k]][1];k++);
		}
		other[i] = other2;
	}
	dfsf();
	for(int i = 1;i <= N;i++)
		printf("%d%c", f[i]-!!f[i], " \n"[i==N]);
	return 0;
}


#include <iostream>
#include <cstdio>

#include <vector>
#include <set>
#include <functional>
#include <utility>
#include <algorithm>

#include <cassert>

using namespace std;

const int MN = 1e5 + 100;

int N, M;
using vi = vector<int>;
#define pb push_back
#define ALL(X) X.begin(),X.end()

vi a[MN];

int o[MN][2];
int p[MN], s[MN];
int dfs(int n = 1, int * c = new int(0))
{
	o[n][0] = (*c)++;
	s[n] = 1;
	for(int x : a[n])
		if(x != p[n])
			p[x] = n, s[n] += dfs(x, c);
	o[n][1] = *c;
	return s[n];
}
bool anc(int x, int y)
{
	return o[x][0] <= o[y][0] && o[x][1] >= o[y][1];
}
bool self[MN];
vi other[MN];
int f[MN];
using comp = function<bool(int, int)>;
const comp cmpo = [](int a, int b){return o[a][0] < o[b][0];};
template<int MS = MN*3> struct C
{
public:
	int s;
	int v[MS], c[MS];
	int z[MS];
	void init(int n, int l, int r)
	{
		if(r-l>1)
		{
			int m = l + (r-l>>1);
			init(n<<1, l, m), init(n<<1|1, m, r);
		}
		v[n] = 0, c[n] = r-l;
		z[n] = 0;
	}
	void init(int s)
	{
		this->s = s;
		init(1, 0, s);
	}
	void addv(int n, int l, int r, int q)
	{
		v[n] += q;
		z[n] += q;
	}
	void down(int n, int l, int r)
	{
		if(!z[n])
			return;
		if(r-l>1)
		{
			int m = l + (r-l>>1);
			addv(n, l, m, z[n]), addv(n<<1|1, m, r, z[n]);
		}
		z[n] = 0;
	}
	void up(int n)
	{
		if(v[n<<1] < v[n<<1|1])
			v[n] = v[n<<1], c[n] = c[n<<1];
		else if(v[n<<1|1] < v[n<<1])
			v[n] = v[n<<1|1], c[n] = c[n<<1|1];
		else
			v[n] = v[n<<1], c[n] = c[n<<1|1] + c[n<<1];
	}
	void add(int n, int l, int r, int ql, int qr)
	{
		if(ql <= l&&r <= qr)
			return addv(n, l, r, 1);
		int m = l + (r-l>>1);
		down(n, l, r);
		if(ql < m) add(n<<1, l, m, ql, qr);
		if(m < qr) add(n<<1|1, m, r, ql, qr);
		up(n);
	}
	void sub(int n, int l, int r, int ql, int qr)
	{
		if(ql <= l&&r <= qr)
			return addv(n, l, r, -1);
		int m = l + (r-l>>1);
		down(n, l, r);
		if(ql < m) sub(n<<1, l, m, ql, qr);
		if(m < qr) sub(n<<1|1, m, r, ql, qr);
		up(n);
	}
	void add(int x)
	{
		add(1, 0, s, o[x][0], o[x][1]);
	}
	void rem(int x)
	{
		sub(1, 0, s, o[x][0], o[x][1]);
	}
	int qry(void)
	{
		if(v[1])
			return s;
		return s - c[1];
	}
};
C<> c;
vi temp;
void dfsf(int n = 1)
{
	for(int x : other[n])
		c.add(x);
	f[n] = c.qry();
	for(int x : a[n])
		if(x != p[n])
			dfsf(x);
	for(int x : other[n])
		c.rem(x);
}
int main(void)
{
	scanf("%d%d", &N, &M);
	for(int i = 0, u, v;i < N-1;i++)
		scanf("%d%d", &u, &v), a[u].pb(v), a[v].pb(u);
	dfs();
	c.init(N);
	for(int i = 0, a, b;i < M;i++)
	{
		scanf("%d%d", &a, &b);
		if(anc(a, b))
			self[a] = 1;
		else if(anc(b, a))
			self[b] = 1;
		else
			self[a] = self[b] = 1, other[a].pb(b), other[b].pb(a);
	}
	for(int i = 1;i <= N;i++)
	{
		if(self[i])
			other[i].pb(i);
		sort(ALL(other[i]), cmpo);
		for(int j = 0, k;j < other[i].size();j=k)
		{
			temp.pb(other[i][j]);
			for(k=j+1;k < other[i].size()&&o[other[i][j]][1] >= o[other[i][k]][1];k++);
		}
		other[i].assign(temp.begin(), temp.end());
		temp.clear();
	}
	dfsf();
	for(int i = 1;i <= N;i++)
		printf("%d%c", f[i]-!!f[i], " \n"[i==N]);
	return 0;
}


#include <iostream>
#include <cstdio>

#include <vector>
#include <set>
#include <functional>
#include <utility>
#include <algorithm>

#include <cassert>

using namespace std;

const int MN = 1e5 + 100;

int N, M;
using vi = vector<int>;
#define pb push_back
#define ALL(X) X.begin(),X.end()

vi a[MN];

int o[MN][2];
int p[MN], s[MN];
int dfs(int n = 1, int * c = new int(0))
{
	o[n][0] = (*c)++;
	s[n] = 1;
	for(int x : a[n])
		if(x != p[n])
			p[x] = n, s[n] += dfs(x, c);
	o[n][1] = *c;
	return s[n];
}
bool anc(int x, int y)
{
	return o[x][0] <= o[y][0] && o[x][1] >= o[y][1];
}
bool self[MN];
vi other[MN];
int f[MN];
using comp = function<bool(int, int)>;
const comp cmpo = [](int a, int b){return o[a][0] < o[b][0];};
using si = set<int, comp>;
#define IT iterator
struct C : public si
{
public:
	int c;
	C() : si(cmpo) {c = 0;}
	bool upd(IT a, IT b)
	{
		if(b == end()) return 0;
		return (o[*a][1] >= o[*b][1]);
	}
	bool add(int x, vi& erased)
	{
		auto v = insert(x);
		if(!v.second) return 0;
		IT n = v.first, p = n;
		if(p != begin()&&upd(--p, n))
			return erase(v.first), 0;
		c += s[x];
		for(p = n;upd(p, ++n);n = erase(n))
			c -= s[*n], erased.pb(*n);
		return 1;
	}
	void ers(int x)
	{
		c -= s[x];
		erase(x);
	}
};
C c;
vi erased[MN];
vi to_erase[MN];
vi temp;
void dfsf(int n = 1)
{
	//if(self[n])
	//	other[n].pb(n);
	for(int x : other[n])
		if(c.add(x, erased[n]))
			to_erase[n].pb(x);
	f[n] = c.c;
	for(int x : a[n])
		if(x != p[n])
			dfsf(x);
	for(int x : to_erase[n])
		c.ers(x);
	for(int x : erased[n])
		c.add(x, temp);
	//assert(temp.empty());
}
int main(void)
{
	scanf("%d%d", &N, &M);
	for(int i = 0, u, v;i < N-1;i++)
		scanf("%d%d", &u, &v), a[u].pb(v), a[v].pb(u);
	dfs();
	for(int i = 0, a, b;i < M;i++)
	{
		scanf("%d%d", &a, &b);
		if(anc(a, b))
			self[a] = 1;
		else if(anc(b, a))
			self[b] = 1;
		else
			self[a] = self[b] = 1, other[a].pb(b), other[b].pb(a);
	}
	for(int i = 1;i <= N;i++)
	{
		if(self[i])
			other[i].pb(i);
		sort(ALL(other[i]), cmpo);
		vi other2(0, 0);
		for(int j = 0, k;j < other[i].size();j=k)
		{
			other2.pb(other[i][j]);
			for(k=j+1;k < other[i].size()&&o[other[i][j]][1] >= o[other[i][k]][1];k++);
		}
		other[i] = other2;
	}
	dfsf();
	for(int i = 1;i <= N;i++)
		printf("%d%c", f[i]-!!f[i], " \n"[i==N]);
	return 0;
}


#include <iostream>
#include <cstdio>

#include <vector>
#include <set>
#include <functional>
#include <utility>
#include <algorithm>

#include <cassert>

using namespace std;

const int MN = 1e5 + 100;

int N, M;
using vi = vector<int>;
#define pb push_back
#define ALL(X) X.begin(),X.end()

vi a[MN];

int o[MN][2];
int p[MN], s[MN];
int dfs(int n = 1, int * c = new int(0))
{
	o[n][0] = (*c)++;
	s[n] = 1;
	for(int x : a[n])
		if(x != p[n])
			p[x] = n, s[n] += dfs(x, c);
	o[n][1] = *c;
	return s[n];
}
bool anc(int x, int y)
{
	return o[x][0] <= o[y][0] && o[x][1] >= o[y][1];
}
bool self[MN];
vi other[MN];
int f[MN];
using comp = function<bool(int, int)>;
const comp cmpo = [](int a, int b){return o[a][0] < o[b][0];};
using si = set<int, comp>;
#define IT iterator
struct C : public si
{
public:
	int c;
	C() : si(cmpo) {c = 0;}
	bool upd(IT a, IT b)
	{
		if(b == end()) return 0;
		return (o[*a][1] >= o[*b][1]);
	}
	bool add(int x, vi& erased)
	{
		auto v = insert(x);
		if(!v.second) return 0;
		IT n = v.first, p = n;
		if(p != begin()&&upd(--p, n))
			return erase(v.first), 0;
		c += s[x];
		for(p = n++;upd(p, n);n = erase(n))
			c -= s[*n], erased.pb(*n);
		return 1;
	}
	void ers(int x)
	{
		c -= s[x];
		erase(x);
	}
};
C c;
vi erased[MN];
vi to_erase[MN];
vi temp;
void dfsf(int n = 1)
{
	for(int x : other[n])
		if(c.add(x, erased[n]))
			to_erase[n].pb(x);
	f[n] = c.c;
	for(int x : a[n])
		if(x != p[n])
			dfsf(x);
	for(int x : to_erase[n])
		c.ers(x);
	for(int x : erased[n])
		c.add(x, temp);
	//assert(temp.empty());
}
int main(void)
{
	scanf("%d%d", &N, &M);
	for(int i = 0, u, v;i < N-1;i++)
		scanf("%d%d", &u, &v), a[u].pb(v), a[v].pb(u);
	dfs();
	for(int i = 0, a, b;i < M;i++)
	{
		scanf("%d%d", &a, &b);
		if(anc(a, b))
			self[a] = 1;
		else if(anc(b, a))
			self[b] = 1;
		else
			self[a] = self[b] = 1, other[a].pb(b), other[b].pb(a);
	}
	for(int i = 1;i <= N;i++)
	{
		if(self[i])
			other[i].pb(i);
		sort(ALL(other[i]), cmpo);
		vi other2(0, 0);
		for(int j = 0, k;j < other[i].size();j=k)
		{
			other2.pb(other[i][j]);
			for(k=j+1;k < other[i].size()&&o[other[i][j]][1] >= o[other[i][k]][1];k++);
		}
		other[i] = other2;
	}
	dfsf();
	for(int i = 1;i <= N;i++)
		printf("%d%c", f[i]-!!f[i], " \n"[i==N]);
	return 0;
}


#include <iostream>
#include <cstdio>

#include <vector>
#include <set>
#include <functional>
#include <utility>
#include <algorithm>

#include <cassert>

using namespace std;

const int MN = 1e5 + 100;

int N, M;
using vi = vector<int>;
#define pb push_back
#define ALL(X) X.begin(),X.end()

vi a[MN];

int o[MN][2];
int p[MN], s[MN];
int dfs(int n = 1, int * c = new int(0))
{
	o[n][0] = (*c)++;
	s[n] = 1;
	for(int x : a[n])
		if(x != p[n])
			p[x] = n, s[n] += dfs(x, c);
	o[n][1] = *c;
	return s[n];
}
bool anc(int x, int y)
{
	return o[x][0] <= o[y][0] && o[x][1] >= o[y][1];
}
bool self[MN];
vi other[MN];
int f[MN];
using comp = function<bool(int, int)>;
const comp cmpo = [](int a, int b){return o[a][0] < o[b][0];};
using si = set<int, comp>;
#define IT iterator
struct C : public si
{
public:
	int c;
	C() : si(cmpo) {c = 0;}
	bool upd(IT a, IT b)
	{
		if(b == end()) return 0;
		return (o[*a][1] >= o[*b][1]);
	}
	bool add(int x, vi& erased)
	{
		auto v = insert(x);
		if(!v.second) return 0;
		IT n = v.first, p = n;
		if(p != begin()&&upd(--p, n))
			return erase(v.first), 0;
		c += s[x];
		for(p = n;upd(p, ++n);)
			c -= s[*n], erased.pb(*n), n = erase(n);
		return 1;
	}
	void ers(int x)
	{
		c -= s[x];
		erase(x);
	}
};
C c;
vi erased[MN];
vi to_erase[MN];
vi temp;
void dfsf(int n = 1)
{
	if(self[n])
		other[n].pb(n);
	for(int x : other[n])
		if(c.add(x, erased[n]))
			to_erase[n].pb(x);
	f[n] = c.c;
	for(int x : a[n])
		if(x != p[n])
			dfsf(x);
	for(int x : to_erase[n])
		c.ers(x);
	for(int x : erased[n])
		c.add(x, temp);
	//assert(temp.empty());
}
int main(void)
{
	scanf("%d%d", &N, &M);
	for(int i = 0, u, v;i < N-1;i++)
		scanf("%d%d", &u, &v), a[u].pb(v), a[v].pb(u);
	dfs();
	for(int i = 0, a, b;i < M;i++)
	{
		scanf("%d%d", &a, &b);
		if(anc(a, b))
			self[a] = 1;
		else if(anc(b, a))
			self[b] = 1;
		else
			self[a] = self[b] = 1, other[a].pb(b), other[b].pb(a);
	}
	for(int i = 1;i <= N;i++)
	{
		sort(ALL(other[i]), cmpo);
		vi other2(0, 0);
		for(int j = 0, k;j < other[i].size();j=k)
		{
			other2.pb(other[i][j]);
			for(k=j+1;k < other[i].size()&&o[other[i][j]][1] >= o[other[i][k]][1];k++);
		}
		other[i] = other2;
	}
	dfsf();
	for(int i = 1;i <= N;i++)
		printf("%d%c", f[i]-!!f[i], " \n"[i==N]);
	return 0;
}


#include <iostream>
#include <cstdio>

#include <vector>
#include <set>
#include <functional>
#include <utility>

#include <cassert>

using namespace std;

const int MN = 1e5 + 100;

int N, M;
using vi = vector<int>;
#define pb push_back

vi a[MN];

int o[MN][2];
int p[MN], s[MN];
int dfs(int n = 1, int * c = new int(0))
{
	o[n][0] = (*c)++;
	s[n] = 1;
	for(int x : a[n])
		if(x != p[n])
			p[x] = n, s[n] += dfs(x, c);
	o[n][1] = *c;
	return s[n];
}
bool anc(int x, int y)
{
	return o[x][0] <= o[y][0] && o[x][1] >= o[y][1];
}
bool self[MN];
vi other[MN];
int f[MN];
using comp = function<bool(int, int)>;
const comp cmpo = [](int a, int b){return o[a][0] < o[b][0];};
using si = set<int, comp>;
#define IT iterator
struct C : public si
{
public:
	int c;
	C() : si(cmpo) {c = 0;}
	bool upd(IT a, IT b)
	{
		if(b == end()) return 0;
		return (o[*a][1] >= o[*b][1]);
	}
	bool add(int x, vi& erased)
	{
		auto v = insert(x);
		if(!v.second) return 0;
		IT n = v.first, p = n;
		if(p != begin()&&upd(--p, n))
			return erase(v.first), 0;
		c += s[x];
		for(p = n;upd(p, ++n);)
			c -= s[*n], erased.pb(*n), n = erase(n);
		return 1;
	}
	void ers(int x)
	{
		c -=s[x];
		erase(x);
	}
};
C c;
vi erased[MN];
vi to_erase[MN];
vi temp;
void dfsf(int n = 1)
{
	if(self[n])
		other[n].pb(n);
	for(int x : other[n])
		if(c.add(x, erased[n]))
			to_erase[n].pb(x);
	f[n] = c.c;
	for(int x : a[n])
		if(x != p[n])
			dfsf(x);
	for(int x : to_erase[n])
		c.ers(x);
	for(int x : erased[n])
		c.add(x, temp);
	//assert(temp.empty());
}
int main(void)
{
	scanf("%d%d", &N, &M);
	for(int i = 0, u, v;i < N-1;i++)
		scanf("%d%d", &u, &v), a[u].pb(v), a[v].pb(u);
	dfs();
	for(int i = 0, a, b;i < M;i++)
	{
		scanf("%d%d", &a, &b);
		if(anc(a, b))
			self[a] = 1;
		else if(anc(b, a))
			self[b] = 1;
		else
			self[a] = self[b] = 1, other[a].pb(b), other[b].pb(a);
	}
	dfsf();
	for(int i = 1;i <= N;i++)
		printf("%d%c", f[i]-!!f[i], " \n"[i==N]);
	return 0;
}


// whats 1000 minus 7 ?
// I'm bad, and that's good. I will never be good, and that's not bad. There's no one I'd rather be than me.
// unless someone like you cares a whole awful lot nothing is going to get better. it's not
#include <bits/stdc++.h>
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline long long lin(){long long x ; scanf("%lld",&x) ; return x ;}
inline string get(){char ch[2000010] ; scanf("%s",ch) ; return ch;}
const int MAX_LG = 21;
//#define int long long
#define X first
#define Y second
#define endl "\n"
#define Mp make_pair
typedef pair<int , int > pii;
typedef long double ld;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pii> vii;
const int maxn = 1e5 + 10;
const int base = 29;
const int mod = 1e9 + 7;
const int INF = 1e9 + 100;
vi g[maxn];
int Root[maxn*30],L[maxn*30],R[maxn*30],st[maxn],en[maxn],cur;
vii query[maxn];
inline void dfs(int node , int fa = -1)
{
    st[node] = cur ++;
    for (auto u : g[node])
    {
        if (u - fa)
            dfs(u,node);
    }
    en[node] = cur - 1;
}
int n , q;
int lazy[maxn*30],stree[maxn*30];
inline int add(int ql , int qr , int p , int l = 0 , int r = n - 1)
{
    if (l > qr || r < ql) return p;
    int ret = cur ++;
    if (l >= ql && r <= qr){
        L[ret] = L[p] , R[ret] = R[p];
        stree[ret] = lazy[ret] = r - l + 1;
        return ret;
    }
    int mid = (l + r) >> 1;
    lazy[ret] = lazy[p];
    L[ret] = add(ql,qr,L[p],l,mid);
    R[ret] = add(ql,qr,R[p],mid+1,r);
    stree[ret] = lazy[ret] ? r - l + 1 : stree[L[ret]] + stree[R[ret]];
    return ret;
}
int res[maxn];
inline void calc(int node , int fa = 0)
{
    Root[node] = Root[fa];
    for (auto q : query[node])
        Root[node] = add(q.first,q.second,Root[node]);
    res[node] = max(stree[Root[node]] - 1,0);
    for (auto u : g[node])
        if (u - fa)
            calc(u,node);
}
inline void build(int p , int l = 0 , int r = n - 1)
{
    if (l == r) return;
    L[p] = cur ++;
    R[p] = cur ++;
    int mid = (l + r) >> 1;
    build(L[p],l,mid),build(R[p],mid+1,r);
}
int32_t main()
{
    n = in() , q = in();
    for (int i = 0 ; i < n - 1; i ++)
    {
        int v = in() , u = in();
        g[v].push_back(u) , g[u].push_back(v);
    }
    dfs(1);
    cur = 1;
    Root[0] = 0;
    build(0,0,n-1);

    for (int i = 0 ; i < q ; i ++)
    {
        int a = in() , b = in();
        query[a].push_back({st[b],en[b]});
        query[b].push_back({st[a],en[a]});
    }
    for (int i = 1 ; i <= n ; i ++)
        if (query[i].size())
            query[i].push_back({st[i],en[i]});
    calc(1);
    for (int i = 1 ; i <= n ; i ++)
        cout << res[i] << " ";
}


// whats 1000 minus 7 ?
// I'm bad, and that's good. I will never be good, and that's not bad. There's no one I'd rather be than me.
// unless someone like you cares a whole awful lot nothing is going to get better. it's not
#include <bits/stdc++.h>
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline long long lin(){long long x ; scanf("%lld",&x) ; return x ;}
inline string get(){char ch[2000010] ; scanf("%s",ch) ; return ch;}
const int MAX_LG = 21;
//#define int long long
#define X first
#define Y second
#define endl "\n"
#define Mp make_pair
typedef pair<int , int > pii;
typedef long double ld;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pii> vii;
const int maxn = 1e5 + 10;
const int base = 29;
const int mod = 1e9 + 7;
const int INF = 1e9 + 100;
vi g[maxn];
int Root[maxn*80],L[maxn*80],R[maxn*80],st[maxn],en[maxn],cur;
vii query[maxn];
inline void dfs(int node , int fa = -1)
{
    st[node] = cur ++;
    for (auto u : g[node])
    {
        if (u - fa)
            dfs(u,node);
    }
    en[node] = cur - 1;
}
int n , q;
int lazy[maxn*80],stree[maxn*80];
inline int add(int ql , int qr , int p , int l = 0 , int r = n - 1)
{
    if (l > qr || r < ql) return p;
    int ret = cur ++;
    if (l >= ql && r <= qr){
        L[ret] = L[p] , R[ret] = R[p];
        stree[ret] = lazy[ret] = r - l + 1;
        return ret;
    }
    int mid = (l + r) >> 1;
    lazy[ret] = lazy[p];
    L[ret] = add(ql,qr,L[p],l,mid);
    R[ret] = add(ql,qr,R[p],mid+1,r);
    stree[ret] = lazy[ret] ? r - l + 1 : stree[L[ret]] + stree[R[ret]];
    return ret;
}
int res[maxn];
inline void calc(int node , int fa = 0)
{
    Root[node] = Root[fa];
    for (auto q : query[node])
        Root[node] = add(q.first,q.second,Root[node]);
    res[node] = max(stree[Root[node]] - 1,0);
    for (auto u : g[node])
        if (u - fa)
            calc(u,node);
}
inline void build(int p , int l = 0 , int r = n - 1)
{
    if (l == r) return;
    L[p] = cur ++;
    R[p] = cur ++;
    int mid = (l + r) >> 1;
    build(L[p],l,mid),build(R[p],mid+1,r);
}
int32_t main()
{
    n = in() , q = in();
    for (int i = 0 ; i < n - 1; i ++)
    {
        int v = in() , u = in();
        g[v].push_back(u) , g[u].push_back(v);
    }
    dfs(1);
    cur = 1;
    Root[0] = 0;
    build(0,0,n-1);
    for (int i = 0 ; i < q ; i ++)
    {
        int a = in() , b = in();
        query[a].push_back({st[b],en[b]});
        query[b].push_back({st[a],en[a]});
    }
    for (int i = 1 ; i <= n ; i ++)
        if (query[i].size())
            query[i].push_back({st[i],en[i]});
    calc(1);
    for (int i = 1 ; i <= n ; i ++)
        cout << res[i] << " ";
}


// whats 1000 minus 7 ?
// I'm bad, and that's good. I will never be good, and that's not bad. There's no one I'd rather be than me.
// unless someone like you cares a whole awful lot nothing is going to get better. it's not
#include <bits/stdc++.h>
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline long long lin(){long long x ; scanf("%lld",&x) ; return x ;}
inline string get(){char ch[2000010] ; scanf("%s",ch) ; return ch;}
const int MAX_LG = 21;
//#define int long long
#define X first
#define Y second
#define endl "\n"
#define Mp make_pair
typedef pair<int , int > pii;
typedef long double ld;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pii> vii;
const int maxn = 5e6 + 10;
const int base = 29;
const int mod = 1e9 + 7;
const int INF = 1e9 + 100;
vi g[maxn];
int Root[maxn],L[maxn],R[maxn],st[maxn],en[maxn],cur;
vii query[maxn];
inline void dfs(int node , int fa = -1)
{
    st[node] = cur ++;
    for (auto u : g[node])
    {
        if (u - fa)
            dfs(u,node);
    }
    en[node] = cur - 1;
}
int n , q;
int lazy[maxn],stree[maxn];
inline int add(int ql , int qr , int p , int l = 0 , int r = n - 1)
{
    if (l > qr || r < ql) return p;
    int ret = cur ++;
    if (l >= ql && r <= qr){
        L[ret] = L[p] , R[ret] = R[p];
        stree[ret] = lazy[ret] = r - l + 1;
        return ret;
    }
    int mid = (l + r) >> 1;
    lazy[ret] = lazy[p];
    L[ret] = add(ql,qr,L[p],l,mid);
    R[ret] = add(ql,qr,R[p],mid+1,r);
    stree[ret] = lazy[ret] ? r - l + 1 : stree[L[ret]] + stree[R[ret]];
    return ret;
}
int res[maxn];
inline void calc(int node , int fa = 0)
{
    Root[node] = Root[fa];
    for (auto q : query[node])
        Root[node] = add(q.first,q.second,Root[node]);
    res[node] = max(stree[Root[node]] - 1,0);
    for (auto u : g[node])
        if (u - fa)
            calc(u,node);
}
inline void build(int p , int l = 0 , int r = n - 1)
{
    if (l == r) return;
    L[p] = cur ++;
    R[p] = cur ++;
    int mid = (l + r) >> 1;
    build(L[p],l,mid),build(R[p],mid+1,r);
}
int32_t main()
{
    n = in() , q = in();
    for (int i = 0 ; i < n - 1; i ++)
    {
        int v = in() , u = in();
        g[v].push_back(u) , g[u].push_back(v);
    }
    dfs(1);
    cur = 1;
    Root[0] = 0;
    build(0,0,n-1);

    for (int i = 0 ; i < q ; i ++)
    {
        int a = in() , b = in();
        query[a].push_back({st[b],en[b]});
        query[b].push_back({st[a],en[a]});
    }
    for (int i = 1 ; i <= n ; i ++)
        if (query[i].size())
            query[i].push_back({st[i],en[i]});
    calc(1);
    for (int i = 1 ; i <= n ; i ++)
        cout << res[i] << " ";
}


// whats 1000 minus 7 ?
// I'm bad, and that's good. I will never be good, and that's not bad. There's no one I'd rather be than me.
// unless someone like you cares a whole awful lot nothing is going to get better. it's not
#include <bits/stdc++.h>
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline long long lin(){long long x ; scanf("%lld",&x) ; return x ;}
inline string get(){char ch[2000010] ; scanf("%s",ch) ; return ch;}
const int MAX_LG = 21;
//#define int long long
#define X first
#define Y second
#define endl "\n"
#define Mp make_pair
typedef pair<int , int > pii;
typedef long double ld;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pii> vii;
const int maxn = 1e5 + 10;
const int base = 29;
const int mod = 1e9 + 7;
const int INF = 1e9 + 100;
vi g[maxn];
int Root[maxn*40],L[maxn*40],R[maxn*40],st[maxn],en[maxn],cur;
vii query[maxn];
inline void dfs(int node , int fa = -1)
{
    st[node] = cur ++;
    for (auto u : g[node])
    {
        if (u - fa)
            dfs(u,node);
    }
    en[node] = cur - 1;
}
int n , q;
int lazy[maxn*40],stree[maxn*40];
inline int add(int ql , int qr , int p , int l = 0 , int r = n - 1 , int fl = 0)
{
    if (l > qr || r < ql) return p;
    int ret = fl == 0 ? cur ++ : p;
    if (l >= ql && r <= qr){
        L[ret] = L[p] , R[ret] = R[p];
        stree[ret] = lazy[ret] = r - l + 1;
        return ret;
    }
    int mid = (l + r) >> 1;
    lazy[ret] = lazy[p];
    L[ret] = add(ql,qr,L[p],l,mid,fl);
    R[ret] = add(ql,qr,R[p],mid+1,r,fl);
    stree[ret] = lazy[ret] ? r - l + 1 : stree[L[ret]] + stree[R[ret]];
    return ret;
}
int res[maxn];
inline void calc(int node , int fa = 0)
{
    Root[node] = Root[fa];
    for (auto q : query[node]){
        Root[node] = add(q.first,q.second,Root[node],Root[node]!=Root[fa]);
    }
    res[node] = max(stree[Root[node]] - 1,0);
    for (auto u : g[node])
        if (u - fa)
            calc(u,node);
}
inline void build(int p , int l = 0 , int r = n - 1)
{
    if (l == r) return;
    L[p] = cur ++;
    R[p] = cur ++;
    int mid = (l + r) >> 1;
    build(L[p],l,mid),build(R[p],mid+1,r);
}
int32_t main()
{
    n = in() , q = in();
    for (int i = 0 ; i < n - 1; i ++)
    {
        int v = in() , u = in();
        g[v].push_back(u) , g[u].push_back(v);
    }
    dfs(1);
    cur = 1;
    Root[0] = 0;
    build(0,0,n-1);
    for (int i = 0 ; i < q ; i ++)
    {
        int a = in() , b = in();
        query[a].push_back({st[b],en[b]});
        query[b].push_back({st[a],en[a]});
    }
    for (int i = 1 ; i <= n ; i ++)
        if (query[i].size())
            query[i].push_back({st[i],en[i]});
    calc(1);
    for (int i = 1 ; i <= n ; i ++)
        printf("%d ",res[i]);
}


// whats 1000 minus 7 ?
// I'm bad, and that's good. I will never be good, and that's not bad. There's no one I'd rather be than me.
// unless someone like you cares a whole awful lot nothing is going to get better. it's not
#include <bits/stdc++.h>
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline long long lin(){long long x ; scanf("%lld",&x) ; return x ;}
inline string get(){char ch[2000010] ; scanf("%s",ch) ; return ch;}
const int MAX_LG = 21;
//#define int long long
#define X first
#define Y second
#define endl "\n"
#define Mp make_pair
typedef pair<int , int > pii;
typedef long double ld;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pii> vii;
const int maxn = 1e5 + 10;
const int base = 29;
const int mod = 1e9 + 7;
const int INF = 1e9 + 100;
vi g[maxn];
int Root[maxn*80],L[maxn*80],R[maxn*80],st[maxn],en[maxn],cur;
vii query[maxn];
inline void dfs(int node , int fa = -1)
{
    st[node] = cur ++;
    for (auto u : g[node])
    {
        if (u - fa)
            dfs(u,node);
    }
    en[node] = cur - 1;
}
int n , q;
int lazy[maxn*80],stree[maxn*80];
inline int add(int ql , int qr , int p , int l = 0 , int r = n - 1)
{
    if (l > qr || r < ql) return p;
    int ret = cur ++;
    if (l >= ql && r <= qr){
        L[ret] = L[p] , R[ret] = R[p];
        stree[ret] = lazy[ret] = r - l + 1;
        return ret;
    }
    int mid = (l + r) >> 1;
    lazy[ret] = lazy[p];
    L[ret] = add(ql,qr,L[p],l,mid);
    R[ret] = add(ql,qr,R[p],mid+1,r);
    stree[ret] = lazy[ret] ? r - l + 1 : stree[L[ret]] + stree[R[ret]];
    return ret;
}
int res[maxn];
inline void calc(int node , int fa = 0)
{
    Root[node] = Root[fa];
    for (auto q : query[node])
        Root[node] = add(q.first,q.second,Root[node]);
    res[node] = max(stree[Root[node]] - 1,0);
    for (auto u : g[node])
        if (u - fa)
            calc(u,node);
}
inline void build(int p , int l = 0 , int r = n - 1)
{
    if (l == r) return;
    L[p] = cur ++;
    R[p] = cur ++;
    int mid = (l + r) >> 1;
    build(L[p],l,mid),build(R[p],mid+1,r);
}
int32_t main()
{
    n = in() , q = in();
    for (int i = 0 ; i < n - 1; i ++)
    {
        int v = in() , u = in();
        g[v].push_back(u) , g[u].push_back(v);
    }
    dfs(1);
    cur = 1;
    Root[0] = 0;
    build(0,0,n-1);
    for (int i = 0 ; i < q ; i ++)
    {
        int a = in() , b = in();
        query[a].push_back({st[b],en[b]});
        query[b].push_back({st[a],en[a]});
    }
    for (int i = 1 ; i <= n ; i ++)
        if (query[i].size())
            query[i].push_back({st[i],en[i]});
    calc(1);
    for (int i = 1 ; i <= n ; i ++)
        printf("%d\n",res[i]);
}


// whats 1000 minus 7 ?
// I'm bad, and that's good. I will never be good, and that's not bad. There's no one I'd rather be than me.
// unless someone like you cares a whole awful lot nothing is going to get better. it's not
#include <bits/stdc++.h>
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline long long lin(){long long x ; scanf("%lld",&x) ; return x ;}
inline string get(){char ch[2000010] ; scanf("%s",ch) ; return ch;}
const int MAX_LG = 21;
//#define int long long
#define X first
#define Y second
#define endl "\n"
#define Mp make_pair
typedef pair<int , int > pii;
typedef long double ld;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pii> vii;
const int maxn = 1e5 + 10;
const int base = 29;
const int mod = 1e9 + 7;
const int INF = 1e9 + 100;
vi g[maxn];
int st[maxn],en[maxn],cur;
vii query[maxn];
struct node
{
    int cnt ;
    bool lazy;
    node *left , *right;
    node()
    {
        cnt = lazy = 0;
        left = right = NULL;
    }
}*Root[maxn];
inline void dfs(int node , int fa = -1)
{
    st[node] = cur ++;
    for (auto u : g[node])
    {
        if (u - fa)
            dfs(u,node);
    }
    en[node] = cur - 1;
}
int n , q;
int lazy[maxn*80],stree[maxn*80];
inline node* add(int ql , int qr , node *p , int l = 0 , int r = n - 1)
{
    if (l > qr || r < ql) return p;
    node *ret = new node();
    if (l >= ql && r <= qr){
        ret->left = p->left;
        ret->right = p->right;
        ret->cnt = r - l + 1;
        ret->lazy = 1;

        return ret;
    }
    int mid = (l + r) >> 1;
    ret->lazy = p->lazy;
    ret->left = add(ql,qr,p->left,l,mid);
    ret->right = add(ql,qr,p->right,mid+1,r);
    ret->cnt = ret->lazy ? r - l + 1 : ret->left->cnt + ret->right->cnt;
    return ret;
}
int res[maxn];
inline void calc(int node , int fa = 0)
{
    Root[node] = Root[fa];
    for (auto q : query[node])
        Root[node] = add(q.first,q.second,Root[node]);
    res[node] = max(Root[node]->cnt - 1,0);
    for (auto u : g[node])
        if (u - fa)
            calc(u,node);
}
inline void build(node *p , int l = 0 , int r = n - 1)
{
    if (l == r) return;
    p->left = new node();
    p->right = new node();
    int mid = (l + r) >> 1;
    build(p->left,l,mid),build(p->right,mid+1,r);
}
int32_t main()
{
    n = in() , q = in();
    for (int i = 0 ; i < n - 1; i ++)
    {
        int v = in() , u = in();
        g[v].push_back(u) , g[u].push_back(v);
    }
    dfs(1);
    Root[0] = new node();
    build(Root[0],0,n-1);
    for (int i = 0 ; i < q ; i ++)
    {
        int a = in() , b = in();
        query[a].push_back({st[b],en[b]});
        query[b].push_back({st[a],en[a]});
    }
    for (int i = 1 ; i <= n ; i ++)
        if (query[i].size())
            query[i].push_back({st[i],en[i]});
    calc(1);
    for (int i = 1 ; i <= n ; i ++)
        printf("%d ",res[i]);
}


// whats 1000 minus 7 ?
// I'm bad, and that's good. I will never be good, and that's not bad. There's no one I'd rather be than me.
// unless someone like you cares a whole awful lot nothing is going to get better. it's not
#include <bits/stdc++.h>
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline long long lin(){long long x ; scanf("%lld",&x) ; return x ;}
inline string get(){char ch[2000010] ; scanf("%s",ch) ; return ch;}
const int MAX_LG = 21;
//#define int long long
#define X first
#define Y second
#define endl "\n"
#define Mp make_pair
typedef pair<int , int > pii;
typedef long double ld;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pii> vii;
const int maxn = 1e5 + 10;
const int base = 29;
const int mod = 1e9 + 7;
const int INF = 1e9 + 100;
vi g[maxn];
int Root[maxn*20],L[maxn*20],R[maxn*20],st[maxn],en[maxn],cur;
vii query[maxn];
inline void dfs(int node , int fa = -1)
{
    st[node] = cur ++;
    for (auto u : g[node])
    {
        if (u - fa)
            dfs(u,node);
    }
    en[node] = cur - 1;
}
int n , q;
int lazy[maxn*20],stree[maxn*20];
inline int add(int ql , int qr , int p , int l = 0 , int r = n - 1)
{
    if (l > qr || r < ql) return p;
    int ret = cur ++;
    if (l >= ql && r <= qr){
        L[ret] = L[p] , R[ret] = R[p];
        stree[ret] = lazy[ret] = r - l + 1;
        return ret;
    }
    int mid = (l + r) >> 1;
    lazy[ret] = lazy[p];
    L[ret] = add(ql,qr,L[p],l,mid);
    R[ret] = add(ql,qr,R[p],mid+1,r);
    stree[ret] = lazy[ret] ? r - l + 1 : stree[L[ret]] + stree[R[ret]];
    return ret;
}
int res[maxn];
inline void calc(int node , int fa = 0)
{
    Root[node] = Root[fa];
    for (auto q : query[node])
        Root[node] = add(q.first,q.second,Root[node]);
    res[node] = max(stree[Root[node]] - 1,0);
    for (auto u : g[node])
        if (u - fa)
            calc(u,node);
}
inline void build(int p , int l = 0 , int r = n - 1)
{
    if (l == r) return;
    L[p] = cur ++;
    R[p] = cur ++;
    int mid = (l + r) >> 1;
    build(L[p],l,mid),build(R[p],mid+1,r);
}
int32_t main()
{
    n = in() , q = in();
    for (int i = 0 ; i < n - 1; i ++)
    {
        int v = in() , u = in();
        g[v].push_back(u) , g[u].push_back(v);
    }
    dfs(1);
    cur = 1;
    Root[0] = 0;
    build(0,0,n-1);

    for (int i = 0 ; i < q ; i ++)
    {
        int a = in() , b = in();
        query[a].push_back({st[b],en[b]});
        query[b].push_back({st[a],en[a]});
    }
    for (int i = 1 ; i <= n ; i ++)
        if (query[i].size())
            query[i].push_back({st[i],en[i]});
    calc(1);
    for (int i = 1 ; i <= n ; i ++)
        cout << res[i] << " ";
}


// whats 1000 minus 7 ?
// I'm bad, and that's good. I will never be good, and that's not bad. There's no one I'd rather be than me.
// unless someone like you cares a whole awful lot nothing is going to get better. it's not
#include <bits/stdc++.h>
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline long long lin(){long long x ; scanf("%lld",&x) ; return x ;}
inline string get(){char ch[2000010] ; scanf("%s",ch) ; return ch;}
const int MAX_LG = 21;
//#define int long long
#define X first
#define Y second
#define endl "\n"
#define Mp make_pair
typedef pair<int , int > pii;
typedef long double ld;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pii> vii;
const int maxn = 1e7 + 10;
const int base = 29;
const int mod = 1e9 + 7;
const int INF = 1e9 + 100;
vi g[maxn];
int Root[maxn],L[maxn],R[maxn],st[maxn],en[maxn],cur;
vii query[maxn];
inline void dfs(int node , int fa = -1)
{
    st[node] = cur ++;
    for (auto u : g[node])
    {
        if (u - fa)
            dfs(u,node);
    }
    en[node] = cur - 1;
}
int n , q;
int lazy[maxn],stree[maxn];
inline int add(int ql , int qr , int p , int l = 0 , int r = n - 1)
{
    if (l > qr || r < ql) return p;
    int ret = cur ++;
    if (l >= ql && r <= qr){
        L[ret] = L[p] , R[ret] = R[p];
        stree[ret] = lazy[ret] = r - l + 1;
        return ret;
    }
    int mid = (l + r) >> 1;
    lazy[ret] = lazy[p];
    L[ret] = add(ql,qr,L[p],l,mid);
    R[ret] = add(ql,qr,R[p],mid+1,r);
    stree[ret] = lazy[ret] ? r - l + 1 : stree[L[ret]] + stree[R[ret]];
    return ret;
}
int res[maxn];
inline void calc(int node , int fa = 0)
{
    Root[node] = Root[fa];
    for (auto q : query[node])
        Root[node] = add(q.first,q.second,Root[node]);
    res[node] = max(stree[Root[node]] - 1,0);
    for (auto u : g[node])
        if (u - fa)
            calc(u,node);
}
inline void build(int p , int l = 0 , int r = n - 1)
{
    if (l == r) return;
    L[p] = cur ++;
    R[p] = cur ++;
    int mid = (l + r) >> 1;
    build(L[p],l,mid),build(R[p],mid+1,r);
}
int32_t main()
{
    n = in() , q = in();
    for (int i = 0 ; i < n - 1; i ++)
    {
        int v = in() , u = in();
        g[v].push_back(u) , g[u].push_back(v);
    }
    dfs(1);
    cur = 1;
    Root[0] = 0;
    build(0,0,n-1);

    for (int i = 0 ; i < q ; i ++)
    {
        int a = in() , b = in();
        query[a].push_back({st[b],en[b]});
        query[b].push_back({st[a],en[a]});
    }
    for (int i = 1 ; i <= n ; i ++)
        if (query[i].size())
            query[i].push_back({st[i],en[i]});
    calc(1);
    for (int i = 1 ; i <= n ; i ++)
        cout << res[i] << " ";
}


// whats 1000 minus 7 ?
// I'm bad, and that's good. I will never be good, and that's not bad. There's no one I'd rather be than me.
// unless someone like you cares a whole awful lot nothing is going to get better. it's not
#include <bits/stdc++.h>
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline long long lin(){long long x ; scanf("%lld",&x) ; return x ;}
inline string get(){char ch[2000010] ; scanf("%s",ch) ; return ch;}
const int MAX_LG = 21;
//#define int long long
#define X first
#define Y second
#define endl "\n"
#define Mp make_pair
typedef pair<int , int > pii;
typedef long double ld;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pii> vii;
const int maxn = 1e5 + 10;
const int base = 29;
const int mod = 1e9 + 7;
const int INF = 1e9 + 100;
vi g[maxn];
int st[maxn],en[maxn],cur;
vii query[maxn];
struct node
{
    int cnt ;
    bool lazy;
    node *left , *right;
    node()
    {
        cnt = lazy = 0;
        left = right = NULL;
    }
}*Root[maxn];
inline void dfs(int node , int fa = -1)
{
    st[node] = cur ++;
    for (auto u : g[node])
    {
        if (u - fa)
            dfs(u,node);
    }
    en[node] = cur - 1;
}
int n , q;
inline node* add(int ql , int qr , node *p , int l = 0 , int r = n - 1)
{
    if (l > qr || r < ql) return p;
    node *ret = new node();
    if (l >= ql && r <= qr){
        ret->left = p->left;
        ret->right = p->right;
        ret->cnt = r - l + 1;
        ret->lazy = 1;

        return ret;
    }
    int mid = (l + r) >> 1;
    ret->lazy = p->lazy;
    ret->left = add(ql,qr,p->left,l,mid);
    ret->right = add(ql,qr,p->right,mid+1,r);
    ret->cnt = ret->lazy ? r - l + 1 : ret->left->cnt + ret->right->cnt;
    return ret;
}
int res[maxn];
inline void calc(int node , int fa = 0)
{
    Root[node] = Root[fa];
    for (auto q : query[node])
        Root[node] = add(q.first,q.second,Root[node]);
    res[node] = max(Root[node]->cnt - 1,0);
    for (auto u : g[node])
        if (u - fa)
            calc(u,node);
}
inline void build(node *p , int l = 0 , int r = n - 1)
{
    if (l == r) return;
    p->left = new node();
    p->right = new node();
    int mid = (l + r) >> 1;
    build(p->left,l,mid),build(p->right,mid+1,r);
}
int32_t main()
{
    n = in() , q = in();
    for (int i = 0 ; i < n - 1; i ++)
    {
        int v = in() , u = in();
        g[v].push_back(u) , g[u].push_back(v);
    }
    dfs(1);
    Root[0] = new node();
    build(Root[0],0,n-1);
    for (int i = 0 ; i < q ; i ++)
    {
        int a = in() , b = in();
        query[a].push_back({st[b],en[b]});
        query[b].push_back({st[a],en[a]});
    }
    for (int i = 1 ; i <= n ; i ++)
        if (query[i].size())
            query[i].push_back({st[i],en[i]});
    calc(1);
    for (int i = 1 ; i <= n ; i ++)
        printf("%d ",res[i]);
}


// whats 1000 minus 7 ?
// I'm bad, and that's good. I will never be good, and that's not bad. There's no one I'd rather be than me.
// unless someone like you cares a whole awful lot nothing is going to get better. it's not
#include <bits/stdc++.h>
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline long long lin(){long long x ; scanf("%lld",&x) ; return x ;}
inline string get(){char ch[2000010] ; scanf("%s",ch) ; return ch;}
const int MAX_LG = 21;
//#define int long long
#define X first
#define Y second
#define endl "\n"
#define Mp make_pair
typedef pair<int , int > pii;
typedef long double ld;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pii> vii;
const int maxn = 1e5 + 10;
const int base = 29;
const int mod = 1e9 + 7;
const int INF = 1e9 + 100;
vi g[maxn];
int Root[maxn],L[maxn*20],R[maxn*20],st[maxn],en[maxn],cur;
vii query[maxn];
inline void dfs(int node , int fa = -1)
{
    st[node] = cur ++;
    for (auto u : g[node])
    {
        if (u - fa)
            dfs(u,node);
    }
    en[node] = cur - 1;
}
int n , q;
int lazy[maxn*20],stree[maxn*20];
inline int add(int ql , int qr , int p , int l = 0 , int r = n - 1)
{
    if (l > qr || r < ql) return p;
    int ret = cur ++;
    if (l >= ql && r <= qr){
        L[ret] = L[p] , R[ret] = R[p];
        stree[ret] = lazy[ret] = r - l + 1;
        return ret;
    }
    int mid = (l + r) >> 1;
    lazy[ret] = lazy[p];
    L[ret] = add(ql,qr,L[p],l,mid);
    R[ret] = add(ql,qr,R[p],mid+1,r);
    stree[ret] = lazy[ret] ? r - l + 1 : stree[L[ret]] + stree[R[ret]];
    return ret;
}
int res[maxn];
inline void calc(int node , int fa = 0)
{
    Root[node] = Root[fa];
    for (auto q : query[node])
        Root[node] = add(q.first,q.second,Root[node]);
    res[node] = max(stree[Root[node]] - 1,0);
    for (auto u : g[node])
        if (u - fa)
            calc(u,node);
}
inline void build(int p , int l = 0 , int r = n - 1)
{
    if (l == r) return;
    L[p] = cur ++;
    R[p] = cur ++;
    int mid = (l + r) >> 1;
    build(L[p],l,mid),build(R[p],mid+1,r);
}
int32_t main()
{
    n = in() , q = in();
    for (int i = 0 ; i < n - 1; i ++)
    {
        int v = in() , u = in();
        g[v].push_back(u) , g[u].push_back(v);
    }
    dfs(1);
    cur = 1;
    Root[0] = 0;
    build(0,0,n-1);

    for (int i = 0 ; i < q ; i ++)
    {
        int a = in() , b = in();
        query[a].push_back({st[b],en[b]});
        query[b].push_back({st[a],en[a]});
    }
    for (int i = 1 ; i <= n ; i ++)
        if (query[i].size())
            query[i].push_back({st[i],en[i]});
    calc(1);
    for (int i = 1 ; i <= n ; i ++)
        cout << res[i] << " ";
}


#include <bits/stdc++.h>
using namespace std;

typedef struct Treap * Arbore;
typedef pair <Arbore, Arbore> Paa;
Arbore NIL;
Arbore root;

struct Treap {
    int prio, g;
    Arbore st, dr, tata;
    Treap() : prio(rand() | (rand() << 16)), g(1), st(NIL), dr(NIL), tata(NIL) { }
};

Arbore firstap[100010], lastap[100010];
vector <int> adia[100010], coresp[100010];
int rez[100010];
int n;

void recalc(Arbore x)
{
    x->g = x->st->g + x->dr->g + 1;
    x->st->tata = x->dr->tata = x;
    x->tata = NIL;
}
int Ord(Arbore x)
{
    int ans(1 + x->st->g);
    while (x->tata != NIL) {
        if (x->tata->dr == x)
            ans += 1 + x->tata->st->g;
        x = x->tata;
    }
    if (x != root)
        return -1;
    return ans;
}
Arbore join(Arbore a, Arbore b)
{
    if (a == NIL)
        return b;
    if (b == NIL)
        return a;
    if (a->prio > b->prio) {
        a->dr = join(a->dr, b);
        recalc(a);
        return a;
    }
    b->st = join(a, b->st);
    recalc(b);
    return b;
}
Paa split(Arbore a, int where)
{
    if (a == NIL)
        return { NIL, NIL };
    if (where <= a->st->g) {
        Paa s = split(a->st, where);
        a->st = NIL;
        recalc(a);
        return { s.first, join(s.second, a) };
    }
    Paa s = split(a->dr, where - a->st->g - 1);
    a->dr = NIL;
    recalc(a);
    return { join(a, s.first), s.second };
}
void insert(Arbore q, int poz)
{
    if (q == NIL)
        return;
    Paa s = split(root, poz - 1);
    root = join(join(s.first, q), s.second);
}
pair <Arbore, int> get_interv(int nod)
{
    int first = Ord(firstap[nod]);
    if (first == -1)
        return { NIL, 0 };
    int last = Ord(lastap[nod]);

    Paa s1 = split(root, last);
    Paa s2 = split(s1.first, first - 1);
    root = join(s2.first, s1.second);
    return { s2.second, first };
}
Arbore build_parc(int nod, int tata)
{
    firstap[nod] = new Treap();
    Arbore ans = firstap[nod];
    for (auto i : adia[nod])
        if (i != tata)
            ans = join(ans, build_parc(i, nod));
    lastap[nod] = new Treap();
    ans = join(ans, lastap[nod]);
    return ans;
}

void get_rez(int nod, int tata)
{
    vector <pair <Arbore, int>> operations;
    for (auto i : coresp[nod])
        operations.push_back(get_interv(i));
    if (!coresp[nod].empty())
        operations.push_back(get_interv(nod));

    rez[nod] = n - root->g / 2;
    if (rez[nod] != 0)
        rez[nod]--;

    for (auto i : adia[nod])
        if (i != tata)
            get_rez(i, nod);

    reverse(operations.begin(), operations.end());

    for (auto i : operations)
        insert(i.first, i.second);
}

int main()
{
    NIL = new Treap();
    NIL->g = 0;
    root = NIL;
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    int m, a, b;
    cin >> n >> m;

    for (int i(1); i < n; i++) {
        cin >> a >> b;
        adia[a].push_back(b);
        adia[b].push_back(a);
    }

    while (m--) {
        cin >> a >> b;
        coresp[a].push_back(b);
        coresp[b].push_back(a);
    }

    root = build_parc(1, 0);
    get_rez(1, 0);

    for (int i(1); i <= n; i++)
        cout << rez[i] << ' ';
    return 0;
}


// KALAM

# include <bits/stdc++.h>
using namespace std;

const int N = 100000 + 77;
int n , m , st[N] , en[N] , tim = 1 , Mn[N << 3] , Cnt[N << 3] , lz[N << 3] , A[N];
vector < int > a[N];
vector < pair < int , int > > Q[N];
void dfs_pre(int v , int prev){
	st[v] = tim;tim ++;
	for(int u : a[v]){
		if(u == prev){continue;}
		dfs_pre(u , v);
	}
	en[v] = tim ;
}
void Shift(int id){
	Mn[id] += lz[id];
	lz[id << 1] += lz[id];
	lz[id << 1 ^ 1] += lz[id];
	lz[id] = 0;
}
void build(int l = 1 , int r = n + 1 , int id = 1){
	Cnt[id] = r - l;
	if(l + 1 == r){return ;}
	build(l , (l + r) >> 1 , id << 1);
	build((l + r) >> 1 , r , id << 1 ^ 1);
}
void change(int ql , int qr , int x , int l = 1 , int r = n + 1 , int id = 1){
	if(qr <= l || r <= ql){return ;}
	if(ql <= l && r <= qr){lz[id] += x;Shift(id);return ;}
	change(ql , qr , x , l , (l + r) >> 1 , id << 1);Shift(id << 1);
	change(ql , qr , x , (l + r) >> 1 , r , id << 1 ^ 1);Shift(id << 1 ^ 1);
	Mn[id] = min(Mn[id << 1] , Mn[id << 1 ^ 1]);
	Cnt[id] = 0;
	if(Mn[id] == Mn[id << 1]){
		Cnt[id] += Cnt[id << 1];
	}
	if(Mn[id] == Mn[id << 1 ^ 1]){
		Cnt[id] += Cnt[id << 1 ^ 1];
	}
}
inline int get(){
	Shift(1);
	if(Mn[1] != 0){return 0;}
	return Cnt[1];
}
void dfs(int v , int prev){
	for(auto x : Q[v]){
		int u = x.second;
		change(st[v] , en[v] , 1);
		change(st[u] , en[u] , 1);
	}
	A[v] = max(0 , n - get() - 1);
	for(int u : a[v]){
		if(u == prev){continue;}
		dfs(u , v);
	}
	for(auto x : Q[v]){
		int u = x.second;
		change(st[v] , en[v] , - 1);
		change(st[u] , en[u] , - 1);
	}
}
int main(){
	ios_base::sync_with_stdio(0);cin.tie(0);
	cin >> n >> m;
	for(int i = 1;i < n;i++){
		int v , u;cin >> v >> u;
		a[v].push_back(u);
		a[u].push_back(v);
	}
	dfs_pre(1 , 1);
	for(int i = 1;i <= m;i++){
		int v , u;cin >> v >> u;
		Q[v].push_back(make_pair(v , u));
		Q[u].push_back(make_pair(u , v));
	}
	build();

	dfs(1 , 1);
	for(int i = 1;i <= n;i++){
		cout << A[i] << ' ';
	}
	return 0;
}


#include<bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define x first
#define y second
#define pii pair<int, int>
#define sz(a) (int)a.size()
#define fit(ta, a) for(ta::iterator i = a.begin(); i != a.end(); advance(i, 1))
#define rep(i, a, n) for(int i = a; i < n; ++i)
#define dec(i, a, n) for(int i = a; i >= n; --i)
#define clr(a,v) memset(a,v,sizeof(a))
#define all(a) a.begin(),a.end()
#define debug printf
#define ler freopen("in","r",stdin)
#define MAXN 101010
typedef long long lint;
using namespace std;

int n, m, vet[MAXN], st[MAXN<<2], ult[MAXN], pos[MAXN], cnt, ans[MAXN], ret[MAXN];
vector<int>adj[MAXN], querys[MAXN];

void dfs1(int v, int p){
    pos[v] = cnt++;
    rep(i,0,sz(adj[v])) if(adj[v][i]!=p)
        dfs1(adj[v][i],v);
    ult[pos[v]] = cnt-1;
}

void upd(int b, int ini, int fim, int x, int y){
    if(x >= 0){
        if(x <= ini && fim <= y){
            ret[b]++;
            st[b] = (fim-ini)+1;
            return;
        }
         if(y < ini || fim < x) return;
    }else{
        x = -x;
        x--;
        if(x <= ini && fim <= y){
            ret[b]--;
            if(!ret[b]){
                st[b] = 0;
                if(ini<fim) st[b] = st[b<<1] + st[(b<<1)+1];
            } else st[b] = (fim-ini+1);
            return;
        }
         if(y < ini || fim < x) return;
        x = -x-1;
    }
    int meio = (ini+fim)>>1;
    upd((b<<1), ini, meio, x, y);
    upd((b<<1)+1, meio+1, fim, x, y);
    st[b] = (ret[b]?(fim-ini+1):(st[(b<<1)] + st[(b<<1)+1]));
}

void dfs(int v, int p){
    if(sz(querys[v])) upd(1,0,n,pos[v], ult[pos[v]]);
    rep(i,0,sz(querys[v])) upd(1,0,n,pos[querys[v][i]], ult[pos[querys[v][i]]]);
    ans[v] = st[1];
    rep(i,0,sz(adj[v])) if(adj[v][i]!=p)
        dfs(adj[v][i],v);
    if(sz(querys[v])) upd(1,0,n,-pos[v]-1, ult[pos[v]]);
    rep(i,0,sz(querys[v])) upd(1,0,n,-pos[querys[v][i]]-1, ult[pos[querys[v][i]]]);
}

int main(){
    scanf("%d%d", &n, &m);
    rep(i,0,n-1){
        int u, v;
        scanf("%d%d", &u, &v);u--,v--;
        adj[u].pb(v);
        adj[v].pb(u);
    }
    dfs1(0,0);
    rep(i,0,m){
        int a, b;
        scanf("%d%d", &a, &b);a--,b--;
        querys[a].pb(b);
        querys[b].pb(a);
    }
    dfs(0,0);
    rep(i,0,n) printf("%d%c", ans[i]?ans[i]-1:0, i==n-1?'\n':' ');
}


#include<bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define x first
#define y second
#define pii pair<int, int>
#define sz(a) (int)a.size()
#define fit(ta, a) for(ta::iterator i = a.begin(); i != a.end(); advance(i, 1))
#define rep(i, a, n) for(int i = a; i < n; ++i)
#define dec(i, a, n) for(int i = a; i >= n; --i)
#define clr(a,v) memset(a,v,sizeof(a))
#define all(a) a.begin(),a.end()
#define debug printf
#define ler freopen("in","r",stdin)
#define MAXN 101010
typedef long long lint;
using namespace std;

int n, m, vet[MAXN], st[MAXN<<2], ult[MAXN], pos[MAXN], cnt, ans[MAXN], ret[MAXN<<2];
vector<int>adj[MAXN], querys[MAXN];

void dfs1(int v, int p){
    pos[v] = cnt++;
    rep(i,0,sz(adj[v])) if(adj[v][i]!=p)
        dfs1(adj[v][i],v);
    ult[pos[v]] = cnt-1;
}

void upd(int b, int ini, int fim, int x, int y){
    if(x >= 0){
        if(x <= ini && fim <= y){
            ret[b]++;
            st[b] = (fim-ini)+1;
            return;
        }
         if(y < ini || fim < x) return;
    }else{
        x = -x;
        x--;
        if(x <= ini && fim <= y){
            ret[b]--;
            if(!ret[b]){
                st[b] = 0;
                if(ini<fim) st[b] = st[b<<1] + st[(b<<1)+1];
            } else st[b] = (fim-ini+1);
            return;
        }
         if(y < ini || fim < x) return;
        x = -x-1;
    }
    int meio = (ini+fim)>>1;
    upd((b<<1), ini, meio, x, y);
    upd((b<<1)+1, meio+1, fim, x, y);
    st[b] = (ret[b]?(fim-ini+1):(st[(b<<1)] + st[(b<<1)+1]));
}

void dfs(int v, int p){
    if(sz(querys[v])) upd(1,0,n,pos[v], ult[pos[v]]);
    rep(i,0,sz(querys[v])) upd(1,0,n,pos[querys[v][i]], ult[pos[querys[v][i]]]);
    ans[v] = st[1];
    if(ans[v]) --ans[v];
    rep(i,0,sz(adj[v])) if(adj[v][i]!=p)
        dfs(adj[v][i],v);
    if(sz(querys[v])) upd(1,0,n,-pos[v]-1, ult[pos[v]]);
    rep(i,0,sz(querys[v])) upd(1,0,n,-pos[querys[v][i]]-1, ult[pos[querys[v][i]]]);
}

int main(){
    scanf("%d%d", &n, &m);
    rep(i,0,n-1){
        int u, v;
        scanf("%d%d", &u, &v);u--,v--;
        adj[u].pb(v);
        adj[v].pb(u);
    }
    dfs1(0,0);
    rep(i,0,m){
        int a, b;
        scanf("%d%d", &a, &b);a--,b--;
        querys[a].pb(b);
        querys[b].pb(a);
    }
    dfs(0,0);
    rep(i,0,n) printf("%d%c", ans[i], i==n-1?'\n':' ');
}


#include<bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define x first
#define y second
#define pii pair<int, int>
#define sz(a) (int)a.size()
#define fit(ta, a) for(ta::iterator i = a.begin(); i != a.end(); advance(i, 1))
#define rep(i, a, n) for(int i = a; i < n; ++i)
#define dec(i, a, n) for(int i = a; i >= n; --i)
#define clr(a,v) memset(a,v,sizeof(a))
#define all(a) a.begin(),a.end()
#define debug printf
#define ler freopen("in","r",stdin)
#define MAXN 101010
typedef long long lint;
using namespace std;

int n, m, vet[MAXN], st[MAXN<<2], ult[MAXN], pos[MAXN], cnt, ans[MAXN], ret[MAXN<<2];
vector<int>adj[MAXN], querys[MAXN];

void dfs1(int v, int p){
    pos[v] = cnt++;
    rep(i,0,sz(adj[v])) if(adj[v][i]!=p)
        dfs1(adj[v][i],v);
    ult[pos[v]] = cnt-1;
}

void upd(int b, int ini, int fim, int x, int y){
    if(x >= 0){
        if(x <= ini && fim <= y){
            ret[b]++;
            st[b] = (fim-ini)+1;
            return;
        }
         if(y < ini || fim < x) return;
    }else{
        x = -x;
        x--;
        if(x <= ini && fim <= y){
            ret[b]--;
            if(!ret[b]){
                st[b] = 0;
                if(ini<fim) st[b] = st[b<<1] + st[(b<<1)+1];
            } else st[b] = (fim-ini+1);
            return;
        }
         if(y < ini || fim < x) return;
        x = -x-1;
    }
    int meio = (ini+fim)>>1;
    upd((b<<1), ini, meio, x, y);
    upd((b<<1)+1, meio+1, fim, x, y);
    st[b] = (ret[b]?(fim-ini+1):(st[(b<<1)] + st[(b<<1)+1]));
}

void dfs(int v, int p){
    if(sz(querys[v])) upd(1,0,n,pos[v], ult[pos[v]]);
    rep(i,0,sz(querys[v])) upd(1,0,n,pos[querys[v][i]], ult[pos[querys[v][i]]]);
    ans[v] = st[1];
    rep(i,0,sz(adj[v])) if(adj[v][i]!=p)
        dfs(adj[v][i],v);
    if(sz(querys[v])) upd(1,0,n,-pos[v]-1, ult[pos[v]]);
    rep(i,0,sz(querys[v])) upd(1,0,n,-pos[querys[v][i]]-1, ult[pos[querys[v][i]]]);
}

int main(){
    scanf("%d%d", &n, &m);
    rep(i,0,n-1){
        int u, v;
        scanf("%d%d", &u, &v);u--,v--;
        adj[u].pb(v);
        adj[v].pb(u);
    }
    dfs1(0,0);
    rep(i,0,m){
        int a, b;
        scanf("%d%d", &a, &b);a--,b--;
        querys[a].pb(b);
        querys[b].pb(a);
    }
    dfs(0,0);
    rep(i,0,n) printf("%d%c", ans[i], i==n-1?'\n':' ');
}


#include <bits/stdc++.h>
using namespace std;

const int mxN=1e5;
int n, m, st[mxN], en[mxN], dt=0, c[mxN], sta[1<<18], stb[1<<19];
vector<int> adj[mxN], v1[mxN];

void upd(int l1, int r1, int x, int i=1, int l2=0, int r2=n-1) {
	if(!(l1<=l2&&r2<=r1)) {
		int m2=(l2+r2)/2;
		if(l1<=m2)
			upd(l1, r1, x, 2*i, l2, m2);
		if(m2<r1)
			upd(l1, r1, x, 2*i+1, m2+1, r2);
	} else
		sta[i]+=x;
	stb[i]=sta[i]?r2-l2+1:stb[2*i]+stb[2*i+1];
}

void dfs1(int u, int p) {
	st[u]=dt++;
	for(int v : adj[u])
		if(v!=p)
			dfs1(v, u);
	en[u]=dt;
}

void dfs2(int u, int p) {
	if(!v1[u].empty())
		upd(st[u], en[u]-1, 1);
	for(int vi : v1[u])
		upd(st[vi], en[vi]-1, 1);
	c[u]=max(stb[1]-1, 0);
	for(int v : adj[u])
		if(v!=p)
			dfs2(v, u);
	for(int vi : v1[u])
		upd(st[vi], en[vi]-1, -1);
	if(!v1[u].empty())
		upd(st[u], en[u]-1, -1);
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	cin >> n >> m;
	for(int i=0; i<n-1; ++i) {
		int u, v;
		cin >> u >> v, --u, --v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	while(m--) {
		int a, b;
		cin >> a >> b, --a, --b;
		v1[a].push_back(b);
		v1[b].push_back(a);
	}
	dfs1(0, -1);
	dfs2(0, -1);
	for(int i=0; i<n; ++i)
		cout << c[i] << " ";
}


#include<bits/stdc++.h>
#define vi vector<int>
#define pb push_back
using namespace std;
const int N=1e5+5;
struct segmentree{
	int mi,num,add;
}tree[N*16];int n,m;
inline void pushup(int id)
{
	tree[id].mi=min(tree[id<<1].mi,tree[id<<1|1].mi);tree[id].num=0;
	if(tree[id].mi==tree[id<<1].mi)tree[id].num+=tree[id<<1].num;
	if(tree[id].mi==tree[id<<1|1].mi)tree[id].num+=tree[id<<1|1].num;
}
inline void pushdown(int id)
{
	tree[id].mi+=tree[id].add;
	tree[id<<1].add+=tree[id].add;
	tree[id<<1|1].add+=tree[id].add;
	tree[id].add=0;
}
void update(int l,int r,int x,int y,int add,int id)
{
	pushdown(id);
	pushdown(id<<1);
	pushdown(id<<1|1);
	if(x<=l&&r<=y)
	{
		tree[id].add+=add;
		pushdown(id);
		return;
	}
	int mid=(l+r)>>1;
	if(mid>=x)update(l,mid,x,y,add,id<<1);
	if(mid<y)update(mid+1,r,x,y,add,id<<1|1);
	pushup(id);
}
void build(int l,int r,int id)
{
	tree[id].num=r-l+1;
	if(l==r)return;
	int mid=(l+r)>>1;
	build(l,mid,id<<1);
	build(mid+1,r,id<<1|1);
}vi v[N],e[N];int ans[N],pos[N],nxt[N],cnt;
void dfs(int now,int fa)
{
	pos[now]=++cnt;
	for(int i=0;i<v[now].size();i++)
	{
		int to=v[now][i];
		if(to!=fa)
			dfs(to,now);
	}
	nxt[now]=cnt;
}
int query(int l,int r,int v,int id)
{
	pushdown(id);
	if(l==r)return tree[id].mi;
	int mid=(l+r)>>1;//////////
	if(mid>=v)return query(l,mid,v,id<<1);
	else return query(mid+1,r,v,id<<1|1);
}
void dfs2(int now,int fa)
{
//	cout<<now<<"_supercheck: ";
	for(int i=0;i<e[now].size();i++)
		update(1,n,pos[e[now][i]],nxt[e[now][i]],1,1);
	pushdown(1);
	ans[now]=n-(tree[1].mi==0?tree[1].num:0)-(query(1,n,pos[now],1)!=0);
//	for(int i=1;i<=n;i++)cout<<query(1,n,i,1)<<" ";cout<<"\n";
	for(int i=0;i<v[now].size();i++)
	{
		int to=v[now][i];
		if(to!=fa)dfs2(to,now);
	}
	for(int i=0;i<e[now].size();i++)
		update(1,n,pos[e[now][i]],nxt[e[now][i]],-1,1);
}
int main()
{
	cin>>n>>m;
	for(int i=0;i<n-1;i++)
	{
		int a,b;
		cin>>a>>b;
		a--,b--;
		v[a].pb(b);
		v[b].pb(a);
	}
	build(1,n,1);
	dfs(0,-1);
	for(int i=0;i<m;i++)
	{
		int a,b;
		cin>>a>>b;
		a--,b--;
		e[a].pb(b);
		e[a].pb(a);
		e[b].pb(b);
		e[b].pb(a);
	}
	dfs2(0,-1);
	for(int i=0;i<n;i++)
		cout<<ans[i]<<" ";
	return 0;
}


#include <cstdio>
#include <algorithm>
#include <cassert>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

#define LOG(x) cerr << #x << " = " << (x) << "\n"

typedef long long llint;
typedef pair<int,int> pii;

const int MAX = 100010, TOUR = 1<<17;

struct tour {
  int val, broj, prop;
  tour (int val, int broj, int prop) : val(val), broj(broj), prop(prop) {}
  tour () {}
} t[2*TOUR];

struct event {
  int t, l, r, val;
  event (int t, int l, int r, int val) : t(t), l(l), r(r), val(val) {}
  event () {}
};

bool operator < (const event &a, const event &b)
{
  return a.t < b.t;
}

vector <int> V[MAX];
vector <event> E;
int disc[MAX], fin[MAX];
int rje[MAX];
int vr=0;

void Propagiraj(int x)
{
  for (int i=2*x; i<=2*x+1; i++) {
    t[i].prop += t[x].prop;
    t[i].val += t[x].prop;
  }

  t[x].prop = 0;
}

tour Merge(tour l, tour r)
{
  if (l.val < r.val)
    return tour(l.val, l.broj, 0);
  if (r.val < l.val)
    return tour(r.val, r.broj, 0);
  return tour(l.val, l.broj + r.broj, 0);
}

void Stavi(int pos, int lo, int hi, int begin, int end, int val)
{
  if (lo >= end || hi <= begin)
    return;
  if (lo >= begin && hi <= end) {
    t[pos].val += val;
    t[pos].prop += val;
    return;
  }

  Propagiraj(pos);
  Stavi(2*pos+0, lo, (lo+hi)/2, begin, end, val);
  Stavi(2*pos+1, (lo+hi)/2, hi, begin, end, val);

  t[pos] = Merge(t[2*pos], t[2*pos+1]);
}

void Dfs(int node, int prosli)
{
  disc[node] = vr++;

  for (int i=0; i<(int) V[node].size(); i++) {
    int nn = V[node][i];
    if (nn != prosli)
      Dfs(nn, node);
  }

  fin[node] = vr;
}

void Init(int n)
{
  for (int i=0; i<n; i++)
    t[i+TOUR] = tour(0, 1, 0);

  for (int i=n; i<TOUR; i++)
    t[i+TOUR] = tour(1e9, 0, 0);

  for (int i=TOUR-1; i; i--)
    t[i] = Merge(t[2*i], t[2*i+1]);
}

int main()
{
  int n, brq;

  scanf("%d%d", &n, &brq);

  Init(n);

  for (int i=0; i<n-1; i++) {
    int a, b;
    scanf("%d%d", &a, &b); a--; b--;
    V[a].push_back(b);
    V[b].push_back(a);
  }

  Dfs(0, -1);

  for (int i=0; i<brq; i++) {
    int a, b;
    scanf("%d%d", &a, &b); a--; b--;
    E.push_back(event(disc[a], disc[a], fin[a], 1));
    E.push_back(event(fin[a], disc[a], fin[a], -1));
    E.push_back(event(disc[b], disc[a], fin[a],  1));
    E.push_back(event(fin[b], disc[a], fin[a], -1));

    E.push_back(event(disc[a], disc[b], fin[b], 1));
    E.push_back(event(fin[a], disc[b], fin[b], -1));
    E.push_back(event(disc[b], disc[b], fin[b],  1));
    E.push_back(event(fin[b], disc[b], fin[b], -1));
  }

  sort(E.begin(), E.end());

  for (int i=0, ind=0; i<n; i++) {
    for (; ind < (int) E.size() && E[ind].t == i; ind++) {
      event ev = E[ind];
      Stavi(1, 0, TOUR, ev.l, ev.r, ev.val);
    }

    if (t[1].val)
      rje[i] = n - 1;
    else
      rje[i] = max(0, n - t[1].broj - 1);
  }

  for (int i=0; i<n; i++)
    printf("%d ", rje[disc[i]]);
  printf("\n");

  return 0;
}


#include <cstdio>
#include <algorithm>
#include <cassert>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

#define LOG(x) cerr << #x << " = " << (x) << "\n"

typedef long long llint;
typedef pair<int,int> pii;

const int MAX = 100010, TOUR = 1<<17;

struct tour {
  int val, broj, prop;
  tour (int val, int broj, int prop) : val(val), broj(broj), prop(prop) {}
  tour () {}
} t[2*TOUR];

struct event {
  int t, l, r, val;
  event (int t, int l, int r, int val) : t(t), l(l), r(r), val(val) {}
  event () {}
};

bool operator < (const event &a, const event &b)
{
  return a.t < b.t;
}

vector <int> V[MAX];
vector <event> E;
int disc[MAX], fin[MAX];
int rje[MAX];
int vr=0;

void Propagiraj(int x)
{
  for (int i=2*x; i<=2*x+1; i++) {
    t[i].prop += t[x].prop;
    t[i].val += t[x].prop;
  }

  t[x].prop = 0;
}

tour Merge(tour l, tour r)
{
  if (l.val < r.val)
    return tour(l.val, l.broj, 0);
  if (r.val < l.val)
    return tour(r.val, r.broj, 0);
  return tour(l.val, l.broj + r.broj, 0);
}

void Stavi(int pos, int lo, int hi, int begin, int end, int val)
{
  if (lo >= end || hi <= begin)
    return;
  if (lo >= begin && hi <= end) {
    t[pos].val += val;
    t[pos].prop += val;
    return;
  }

  Propagiraj(pos);
  Stavi(2*pos+0, lo, (lo+hi)/2, begin, end, val);
  Stavi(2*pos+1, (lo+hi)/2, hi, begin, end, val);

  t[pos] = Merge(t[2*pos], t[2*pos+1]);
}

void Dfs(int node, int prosli)
{
  disc[node] = vr++;

  for (int i=0; i<(int) V[node].size(); i++) {
    int nn = V[node][i];
    if (nn != prosli)
      Dfs(nn, node);
  }

  fin[node] = vr;
}

void Init(int n)
{
  for (int i=0; i<n; i++)
    t[i+TOUR] = tour(0, 1, 0);

  for (int i=n; i<TOUR; i++)
    t[i+TOUR] = tour(1e9, 0, 0);

  for (int i=TOUR-1; i; i--)
    t[i] = Merge(t[2*i], t[2*i+1]);
}

int main()
{
  int n, brq;

  scanf("%d%d", &n, &brq);

  Init(n);

  for (int i=0; i<n-1; i++) {
    int a, b;
    scanf("%d%d", &a, &b); a--; b--;
    V[a].push_back(b);
    V[b].push_back(a);
  }

  Dfs(0, -1);
  for (int i=0; i<n; i++)
    printf("III %d %d\n", i, disc[i]);

  for (int i=0; i<brq; i++) {
    int a, b;
    scanf("%d%d", &a, &b); a--; b--;
    E.push_back(event(disc[a], disc[a], fin[a], 1));
    E.push_back(event(fin[a], disc[a], fin[a], -1));
    E.push_back(event(disc[b], disc[a], fin[a],  1));
    E.push_back(event(fin[b], disc[a], fin[a], -1));

    E.push_back(event(disc[a], disc[b], fin[b], 1));
    E.push_back(event(fin[a], disc[b], fin[b], -1));
    E.push_back(event(disc[b], disc[b], fin[b],  1));
    E.push_back(event(fin[b], disc[b], fin[b], -1));
  }

  sort(E.begin(), E.end());

  for (int i=0, ind=0; i<n; i++) {
    for (; ind < (int) E.size() && E[ind].t == i; ind++) {
      event ev = E[ind];
      Stavi(1, 0, TOUR, ev.l, ev.r, ev.val);
    }

    if (t[1].val)
      rje[i] = 0;
    else
      rje[i] = max(0, n - t[1].broj - 1);
  }

  for (int i=0; i<n; i++)
    printf("%d ", rje[disc[i]]);
  printf("\n");

  return 0;
}