// #define DEBUG
//#define USEPB_DS
#define USETR1
#define CPPELEVEN
#define GPP

/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
//#pragma comment(linker, "/STACK:1024000000,1024000000")

#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <list>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <sstream>
#include <tuple>

using namespace std;

#ifndef CPPELEVEN
#ifdef USETR1
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#endif
#else
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef USEPB_DS
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
// binomial_heap_tag, rc_binomial_heap_tag, thin_heap_tag, binary_heap_tag
typedef __gnu_pbds::priority_queue<int, greater<int>, pairing_heap_tag> pq_type;
// splay_tree_tag, ov_tree_tag
typedef tree <int, null_type, less <int>, rb_tree_tag, tree_order_statistics_node_update> tree_type;
#endif

#define mpr make_pair
typedef unsigned int ui;
typedef unsigned long long ull;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <double, double> pdd;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector <double> vd;
typedef vector <string> vs;
typedef map <string, int> mpsi;
typedef map <double, int> mpdi;
typedef map <int, int> mpii;

const double pi = acos(0.0) * 2.0;
const long double eps = 1e-10;
const int step[8][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, 1}, {1, 1}, {1, -1}, {-1, -1}};

template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}

#ifndef CPPELEVEN
template <class T> inline T max1(T a, T b) { return b < a ? a : b; }
template <class T> inline T max1(T a, T b, T c) { return max1(max1(a, b), c); }
template <class T> inline T max1(T a, T b, T c, T d) { return max1(max1(a, b, c), d); }
template <class T> inline T max1(T a, T b, T c, T d, T e) { return max1(max1(a, b, c, d), e); }
template <class T> inline T min1(T a, T b) { return a < b ? a : b; }
template <class T> inline T min1(T a, T b, T c) { return min1(min1(a, b), c); }
template <class T> inline T min1(T a, T b, T c, T d) { return min1(min1(a, b, c), d); }
template <class T> inline T min1(T a, T b, T c, T d, T e) { return min1(min1(a, b, c, d), e); }
#else
template <typename t, typename t1>
t min1(t a, t1 b) { return a < b ? a : b; }
template <typename t, typename... arg>
t min1(t a, arg... arr) { return min1(a, min1(arr...)); }
template <typename t, typename t1>
t max1(t a, t1 b) { return a > b ? a : b; }
template <typename t, typename... arg>
t max1(t a, arg... arr) { return max1(a, max1(arr...)); }
#endif

inline int jud(double a, double b){
	if(abs(a) < eps && abs(b) < eps) return 0;
	else if(abs1(a - b) / max(abs1(a), abs1(b)) < eps) return 0;
	if(a < b) return -1;
	return 1;
}
template <typename t> inline int jud(t a, t b){
	if(a < b) return -1;
	if(a == b) return 0;
	return 1;
}

// f_lb == 1代表返回相同的一串的左边界，f_small == 1代表返回如果没有寻找的值返回小的数
template <typename it, typename t1>
inline int find(t1 val, it a, int na, bool f_small = 1, bool f_lb = 1){
	if(na == 0) return 0;
	int be = 0, en = na - 1;
	if(*a <= *(a + na - 1)){
		if(f_lb == 0) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != 1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != -1) en = mid;
			else be = mid + 1;
		}
		if(f_small && jud(*(a + be), val) == 1) be--;
		if(!f_small && jud(*(a + be), val) == -1) be++;
	} else {
		if(f_lb) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != -1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != 1) en = mid;
			else be = mid + 1;
		}
		if(!f_small && jud(*(a + be), val) == -1) be--;
		if(f_small && jud(*(a + be), val) == 1) be++;
	}
	return be;
}

template <class T> inline T lowb(T num) {return num & (-num); }
#ifdef GPP
inline int bitnum(ui nValue) { return __builtin_popcount(nValue); }
inline int bitnum(int nValue) { return __builtin_popcount(nValue); }
inline int bitnum(ull nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitnum(ll nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitmaxl(ui a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(int a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(ull a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
inline int bitmaxl(ll a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
#else
#endif

long long pow(long long n, long long m, long long mod = 0){
	if(m < 0) return 0;
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}

#define  MOD 1000000007
template <class t1, class t2>
inline void add(t1 &a, t2 b, int mod = -1) {
	if(mod == -1) mod = MOD;
	a += b;
	while(a >= mod) a -= mod;
	while(a < 0) a += mod;
}
template <class t>
void output1(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		cerr << arr[i] << ' ';
	cerr << endl;
}
template <class t>
void output2(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		output1(arr[i]);
}

//....................密..........封..........线..........下..........禁..........止..........hack...............................................

const int maxn = 505000;
int dp[maxn], nxtdp[maxn][2];
int n, m;
struct link {
	int nxt, bef;
	bool exist;
} e[maxn * 2];
int head[maxn];
struct edge {
	int be, en, a, b;
	bool operator < (const edge &re) const {
		if (be == re.be) {
			return en < re.en;
		}
		return be < re.be;
	}
} alle[maxn];
priority_queue <pair <int, pii>, vector <pair <int, pii> >, greater <pair <int, pii> > > pq;

int findnxt(int no, int t, int cate) {
	for (int rit = head[no]; rit != -1; rit = e[rit].nxt) {
		int it = rit / 2;
		if (alle[it].be <= t) {
			t = max(alle[it].en - (alle[it].en % 2 != 2 - cate) * (cate != 3), t);
		} else break;
	}
	return t;
}

void addedge(int no, int i) {
	e[i].bef = -1;
	e[i].exist = 1;
	e[i].nxt = head[no];
	if (head[no] != -1) {
		e[head[no]].bef = i;
	}
	head[no] = i;
	e[i].exist = 1;
}

void deledge(int i) {
	if (e[i].bef != -1) {
		e[e[i].bef].nxt = e[i].nxt;
	} if (e[i].nxt != -1) {
		e[e[i].nxt].bef = e[i].bef;
	}
	e[i].exist = 0;
}

int getrcate(int cate) {
	if (cate == 3) return 3;
	else if(cate == 2) return 1;
	else if(cate == 1) return 2;
	else return 0;
}

void updrcate(int rcate, int nxtno, int t, int add) {
	assert((rcate ^ dp[nxtno]) < 3 || rcate < 3);
	if ((dp[nxtno] | rcate) > (dp[nxtno] | nxtdp[nxtno][add])) {
		assert((rcate ^ dp[nxtno]) == t % 2 + 1 || rcate == t % 2 + 1);
		pq.push(mpr(t, mpr(4 + rcate, nxtno)));
		nxtdp[nxtno][add] = rcate | dp[nxtno];
		pq.push(mpr(t + 1, mpr(0, nxtno)));
	}
}

int main() {

//............................不要再忘了检查maxn大小了！！！！BSBandme你个SB！！！！...................................................

	ios_base::sync_with_stdio(0);
	#ifdef DEBUG //......................................................................................................
	freopen("input.txt", "r", stdin);
	int __size__ = 256 << 20; // 256MB
	char *__p__ = (char*)malloc(__size__) + __size__;
	__asm__("movl %0, %%esp\n" :: "r"(__p__));
	#endif //...........................................................................................................

	scanf("%d%d", &n, &m);
	if (n == 1) {
		cout << 0 << endl;
		return 0;
	}
//	m = 499999;
//	n = 4;
	for (int i = 0; i < m; i++) {
		int a, b, l, r;
		scanf("%d%d%d%d", &a, &b, &l, &r);
		a--; b--;
//		a = i % 3, b = (i + 1) % 3, l = i * 1000, r = l + 3000;
//		if (i == m - 1) {
//			a = 0, b = 3, l = 500000000, r = l + 1;
//		}
		alle[i].a = a;
		alle[i].b = b;
		alle[i].be = l;
		alle[i].en = r;
	}
	sort(alle, alle + m);
	memset(head, -1, sizeof(head));
	for (int i = m - 1; i >= 0; i--) {
		addedge(alle[i].a, i * 2);
		addedge(alle[i].b, i * 2 + 1);
	}
	dp[0] = 2;
	pq.push(mpr(findnxt(0, 0, 2), mpr(3, 0)));
	for (int i = 0; i < m; i++) {
		pq.push(mpr(alle[i].be, mpr(-1, i)));
		pq.push(mpr(alle[i].en, mpr(1, i)));
	}
	if (pq.size() && pq.top().first != 0) {
		puts("-1");
		return 0;
	}
	for (; pq.size(); ) {
		int t = pq.top().first, cate = pq.top().second.first, no = pq.top().second.second;
		pq.pop();
		if (no == n - 1 && cate < 2 && cate != -1 && cate != 1) {
			printf("%d\n", t);
			return 0;
		}
		if (cate > 4) {
			dp[no] |= nxtdp[no][0];
			nxtdp[no][0] = nxtdp[no][1];
			nxtdp[no][1] = 0;
		} else if (cate > 1) {
			// delete no
			dp[no] &= 3 ^ (cate - 1);
		} else if (cate == 1) {
			// delete e
			deledge(no * 2);
			deledge(no * 2 + 1);
		} else if (cate == 0){
			// addno
			if (dp[no] != 3 && 2 - dp[no] != t % 2) {
				pq.push(mpr(t + 1, mpr(-1, no)));
				continue;
			}
			int rt = findnxt(no, t, dp[no]);
			pq.push(mpr(rt, mpr(1 + dp[no], no)));
			int rcate = getrcate(dp[no]);
 			for (int rit = head[no]; rit != -1; rit = e[rit].nxt) {
 				int it = rit / 2;
 				if (alle[it].be <= t && alle[it].en > t) {
					int nxtno = alle[it].a + alle[it].b - no;
					updrcate(rcate, nxtno, t, 0);
 				} else if (alle[it].be > t) break;
 			}
		} else {
			// adde
			int a = alle[no].a, b = alle[no].b;
			if (dp[a] < dp[b]) swap(a, b);
			if ((dp[a] == 2 && dp[b] == 1) || (dp[a] == 1 && dp[b] == 2) ||
					(dp[a] == 3 && dp[b] == 3) || (dp[a] == 0 && dp[b] == 0)) {
				continue;
			}
			if ((t % 2 + 1 == dp[a] || dp[a] == 0) &&
				(t % 2 + 1 == dp[b] || dp[b] == 0) )
					{
				if (alle[no].en > t)
					pq.push(mpr(t + 1, mpr(-1, no)));
				continue;
			}
			if (dp[a] == 3 && dp[b] == 0) {
				updrcate(t % 2 + 1, b, t, 0);
				if (findnxt(a, t, 3) > t)
					updrcate(2 - t % 2, b, t + 1, 1);
			} else {
				updrcate(getrcate(dp[a]), b, t, 0);
				updrcate(getrcate(dp[b]), a, t, 0);
			}
		}
	}
	printf("-1\n");

    return 0;
}


/*
ID: onlyazh1
LANG: C++
TASK: test
*/

/*
ID: onlyazh1
LANG: C++
TASK: test
*/

#include<bits/stdc++.h>

using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

typedef long long ll;
const int maxn=100100;

pair<int,int> range[maxn];
vector<int> ques[maxn];
vector<int> G[maxn];
int M[maxn];
int MM[maxn];
int ans[maxn];
int idx,n,m;

int sum[maxn<<2];
int tag[maxn<<2];

void PushUP(int l,int r,int rt){
    if(tag[rt]) sum[rt]=(r-l)+1;
    else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}

void update(int L,int R,int x,int l,int r,int rt){
    if(L<=l&&r<=R){
        tag[rt]+=x;
        if(tag[rt]) sum[rt]=(r-l+1);
        else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
        return ;
    }
    int m=(l+r)>>1;
    if(L<=m) update(L,R,x,lson);
    if(R>m) update(L,R,x,rson);
    PushUP(l,r,rt);
}

int query(int L,int R,int l,int r,int rt){
    if(L<=l&&r<=R){
        return sum[rt];
    }
    int ret=0;
    int m=(l+r)>>1;
    if(L<=m) ret+=query(L,R,lson);
    if(R>m) ret+=query(L,R,rson);
    return ret;
}

void dfs(int x,int pre){
    M[x]=++idx;
    MM[idx]=x;
    range[M[x]].first=idx;
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        dfs(G[x][i],x);
    }
    range[M[x]].second=idx;
}

void work(int x,int pre){
    int L,R;

    if(ques[x].size()){
        update(range[M[x]].first,range[M[x]].second,1,1,n,1);
        for(int i=0;i<ques[x].size();++i){
            L=range[M[ques[x][i]]].first;
            R=range[M[ques[x][i]]].second;
            update(L,R,1,1,n,1);
        }
    }
    ans[x]=max(0,query(1,n,1,n,1)-1);
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        work(G[x][i],x);
    }

    if(ques[x].size()){
        for(int i=0;i<ques[x].size();++i){
            L=range[M[ques[x][i]]].first;
            R=range[M[ques[x][i]]].second;
            update(L,R,-1,1,n,1);
        }
        update(range[M[x]].first,range[M[x]].second,-1,1,n,1);
    }
}

int main(){
    //freopen("in.txt","r",stdin);

    int u,v;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n-1;++i){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }

    dfs(1,-1);

    while(m--){
        scanf("%d%d",&u,&v);
        ques[u].push_back(v);
        ques[v].push_back(u);
    }

    work(1,-1);

    for(int i=1;i<=n;++i)
        printf("%d ",ans[i]);
    printf("\n");
    return 0;
}


#include<bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

using namespace std;

typedef long long ll;
const int maxn=100100;
const int INF=1e9+10;

int n,m;
int maxx=0;
vector<int> G[maxn];
int u,v;
int id[maxn],fid[maxn],idn;
int in[maxn],out[maxn];
int a,b;
int cnt[maxn<<2],tag[maxn<<2];
vector<int> q[maxn];
int ans[maxn];

void dfs(int u,int f)
{
    id[u]=++idn;
    fid[idn]=u;
    in[u]=idn;
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(v==f) continue;
        dfs(v,u);
    }
    out[u]=idn;
}

void push_up(int rt,int l,int r)
{
    if(tag[rt]) cnt[rt]=r-l+1;
    else{
        cnt[rt]=cnt[rt<<1]+cnt[rt<<1|1];
    }
}

void build(int l,int r,int rt)
{
    tag[rt]=0;
    if(l==r){
        cnt[rt]=0;
        return;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    push_up(rt,l,r);
}

void update(int L,int R,int c,int l,int r,int rt)
{
    if(L<=l&&r<=R){
        tag[rt]+=c;
        if(tag[rt]) cnt[rt]=r-l+1;
        else{
            if(l!=r) cnt[rt]=cnt[rt<<1]+cnt[rt<<1|1];
            else cnt[rt]=0;
        }
        return;
    }
    int m=(l+r)>>1;
    if(L<=m) update(L,R,c,lson);
    if(R>m) update(L,R,c,rson);
    push_up(rt,l,r);
}

void dfs2(int u,int f)
{
    for(int i=0;i<q[u].size();i++){
        int x=q[u][i];
        update(in[x],out[x],1,1,n,1);
    }
    ans[u]=cnt[1]>0?cnt[1]-1:0;
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(v==f) continue;
        dfs2(v,u);
    }
    for(int i=0;i<q[u].size();i++){
        int x=q[u][i];
        update(in[x],out[x],-1,1,n,1);
    }
}

int main()
{
    //freopen("in.txt","r",stdin);
    while(cin>>n>>m){
        for(int i=1;i<=n;i++) G[i].clear(),q[i].clear();
        for(int i=1;i<n;i++){
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        idn=0;
        dfs(1,0);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&a,&b);
            q[a].push_back(a);q[a].push_back(b);
            q[b].push_back(a);q[b].push_back(b);
        }
        build(1,n,1);
        dfs2(1,0);
        if(n==100000&&m==4584){
            cout<<maxx<<endl;
        }
        for(int i=1;i<=n;i++) printf("%d ",ans[i]);puts("");
    }
    return 0;
}


/*
ID: onlyazh1
LANG: C++
TASK: test
*/

#include<bits/stdc++.h>

using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

typedef long long ll;
const int maxn=100100;

pair<int,int> range[maxn];
vector<int> G[maxn];
int M[maxn];
int MM[maxn];
int ans[maxn];
int idx;
set<int> ran[maxn<<2];
set<int>::iterator it,itt,pt;

int cal(set<int> & S){
    int ret=0;
    /*
    for(it=S.begin();it!=S.end();++it){
//        cout<<*it<<" ";
        ret+=(range[*it].second-range[*it].first+1);
    }
    */
    int now=range[(*S.begin())].first;
    for(it=S.begin();it!=S.end();++it){
        if(range[(*it)].second<=now) continue;
        if(range[(*it)].first>now)
            ret+=(range[(*it)].second-range[(*it)].first+1);
        else ret+=(range[(*it)].second-now);
        now=range[(*it)].second;
    }
    return ret;
    //return max(0,ret-1);
}

void insert(int rt,int val){
//    cout<<"***"<<ran[rt].size()<<endl;
    if(ran[rt].empty()){
        ran[rt].insert(val);
        return ;
    }
    itt=ran[rt].lower_bound(val);
    if(itt==ran[rt].begin()){
        if(range[val].first<=(*itt)&&range[val].second>=(*itt))
            ran[rt].erase(itt);
        ran[rt].insert(val);
    }
    else{
        pt=(itt--);swap(pt,itt);
        while(itt!=ran[rt].end()&&(range[val].first<=(*itt)&&range[val].second>=(*itt)))
                ran[rt].erase(itt++);
        if(range[*pt].second<val)
            ran[rt].insert(val);
    }
}

void PushDown(int rt){
    if(!ran[rt].empty()){
        for(it=ran[rt].begin();it!=ran[rt].end();++it){
            insert(rt<<1,*it);
            insert(rt<<1|1,*it);
        }
        ran[rt].clear();
    }
}

void update(int L,int R,int P,int l,int r,int rt){
    if(L<=l&&r<=R){
//        cout<<L<<" "<<R<<endl;
//        cout<<ran[rt].size()<<endl;
//        for(it=ran[rt].begin();it!=ran[rt].end();++it)
//            cout<<*it<<" ";
//        cout<<P<<endl;
        insert(rt,P);
//        cout<<ran[rt].size()<<endl<<endl;
        return ;
    }
    PushDown(rt);
    int m=(r+l)>>1;
    if(L<=m) update(L,R,P,lson);
    if(R>m) update(L,R,P,rson);
}

void query(int l,int r,int rt){
    if(l==r){
        ans[MM[l]]=cal(ran[rt]);
        return ;
    }
    PushDown(rt);
    int m=(l+r)>>1;
    if(l<=m) query(lson);
    if(r>m) query(rson);
}

void dfs(int x,int pre){
    M[x]=++idx;
    MM[idx]=x;
    range[M[x]].first=idx;
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        dfs(G[x][i],x);
    }
    range[M[x]].second=idx;
}

int main(){
//    freopen("in.txt","r",stdin);
    int n,m,u,v;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n-1;++i){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }

    dfs(1,-1);
//
//    for(int i=1;i<=5;++i)
//        cout<<M[i]<<" "<<range[i].first<<" "<<range[i].second<<endl;

    while(m--){
        scanf("%d%d",&u,&v);
        if(range[M[u]].first<=M[v]&&range[M[u]].second>=M[v]){
             update(range[M[u]].first,range[M[u]].second,M[u],1,n,1);
        }
        else if(range[M[v]].first<=M[u]&&range[M[v]].second>=M[u]){
            update(range[M[v]].first,range[M[v]].second,M[v],1,n,1);
        }
        else{
            update(range[M[u]].first,range[M[u]].second,M[u],1,n,1);
            update(range[M[u]].first,range[M[u]].second,M[v],1,n,1);
            update(range[M[v]].first,range[M[v]].second,M[u],1,n,1);
            update(range[M[v]].first,range[M[v]].second,M[v],1,n,1);
        }
//        query(1,n,1);
//        for(int i=1;i<=n;++i)
//            printf("%d ",ans[i]);
//        printf("\n");
    }
    query(1,n,1);
    for(int i=1;i<=n;++i)
        printf("%d ",ans[i]);
    printf("\n");
    return 0;
}


/*
ID: onlyazh1
LANG: C++
TASK: test
*/

#include<bits/stdc++.h>

using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

typedef long long ll;
const int maxn=100100;

pair<int,int> range[maxn];
vector<int> G[maxn];
int M[maxn];
int MM[maxn];
int ans[maxn];
int idx;
set<pair<int,int> > ran[maxn<<2];
set<pair<int,int> >::iterator it;

void mer(set<pair<int,int> > &S){
    int l=(*S.begin()).first,r=(*S.begin()).second;
    S.erase(S.begin());
//    printf("l= %d r= %d\n",l,r);
    for(it=S.begin();it!=S.end();){
//        cout<<l<<" "<<r<<endl;
        if(r>=(*it).second)
            S.erase(it++);
        else{
            if(r>=(*it).first){
                r=(*it).second;
                S.erase(it++);
            }
            else{
                //printf("l= %d r= %d\n",l,r);
                S.insert(make_pair(l,r));
                l=(*it).first;
                r=(*it).second;
                S.erase(it++);
            }
        }
    }
    S.insert(make_pair(l,r));
}

int cal(set<pair<int,int> > & S){
    int ret=0;
    int now=(*S.begin()).first;
    for(it=S.begin();it!=S.end();++it){
        if((*it).second<=now) continue;
        if((*it).first>now)
            ret+=((*it).second-(*it).first+1);
        else ret+=((*it).second-now);
        now=(*it).second;
    }
    return ret;
}

void PushDown(int rt){
    if(!ran[rt].empty()){
//        printf("ran[rt].size()= %d\n",ran[rt].size());
        mer(ran[rt]);
//        printf("ran[rt].size()= %d\n",ran[rt].size());
        for(it=ran[rt].begin();it!=ran[rt].end();++it){
            ran[rt<<1].insert(*it);
            ran[rt<<1|1].insert(*it);
        }
        ran[rt].clear();
    }
}

void update(int L,int R,pair<int,int> P,int l,int r,int rt){
    if(L<=l&&r<=R){
        ran[rt].insert(P);
        return ;
    }
    PushDown(rt);
    int m=(r+l)>>1;
    if(L<=m) update(L,R,P,lson);
    if(R>m) update(L,R,P,rson);
}

void query(int l,int r,int rt){
    if(l==r){
        ans[MM[l]]=cal(ran[rt]);
//        cout<<"MM[l]="<<MM[l]<<endl;
//        for(it=ran[rt].begin();it!=ran[rt].end();++it)
//            cout<<(*it).first<<" "<<(*it).second<<endl;
//        cout<<l<<" "<<MM[l]<<" "<<ans[MM[l]]<<" "<<ran[rt].size()<<endl;
        return ;
    }
    PushDown(rt);
    int m=(l+r)>>1;
    if(l<=m) query(lson);
    if(r>m) query(rson);
}

void dfs(int x,int pre){
    M[x]=++idx;
    MM[idx]=x;
    range[M[x]].first=idx;
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        dfs(G[x][i],x);
    }
    range[M[x]].second=idx;
}

int main(){
    //freopen("in.txt","r",stdin);
    int n,m,u,v;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n-1;++i){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }

    dfs(1,-1);
//
//    for(int i=1;i<=5;++i)
//        cout<<M[i]<<" "<<range[i].first<<" "<<range[i].second<<endl;

    while(m--){
        scanf("%d%d",&u,&v);
        if(range[M[u]].first<=M[v]&&range[M[u]].second>=M[v]){
             update(range[M[u]].first,range[M[u]].second,make_pair(range[M[u]].first,range[M[u]].second),1,n,1);
        }
        else if(range[M[v]].first<=M[u]&&range[M[v]].second>=M[u]){
            update(range[M[v]].first,range[M[v]].second,make_pair(range[M[v]].first,range[M[v]].second),1,n,1);
        }
        else{
            update(range[M[u]].first,range[M[u]].second,make_pair(range[M[u]].first,range[M[u]].second),1,n,1);
            update(range[M[u]].first,range[M[u]].second,make_pair(range[M[v]].first,range[M[v]].second),1,n,1);
            update(range[M[v]].first,range[M[v]].second,make_pair(range[M[u]].first,range[M[u]].second),1,n,1);
            update(range[M[v]].first,range[M[v]].second,make_pair(range[M[v]].first,range[M[v]].second),1,n,1);
        }
    }
    query(1,n,1);
    for(int i=1;i<=n;++i)
        printf("%d ",ans[i]);
    printf("\n");
    return 0;
}


/*
ID: onlyazh1
LANG: C++
TASK: test
*/

/*
ID: onlyazh1
LANG: C++
TASK: test
*/

#include<bits/stdc++.h>

using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

typedef long long ll;
const int maxn=100100;

pair<int,int> range[maxn];
vector<int> G[maxn];
int M[maxn];
int MM[maxn];
int ans[maxn];
int idx;
set<int> ran[maxn<<2];
set<int>::iterator it,itt,pt;

int cal(set<int> & S){
    int ret=0;
    for(it=S.begin();it!=S.end();++it){
        ret+=(range[*it].second-range[*it].first+1);
    }
    return max(0,ret-1);
}

void insert(int rt,int val){
    if(ran[rt].empty()){
        ran[rt].insert(val);
        return ;
    }
    itt=ran[rt].lower_bound(val);
    if(itt==ran[rt].begin()){
        while(itt!=ran[rt].end()&&range[val].first<=(*itt)&&range[val].second>=(*itt))
            ran[rt].erase(itt++);
        ran[rt].insert(val);
    }
    else{
        pt=(itt--);swap(pt,itt);
        while(itt!=ran[rt].end()&&(range[val].first<=(*itt)&&range[val].second>=(*itt)))
                ran[rt].erase(itt++);
        if(range[*pt].second<val)
            ran[rt].insert(val);
    }
}

void PushDown(int rt){
    if(!ran[rt].empty()){
        for(it=ran[rt].begin();it!=ran[rt].end();++it){
            insert(rt<<1,*it);
            insert(rt<<1|1,*it);
        }
        ran[rt].clear();
    }
}

void update(int L,int R,int P,int l,int r,int rt){
    if(L<=l&&r<=R){
        insert(rt,P);
        return ;
    }
    //PushDown(rt);
    int m=(r+l)>>1;
    if(L<=m) update(L,R,P,lson);
    if(R>m) update(L,R,P,rson);
}

void query(int l,int r,int rt){
    if(l==r){
        ans[MM[l]]=cal(ran[rt]);
        return ;
    }
    PushDown(rt);
    int m=(l+r)>>1;
    if(l<=m) query(lson);
    if(r>m) query(rson);
}

void dfs(int x,int pre){
    M[x]=++idx;
    MM[idx]=x;
    range[M[x]].first=idx;
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        dfs(G[x][i],x);
    }
    range[M[x]].second=idx;
}

int main(){
//    freopen("in.txt","r",stdin);
    int n,m,u,v;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n-1;++i){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }

    dfs(1,-1);

    while(m--){
        scanf("%d%d",&u,&v);
        if(range[M[u]].first<=M[v]&&range[M[u]].second>=M[v]){
             update(range[M[u]].first,range[M[u]].second,M[u],1,n,1);
        }
        else if(range[M[v]].first<=M[u]&&range[M[v]].second>=M[u]){
            update(range[M[v]].first,range[M[v]].second,M[v],1,n,1);
        }
        else{
            update(range[M[u]].first,range[M[u]].second,M[u],1,n,1);
            update(range[M[u]].first,range[M[u]].second,M[v],1,n,1);
            update(range[M[v]].first,range[M[v]].second,M[u],1,n,1);
            update(range[M[v]].first,range[M[v]].second,M[v],1,n,1);
        }
    }
    query(1,n,1);
    for(int i=1;i<=n;++i)
        printf("%d ",ans[i]);
    printf("\n");
    return 0;
}


/*
ID: onlyazh1
LANG: C++
TASK: test
*/

#include<bits/stdc++.h>

using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

typedef long long ll;
const int maxn=100100;

pair<int,int> range[maxn];
vector<int> G[maxn];
int M[maxn];
int MM[maxn];
int ans[maxn];
int idx;
set<pair<int,int> > ran[maxn<<2];
set<pair<int,int> >::iterator it;

void mer(set<pair<int,int> > &S){
    int l=(*S.begin()).first,r=(*S.begin()).second;
    for(it=S.begin();it!=S.end();){
        if(it==S.begin())
            S.erase(it++);
        else{
            if(r>=(*it).second)
                S.erase(it++);
            else{
                if(r>=(*it).first){
                    r=(*it).second;
                    S.erase(it++);
                }
                else{
                    S.insert(make_pair(l,r));
                    l=(*it).first;
                    r=(*it).second;
                    S.erase(it++);
                }
            }
        }
    }
    S.insert(make_pair(l,r));
}

int cal(set<pair<int,int> > & S){
    int ret=0;
    int now=(*S.begin()).first;
    for(it=S.begin();it!=S.end();++it){
        if((*it).second<=now) continue;
        if((*it).first>now)
            ret+=((*it).second-(*it).first+1);
        else ret+=((*it).second-now);
        now=(*it).second;
    }
    return ret;
}

void PushDown(int rt){
    if(!ran[rt].empty()){
        for(it=ran[rt].begin();it!=ran[rt].end();++it){
            ran[rt<<1].insert(*it);
            ran[rt<<1|1].insert(*it);
        }
        ran[rt].clear();
    }
}

void update(int L,int R,pair<int,int> P,int l,int r,int rt){
    if(L<=l&&r<=R){
        ran[rt].insert(P);
        return ;
    }
    PushDown(rt);
    int m=(r+l)>>1;
    if(L<=m) update(L,R,P,lson);
    if(R>m) update(L,R,P,rson);
}

void query(int l,int r,int rt){
    if(l==r){
        ans[MM[l]]=cal(ran[rt]);
//        cout<<l<<" "<<MM[l]<<" "<<ans[MM[l]]<<" "<<ran[rt].size()<<endl;
        return ;
    }
    PushDown(rt);
    int m=(l+r)>>1;
    if(l<=m) query(lson);
    if(r>m) query(rson);
}

void dfs(int x,int pre){
    M[x]=++idx;
    MM[idx]=x;
    range[M[x]].first=idx;
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        dfs(G[x][i],x);
    }
    range[M[x]].second=idx;
}

int main(){
    //freopen("in.txt","r",stdin);
    int n,m,u,v;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n-1;++i){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }

    dfs(1,-1);
//
//    for(int i=1;i<=5;++i)
//        cout<<M[i]<<" "<<range[i].first<<" "<<range[i].second<<endl;

    while(m--){
        scanf("%d%d",&u,&v);
        update(range[M[u]].first,range[M[u]].second,make_pair(range[M[u]].first,range[M[u]].second),1,n,1);
        update(range[M[u]].first,range[M[u]].second,make_pair(range[M[v]].first,range[M[v]].second),1,n,1);
        update(range[M[v]].first,range[M[v]].second,make_pair(range[M[u]].first,range[M[u]].second),1,n,1);
        update(range[M[v]].first,range[M[v]].second,make_pair(range[M[v]].first,range[M[v]].second),1,n,1);
    }
    query(1,n,1);
    for(int i=1;i<=n;++i)
        printf("%d ",ans[i]);
    printf("\n");
    return 0;
}


/*
ID: onlyazh1
LANG: C++
TASK: test
*/

#include<bits/stdc++.h>

using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

typedef long long ll;
const int maxn=100100;

pair<int,int> range[maxn];
vector<int> G[maxn];
int M[maxn];
int MM[maxn];
int ans[maxn];
int idx;
set<pair<int,int> > ran[maxn<<2];
set<pair<int,int> >::iterator it;

void mer(set<pair<int,int> > &S){
    int l=(*S.begin()).first,r=(*S.begin()).second;
    for(it=S.begin();it!=S.end();){
        if(it==S.begin())
            S.erase(it++);
        else{
            if(r>=(*it).second)
                S.erase(it++);
            else{
                if(r>=(*it).first){
                    r=(*it).second;
                    S.erase(it++);
                }
                else{
                    S.insert(make_pair(l,r));
                    l=(*it).first;
                    r=(*it).second;
                    S.erase(it++);
                }
            }
        }
    }
    S.insert(make_pair(l,r));
}

int cal(set<pair<int,int> > & S){
    int ret=0;
    int now=(*S.begin()).first;
    for(it=S.begin();it!=S.end();++it){
        if((*it).second<=now) continue;
        if((*it).first>now)
            ret+=((*it).second-(*it).first+1);
        else ret+=((*it).second-now);
        now=(*it).second;
    }
    return ret;
}

void PushDown(int rt){
    if(!ran[rt].empty()){
        mer(ran[rt]);
        for(it=ran[rt].begin();it!=ran[rt].end();++it){
            ran[rt<<1].insert(*it);
            ran[rt<<1|1].insert(*it);
        }
        ran[rt].clear();
    }
}

void update(int L,int R,pair<int,int> P,int l,int r,int rt){
    if(L<=l&&r<=R){
        ran[rt].insert(P);
        return ;
    }
    PushDown(rt);
    int m=(r+l)>>1;
    if(L<=m) update(L,R,P,lson);
    if(R>m) update(L,R,P,rson);
}

void query(int l,int r,int rt){
    if(l==r){
        ans[MM[l]]=cal(ran[rt]);
//        cout<<l<<" "<<MM[l]<<" "<<ans[MM[l]]<<" "<<ran[rt].size()<<endl;
        return ;
    }
    PushDown(rt);
    int m=(l+r)>>1;
    if(l<=m) query(lson);
    if(r>m) query(rson);
}

void dfs(int x,int pre){
    M[x]=++idx;
    MM[idx]=x;
    range[M[x]].first=idx;
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        dfs(G[x][i],x);
    }
    range[M[x]].second=idx;
}

int main(){
    //freopen("in.txt","r",stdin);
    int n,m,u,v;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n-1;++i){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }

    dfs(1,-1);
//
//    for(int i=1;i<=5;++i)
//        cout<<M[i]<<" "<<range[i].first<<" "<<range[i].second<<endl;

    while(m--){
        scanf("%d%d",&u,&v);
        update(range[M[u]].first,range[M[u]].second,make_pair(range[M[u]].first,range[M[u]].second),1,n,1);
        update(range[M[u]].first,range[M[u]].second,make_pair(range[M[v]].first,range[M[v]].second),1,n,1);
        update(range[M[v]].first,range[M[v]].second,make_pair(range[M[u]].first,range[M[u]].second),1,n,1);
        update(range[M[v]].first,range[M[v]].second,make_pair(range[M[v]].first,range[M[v]].second),1,n,1);
    }
    query(1,n,1);
    for(int i=1;i<=n;++i)
        printf("%d ",ans[i]);
    printf("\n");
    return 0;
}


/*
ID: onlyazh1
LANG: C++
TASK: test
*/

/*
ID: onlyazh1
LANG: C++
TASK: test
*/

#include<bits/stdc++.h>

using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

typedef long long ll;
const int maxn=100100;

pair<int,int> range[maxn];
vector<int> ques[maxn];
vector<int> G[maxn];
int M[maxn];
int ans[maxn];
int idx,n,m;

int sum[maxn<<2];
int tag[maxn<<2];

void PushUP(int l,int r,int rt){
    if(tag[rt]) sum[rt]=(r-l+1);
    else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}

void update(int L,int R,int x,int l,int r,int rt){
    if(L<=l&&r<=R){
        tag[rt]+=x;
        if(tag[rt]) sum[rt]=(r-l+1);
        else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
        return ;
    }
    int m=(l+r)>>1;
    if(L<=m) update(L,R,x,lson);
    if(R>m) update(L,R,x,rson);
    PushUP(l,r,rt);
}

int query(int L,int R,int l,int r,int rt){
    if(L<=l&&r<=R){
        return sum[rt];
    }
    int ret=0;
    int m=(l+r)>>1;
    if(L<=m) ret+=query(L,R,lson);
    if(R>m) ret+=query(L,R,rson);
    return ret;
}

void dfs(int x,int pre){
    M[x]=++idx;
    range[M[x]].first=idx;
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        dfs(G[x][i],x);
    }
    range[M[x]].second=idx;
}

void work(int x,int pre){
    int L,R;

    for(int i=0;i<ques[x].size();++i){
        L=range[M[ques[x][i]]].first;
        R=range[M[ques[x][i]]].second;
        update(L,R,1,1,n,1);
    }

    ans[x]=max(0,query(1,n,1,n,1)-1);
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        work(G[x][i],x);
    }

    for(int i=0;i<ques[x].size();++i){
        L=range[M[ques[x][i]]].first;
        R=range[M[ques[x][i]]].second;
        update(L,R,-1,1,n,1);
    }
}

int main(){
    //freopen("in.txt","r",stdin);

    int u,v;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n-1;++i){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }

    dfs(1,-1);

    while(m--){
        scanf("%d%d",&u,&v);
        ques[u].push_back(v);ques[u].push_back(u);
        ques[v].push_back(u);ques[v].push_back(v);
    }

    work(1,-1);

    for(int i=1;i<=n;++i)
        printf("%d ",ans[i]);
    printf("\n");
    return 0;
}


/*
ID: onlyazh1
LANG: C++
TASK: test
*/

#include<bits/stdc++.h>

using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

typedef long long ll;
const int maxn=100100;

pair<int,int> range[maxn];
vector<int> G[maxn];
int M[maxn];
int MM[maxn];
int ans[maxn];
int idx;
set<int> ran[maxn<<2];
set<int>::iterator it,itt,pt;

int cal(set<int> & S){
    int ret=0;
    for(it=S.begin();it!=S.end();++it){
//        cout<<*it<<" ";
        ret+=(range[*it].second-range[*it].first+1);
    }
    return max(0,ret-1);
}

void insert(int rt,int val){
//    cout<<"***"<<ran[rt].size()<<endl;
    if(ran[rt].empty()){
        ran[rt].insert(val);
        return ;
    }
    itt=ran[rt].lower_bound(val);
    if(itt==ran[rt].begin()){
        if(range[val].first<=(*itt)&&range[val].second>=(*itt))
            ran[rt].erase(itt);
        ran[rt].insert(val);
    }
    else{
        pt=(itt--);swap(pt,itt);
        if(itt!=ran[rt].end()&&(range[val].first<=(*itt)&&range[val].second>=(*itt)))
                ran[rt].erase(itt);
        if(range[*pt].second<val)
            ran[rt].insert(val);
    }
}

void PushDown(int rt){
    if(!ran[rt].empty()){
        for(it=ran[rt].begin();it!=ran[rt].end();++it){
            insert(rt<<1,*it);
            insert(rt<<1|1,*it);
        }
        ran[rt].clear();
    }
}

void update(int L,int R,int P,int l,int r,int rt){
    if(L<=l&&r<=R){
//        cout<<L<<" "<<R<<endl;
//        cout<<ran[rt].size()<<endl;
//        for(it=ran[rt].begin();it!=ran[rt].end();++it)
//            cout<<*it<<" ";
//        cout<<P<<endl;
        insert(rt,P);
//        cout<<ran[rt].size()<<endl<<endl;
        return ;
    }
    PushDown(rt);
    int m=(r+l)>>1;
    if(L<=m) update(L,R,P,lson);
    if(R>m) update(L,R,P,rson);
}

void query(int l,int r,int rt){
    if(l==r){
        ans[MM[l]]=cal(ran[rt]);
        return ;
    }
    PushDown(rt);
    int m=(l+r)>>1;
    if(l<=m) query(lson);
    if(r>m) query(rson);
}

void dfs(int x,int pre){
    M[x]=++idx;
    MM[idx]=x;
    range[M[x]].first=idx;
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        dfs(G[x][i],x);
    }
    range[M[x]].second=idx;
}

int main(){
//    freopen("in.txt","r",stdin);
    int n,m,u,v;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n-1;++i){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }

    dfs(1,-1);
//
//    for(int i=1;i<=5;++i)
//        cout<<M[i]<<" "<<range[i].first<<" "<<range[i].second<<endl;

    while(m--){
        scanf("%d%d",&u,&v);
        if(range[M[u]].first<=M[v]&&range[M[u]].second>=M[v]){
             update(range[M[u]].first,range[M[u]].second,M[u],1,n,1);
        }
        else if(range[M[v]].first<=M[u]&&range[M[v]].second>=M[u]){
            update(range[M[v]].first,range[M[v]].second,M[v],1,n,1);
        }
        else{
            update(range[M[u]].first,range[M[u]].second,M[u],1,n,1);
            update(range[M[u]].first,range[M[u]].second,M[v],1,n,1);
            update(range[M[v]].first,range[M[v]].second,M[u],1,n,1);
            update(range[M[v]].first,range[M[v]].second,M[v],1,n,1);
        }
//        query(1,n,1);
//        for(int i=1;i<=n;++i)
//            printf("%d ",ans[i]);
//        printf("\n");
    }
    query(1,n,1);
    for(int i=1;i<=n;++i)
        printf("%d ",ans[i]);
    printf("\n");
    return 0;
}


#include<bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

using namespace std;

typedef long long ll;
const int maxn=100100;
const int INF=1e9+10;

int n,m;
int maxx=0;
vector<int> G[maxn];
int u,v;
int id[maxn],fid[maxn],idn;
int in[maxn],out[maxn];
int a,b;
int cnt[maxn<<2],tag[maxn<<2];
vector<int> q[maxn];
int ans[maxn];

void dfs(int u,int f)
{
    id[u]=++idn;
    fid[idn]=u;
    in[u]=idn;
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(v==f) continue;
        dfs(v,u);
    }
    out[u]=idn;
}

void push_up(int rt,int l,int r)
{
    if(tag[rt]) cnt[rt]=r-l+1;
    else{
        cnt[rt]=cnt[rt<<1]+cnt[rt<<1|1];
        maxx=max(maxx,rt<<1|1);
    }
}

void build(int l,int r,int rt)
{
    tag[rt]=0;
    if(l==r){
        cnt[rt]=0;
        return;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    push_up(rt,l,r);
}

void update(int L,int R,int c,int l,int r,int rt)
{
    if(L<=l&&r<=R){
        tag[rt]+=c;
        if(tag[rt]) cnt[rt]=r-l+1;
        else{
            cnt[rt]=cnt[rt<<1]+cnt[rt<<1|1];
            maxx=max(maxx,rt<<1|1);
        }
        return;
    }
    int m=(l+r)>>1;
    if(L<=m) update(L,R,c,lson);
    if(R>m) update(L,R,c,rson);
    push_up(rt,l,r);
}

void dfs2(int u,int f)
{
    for(int i=0;i<q[u].size();i++){
        int x=q[u][i];
        update(in[x],out[x],1,1,n,1);
    }
    ans[u]=cnt[1]>0?cnt[1]-1:0;
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(v==f) continue;
        dfs2(v,u);
    }
    for(int i=0;i<q[u].size();i++){
        int x=q[u][i];
        update(in[x],out[x],-1,1,n,1);
    }
}

int main()
{
    //freopen("in.txt","r",stdin);
    while(cin>>n>>m){
        for(int i=1;i<=n;i++) G[i].clear(),q[i].clear();
        for(int i=1;i<n;i++){
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        idn=0;
        dfs(1,0);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&a,&b);
            q[a].push_back(a);q[a].push_back(b);
            q[b].push_back(a);q[b].push_back(b);
        }
        build(1,n,1);
        dfs2(1,0);
        if(n==100000&&m==4584){
            cout<<maxx<<endl;
        }
        for(int i=1;i<=n;i++) printf("%d ",ans[i]);puts("");
    }
    return 0;
}


/*
ID: onlyazh1
LANG: C++
TASK: test
*/

#include<bits/stdc++.h>

using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

typedef long long ll;
const int maxn=100100;

pair<int,int> range[maxn];
vector<int> G[maxn];
int M[maxn];
bitset<100010> tag[maxn<<2];
/*
struct Node{
    vector<pair<int,int> > ran;
};

void PushUP(int rt){
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}

void PushDown(int rt){

}
void update(int L,int R,int l,int r,int rt){

}

void query(int L,int R,int l,int r,int rt){

}

void dfs(int x,int pre){
    M[x]=++idx;
    range[M[x]].first=idx;
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        dfs(G[x][i],x);
    }
    range[M[x]].second=idx;
}
*/
int main(){
    int n,m,u,v;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n-1;++i){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }

//    dfs(1,-1);

    return 0;
}


/*
ID: onlyazh1
LANG: C++
TASK: test
*/

/*
ID: onlyazh1
LANG: C++
TASK: test
*/

#include<bits/stdc++.h>

using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

typedef long long ll;
const int maxn=100100;

pair<int,int> range[maxn];
vector<int> ques[maxn];
vector<int> G[maxn];
int M[maxn];
int ans[maxn];
int idx,n,m;

int sum[maxn<<2];
int tag[maxn<<2];

void PushUP(int l,int r,int rt){
    if(tag[rt]) sum[rt]=(r-l+1);
    else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}

void update(int L,int R,int x,int l,int r,int rt){
    if(L<=l&&r<=R){
        tag[rt]+=x;
        if(tag[rt]) sum[rt]=(r-l+1);
        else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
        return ;
    }
    int m=(l+r)>>1;
    if(L<=m) update(L,R,x,lson);
    if(R>m) update(L,R,x,rson);
    PushUP(l,r,rt);
}

void dfs(int x,int pre){
    M[x]=++idx;
    range[M[x]].first=idx;
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        dfs(G[x][i],x);
    }
    range[M[x]].second=idx;
}

void work(int x,int pre){
    int L,R;

    for(int i=0;i<ques[x].size();++i){
        L=range[M[ques[x][i]]].first;
        R=range[M[ques[x][i]]].second;
        update(L,R,1,1,n,1);
    }

    ans[x]=max(0,sum[1]-1);
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        work(G[x][i],x);
    }

    for(int i=0;i<ques[x].size();++i){
        L=range[M[ques[x][i]]].first;
        R=range[M[ques[x][i]]].second;
        update(L,R,-1,1,n,1);
    }
}

int main(){
    //freopen("in.txt","r",stdin);

    int u,v;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n-1;++i){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }

    dfs(1,-1);

    while(m--){
        scanf("%d%d",&u,&v);
        ques[u].push_back(v);ques[u].push_back(u);
        ques[v].push_back(u);ques[v].push_back(v);
    }
    work(1,-1);

    for(int i=1;i<=n;++i)
        printf("%d ",ans[i]);
    printf("\n");
    return 0;
}


#include<bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

using namespace std;

typedef long long ll;
const int maxn=100100;
const int INF=1e9+10;

int n,m;
vector<int> G[maxn];
int u,v;
int id[maxn],fid[maxn],idn;
int in[maxn],out[maxn];
int a,b;
int cnt[maxn<<2],tag[maxn<<2];
vector<int> q[maxn];
int ans[maxn];

void dfs(int u,int f)
{
    id[u]=++idn;
    fid[idn]=u;
    in[u]=idn;
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(v==f) continue;
        dfs(v,u);
    }
    out[u]=idn;
}

void push_up(int rt,int l,int r)
{
    if(tag[rt]) cnt[rt]=r-l+1;
    else cnt[rt]=cnt[rt<<1]+cnt[rt<<1|1];
}

void build(int l,int r,int rt)
{
    tag[rt]=0;
    if(l==r){
        cnt[rt]=0;return;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    push_up(rt,l,r);
}

void update(int L,int R,int c,int l,int r,int rt)
{
    if(L<=l&&r<=R){
        tag[rt]+=c;
        if(tag[rt]) cnt[rt]=r-l+1;
        else cnt[rt]=cnt[rt<<1]+cnt[rt<<1|1];
        return;
    }
    int m=(l+r)>>1;
    if(L<=m) update(L,R,c,lson);
    if(R>m) update(L,R,c,rson);
    push_up(rt,l,r);
}

void dfs2(int u,int f)
{
    for(int i=0;i<q[u].size();i++){
        int x=q[u][i];
        update(in[x],out[x],1,1,n,1);
    }
    ans[u]=cnt[1]>0?cnt[1]-1:0;
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(v==f) continue;
        dfs2(v,u);
    }
    for(int i=0;i<q[u].size();i++){
        int x=q[u][i];
        update(in[x],out[x],-1,1,n,1);
    }
}

int main()
{
    //freopen("in.txt","r",stdin);
    while(cin>>n>>m){
        for(int i=1;i<=n;i++) G[i].clear(),q[i].clear();
        for(int i=1;i<n;i++){
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        idn=0;
        dfs(1,0);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&a,&b);
            q[a].push_back(a);q[a].push_back(b);
            q[b].push_back(a);q[b].push_back(b);
        }
        build(1,n,1);
        dfs2(1,0);
        for(int i=1;i<=n;i++) printf("%d ",ans[i]);puts("");
    }
    return 0;
}


/*
ID: onlyazh1
LANG: C++
TASK: test
*/

#include<bits/stdc++.h>

using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

typedef long long ll;
const int maxn=100100;

pair<int,int> range[maxn];
vector<int> G[maxn];
int M[maxn];
int MM[maxn];
int ans[maxn];
int idx;
set<pair<int,int> > ran[maxn<<2];
set<pair<int,int> >::iterator it;

void mer(set<pair<int,int> > &S){
    int l=(*S.begin()).first,r=(*S.begin()).second;
    S.erase(S.begin());
//    printf("l= %d r= %d\n",l,r);
    for(it=S.begin();it!=S.end();){
//        cout<<l<<" "<<r<<endl;
        if(r>=(*it).second)
            S.erase(it++);
        else{
            if(r>=(*it).first){
                r=(*it).second;
                S.erase(it++);
            }
            else{
                //printf("l= %d r= %d\n",l,r);
                S.insert(make_pair(l,r));
                l=(*it).first;
                r=(*it).second;
                S.erase(it++);
            }
        }
    }
    S.insert(make_pair(l,r));
}

int cal(set<pair<int,int> > & S){
    int ret=0;
    int now=(*S.begin()).first;
    for(it=S.begin();it!=S.end();++it){
        if((*it).second<=now) continue;
        if((*it).first>now)
            ret+=((*it).second-(*it).first+1);
        else ret+=((*it).second-now);
        now=(*it).second;
    }
    return ret;
}

void PushDown(int rt){
    if(!ran[rt].empty()){
//        printf("ran[rt].size()= %d\n",ran[rt].size());
        mer(ran[rt]);
//        printf("ran[rt].size()= %d\n",ran[rt].size());
        for(it=ran[rt].begin();it!=ran[rt].end();++it){
            ran[rt<<1].insert(*it);
            ran[rt<<1|1].insert(*it);
        }
        ran[rt].clear();
    }
}

void update(int L,int R,pair<int,int> P,int l,int r,int rt){
    if(L<=l&&r<=R){
        ran[rt].insert(P);
        return ;
    }
    PushDown(rt);
    int m=(r+l)>>1;
    if(L<=m) update(L,R,P,lson);
    if(R>m) update(L,R,P,rson);
}

void query(int l,int r,int rt){
    if(l==r){
        ans[MM[l]]=cal(ran[rt]);
//        cout<<"MM[l]="<<MM[l]<<endl;
//        for(it=ran[rt].begin();it!=ran[rt].end();++it)
//            cout<<(*it).first<<" "<<(*it).second<<endl;
//        cout<<l<<" "<<MM[l]<<" "<<ans[MM[l]]<<" "<<ran[rt].size()<<endl;
        return ;
    }
    PushDown(rt);
    int m=(l+r)>>1;
    if(l<=m) query(lson);
    if(r>m) query(rson);
}

void dfs(int x,int pre){
    M[x]=++idx;
    MM[idx]=x;
    range[M[x]].first=idx;
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        dfs(G[x][i],x);
    }
    range[M[x]].second=idx;
}

int main(){
    //freopen("in.txt","r",stdin);
    int n,m,u,v;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n-1;++i){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }

    dfs(1,-1);
//
//    for(int i=1;i<=5;++i)
//        cout<<M[i]<<" "<<range[i].first<<" "<<range[i].second<<endl;

    while(m--){
        scanf("%d%d",&u,&v);
        update(range[M[u]].first,range[M[u]].second,make_pair(range[M[u]].first,range[M[u]].second),1,n,1);
        update(range[M[u]].first,range[M[u]].second,make_pair(range[M[v]].first,range[M[v]].second),1,n,1);
        update(range[M[v]].first,range[M[v]].second,make_pair(range[M[u]].first,range[M[u]].second),1,n,1);
        update(range[M[v]].first,range[M[v]].second,make_pair(range[M[v]].first,range[M[v]].second),1,n,1);
    }
    query(1,n,1);
    for(int i=1;i<=n;++i)
        printf("%d ",ans[i]);
    printf("\n");
    return 0;
}


/*
ID: onlyazh1
LANG: C++
TASK: test
*/

/*
ID: onlyazh1
LANG: C++
TASK: test
*/

#include<bits/stdc++.h>

using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

typedef long long ll;
const int maxn=100100;

pair<int,int> range[maxn];
vector<int> ques[maxn];
vector<int> G[maxn];
int M[maxn];
int ans[maxn];
int idx,n,m;

int sum[maxn<<2];
int tag[maxn<<2];

void PushUP(int l,int r,int rt){
    if(tag[rt]) sum[rt]=(r-l+1);
    else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}

void update(int L,int R,int x,int l,int r,int rt){
    if(L<=l&&r<=R){
        tag[rt]+=x;
        if(tag[rt]) sum[rt]=(r-l+1);
        else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
        return ;
    }
    int m=(l+r)>>1;
    if(L<=m) update(L,R,x,lson);
    if(R>m) update(L,R,x,rson);
    PushUP(l,r,rt);
}

int query(int L,int R,int l,int r,int rt){
    if(L<=l&&r<=R){
        return sum[rt];
    }
    int ret=0;
    int m=(l+r)>>1;
    if(L<=m) ret+=query(L,R,lson);
    if(R>m) ret+=query(L,R,rson);
    return ret;
}

void dfs(int x,int pre){
    M[x]=++idx;
    range[M[x]].first=idx;
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        dfs(G[x][i],x);
    }
    range[M[x]].second=idx;
}

void work(int x,int pre){
    int L,R;

    for(int i=0;i<ques[x].size();++i){
        L=range[M[ques[x][i]]].first;
        R=range[M[ques[x][i]]].second;
        update(L,R,1,1,n,1);
    }

    ans[x]=max(0,sum[1]-1);
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        work(G[x][i],x);
    }

    for(int i=0;i<ques[x].size();++i){
        L=range[M[ques[x][i]]].first;
        R=range[M[ques[x][i]]].second;
        update(L,R,-1,1,n,1);
    }
}

int main(){
    //freopen("in.txt","r",stdin);

    int u,v;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n-1;++i){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }

    dfs(1,-1);

    while(m--){
        scanf("%d%d",&u,&v);
        ques[u].push_back(v);ques[u].push_back(u);
        ques[v].push_back(u);ques[v].push_back(v);
    }
    work(1,-1);

    for(int i=1;i<=n;++i)
        printf("%d ",ans[i]);
    printf("\n");
    return 0;
}


/*
ID: onlyazh1
LANG: C++
TASK: test
*/

/*
ID: onlyazh1
LANG: C++
TASK: test
*/

#include<bits/stdc++.h>

using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

typedef long long ll;
const int maxn=1000100;

pair<int,int> range[maxn];
vector<int> ques[maxn];
vector<int> G[maxn];
int M[maxn];
int ans[maxn];
int idx,n,m;

int sum[maxn<<2];
int tag[maxn<<2];

void PushUP(int l,int r,int rt){
    if(tag[rt]) sum[rt]=(r-l+1);
    else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}

void update(int L,int R,int x,int l,int r,int rt){
    if(L<=l&&r<=R){
        tag[rt]+=x;
        if(tag[rt]) sum[rt]=(r-l+1);
        else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
        return ;
    }
    int m=(l+r)>>1;
    if(L<=m) update(L,R,x,lson);
    if(R>m) update(L,R,x,rson);
    PushUP(l,r,rt);
}

void dfs(int x,int pre){
    M[x]=++idx;
    range[M[x]].first=idx;
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        dfs(G[x][i],x);
    }
    range[M[x]].second=idx;
}

void work(int x,int pre){
    int L,R;

    for(int i=0;i<ques[x].size();++i){
        L=range[M[ques[x][i]]].first;
        R=range[M[ques[x][i]]].second;
        update(L,R,1,1,n,1);
    }

    ans[x]=max(0,sum[1]-1);
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        work(G[x][i],x);
    }

    for(int i=0;i<ques[x].size();++i){
        L=range[M[ques[x][i]]].first;
        R=range[M[ques[x][i]]].second;
        update(L,R,-1,1,n,1);
    }
}

int main(){
    //freopen("in.txt","r",stdin);

    int u,v;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n-1;++i){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }

    dfs(1,-1);

    while(m--){
        scanf("%d%d",&u,&v);
        ques[u].push_back(v);ques[u].push_back(u);
        ques[v].push_back(u);ques[v].push_back(v);
    }
    work(1,-1);

    for(int i=1;i<=n;++i)
        printf("%d ",ans[i]);
    printf("\n");
    return 0;
}


/*
ID: onlyazh1
LANG: C++
TASK: test
*/

/*
ID: onlyazh1
LANG: C++
TASK: test
*/

#include<bits/stdc++.h>

using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

typedef long long ll;
const int maxn=100100;

pair<int,int> range[maxn];
vector<int> G[maxn];
int M[maxn];
int MM[maxn];
int ans[maxn];
int idx;
set<int> ran[maxn<<2];
set<int>::iterator it,itt,pt;

int cal(set<int> & S){
    int ret=0;
    for(it=S.begin();it!=S.end();++it){
        ret+=(range[*it].second-range[*it].first+1);
    }
    return max(0,ret-1);
}

void insert(int rt,int val){
    if(ran[rt].empty()){
        ran[rt].insert(val);
        return ;
    }
    itt=ran[rt].lower_bound(val);
    if(itt==ran[rt].begin()){
        while(itt!=ran[rt].end()&&range[val].first<=(*itt)&&range[val].second>=(*itt))
            ran[rt].erase(itt++);
        ran[rt].insert(val);
    }
    else{
        pt=(itt--);swap(pt,itt);
        while(itt!=ran[rt].end()&&(range[val].first<=(*itt)&&range[val].second>=(*itt)))
                ran[rt].erase(itt++);
        if(range[*pt].second<val)
            ran[rt].insert(val);
    }
}

void PushDown(int rt){
    if(!ran[rt].empty()){
        for(it=ran[rt].begin();it!=ran[rt].end();++it){
            insert(rt<<1,*it);
            insert(rt<<1|1,*it);
        }
        ran[rt].clear();
    }
}

void update(int L,int R,int P,int l,int r,int rt){
    if(L<=l&&r<=R){
//        cout<<L<<" "<<R<<endl;
//        cout<<ran[rt].size()<<endl;
//        for(it=ran[rt].begin();it!=ran[rt].end();++it)
//            cout<<*it<<" ";
//        cout<<P<<endl;
        insert(rt,P);
//        cout<<ran[rt].size()<<endl<<endl;
        return ;
    }
    PushDown(rt);
    int m=(r+l)>>1;
    if(L<=m) update(L,R,P,lson);
    if(R>m) update(L,R,P,rson);
}

void query(int l,int r,int rt){
    if(l==r){
        ans[MM[l]]=cal(ran[rt]);
        return ;
    }
    PushDown(rt);
    int m=(l+r)>>1;
    if(l<=m) query(lson);
    if(r>m) query(rson);
}

void dfs(int x,int pre){
    M[x]=++idx;
    MM[idx]=x;
    range[M[x]].first=idx;
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        dfs(G[x][i],x);
    }
    range[M[x]].second=idx;
}

int main(){
//    freopen("in.txt","r",stdin);
    int n,m,u,v;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n-1;++i){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }

    dfs(1,-1);

    while(m--){
        scanf("%d%d",&u,&v);
        if(range[M[u]].first<=M[v]&&range[M[u]].second>=M[v]){
             update(range[M[u]].first,range[M[u]].second,M[u],1,n,1);
        }
        else if(range[M[v]].first<=M[u]&&range[M[v]].second>=M[u]){
            update(range[M[v]].first,range[M[v]].second,M[v],1,n,1);
        }
        else{
            update(range[M[u]].first,range[M[u]].second,M[u],1,n,1);
            update(range[M[u]].first,range[M[u]].second,M[v],1,n,1);
            update(range[M[v]].first,range[M[v]].second,M[u],1,n,1);
            update(range[M[v]].first,range[M[v]].second,M[v],1,n,1);
        }
    }
    query(1,n,1);
    for(int i=1;i<=n;++i)
        printf("%d ",ans[i]);
    printf("\n");
    return 0;
}


#include<bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

using namespace std;

typedef long long ll;
const int maxn=100100;
const int INF=1e9+10;

int n,m;
int maxx=0;
vector<int> G[maxn];
int u,v;
int id[maxn],fid[maxn],idn;
int in[maxn],out[maxn];
int a,b;
int cnt[maxn<<2],tag[maxn<<2];
vector<int> q[maxn];
int ans[maxn];

void dfs(int u,int f)
{
    id[u]=++idn;
    fid[idn]=u;
    in[u]=idn;
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(v==f) continue;
        dfs(v,u);
    }
    out[u]=idn;
}

void push_up(int rt,int l,int r)
{
    if(tag[rt]) cnt[rt]=r-l+1;
    else{
        cnt[rt]=cnt[rt<<1]+cnt[rt<<1|1];
    }
}

void build(int l,int r,int rt)
{
    tag[rt]=0;
    if(l==r){
        cnt[rt]=0;
        return;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    push_up(rt,l,r);
}

void update(int L,int R,int c,int l,int r,int rt)
{
    if(L<=l&&r<=R){
        tag[rt]+=c;
        if(tag[rt]) cnt[rt]=r-l+1;
        else{
            if(l!=r) cnt[rt]=cnt[rt<<1]+cnt[rt<<1|1];
            else cnt[rt]=0;
        }
        return;
    }
    int m=(l+r)>>1;
    if(L<=m) update(L,R,c,lson);
    if(R>m) update(L,R,c,rson);
    push_up(rt,l,r);
}

void dfs2(int u,int f)
{
    for(int i=0;i<q[u].size();i++){
        int x=q[u][i];
        update(in[x],out[x],1,1,n,1);
    }
    ans[u]=cnt[1]>0?cnt[1]-1:0;
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(v==f) continue;
        dfs2(v,u);
    }
    for(int i=0;i<q[u].size();i++){
        int x=q[u][i];
        update(in[x],out[x],-1,1,n,1);
    }
}

int main()
{
    //freopen("in.txt","r",stdin);
    while(cin>>n>>m){
        for(int i=1;i<=n;i++) G[i].clear(),q[i].clear();
        for(int i=1;i<n;i++){
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        idn=0;
        dfs(1,0);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&a,&b);
            q[a].push_back(a);q[a].push_back(b);
            q[b].push_back(a);q[b].push_back(b);
        }
        build(1,n,1);
        dfs2(1,0);
//        if(n==100000&&m==4584){
//            cout<<maxx<<endl;
//        }
        for(int i=1;i<=n;i++) printf("%d ",ans[i]);puts("");
    }
    return 0;
}


/*
ID: onlyazh1
LANG: C++
TASK: test
*/

#include<bits/stdc++.h>

using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

typedef long long ll;
const int maxn=100100;

pair<int,int> range[maxn];
vector<int> G[maxn];
int M[maxn];
int MM[maxn];
int ans[maxn];
int idx;
set<pair<int,int> > ran[maxn<<2];
set<pair<int,int> >::iterator it;

int cal(set<pair<int,int> > & S){
    int ret=0;
    int now=(*S.begin()).first;
    for(it=S.begin();it!=S.end();++it){
        if((*it).second<=now) continue;
        if((*it).first>now)
            ret+=((*it).second-(*it).first+1);
        else ret+=((*it).second-now);
        now=(*it).second;
    }
    return ret;
}

void PushDown(int rt){
    if(!ran[rt].empty()){
        for(it=ran[rt].begin();it!=ran[rt].end();++it){
            ran[rt<<1].insert(*it);
            ran[rt<<1|1].insert(*it);
        }
        ran[rt].clear();
    }
}

void update(int L,int R,pair<int,int> P,int l,int r,int rt){
    if(L<=l&&r<=R){
        ran[rt].insert(P);
        return ;
    }
    PushDown(rt);
    int m=(r+l)>>1;
    if(L<=m) update(L,R,P,lson);
    if(R>m) update(L,R,P,rson);
}

void query(int l,int r,int rt){
    if(l==r){
        ans[MM[l]]=cal(ran[rt]);
//        cout<<l<<" "<<MM[l]<<" "<<ans[MM[l]]<<" "<<ran[rt].size()<<endl;
        return ;
    }
    PushDown(rt);
    int m=(l+r)>>1;
    if(l<=m) query(lson);
    if(r>m) query(rson);
}

void dfs(int x,int pre){
    M[x]=++idx;
    MM[idx]=x;
    range[M[x]].first=idx;
    for(int i=0,sz=G[x].size();i<sz;++i){
        if(G[x][i]==pre) continue;
        dfs(G[x][i],x);
    }
    range[M[x]].second=idx;
}

int main(){
    //freopen("in.txt","r",stdin);
    int n,m,u,v;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n-1;++i){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }

    dfs(1,-1);
//
//    for(int i=1;i<=5;++i)
//        cout<<M[i]<<" "<<range[i].first<<" "<<range[i].second<<endl;

    while(m--){
        scanf("%d%d",&u,&v);
        update(range[M[u]].first,range[M[u]].second,make_pair(range[M[u]].first,range[M[u]].second),1,n,1);
        update(range[M[u]].first,range[M[u]].second,make_pair(range[M[v]].first,range[M[v]].second),1,n,1);
        update(range[M[v]].first,range[M[v]].second,make_pair(range[M[u]].first,range[M[u]].second),1,n,1);
        update(range[M[v]].first,range[M[v]].second,make_pair(range[M[v]].first,range[M[v]].second),1,n,1);
    }
    query(1,n,1);
    for(int i=1;i<=n;++i)
        printf("%d ",ans[i]);
    printf("\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*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 = 1e5 + 10;
const int base = 29;
const int mod = 1e9 + 7;
const int INF = 1e9 + 100;
vi g[maxn];
int Root[maxn*50],L[maxn*50],R[maxn*50],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*50],stree[maxn*50];
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*70],L[maxn*70],R[maxn*70],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*70],stree[maxn*70];
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)
{
    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*60],L[maxn*60],R[maxn*60],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*60],stree[maxn*60];
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] << " ";
}


/* by Natsu Kinmoe */
#include <bits/stdc++.h>
using namespace std;

#define all(x) (x).begin(),(x).end()
#define loop(i,n) for(int i=0;i<(n);i++)
#define cont(i,n) for(int i=1;i<=(n);i++)
#define circ(i,a,b) for(int i=(a);i<=(b);i++)
#define range(i,a,b,c) for(int i=(a);((c)>0?i<=(b):i>=(b));i+=(c))
#define foreach(it,v) for(__typeof((v).begin()) it=(v).begin(),_e_D_=(v).end();it!=_e_D_;it++)
#define y0 y0O0OO00OO0OO0OO0OOO00OO0OO0O0O000OO0
#define y1 y1II11II11III11I1III11II111IIII1II1I1
#define pub push_back
#define pob pop_back
#define mak make_pair

typedef long long ll;
typedef long double lf;
const int Inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
/* Source code starts here */

int n,m;
vector<int> nei[1<<17];
vector<int> hv[1<<17];
int bg[1<<17],en[1<<17],tmc;
int res[1<<17];

struct Segtree{
	int dt[8<<17],is[8<<17];
	void inline add(int l,int r,int x,int now=1,int nl=1,int nr=n){
		if(nl>r||nr<l)return;
		if(nl>=l&&nr<=r)dt[now]+=x;
		else{
			int m=(nl+nr)>>1;
			add(l,r,x,now<<1,nl,m);
			add(l,r,x,now<<1|1,m+1,nr);
		}
		if(dt[now])is[now]=nr-nl+1;
		else is[now]=is[now<<1]+is[now<<1|1];
	}
}seg;

void dfs(int now,int lst){
	bg[now]=++tmc;
	foreach(i,nei[now])if(*i!=lst)dfs(*i,now);
	en[now]=tmc;
}

void dfs2(int now,int lst){
	if(hv[now].size())seg.add(bg[now],en[now],1);
	foreach(i,hv[now])seg.add(bg[*i],en[*i],1);
	res[now]=max(0,seg.is[1]-1);
	foreach(i,nei[now])if(*i!=lst)dfs2(*i,now);
	if(hv[now].size())seg.add(bg[now],en[now],-1);
	foreach(i,hv[now])seg.add(bg[*i],en[*i],-1);
}

int main(){
	scanf("%d%d",&n,&m);
	cont(i,n-1){
		int a,b;scanf("%d%d",&a,&b);
		nei[a].pub(b);nei[b].pub(a);
	}
	cont(i,m){
		int a,b;scanf("%d%d",&a,&b);
		hv[a].pub(b);hv[b].pub(a);
	}
	dfs(1,0);
	dfs2(1,0);
	cont(i,n)printf("%d%c",res[i]," \n"[i==n]);
	return 0;
}


/* by Natsu Kinmoe */
#include <bits/stdc++.h>
using namespace std;

#define all(x) (x).begin(),(x).end()
#define loop(i,n) for(int i=0;i<(n);i++)
#define cont(i,n) for(int i=1;i<=(n);i++)
#define circ(i,a,b) for(int i=(a);i<=(b);i++)
#define range(i,a,b,c) for(int i=(a);((c)>0?i<=(b):i>=(b));i+=(c))
#define foreach(it,v) for(__typeof((v).begin()) it=(v).begin(),_e_D_=(v).end();it!=_e_D_;it++)
#define y0 y0O0OO00OO0OO0OO0OOO00OO0OO0O0O000OO0
#define y1 y1II11II11III11I1III11II111IIII1II1I1
#define pub push_back
#define pob pop_back
#define mak make_pair

typedef long long ll;
typedef long double lf;
const int Inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
/* Source code starts here */

int n,m;
vector<int> nei[1<<17];
vector<int> hv[1<<17];
int bg[1<<17],en[1<<17],tmc;
int res[1<<17];

struct Segtree{
	int dt[8<<17],is[8<<17];
	void inline add(int l,int r,int x,int now=1,int nl=1,int nr=n){
		if(nl>r||nr<l)return;
		if(nl>=l&&nr<=r)dt[now]+=x;
		else{
			int m=(nl+nr)>>1;
			add(l,r,x,now<<1,nl,m);
			add(l,r,x,now<<1|1,m+1,nr);
		}
		if(dt[now])is[now]=nr-nl+1;
		else is[now]=is[now<<1]+is[now<<1|1];
	}
}seg;

void dfs(int now,int lst){
	bg[now]=++tmc;
	foreach(i,nei[now])if(*i!=lst)dfs(*i,now);
	en[now]=tmc;
}

void dfs2(int now,int lst){
	if(hv[now].size())seg.add(bg[now]+1,en[now],1);
	foreach(i,hv[now])seg.add(bg[*i],en[*i],1);
	res[now]=seg.is[1];
	foreach(i,nei[now])if(*i!=lst)dfs2(*i,now);
	if(hv[now].size())seg.add(bg[now]+1,en[now],-1);
	foreach(i,hv[now])seg.add(bg[*i],en[*i],-1);
}

int main(){
	scanf("%d%d",&n,&m);
	cont(i,n-1){
		int a,b;scanf("%d%d",&a,&b);
		nei[a].pub(b);nei[b].pub(a);
	}
	cont(i,m){
		int a,b;scanf("%d%d",&a,&b);
		hv[a].pub(b);hv[b].pub(a);
	}
	dfs(1,0);
	dfs2(1,0);
	cont(i,n)printf("%d%c",res[i]," \n"[i==n]);
	return 0;
}


#include <bits/stdc++.h>
#define F first
#define S second
#define sz(x) ((int)x.size())
#define _ ios::sync_with_stdio(0);

using namespace std;
const int N = 1e6 + 7;
int n, vis[N], pos1[N], pos2[N];
vector<int> g[N], q[N];
vector<int> ord;

int sz[N], ans[N];

int dfs(int x) {
	sz[x] = true;
	pos1[x] = sz(ord);
	for(auto i : g[x])
		if(!sz[i])
			sz[x] += dfs(i);
	ord.push_back(x);
	pos2[x] = sz(ord);
	return sz[x];
}

int cnt[N], val[N];

void calc(int l, int r, int pl, int sum = 0, int tag = 1, int s = 0, int e = n){
	if( s >= r || e <= l) return;
	if( s >= l && e <= r) {
		val[tag] += pl;
		if(val[tag] == 0 && pl == -1)
			cnt[tag] = cnt[2 * tag] + cnt[2 * tag + 1];
		if(val[tag] == 1 && pl == 1)
			cnt[tag] = e - s;
		return;
		//val[tag] += pl;
		//if((sum + val[tag]) == 0)
		//	cnt[tag] = cnt[tag*2] + cnt[tag*2+1];
		//else
		//	cnt[tag] = e-s;
		//return;
	}
	int mid = (s+e)/2;
	//sum += val[tag];
	calc(l, r, pl, sum, tag*2+0, s, mid);
	calc(l, r, pl, sum, tag*2+1, mid, e);
	if(val[tag] == 0)
		cnt[tag] = cnt[tag*2] + cnt[tag*2+1];
//	else
//		cnt[tag] = e-s;
}

void solve(int x) {
	vis[x] = true;
	for(auto i : q[x])
		calc(pos1[i], pos2[i], 1);
//	if (sz(q[x]))
//		calc(pos1[x], pos2[x], 1);
	//calc(pos2[x]-1, pos2[x], 1);
	ans[x] = max(0, cnt[1]-1);
	//calc(pos2[x]-1, pos2[x], -1);
	for(auto i : g[x])if(!vis[i])
		solve(i);
	for(auto i : q[x])
		calc(pos1[i], pos2[i], -1);
//	if (sz(q[x]))
//		calc(pos1[x], pos2[x], -1);
}

int32_t main(){_
	int Q;
	cin >> n >> Q;
	for(int i = 1; i < n; i++){
		int x, y; cin >> x >> y;
		g[x].push_back(y);
		g[y].push_back(x);
	}
	while(Q--) {
		int x, y; cin >> x >> y;
		q[x].push_back(y);
		q[y].push_back(x);
	}
	dfs(1);
	//for(auto i : ord)
	//	cerr <<i << ' ';
	for(int i = 1; i <= n; i++){
		if(sz(q[i]))
			q[i].push_back(i);
	//	cerr << i << ' ' << pos1[i] << ' ' << pos2[i] << endl;
	}
	solve(1);
	for(int i = 1; i <= n; i++)
		cout << ans[i] << ' ';
}


#include <bits/stdc++.h>
#define F first
#define S second
#define sz(x) ((int)x.size())
#define _ ios::sync_with_stdio(0);

using namespace std;
const int N = 4e5 + 1000;
int n, vis[N], pos1[N], pos2[N];
vector<int> g[N], q[N];
vector<int> ord;

int sz[N], ans[N];

int dfs(int x) {
	sz[x] = true;
	pos1[x] = sz(ord);
	for(auto i : g[x])
		if(!sz[i])
			sz[x] += dfs(i);
	ord.push_back(x);
	pos2[x] = sz(ord);
	return sz[x];
}

int cnt[N], val[N];

void calc(int l, int r, int pl, int sum = 0, int tag = 1, int s = 0, int e = n){
	if( s >= r || e <= l) return;
	if( s >= l && e <= r) {
		val[tag] += pl;
		if(val[tag] == 0 && pl == -1)
			cnt[tag] = cnt[2 * tag] + cnt[2 * tag + 1];
		if(val[tag] == 1 && pl == 1)
			cnt[tag] = e - s;
		return;
		//val[tag] += pl;
		//if((sum + val[tag]) == 0)
		//	cnt[tag] = cnt[tag*2] + cnt[tag*2+1];
		//else
		//	cnt[tag] = e-s;
		//return;
	}
	int mid = (s+e)/2;
	//sum += val[tag];
	calc(l, r, pl, sum, tag*2+0, s, mid);
	calc(l, r, pl, sum, tag*2+1, mid, e);
	if(val[tag] == 0)
		cnt[tag] = cnt[tag*2] + cnt[tag*2+1];
//	else
//		cnt[tag] = e-s;
}

void solve(int x) {
	vis[x] = true;
	for(auto i : q[x])
		calc(pos1[i], pos2[i], 1);
//	if (sz(q[x]))
//		calc(pos1[x], pos2[x], 1);
	//calc(pos2[x]-1, pos2[x], 1);
	ans[x] = max(0, cnt[1]-1);
	//calc(pos2[x]-1, pos2[x], -1);
	for(auto i : g[x])if(!vis[i])
		solve(i);
	for(auto i : q[x])
		calc(pos1[i], pos2[i], -1);
//	if (sz(q[x]))
//		calc(pos1[x], pos2[x], -1);
}

int32_t main(){_
	int Q;
	cin >> n >> Q;
	for(int i = 1; i < n; i++){
		int x, y; cin >> x >> y;
		g[x].push_back(y);
		g[y].push_back(x);
	}
	while(Q--) {
		int x, y; cin >> x >> y;
		q[x].push_back(y);
		q[y].push_back(x);
	}
	dfs(1);
	//for(auto i : ord)
	//	cerr <<i << ' ';
	for(int i = 1; i <= n; i++){
		if(sz(q[i]))
			q[i].push_back(i);
	//	cerr << i << ' ' << pos1[i] << ' ' << pos2[i] << endl;
	}
	solve(1);
	for(int i = 1; i <= n; i++)
		cout << ans[i] << ' ';
}


#include <bits/stdc++.h>
#define F first
#define S second
#define sz(x) ((int)x.size())
#define _ ios::sync_with_stdio(0);

using namespace std;
const int N = 4e5 + 7;
int n, vis[N], pos1[N], pos2[N];
vector<int> g[N], q[N];
vector<int> ord;

int sz[N], ans[N];

int dfs(int x) {
	sz[x] = true;
	pos1[x] = sz(ord);
	for(auto i : g[x])
		if(!sz[i])
			sz[x] += dfs(i);
	ord.push_back(x);
	pos2[x] = sz(ord);
	return sz[x];
}

int cnt[N], val[N];

void calc(int l, int r, int pl, int sum = 0, int tag = 1, int s = 0, int e = n){
	if( s >= r || e <= l) return;
	if( s >= l && e <= r) {
		val[tag] += pl;
		if(val[tag] == 0 && pl == -1)
			cnt[tag] = cnt[2 * tag] + cnt[2 * tag + 1];
		if(val[tag] == 1 && pl == 1)
			cnt[tag] = e - s;
		return;
		//val[tag] += pl;
		//if((sum + val[tag]) == 0)
		//	cnt[tag] = cnt[tag*2] + cnt[tag*2+1];
		//else
		//	cnt[tag] = e-s;
		//return;
	}
	int mid = (s+e)/2;
	//sum += val[tag];
	calc(l, r, pl, sum, tag*2+0, s, mid);
	calc(l, r, pl, sum, tag*2+1, mid, e);
	if(val[tag] == 0)
		cnt[tag] = cnt[tag*2] + cnt[tag*2+1];
//	else
//		cnt[tag] = e-s;
}

void solve(int x) {
	vis[x] = true;
	for(auto i : q[x])
		calc(pos1[i], pos2[i], 1);
//	if (sz(q[x]))
//		calc(pos1[x], pos2[x], 1);
	//calc(pos2[x]-1, pos2[x], 1);
	ans[x] = max(0, cnt[1]-1);
	//calc(pos2[x]-1, pos2[x], -1);
	for(auto i : g[x])if(!vis[i])
		solve(i);
	for(auto i : q[x])
		calc(pos1[i], pos2[i], -1);
//	if (sz(q[x]))
//		calc(pos1[x], pos2[x], -1);
}

int32_t main(){_
	int Q;
	cin >> n >> Q;
	for(int i = 1; i < n; i++){
		int x, y; cin >> x >> y;
		g[x].push_back(y);
		g[y].push_back(x);
	}
	while(Q--) {
		int x, y; cin >> x >> y;
		q[x].push_back(y);
		q[y].push_back(x);
	}
	dfs(1);
	//for(auto i : ord)
	//	cerr <<i << ' ';
	for(int i = 1; i <= n; i++){
		if(sz(q[i]))
			q[i].push_back(i);
	//	cerr << i << ' ' << pos1[i] << ' ' << pos2[i] << endl;
	}
	solve(1);
	for(int i = 1; i <= n; i++)
		cout << ans[i] << ' ';
}


#include <bits/stdc++.h>
using namespace std;
#define erorp(x) cout<<#x<<"={"<<(x.F)<<" , "<<x.S<<"}"<<endl;
#define print(v,r) f(i,0,r) cout<<v[i]<<" "; cout<<endl;
#define Get(x,y) scanf("%I64d%I64d",&x,&y);
#define is_bit(x,y) (x%(1<<(y+1))>=(1<<y))
#define eror(x) cout<<#x<<'='<<(x)<<endl;
#define f_(i,a,b) for(int i=a;i>=b;i--)
#define Gett(x,y) scanf("%d%d",&x,&y);
#define f(i,a,b) for(int i=a;i<b;i++)
#define get(x) scanf("%I64d",&x);
#define gett(x) scanf("%d",&x);
#define maxm(a,b) a=max(a,b);
#define minm(a,b) a=min(a,b);
#define Add(x,y) x=(x+y)%mod
#define lst(x) x[x.size()-1]
#define sz(x) int(x.size())
#define mp make_pair
#define ll long long
#define pb push_back
#define S second
#define F first

const int N=1e6+9;

int n,m,c,s[N],t[N],ans[N],lazy[N];
pair<int,int> seg[N];
vector<int> g[N];
vector<pair<int,int> > query[N];

void shift(int,int,int);

pair<int,int> Min(pair<int,int> x,pair<int,int> y){
    if(y<x) swap(x,y);
    if(x.F == y.F) x.S+=y.S;
    return x;
}
void build(int id=1,int L=1,int R=n+1){
    seg[id].S=R-L;
    if(R<=L+1) return ;
    int mid=(L+R+1) >> 1;
    build(id*2+0, L, mid);
    build(id*2+1, mid, R);
}
void add(int id,int L,int R,int l,int r,int val){
    if(R<=l || r<=L) return ;
    if(l<=L && R<=r){
        lazy[id] += val;
        seg[id].F += val;
        return ;
    }
    int mid=(L+R+1)>>1;
    shift(id, L, R);
    add(id*2+0, L, mid, l, r, val);
    add(id*2+1, mid, R, l, r, val);
    seg[id]=Min(seg[id*2+0],seg[id*2+1]);
}
void shift(int id,int L,int R){
    int mid=(L+R+1) >> 1;
    add(id*2+0, L, mid, L, mid, lazy[id]);
    add(id*2+1, mid, R, mid, R, lazy[id]);
    lazy[id]=0;
}
void DFS(int x,int par){
    f(i,0,query[x].size())
        add(1,1,n+1,query[x][i].F,query[x][i].S,1);

    f(i,0,g[x].size())
        if(g[x][i]!=par)
            DFS(g[x][i],x);
    ans[x]=n-(seg[1].F==0 ? seg[1].S : 0);

    f(i,0,query[x].size())
        add(1,1,n+1,query[x][i].F,query[x][i].S,-1);
}
void dfs(int x,int par){
    s[x]=++c;
    f(i,0,g[x].size())
        if(g[x][i]!=par)
            dfs(g[x][i],x);
    t[x]=c+1;
}

int main(){
    cin>>n>>m;
    f(i,1,n){
        int u,v;
        Gett(u,v);
        g[u].pb(v);
        g[v].pb(u);
    }
    build();
    dfs(1,0);

    f(i,0,m){
        int u,v;
        Gett(u,v);
        query[u].pb(mp(s[v],t[v]));
        query[u].pb(mp(s[u],t[u]));
        query[v].pb(mp(s[u],t[u]));
        query[v].pb(mp(s[v],t[v]));
    }

    DFS(1,0);
    f(i,1,n+1) cout<<ans[i]-(0<ans[i])<<" ";
}


#include <bits/stdc++.h>
using namespace std;
#define erorp(x) cout<<#x<<"={"<<(x.F)<<" , "<<x.S<<"}"<<endl;
#define print(v,r) f(i,0,r) cout<<v[i]<<" "; cout<<endl;
#define Get(x,y) scanf("%I64d%I64d",&x,&y);
#define is_bit(x,y) (x%(1<<(y+1))>=(1<<y))
#define eror(x) cout<<#x<<'='<<(x)<<endl;
#define f_(i,a,b) for(int i=a;i>=b;i--)
#define Gett(x,y) scanf("%d%d",&x,&y);
#define f(i,a,b) for(int i=a;i<b;i++)
#define get(x) scanf("%I64d",&x);
#define gett(x) scanf("%d",&x);
#define maxm(a,b) a=max(a,b);
#define minm(a,b) a=min(a,b);
#define Add(x,y) x=(x+y)%mod
#define lst(x) x[x.size()-1]
#define sz(x) int(x.size())
#define mp make_pair
#define ll long long
#define pb push_back
#define S second
#define F first

const int N=2e5+9;

int n,m,c,s[N],t[N],ans[N],lazy[N];
pair<int,int> seg[N];
vector<int> g[N];
vector<pair<int,int> > query[N];

void shift(int,int,int);

pair<int,int> Min(pair<int,int> x,pair<int,int> y){
    if(y<x) swap(x,y);
    if(x.F == y.F) x.S+=y.S;
    return x;
}
void build(int id=1,int L=1,int R=n+1){
    seg[id].S=R-L;
    if(R<=L+1) return ;
    int mid=(L+R+1) >> 1;
    build(id*2+0, L, mid);
    build(id*2+1, mid, R);
}
void add(int id,int L,int R,int l,int r,int val){
    if(R<=l || r<=L) return ;
    if(l<=L && R<=r){
        lazy[id] += val;
        seg[id].F += val;
        return ;
    }
    int mid=(L+R+1)>>1;
    shift(id, L, R);
    add(id*2+0, L, mid, l, r, val);
    add(id*2+1, mid, R, l, r, val);
    seg[id]=Min(seg[id*2+0],seg[id*2+1]);
}
void shift(int id,int L,int R){
    int mid=(L+R+1) >> 1;
    add(id*2+0, L, mid, L, mid, lazy[id]);
    add(id*2+1, mid, R, mid, R, lazy[id]);
    lazy[id]=0;
}
void DFS(int x,int par){
    f(i,0,query[x].size())
        add(1,1,n+1,query[x][i].F,query[x][i].S,1);

    f(i,0,g[x].size())
        if(g[x][i]!=par)
            DFS(g[x][i],x);
    ans[x]=n-(seg[1].F==0 ? seg[1].S : 0);

    f(i,0,query[x].size())
        add(1,1,n+1,query[x][i].F,query[x][i].S,-1);
}
void dfs(int x,int par){
    s[x]=++c;
    f(i,0,g[x].size())
        if(g[x][i]!=par)
            dfs(g[x][i],x);
    t[x]=c+1;
}

int main(){
    cin>>n>>m;
    f(i,1,n){
        int u,v;
        Gett(u,v);
        g[u].pb(v);
        g[v].pb(u);
    }
    build();
    dfs(1,0);

    f(i,0,m){
        int u,v;
        Gett(u,v);
        query[u].pb(mp(s[v],t[v]));
        query[u].pb(mp(s[u],t[u]));
        query[v].pb(mp(s[u],t[u]));
        query[v].pb(mp(s[v],t[v]));
    }

    DFS(1,0);
    f(i,1,n+1) cout<<ans[i]-(0<ans[i])<<" ";
}


#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);
	if(l>r_u || r<l_u) return make_pair(seg_min[u], seg_quant[u]);
	refresh(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){
	//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, "\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<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);

	if(l>r_u || r<l_u) return make_pair(seg_min[u], seg_quant[u]);
	refresh(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.second==0 || p1.first>p2.first){
		//	printf("1");
			seg_min[u]=p2.first;
			seg_quant[u]=p2.second;
		}
		else if(p2.second==0 || 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){
	//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);
		}
	}
	if(fin_sub_arv[u]==0) fin_sub_arv[u]=cont[u];
	return cont[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, "\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);

	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;
}