/** Micro Mezzo Macro Flation -- Overheated Economy ., Last Update: Dec. 20th 2012 **/ //{

/** Header .. **/ //{
#define LOCAL

#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <numeric>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>

using namespace std;

#define REP(i, n) for (int i=0;i<int(n);++i)
#define FOR(i, a, b) for (int i=int(a);i<int(b);++i)
#define DWN(i, b, a) for (int i=int(b-1);i>=int(a);--i)
#define REP_1(i, n) for (int i=1;i<=int(n);++i)
#define FOR_1(i, a, b) for (int i=int(a);i<=int(b);++i)
#define DWN_1(i, b, a) for (int i=int(b);i>=int(a);--i)
#define REP_C(i, n) for (int n____=int(n),i=0;i<n____;++i)
#define FOR_C(i, a, b) for (int b____=int(b),i=a;i<b____;++i)
#define DWN_C(i, b, a) for (int a____=int(a),i=b-1;i>=a____;--i)
#define REP_N(i, n) for (i=0;i<int(n);++i)
#define FOR_N(i, a, b) for (i=int(a);i<int(b);++i)
#define DWN_N(i, b, a) for (i=int(b-1);i>=int(a);--i)
#define REP_1_C(i, n) for (int n____=int(n),i=1;i<=n____;++i)
#define FOR_1_C(i, a, b) for (int b____=int(b),i=a;i<=b____;++i)
#define DWN_1_C(i, b, a) for (int a____=int(a),i=b;i>=a____;--i)
#define REP_1_N(i, n) for (i=1;i<=int(n);++i)
#define FOR_1_N(i, a, b) for (i=int(a);i<=int(b);++i)
#define DWN_1_N(i, b, a) for (i=int(b);i>=int(a);--i)
#define REP_C_N(i, n) for (int n____=(i=0,int(n));i<n____;++i)
#define FOR_C_N(i, a, b) for (int b____=(i=0,int(b);i<b____;++i)
#define DWN_C_N(i, b, a) for (int a____=(i=b-1,int(a));i>=a____;--i)
#define REP_1_C_N(i, n) for (int n____=(i=1,int(n));i<=n____;++i)
#define FOR_1_C_N(i, a, b) for (int b____=(i=1,int(b);i<=b____;++i)
#define DWN_1_C_N(i, b, a) for (int a____=(i=b,int(a));i>=a____;--i)

#define ECH(it, A) for (__typeof(A.begin()) it=A.begin(); it != A.end(); ++it)
#define REP_S(i, str) for (char*i=str;*i;++i)
#define REP_L(i, hd, nxt) for (int i=hd;i;i=nxt[i])
#define REP_G(i, u) REP_L(i,hd[u],suc)
#define DO(n) for ( int ____n ## __line__ = n; ____n ## __line__ -- ; )
#define REP_2(i, j, n, m) REP(i, n) REP(j, m)
#define REP_2_1(i, j, n, m) REP_1(i, n) REP_1(j, m)
#define REP_3(i, j, k, n, m, l) REP(i, n) REP(j, m) REP(k, l)
#define REP_3_1(i, j, k, n, m, l) REP_1(i, n) REP_1(j, m) REP_1(k, l)

#define ALL(A) A.begin(), A.end()
#define LLA(A) A.rbegin(), A.rend()
#define CPY(A, B) memcpy(A, B, sizeof(A))
#define INS(A, P, B) A.insert(A.begin() + P, B)
#define ERS(A, P) A.erase(A.begin() + P)
#define BSC(A, x) (lower_bound(ALL(A), x) - A.begin())
#define CTN(T, x) (T.find(x) != T.end())
#define SZ(A) int(A.size())
#define PB push_back
#define MP(A, B) make_pair(A, B)
#define PTT pair<T, T>
#define fi first
#define se second

#define Rush for(int ____T=RD(); ____T--;)

#define Display(A, n, m) {                      \
	REP(i, n){		                            \
        REP(j, m) cout << A[i][j] << " ";       \
        cout << endl;				            \
	}						                    \
}

#define Display_1(A, n, m) {				    \
	REP_1(i, n){		                        \
        REP_1(j, m) cout << A[i][j] << " ";     \
		cout << endl;		            		\
	}						                    \
}

#pragma comment(linker, "/STACK:36777216")
//#pragma GCC optimize ("O2")
#define Ruby system("ruby main.rb")
#define Haskell system("runghc main.hs")
#define Python system("python main.py")
#define Pascal system("fpc main.pas")

typedef long long LL;
//typedef long double DB;
typedef double DB;
typedef unsigned UINT;
typedef unsigned long long ULL;

typedef vector<int> VI;
typedef vector<char> VC;
typedef vector<string> VS;
typedef vector<LL> VL;
typedef vector<DB> VF;
typedef set<int> SI;
typedef set<string> SS;
typedef map<int, int> MII;
typedef map<string, int> MSI;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef vector<PII> VII;
typedef vector<VI> VVI;
typedef vector<VII> VVII;

template<class T> inline T& RD(T &);
template<class T> inline void OT(const T &);
inline LL RD(){LL x; return RD(x);}
inline DB& RF(DB &x){scanf("%lf", &x); return x;}
inline DB RF(){DB x; return RF(x);}
inline char* RS(char *s);
inline char& RC(char &c);
inline char RC();
inline char& RC(char &c){scanf(" %c", &c); return c;}
inline char RC(){char c; return RC(c);}
//inline char& RC(char &c){c = getchar(); return c;}
//inline char RC(){return getchar();}

template<class T0, class T1> inline T0& RD(T0 &x0, T1 &x1){RD(x0), RD(x1); return x0;}
template<class T0, class T1, class T2> inline T0& RD(T0 &x0, T1 &x1, T2 &x2){RD(x0), RD(x1), RD(x2); return x0;}
template<class T0, class T1, class T2, class T3> inline T0& RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3){RD(x0), RD(x1), RD(x2), RD(x3); return x0;}
template<class T0, class T1, class T2, class T3, class T4> inline T0& RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4); return x0;}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline T0& RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5); return x0;}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline T0& RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5, T6 &x6){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5), RD(x6); return x0;}
template<class T0, class T1> inline void OT(const T0 &x0, const T1 &x1){OT(x0), OT(x1);}
template<class T0, class T1, class T2> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2){OT(x0), OT(x1), OT(x2);}
template<class T0, class T1, class T2, class T3> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3){OT(x0), OT(x1), OT(x2), OT(x3);}
template<class T0, class T1, class T2, class T3, class T4> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3, const T4 &x4){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3, const T4 &x4, const T5 &x5){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3, const T4 &x4, const T5 &x5, const T6 &x6){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5), OT(x6);}
inline char& RC(char &a, char &b){RC(a), RC(b); return a;}
inline char& RC(char &a, char &b, char &c){RC(a), RC(b), RC(c); return a;}
inline char& RC(char &a, char &b, char &c, char &d){RC(a), RC(b), RC(c), RC(d); return a;}
inline char& RC(char &a, char &b, char &c, char &d, char &e){RC(a), RC(b), RC(c), RC(d), RC(e); return a;}
inline char& RC(char &a, char &b, char &c, char &d, char &e, char &f){RC(a), RC(b), RC(c), RC(d), RC(e), RC(f); return a;}
inline char& RC(char &a, char &b, char &c, char &d, char &e, char &f, char &g){RC(a), RC(b), RC(c), RC(d), RC(e), RC(f), RC(g); return a;}
inline DB& RF(DB &a, DB &b){RF(a), RF(b); return a;}
inline DB& RF(DB &a, DB &b, DB &c){RF(a), RF(b), RF(c); return a;}
inline DB& RF(DB &a, DB &b, DB &c, DB &d){RF(a), RF(b), RF(c), RF(d); return a;}
inline DB& RF(DB &a, DB &b, DB &c, DB &d, DB &e){RF(a), RF(b), RF(c), RF(d), RF(e); return a;}
inline DB& RF(DB &a, DB &b, DB &c, DB &d, DB &e, DB &f){RF(a), RF(b), RF(c), RF(d), RF(e), RF(f); return a;}
inline DB& RF(DB &a, DB &b, DB &c, DB &d, DB &e, DB &f, DB &g){RF(a), RF(b), RF(c), RF(d), RF(e), RF(f), RF(g); return a;}
inline void RS(char *s1, char *s2){RS(s1), RS(s2);}
inline void RS(char *s1, char *s2, char *s3){RS(s1), RS(s2), RS(s3);}

template<class T> inline void RST(T &A){memset(A, 0, sizeof(A));}
template<class T0, class T1> inline void RST(T0 &A0, T1 &A1){RST(A0), RST(A1);}
template<class T0, class T1, class T2> inline void RST(T0 &A0, T1 &A1, T2 &A2){RST(A0), RST(A1), RST(A2);}
template<class T0, class T1, class T2, class T3> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3){RST(A0), RST(A1), RST(A2), RST(A3);}
template<class T0, class T1, class T2, class T3, class T4> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5), RST(A6);}
template<class T> inline void FLC(T &A, int x){memset(A, x, sizeof(A));}
template<class T0, class T1> inline void FLC(T0 &A0, T1 &A1, int x){FLC(A0, x), FLC(A1, x);}
template<class T0, class T1, class T2> inline void FLC(T0 &A0, T1 &A1, T2 &A2, int x){FLC(A0, x), FLC(A1, x), FLC(A2, x);}
template<class T0, class T1, class T2, class T3> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, int x){FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x);}
template<class T0, class T1, class T2, class T3, class T4> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, int x){FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x), FLC(A4, x);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, int x){FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x), FLC(A4, x), FLC(A5, x);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6, int x){FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x), FLC(A4, x), FLC(A5, x), FLC(A6, x);}
template<class T> inline void CLR(priority_queue<T, vector<T>, less<T> > &Q){while (!Q.empty()) Q.pop();}
template<class T> inline void CLR(priority_queue<T, vector<T>, greater<T> > &Q){while (!Q.empty()) Q.pop();}
template<class T> inline void CLR(T &A){A.clear();}
template<class T0, class T1> inline void CLR(T0 &A0, T1 &A1){CLR(A0), CLR(A1);}
template<class T0, class T1, class T2> inline void CLR(T0 &A0, T1 &A1, T2 &A2){CLR(A0), CLR(A1), CLR(A2);}
template<class T0, class T1, class T2, class T3> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3){CLR(A0), CLR(A1), CLR(A2), CLR(A3);}
template<class T0, class T1, class T2, class T3, class T4> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5), CLR(A6);}
template<class T> inline void CLR(T &A, int n){REP(i, n) CLR(A[i]);}

template<class T> inline T& SRT(T &A){sort(ALL(A)); return A;}
template<class T, class C> inline T& SRT(T &A, C B){sort(ALL(A), B); return A;}
template<class T> inline T& UNQ(T &A){A.resize(unique(ALL(SRT(A))) - A.begin());return A;}

//}

/** Constant List .. **/ //{

const int MOD = 1000000007;
//int MOD = 99990001;
const int INF = 0x3f3f3f3f;
const LL INFF = 1LL << 60;
const DB EPS = 1e-9;
const DB OO = 1e15;
const DB PI = acos(-1.0); //M_PI;

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};

//}

/** Add On .. **/ //{
// <<= '0. Nichi Joo ., //{
template<class T> inline void checkMin(T &a,const T b){if (b<a) a=b;}
template<class T> inline void checkMax(T &a,const T b){if (a<b) a=b;}
template<class T> inline void checkMin(T &a, T &b, const T x){checkMin(a, x), checkMin(b, x);}
template<class T> inline void checkMax(T &a, T &b, const T x){checkMax(a, x), checkMax(b, x);}
template <class T, class C> inline void checkMin(T& a, const T b, C c){if (c(b,a)) a = b;}
template <class T, class C> inline void checkMax(T& a, const T b, C c){if (c(a,b)) a = b;}
template<class T> inline T min(T a, T b, T c){return min(min(a, b), c);}
template<class T> inline T max(T a, T b, T c){return max(max(a, b), c);}
template<class T> inline T min(T a, T b, T c, T d){return min(min(a, b), min(c, d));}
template<class T> inline T max(T a, T b, T c, T d){return max(max(a, b), max(c, d));}
template<class T> inline T sqr(T a){return a*a;}
template<class T> inline T cub(T a){return a*a*a;}
inline int Ceil(int x, int y){return (x - 1) / y + 1;}
//}
// <<= '1. Bitwise Operation ., //{
namespace BO{

inline bool _1(int x, int i){return bool(x&1<<i);}
inline bool _1(LL x, int i){return bool(x&1LL<<i);}
inline LL _1(int i){return 1LL<<i;}
inline LL _U(int i){return _1(i) - 1;};

inline int reverse_bits(int x){
    x = ((x >> 1) & 0x55555555) | ((x << 1) & 0xaaaaaaaa);
    x = ((x >> 2) & 0x33333333) | ((x << 2) & 0xcccccccc);
    x = ((x >> 4) & 0x0f0f0f0f) | ((x << 4) & 0xf0f0f0f0);
    x = ((x >> 8) & 0x00ff00ff) | ((x << 8) & 0xff00ff00);
    x = ((x >>16) & 0x0000ffff) | ((x <<16) & 0xffff0000);
    return x;
}

inline LL reverse_bits(LL x){
    x = ((x >> 1) & 0x5555555555555555LL) | ((x << 1) & 0xaaaaaaaaaaaaaaaaLL);
    x = ((x >> 2) & 0x3333333333333333LL) | ((x << 2) & 0xccccccccccccccccLL);
    x = ((x >> 4) & 0x0f0f0f0f0f0f0f0fLL) | ((x << 4) & 0xf0f0f0f0f0f0f0f0LL);
    x = ((x >> 8) & 0x00ff00ff00ff00ffLL) | ((x << 8) & 0xff00ff00ff00ff00LL);
    x = ((x >>16) & 0x0000ffff0000ffffLL) | ((x <<16) & 0xffff0000ffff0000LL);
    x = ((x >>32) & 0x00000000ffffffffLL) | ((x <<32) & 0xffffffff00000000LL);
    return x;
}

template<class T> inline bool odd(T x){return x&1;}
template<class T> inline bool even(T x){return !odd(x);}
template<class T> inline T low_bit(T x) {return x & -x;}
template<class T> inline T high_bit(T x) {T p = low_bit(x);while (p != x) x -= p, p = low_bit(x);return p;}
template<class T> inline T cover_bit(T x){T p = 1; while (p < x) p <<= 1;return p;}

inline int low_idx(int x){return __builtin_ffs(x);}
inline int low_idx(LL x){return __builtin_ffsll(x);}
inline int high_idx(int x){return low_idx(reverse_bits(x));}
inline int high_idx(LL x){return low_idx(reverse_bits(x));}
inline int clz(int x){return __builtin_clz(x);}
inline int clz(LL x){return __builtin_clzll(x);}
inline int ctz(int x){return __builtin_ctz(x);}
inline int ctz(LL x){return __builtin_ctzll(x);}
inline int parity(int x){return __builtin_parity(x);}
inline int parity(LL x){return __builtin_parityll(x);}
inline int lg2(int a){return 31 - clz(a);}
inline int lg2(LL a){return 63 - clz(a);}
inline int count_bits(int x){return __builtin_popcount(x);}
inline int count_bits(LL x){return __builtin_popcountll(x);}

} using namespace BO;//}
namespace SL{
    namespace KMP{

        void calc_pi(const char *P, int n, int *pi){
            for (int i = 1, j = pi[0] = -1; i < n; ++i){
                while (j >= 0 && P[i] != P[j+1]) j = pi[j];
                if (P[i] == P[j+1]) ++j;
                pi[i] = j;
            }
            //REP(i, n) cout << pi[i] << " "; cout << endl;
        }

        bool run(const char *T, int n, const char *P, int m, const int *pi){
            for (int i = 0, j = -1; i < n; ++i){
                while (j >= 0 && T[i] != P[j+1]) j = pi[j];
                if (T[i] == P[j+1]) ++j;
                if (j == m - 1) return true;
            }
            return false;
        }

    } //using namespace KMP;

    namespace Z{
        void calc_z(const char *P, int n, int *z){

            z[0] = n;

            for (int i = 1, l = 0, r = 0; i < n; ++i){
                if (i > r){
                    for(l = r = i; r < n && P[r] == P[r - l];) ++r;
                    z[i] = r - l, --r;
                }
                else {
                    if (z[i - l] < r - i + 1) z[i] = z[i - l];
                    else {
                        for (l = i;r < n && P[r] == P[r - l];) ++r;
                        z[i] = r - l, --r;
                    }
                }
            }

            //REP(i, n) cout << z[i] << " "; cout << endl;
        }

        int run(const char *T, int n, const char *P, int m, const int *z){

            int ex; REP_C_N(ex, min(n, m)) if (T[ex] != P[ex]) break;

            int res = ex == m;

            for (int i = 1, l = 0, r = 0; i < n; ++i){
                if (i > r){
                    for (l = r = i; r < n && T[r] == P[r - l];) ++r;
                    ex = r - l, --r;
                }
                else {
                    if (z[i - l] < r - i + 1) ex = z[i - l];
                    else {
                        for (l = i; r < n && T[r] == P[r - l];) ++r;
                        ex = r - l, --r;
                    }
                }
                if (ex == m) ++res;
            }

            return res;
        }
    } //using namespace Z;

    void Manacher(char s[], int n, int p[]){
        const int NN = 0;
        static char ss[NN*2+2]; int nn = 2*n+2;
        ss[0] = '$', ss[nn-1] = '#', ss[nn] = 0;
        REP(i, n) ss[i*2+1] ='#', ss[i*2+2] = s[i];
        int mx = 0, id = 0; FOR(i, 1, nn){
            p[i] = mx > i ? min(p[2*id-i], mx - i) : 1;
            while (ss[i+p[i]] == ss[i-p[i]]) ++p[i];
            if (i + p[i] > mx) mx = i + p[i], id = i;
        }
    }

} //using namespace SL;//}
// <<= '9. Comutational Geometry .,//{
namespace CG{

struct Po; struct Line; struct Seg;

inline int sgn(DB x){return x < -EPS ? -1 : x > EPS;}
inline int sgn(DB x, DB y){return sgn(x - y);}

struct Po{
    DB x, y; Po(DB _x=0, DB _y=0):x(_x), y(_y){}
    friend istream& operator >>(istream& in, Po &p){return in >> p.x >> p.y;}
    friend ostream& operator <<(ostream& out, Po p){return out << "(" << p.x << ", " << p.y << ")";}
    bool operator ==(const Po& r)const{return !sgn(x-r.x) && !sgn(y-r.y);};
    bool operator !=(const Po& r)const{return sgn(x-r.x) || sgn(y-r.y);}
    Po operator +(const Po& r)const{return Po(x+r.x, y+r.y);}
    Po operator -(const Po& r)const{return Po(x-r.x, y-r.y);}
    Po operator *(DB k)const{return Po(x*k,y*k);}
    Po operator /(DB k)const{return Po(x/k,y/k);}
    DB operator *(const Po&) const;
    DB operator ^(const Po&) const;

    bool operator <(const Po &r) const{return sgn(x,r.x)<0||!sgn(x,r.x)&&sgn(y,r.y)<0;}
    Po operator -()const{return Po(-x,-y);}
    Po& operator +=(const Po &r){x+=r.x,y+=r.y;return *this;}
    Po& operator -=(const Po &r){x-=r.x,y-=r.y;return *this;}
    Po& operator *=(DB k){x*=k,y*=k;return*this;}
    Po& operator /=(DB k){x/=k,y/=k;return*this;}

    DB length_sqr()const{return sqr(x)+sqr(y);}
    DB length()const{return sqrt(length_sqr());}
    Po unit()const{return *this/length();}
    bool dgt()const{return !sgn(x)&&!sgn(y);}
    DB atan()const{return atan2(y,x);}
    void input(){RF(x,y);}
};

Po operator *(DB k, Po a){return a * k;}

struct Line{
    Po a, b;
    Line(DB x0=0, DB y0=0, DB x1=0, DB y1=0):a(Po(x0, y0)), b(Po(x1, y1)){}
    Line(const Po &a, const Po &b):a(a), b(b){}
    Line(const Line &l):a(l.a), b(l.b){}

    friend ostream& operator <<(ostream& out, Line p){return out << p.a << "-" << p.b;}
    Line operator +(Po x)const{return Line(a + x, b + x);}
    DB length()const{return (b-a).length();}
    bool dgt()const{return (b-a).dgt();}
    void input(){a.input(), b.input();}
    void getequation(DB, DB, DB) const;
};

struct Seg: Line{
};

#define innerProduct dot
#define scalarProduct dot
#define dotProduct dot
#define outerProduct det
#define crossProduct det

inline DB dot(const DB &x1, const DB &y1, const DB &x2, const DB &y2){return x1 * x2 + y1 * y2;}
inline DB dot(const Po &a, const Po &b){return dot(a.x, a.y, b.x, b.y);}
inline DB dot(const Po &p0, const Po &p1, const Po &p2){return dot(p1 - p0, p2 - p0);}
inline DB dot(const Po &o, const Line &l){return dot(o, l.a, l.b);}
inline DB dot(const Line &l, const Po &o){return dot(o, l.a, l.b);}
inline DB dot(const Line &l1, const Line &l2){return dot(l1.b - l1.a, l2.b - l2.a);}

inline DB det(const DB &x1, const DB &y1, const DB &x2, const DB &y2){return x1 * y2 - x2 * y1;}
inline DB det(const Po &a, const Po &b){return det(a.x, a.y, b.x, b.y);}
inline DB det(const Po &p0, const Po &p1, const Po &p2){return det(p1 - p0, p2 - p0);}
inline DB det(const Po &o, const Line &l){return det(o, l.a, l.b);}
inline DB det(const Line &l, const Po &o){return det(o, l.a, l.b);}
inline DB det(const Line &l1, const Line &l2){return det(l1.b - l1.a, l2.b - l2.a);}

DB Po::operator *(const Po &r)const{return dot(*this, r);}
DB Po::operator ^(const Po &r)const{return det(*this, r);}

void Line::getequation(DB A, DB B, DB C) const{
    A = a.y - b.y, B = b.x - a.x, C = det(a, b);
}

template<class T1, class T2> inline DB dist(const T1 &x, const T2 &y){return sqrt(dist_sqr(x, y));}
template<class T1, class T2, class T3> inline DB dist(const T1 &x, const T2 &y, const T3 &z){return sqrt(dist_sqr(x, y, z));}
template<class T1, class T2> inline int dett(const T1 &x, const T2 &y){return sgn(det(x, y));}
template<class T1, class T2> inline int dott(const T1 &x, const T2 &y){return sgn(dot(x, y));}
template<class T1, class T2, class T3> inline int dett(const T1 &x, const T2 &y, const T3 &z){return sgn(det(x, y, z));}
template<class T1, class T2, class T3> inline int dott(const T1 &x, const T2 &y, const T3 &z){return sgn(dot(x, y, z));}
template<class T1, class T2, class T3, class T4> inline int dett(const T1 &x, const T2 &y, const T3 &z, const T4 &w){return sgn(det(x, y, z, w));}
template<class T1, class T2, class T3, class T4> inline int dott(const T1 &x, const T2 &y, const T3 &z, const T4 &w){return sgn(dot(x, y, z, w));}

inline DB dist_sqr(const DB &x, const DB &y){return sqr(x) + sqr(y);}
inline DB dist_sqr(const DB &x, const DB &y, const DB &z){return sqr(x) + sqr(y) + sqr(z);}
inline DB dist_sqr(const Po &a, const Po &b){return sqr(a.x - b.x) + sqr(a.y - b.y);}
inline DB dist_sqr(const Po &p, const Line &l){Po v0 = l.b - l.a, v1 = p - l.a; return sqr(fabs(det(v0, v1))) / v0.length_sqr();}
inline DB dist_sqr(const Po &p, const Seg &l){
    Po v0 = l.b - l.a, v1 = p - l.a, v2 = p - l.b;
    if (sgn(dot(v0, v1)) * sgn(dot(v0, v2)) <= 0) return dist_sqr(p, Line(l));
    else return min(v1.length_sqr(), v2.length_sqr());
}
inline DB dist_sqr(Line l, Po p){return dist_sqr(p, l);}
inline DB dist_sqr(Seg l, Po p){return dist_sqr(p, l);}
inline DB dist_sqr(Line l1, Line l2){
    if (sgn(det(l1, l2)) != 0) return 0;
    return dist_sqr(l1.a, l2);
}
inline DB dist_sqr(Line l1, Seg l2){
    Po v0 = l1.b - l1.a, v1 = l2.a - l1.a, v2 = l2.b - l1.a; DB c1 = det(v0, v1), c2 = det(v0, v2);
    return sgn(c1) != sgn(c2) ? 0 : sqr(min(fabs(c1), fabs(c2))) / v0.length_sqr();
}

bool isIntersect(Seg l1, Seg l2){

    if (l1.a == l2.a || l1.a == l2.b || l1.b == l2.a || l1.b == l2.b) return true;

    return
        min(l1.a.x, l1.b.x) <= max(l2.a.x, l2.b.x) &&
        min(l2.a.x, l2.b.x) <= max(l1.a.x, l1.b.x) &&
        min(l1.a.y, l1.b.y) <= max(l2.a.y, l2.b.y) &&
        min(l2.a.y, l2.b.y) <= max(l1.a.y, l1.b.y) &&
    sgn( det(l1.a, l2.a, l2.b) ) * sgn( det(l1.b, l2.a, l2.b) ) <= 0 &&
    sgn( det(l2.a, l1.a, l1.b) ) * sgn( det(l2.b, l1.a, l1.b) ) <= 0;

}

inline DB dist_sqr(Seg l1, Seg l2){
    if (isIntersect(l1, l2)) return 0;
    else return min(dist_sqr(l1.a, l2), dist_sqr(l1.b, l2), dist_sqr(l2.a, l1), dist_sqr(l2.b, l1));
}

inline bool isOnSide(const Po &p, const Seg &l){
    return p == l.a || p == l.b;
}

inline bool isOnSeg(const Po &p, const Seg &l){
    return sgn(det(p, l.a, l.b)) == 0 &&
        sgn(l.a.x, p.x) * sgn(l.b.x, p.x) <= 0 && sgn(l.a.y, p.y) * sgn(l.b.y, p.y) <= 0;
}

inline bool isOnSegg(const Po &p, const Seg &l){
    return sgn(det(p, l.a, l.b)) == 0 &&
        sgn(l.a.x, p.x) * sgn(l.b.x, p.x) < 0 && sgn(l.a.y, p.y) * sgn(l.b.y, p.y) < 0;
}

inline Po intersect(const Line &l1, const Line &l2){
    return l1.a + (l1.b - l1.a) * (det(l2.a, l1.a, l2.b) / det(l2, l1));
}

// perpendicular foot
inline Po intersect(const Po & p, const Line &l){
    return intersect(Line(p, p + Po(l.a.y - l.b.y, l.b.x - l.a.x)), l);
}

inline Po rotate(Po p, DB alpha, Po o = Po()){
    p.x -= o.x, p.y -= o.y;
    return Po(p.x * cos(alpha) - p.y * sin(alpha), p.y * cos(alpha) + p.x * sin(alpha)) + o;
}

} using namespace CG;//}
//}

/** I/O Accelerator Interface .. **/ //{
template<class T> inline T& RD(T &x){
    //cin >> x;
    scanf("%d", &x);
    //char c; for (c = getchar(); c < '0'; c = getchar()); x = c - '0'; for (c = getchar(); '0' <= c && c <= '9'; c = getchar()) x = x * 10 + c - '0';
    //char c; c = getchar(); x = c - '0'; for (c = getchar(); c >= '0'; c = getchar()) x = x * 10 + c - '0';
    return x;
}

inline char* RS(char *s){
    //gets(s);
    scanf("%s", s);
    return s;
}

int Case; template<class T> inline void OT(const T &x){
    //printf("Case %d: %d\n", ++Case, x);
    //printf("%.2lf\n", x);
    printf("%d\n", x);
    //cout << x << endl;
}
//}

//}/* .................................................................................................................................. */

const int N = 100009;

VI adj[N]; int dep[N], sz[N], bj[N];
int n, m, cnt; int ans[N];

int L[N], R[N];

int C[4*N], I[4*N]; VI op[N];
// Interval Tree

#define root 1, 1, n
#define lx (x<<1)
#define rx (lx|1)
#define m ((l+r)>>1)
#define lc lx, l, m, a, b
#define rc rx, m+1, r, a, b

void Update(int x, int l, int r){
    if (C[x]) I[x] = r - l + 1;
    else if (l != r) I[x] = I[lx] + I[rx];
    else I[x] = 0;
}

void Modify(int x, int l, int r, int a, int b, int delta){
    if (b < l || r < a) return;
    if (a <= l && r <= b) C[x] += delta;
    else {
        Modify(lc, delta), Modify(rc, delta);
    }
    Update(x, l, r);
}
#undef pos
#undef m

#define v adj[u][i]
void dfs(int u = 1, int p = -1){
    L[u] = ++cnt; sz[u] = 1;

    REP(i, SZ(adj[u])) if (v != p){
        dep[v] = dep[u] + 1; dfs(v, u);
        sz[u] += sz[v];
    }
    R[u] = cnt;
}

void gao(int u = 1, int p = -1){

    if (SZ(op[u])) Modify(root, L[u], R[u], 1);
    REP(i, SZ(op[u])){
        Modify(root, L[op[u][i]], R[op[u][i]], 1);
    }

    ans[u] = I[1];

    REP(i, SZ(adj[u])) if (v != p){
        gao(v, u);
    }

    if (SZ(op[u])) Modify(root, L[u], R[u], -1);
    REP(i, SZ(op[u])){
        Modify(root, L[op[u][i]], R[op[u][i]], -1);
    }
}

#undef v

int main(){

#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
#endif

    RD(n, m); DO(n-1){
        int u, v; RD(u, v);
        adj[u].PB(v); adj[v].PB(u);
    }

    dfs(); DO(m){
        int u, v; RD(u, v);
        op[u].PB(v);
        op[v].PB(u);
    }

    gao();

    REP_1(i, n) printf("%d ", max(0, ans[i]-1));
}


//ITNOG
#include<bits/stdc++.h>

using namespace std;
//#define int long long
const int maxN = 100*1000 + 10;
const int mod = 1000*1000*1000 + 7;

int n, m;
int cnt;
vector<int> a[maxN];
vector<int> c[maxN];
int st[maxN], fi[maxN];
int ans[maxN];

int ad[4 * maxN], seg[4 * maxN];

void add(int l, int r, int val, int s, int e, int ind)
{
    if(e <= l || r <= s) return;
    if(l <= s && e <= r)
    {
	  ad[ind] += val;
	  if(ad[ind]) seg[ind] = e - s;
	  else
	  {
		if(e - s == 1) seg[ind] = 0;
		else seg[ind] = seg[2 * ind] + seg[2 * ind + 1];
	  }
	  return;
    }

    int mid = (s + e) >> 1;

    add(l, r, val, s, mid, 2 * ind + 0);
    add(l, r, val, mid, e, 2 * ind + 1);
    if(!ad[ind])
	  seg[ind] = seg[2 * ind] + seg[2 * ind + 1];
}

bool get(int p, int s, int e, int ind)
{
    if(e - s == 1) return seg[ind];

    int mid = (s + e) >> 1;
    if(ad[ind]) return 1;
    if(p < mid) return get(p, s, mid, 2 * ind);
    else return get(p, mid, e, 2 * ind + 1);
}
void dfs(int v, int par = -1)
{
    st[v] = cnt ++;
    for(auto u : a[v])
	  if(u - par)
		dfs(u, v);
    fi[v] = cnt;
}

void DFS(int v, int par = -1)
{
    for(auto u : c[v])
    {
	  add(st[v], fi[v], 1, 0, n, 1);
	  add(st[u], fi[u], 1, 0, n, 1);
    }
    //if(v == 0) cout << seg[1] << endl;
    ans[v] = seg[1] - get(st[v], 0, n, 1);
    for(auto u : a[v])
	  if(u - par)
		DFS(u, v);

    for(auto u : c[v])
    {
	  add(st[v], fi[v], -1, 0, n, 1);
	  add(st[u], fi[u], -1, 0, n, 1);
    }
}
main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m;
    for(int i = 1; i < n; i ++)
    {
	  int v, u; cin >> v >> u; v  --; u --;
	  a[v].push_back(u);
	  a[u].push_back(v);
    }

    for(int i = 0; i < m; i ++)
    {
	  int v, u; cin >> v >> u; v --; u --;
	  c[v].push_back(u);
	  c[u].push_back(v);
    }

    dfs(0);
    //cout << st[0] << ' ' << fi[0] << endl; return 0;
    DFS(0); //return 0;

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


//ITNOG
#include<bits/stdc++.h>

using namespace std;
//#define int long long
const int maxN = 100*1000 + 10;
const int mod = 1000*1000*1000 + 7;

int n, m;
int cnt;
vector<int> a[maxN];
vector<int> c[maxN];
int st[maxN], fi[maxN];
int ans[maxN];

int ad[4 * maxN], seg[4 * maxN];

void add(int l, int r, int val, int s, int e, int ind)
{
    if(e <= l || r <= s) return;
    if(l <= s && e <= r)
    {
	  ad[ind] += val;
	  if(ad[ind]) seg[ind] = e - s;
	  else
	  {
		if(e - s == 1) seg[ind] = 0;
		else seg[ind] = seg[2 * ind] + seg[2 * ind + 1];
	  }
	  return;
    }

    int mid = (s + e) >> 1;

    add(l, r, val, s, mid, 2 * ind + 0);
    add(l, r, val, mid, e, 2 * ind + 1);

    seg[ind] = seg[2 * ind] + seg[2 * ind + 1];
}

bool get(int p, int s, int e, int ind)
{
    if(e - s == 1) return seg[ind];

    int mid = (s + e) >> 1;
    if(ad[ind]) return 1;
    if(p < mid) return get(p, s, mid, 2 * ind);
    else return get(p, mid, e, 2 * ind + 1);
}
void dfs(int v, int par = -1)
{
    st[v] = cnt ++;
    for(auto u : a[v])
	  if(u - par)
		dfs(u, v);
    fi[v] = cnt;
}

void DFS(int v, int par = -1)
{
    for(auto u : c[v])
    {
	  add(st[v], fi[v], 1, 0, n, 1);
	  add(st[u], fi[u], 1, 0, n, 1);
    }
    ans[v] = seg[1] - get(st[v], 0, n, 1);
    for(auto u : a[v])
	  if(u - par)
		DFS(u, v);

    for(auto u : c[v])
    {
	  add(st[v], fi[v], -1, 0, n, 1);
	  add(st[u], fi[u], -1, 0, n, 1);
    }
}
main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m;
    for(int i = 1; i < n; i ++)
    {
	  int v, u; cin >> v >> u; v  --; u --;
	  a[v].push_back(u);
	  a[u].push_back(v);
    }

    for(int i = 0; i < m; i ++)
    {
	  int v, u; cin >> v >> u; v --; u --;
	  c[v].push_back(u);
	  c[u].push_back(v);
    }

    dfs(0);
    DFS(0);

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


//ITNOG
#include<bits/stdc++.h>

using namespace std;
#define int long long
const int maxN = 100*1000 + 10;
const int mod = 1000*1000*1000 + 7;

int n, m;
int cnt;
vector<int> a[maxN];
vector<int> c[maxN];
int st[maxN], fi[maxN];
int ans[maxN];

int ad[4 * maxN], seg[4 * maxN];

void add(int l, int r, int val, int s, int e, int ind)
{
    if(e <= l || r <= s) return;
    if(l <= s && e <= r)
    {
	  ad[ind] += val;
	  if(ad[ind]) seg[ind] = e - s;
	  else
	  {
		if(e - s == 1) seg[ind] = 0;
		else seg[ind] = seg[2 * ind] + seg[2 * ind + 1];
	  }
	  return;
    }

    int mid = (s + e) >> 1;

    add(l, r, val, s, mid, 2 * ind + 0);
    add(l, r, val, mid, e, 2 * ind + 1);

    seg[ind] = seg[2 * ind] + seg[2 * ind + 1];
}

bool get(int p, int s, int e, int ind)
{
    if(e - s == 1) return seg[ind];

    int mid = (s + e) >> 1;
    if(ad[ind]) return 1;
    if(p < mid) return get(p, s, mid, 2 * ind);
    else return get(p, mid, e, 2 * ind + 1);
}
void dfs(int v, int par = -1)
{
    st[v] = cnt ++;
    for(auto u : a[v])
	  if(u - par)
		dfs(u, v);
    fi[v] = cnt;
}

void DFS(int v, int par = -1)
{
    for(auto u : c[v])
    {
	  add(st[v], fi[v], 1, 0, n, 1);
	  add(st[u], fi[u], 1, 0, n, 1);
    }
    ans[v] = seg[1] - get(st[v], 0, n, 1);
    for(auto u : a[v])
	  if(u - par)
		DFS(u, v);

    for(auto u : c[v])
    {
	  add(st[v], fi[v], -1, 0, n, 1);
	  add(st[u], fi[u], -1, 0, n, 1);
    }
}
main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m;
    for(int i = 1; i < n; i ++)
    {
	  int v, u; cin >> v >> u; v  --; u --;
	  a[v].push_back(u);
	  a[u].push_back(v);
    }

    for(int i = 0; i < m; i ++)
    {
	  int v, u; cin >> v >> u; v --; u --;
	  c[v].push_back(u);
	  c[u].push_back(v);
    }

    dfs(0);
    DFS(0);

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


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#define SIZE 100005
#define MX 200005
#define SQR 320

using namespace std;
typedef long long int ll;

struct SQRT
{
	int cnt[SQR][MX*2];
	int in[MX],gen[SQR];

	void init()
	{
		for(int i=0;i<MX;i++) in[i]=MX;
		for(int i=0;i<SQR;i++) calc(i);
	}
	void calc(int k)
	{
		memset(cnt[k],0,sizeof(cnt[k]));
		for(int i=k*SQR;i<(k+1)*SQR;i++)
		{
			cnt[k][in[i]]++;
		}
	}
	void add(int l,int r,int v)
	{
		int vl=l/SQR,vr=r/SQR;
		if(vl==vr)
		{
			for(int i=l;i<=r;i++) in[i]+=v;
			calc(vl);
		}
		else
		{
			while(l%SQR) in[l++]+=v;
			while((r+1)%SQR) in[r--]+=v;
			calc(vl);
			calc(vr);
			for(int i=l/SQR;i<=r/SQR;i++) gen[i]+=v;
		}
	}
	int all()
	{
		int ret=SQR*SQR;
		for(int i=0;i<SQR;i++)
		{
			ret-=cnt[i][MX-gen[i]];
		}
		return ret;
	}
};
SQRT sqr;
vector <int> vec[SIZE];
vector <int> add[SIZE];
int id[SIZE],ch[SIZE];
int ans[SIZE];
int nw;

void dfs(int v=0,int p=-1)
{
	id[v]=nw++;
	for(int i=0;i<vec[v].size();i++)
	{
		int to=vec[v][i];
		if(to!=p) dfs(to,v);
	}
	ch[v]=nw-1;
}
void solve(int v=0,int p=-1)
{
	for(int i=0;i<add[v].size();i++)
	{
		int to=add[v][i];
		sqr.add(id[v],ch[v],1);
		sqr.add(id[to],ch[to],1);
	}
	ans[v]=sqr.all();
	for(int i=0;i<vec[v].size();i++)
	{
		int to=vec[v][i];
		if(to!=p) solve(to,v);
	}
	for(int i=0;i<add[v].size();i++)
	{
		int to=add[v][i];
		sqr.add(id[v],ch[v],-1);
		sqr.add(id[to],ch[to],-1);
	}
}
int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	for(int i=0;i<n-1;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);a--;b--;
		vec[a].push_back(b);
		vec[b].push_back(a);
	}
	for(int i=0;i<m;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);a--;b--;
		add[a].push_back(b);
		add[b].push_back(a);
	}
	dfs();
	sqr.init();
	solve();
	for(int i=0;i<n;i++)
	{
		if(i!=0) printf(" ");
		printf("%d",max(0,ans[i]-1));
	}puts("");
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#define SIZE 100000
#define MX 200000
#define SQR 308
#define SZ 325

using namespace std;
typedef long long int ll;

struct SQRT
{
	int cnt[SZ][MX];
	int in[MX],gen[SZ];

	void init()
	{
		for(int i=0;i<MX;i++) in[i]=MX/2;
		for(int i=0;i<SZ;i++) calc(i);
	}
	void calc(int k)
	{
		memset(cnt[k],0,sizeof(cnt[k]));
		for(int i=k*SQR;i<(k+1)*SQR;i++)
		{
			cnt[k][in[i]]++;
		}
	}
	void add(int l,int r,int v)
	{
		int vl=l/SQR,vr=r/SQR;
		if(vl==vr)
		{
			for(int i=l;i<=r;i++) in[i]+=v;
			calc(vl);
		}
		else
		{
			while(l%SQR) in[l++]+=v;
			while((r+1)%SQR) in[r--]+=v;
			calc(vl);
			calc(vr);
			for(int i=l/SQR;i<=r/SQR;i++) gen[i]+=v;
		}
	}
	int all()
	{
		int ret=SQR*SZ;
		for(int i=0;i<SZ;i++)
		{
			ret-=cnt[i][MX/2-gen[i]];
		}
		return ret;
	}
};
SQRT sqr;
vector <int> vec[SIZE];
vector <int> add[SIZE];
int id[SIZE],ch[SIZE];
int ans[SIZE],cnt[SIZE];
int nw;

void dfs(int v=0,int p=-1)
{
	id[v]=nw++;
	for(int i=0;i<vec[v].size();i++)
	{
		int to=vec[v][i];
		if(to!=p) dfs(to,v);
	}
	ch[v]=nw-1;
}
void solve(int v=0,int p=-1)
{
	for(int i=0;i<add[v].size();i++)
	{
		int to=add[v][i];
		if(cnt[v]==0) sqr.add(id[v],ch[v],1);
		if(cnt[to]==0) sqr.add(id[to],ch[to],1);
		cnt[v]++;cnt[to]++;
	}
	ans[v]=sqr.all();
	for(int i=0;i<vec[v].size();i++)
	{
		int to=vec[v][i];
		if(to!=p) solve(to,v);
	}
	for(int i=0;i<add[v].size();i++)
	{
		int to=add[v][i];
		cnt[v]--;cnt[to]--;
		if(cnt[v]==0) sqr.add(id[v],ch[v],-1);
		if(cnt[to]==0) sqr.add(id[to],ch[to],-1);
	}
}
int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	for(int i=0;i<n-1;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);a--;b--;
		vec[a].push_back(b);
		vec[b].push_back(a);
	}
	for(int i=0;i<m;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);a--;b--;
		add[a].push_back(b);
		add[b].push_back(a);
	}
	dfs();
	sqr.init();
	solve();
	for(int i=0;i<n;i++)
	{
		if(i!=0) printf(" ");
		printf("%d",max(0,ans[i]-1));
	}puts("");
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#define SIZE 100000
#define MX 200000
#define SQR 308
#define SZ 325

using namespace std;
typedef long long int ll;

struct SQRT
{
	int cnt[SZ][MX];
	int in[MX],gen[SZ];
	int ret;

	void init()
	{
		for(int i=0;i<MX;i++) in[i]=MX/2;
		for(int i=0;i<SZ;i++) calc(i);
		ret=SZ*SQR;
	}
	void calc(int k)
	{
		ret-=cnt[k][MX/2-gen[k]];
		memset(cnt[k],0,sizeof(cnt[k]));
		for(int i=k*SQR;i<(k+1)*SQR;i++)
		{
			cnt[k][in[i]]++;
		}
		ret+=cnt[k][MX/2-gen[k]];
	}
	void add(int l,int r,int v)
	{
		int vl=l/SQR,vr=r/SQR;
		if(vl==vr)
		{
			for(int i=l;i<=r;i++) in[i]+=v;
			calc(vl);
		}
		else
		{
			while(l%SQR) in[l++]+=v;
			while((r+1)%SQR) in[r--]+=v;
			calc(vl);
			calc(vr);
			for(int i=l/SQR;i<=r/SQR;i++)
			{
				ret-=cnt[i][MX/2-gen[i]];
				gen[i]+=v;
				ret+=cnt[i][MX/2-gen[i]];
			}
		}
	}
	int all()
	{
		return SZ*SQR-ret;
	}
};
SQRT sqr;
vector <int> vec[SIZE];
vector <int> add[SIZE];
int id[SIZE],ch[SIZE];
int ans[SIZE],cnt[SIZE];
int nw;

void dfs(int v=0,int p=-1)
{
	id[v]=nw++;
	for(int i=0;i<vec[v].size();i++)
	{
		int to=vec[v][i];
		if(to!=p) dfs(to,v);
	}
	ch[v]=nw-1;
}
void solve(int v=0,int p=-1)
{
	for(int i=0;i<add[v].size();i++)
	{
		int to=add[v][i];
		if(cnt[v]==0) sqr.add(id[v],ch[v],1);
		if(cnt[to]==0) sqr.add(id[to],ch[to],1);
		cnt[v]++;cnt[to]++;
	}
	ans[v]=sqr.all();
	for(int i=0;i<vec[v].size();i++)
	{
		int to=vec[v][i];
		if(to!=p) solve(to,v);
	}
	for(int i=0;i<add[v].size();i++)
	{
		int to=add[v][i];
		cnt[v]--;cnt[to]--;
		if(cnt[v]==0) sqr.add(id[v],ch[v],-1);
		if(cnt[to]==0) sqr.add(id[to],ch[to],-1);
	}
}
int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	for(int i=0;i<n-1;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);a--;b--;
		vec[a].push_back(b);
		vec[b].push_back(a);
	}
	for(int i=0;i<m;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);a--;b--;
		add[a].push_back(b);
		add[b].push_back(a);
	}
	dfs();
	sqr.init();
	solve();
	for(int i=0;i<n;i++)
	{
		if(i!=0) printf(" ");
		printf("%d",max(0,ans[i]-1));
	}puts("");
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#define SIZE 100000
#define MX 100000
#define SQR 200
#define SZ 501

using namespace std;
typedef long long int ll;

struct SQRT
{
	int cnt[SZ][MX];
	int in[MX],gen[SZ];
	int ret;

	void init()
	{
		for(int i=0;i<MX;i++) in[i]=MX/2;
		for(int i=0;i<SZ;i++) calc(i);
		ret=SZ*SQR;
	}
	void calc(int k)
	{
		ret-=cnt[k][MX/2-gen[k]];
		memset(cnt[k],0,sizeof(cnt[k]));
		for(int i=k*SQR;i<(k+1)*SQR;i++)
		{
			cnt[k][in[i]]++;
		}
		ret+=cnt[k][MX/2-gen[k]];
	}
	void add(int l,int r,int v)
	{
		int vl=l/SQR,vr=r/SQR;
		if(vl==vr)
		{
			for(int i=l;i<=r;i++) in[i]+=v;
			calc(vl);
		}
		else
		{
			while(l%SQR) in[l++]+=v;
			while((r+1)%SQR) in[r--]+=v;
			calc(vl);
			calc(vr);
			for(int i=l/SQR;i<=r/SQR;i++)
			{
				ret-=cnt[i][MX/2-gen[i]];
				gen[i]+=v;
				ret+=cnt[i][MX/2-gen[i]];
			}
		}
	}
	int all()
	{
		return SZ*SQR-ret;
	}
};
SQRT sqr;
vector <int> vec[SIZE];
vector <int> add[SIZE];
int id[SIZE],ch[SIZE];
int ans[SIZE],cnt[SIZE];
int nw;

void dfs(int v=0,int p=-1)
{
	id[v]=nw++;
	for(int i=0;i<vec[v].size();i++)
	{
		int to=vec[v][i];
		if(to!=p) dfs(to,v);
	}
	ch[v]=nw-1;
}
void solve(int v=0,int p=-1)
{
	for(int i=0;i<add[v].size();i++)
	{
		int to=add[v][i];
		if(cnt[v]==0) sqr.add(id[v],ch[v],1);
		if(cnt[to]==0) sqr.add(id[to],ch[to],1);
		cnt[v]++;cnt[to]++;
	}
	ans[v]=sqr.all();
	for(int i=0;i<vec[v].size();i++)
	{
		int to=vec[v][i];
		if(to!=p) solve(to,v);
	}
	for(int i=0;i<add[v].size();i++)
	{
		int to=add[v][i];
		cnt[v]--;cnt[to]--;
		if(cnt[v]==0) sqr.add(id[v],ch[v],-1);
		if(cnt[to]==0) sqr.add(id[to],ch[to],-1);
	}
}
int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	for(int i=0;i<n-1;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);a--;b--;
		vec[a].push_back(b);
		vec[b].push_back(a);
	}
	for(int i=0;i<m;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);a--;b--;
		add[a].push_back(b);
		add[b].push_back(a);
	}
	dfs();
	sqr.init();
	solve();
	for(int i=0;i<n;i++)
	{
		if(i!=0) printf(" ");
		printf("%d",max(0,ans[i]-1));
	}puts("");
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#define SIZE 100005
#define MX 200005
#define SQR 320

using namespace std;
typedef long long int ll;

struct SQRT
{
	int cnt[SQR][MX];
	int in[MX],gen[SQR];

	void init()
	{
		memset(in,0,sizeof(in));
		memset(gen,0,sizeof(gen));
		for(int i=0;i<SQR;i++) calc(i);
	}
	void calc(int k)
	{
		memset(cnt[k],0,sizeof(cnt[k]));
		for(int i=k*SQR;i<(k+1)*SQR;i++)
		{
			cnt[k][in[i]]++;
		}
	}
	void add(int l,int r,int v)
	{
		int vl=l/SQR,vr=r/SQR;
		if(vl==vr)
		{
			for(int i=l;i<=r;i++) in[i]+=v;
			calc(vl);
		}
		else
		{
			while(l%SQR) in[l++]+=v;
			while((r+1)%SQR) in[r--]+=v;
			calc(vl);
			calc(vr);
			for(int i=l/SQR;i<=r/SQR;i++) gen[i]+=v;
		}
	}
	int all()
	{
		int ret=SQR*SQR;
		for(int i=0;i<SQR;i++)
		{
			ret-=cnt[i][gen[i]];
		}
		return ret;
	}
};
SQRT sqr;
vector <int> vec[SIZE];
vector <int> add[SIZE];
int id[SIZE],ch[SIZE];
int ans[SIZE];
int nw;

void dfs(int v=0,int p=-1)
{
	id[v]=nw++;
	for(int i=0;i<vec[v].size();i++)
	{
		int to=vec[v][i];
		if(to!=p) dfs(to,v);
	}
	ch[v]=nw-1;
}
void solve(int v=0,int p=-1)
{
	ll pl=0;
	for(int i=0;i<add[v].size();i++)
	{
		int to=add[v][i];
		sqr.add(id[v],ch[v],1);
		sqr.add(id[to],ch[to],1);
	}
	ans[v]=sqr.all();
	for(int i=0;i<vec[v].size();i++)
	{
		int to=vec[v][i];
		if(to!=p) solve(to,v);
	}
	for(int i=0;i<add[v].size();i++)
	{
		int to=add[v][i];
		sqr.add(id[v],ch[v],-1);
		sqr.add(id[to],ch[to],-1);
	}
}
int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	for(int i=0;i<n-1;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);a--;b--;
		vec[a].push_back(b);
		vec[b].push_back(a);
	}
	for(int i=0;i<m;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);a--;b--;
		add[a].push_back(b);
		add[b].push_back(a);
	}
	dfs();
	sqr.init();
	solve();
	for(int i=0;i<n;i++)
	{
		if(i!=0) printf(" ");
		printf("%d",max(0,ans[i]-1));
	}puts("");
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#define SIZE 100005
#define MX 200005
#define SQR 320

using namespace std;
typedef long long int ll;

struct SQRT
{
	int cnt[SQR][MX];
	int in[MX],gen[SQR];

	void init()
	{
		for(int i=0;i<MX;i++) in[i]=MX/2;
		for(int i=0;i<SQR;i++) calc(i);
	}
	void calc(int k)
	{
		memset(cnt[k],0,sizeof(cnt[k]));
		for(int i=k*SQR;i<(k+1)*SQR;i++)
		{
			cnt[k][in[i]]++;
		}
	}
	void add(int l,int r,int v)
	{
		int vl=l/SQR,vr=r/SQR;
		if(vl==vr)
		{
			for(int i=l;i<=r;i++) in[i]+=v;
			calc(vl);
		}
		else
		{
			while(l%SQR) in[l++]+=v;
			while((r+1)%SQR) in[r--]+=v;
			calc(vl);
			calc(vr);
			for(int i=l/SQR;i<=r/SQR;i++) gen[i]+=v;
		}
	}
	int all()
	{
		int ret=SQR*SQR;
		for(int i=0;i<SQR;i++)
		{
			ret-=cnt[i][MX/2-gen[i]];
		}
		return ret;
	}
};
SQRT sqr;
vector <int> vec[SIZE];
vector <int> add[SIZE];
int id[SIZE],ch[SIZE];
int ans[SIZE],cnt[SIZE];
int nw;

void dfs(int v=0,int p=-1)
{
	id[v]=nw++;
	for(int i=0;i<vec[v].size();i++)
	{
		int to=vec[v][i];
		if(to!=p) dfs(to,v);
	}
	ch[v]=nw-1;
}
void solve(int v=0,int p=-1)
{
	for(int i=0;i<add[v].size();i++)
	{
		int to=add[v][i];
		if(cnt[v]==0) sqr.add(id[v],ch[v],1);
		if(cnt[to]==0) sqr.add(id[to],ch[to],1);
		cnt[v]++;cnt[to]++;
	}
	ans[v]=sqr.all();
	for(int i=0;i<vec[v].size();i++)
	{
		int to=vec[v][i];
		if(to!=p) solve(to,v);
	}
	for(int i=0;i<add[v].size();i++)
	{
		int to=add[v][i];
		cnt[v]--;cnt[to]--;
		if(cnt[v]==0) sqr.add(id[v],ch[v],-1);
		if(cnt[to]==0) sqr.add(id[to],ch[to],-1);
	}
}
int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	for(int i=0;i<n-1;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);a--;b--;
		vec[a].push_back(b);
		vec[b].push_back(a);
	}
	for(int i=0;i<m;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);a--;b--;
		add[a].push_back(b);
		add[b].push_back(a);
	}
	dfs();
	sqr.init();
	solve();
	for(int i=0;i<n;i++)
	{
		if(i!=0) printf(" ");
		printf("%d",max(0,ans[i]-1));
	}puts("");
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#define SIZE 100005
#define BT 128*1024*2
#define INF 1000000000

using namespace std;

struct P
{
	int mn,cnt;
	P(int mn=0,int cnt=0):mn(mn),cnt(cnt){}
};
P unite(P p,P q)
{
	P ret;
	ret.mn=min(p.mn,q.mn);
	if(ret.mn==p.mn) ret.cnt+=p.cnt;
	if(ret.mn==q.mn) ret.cnt+=q.cnt;
	return ret;
}
struct segtree
{
	P seg[BT];
	int add[BT];
	int mum;

	void init(int n)
	{
		mum=1;
		while(mum<n) mum<<=1;
		memset(add,0,sizeof(add));
		for(int i=mum-1;i<mum+n-1;i++) seg[i]=P(0,1);
		for(int i=mum+n-1;i<mum*2;i++) seg[i]=P(INF,1);
		for(int i=mum-2;i>=0;i--) make(i);
	}
	void make(int k)
	{
		seg[k]=unite(seg[k*2+1],seg[k*2+2]);
		seg[k].mn+=add[k];
	}
	void update(int a,int b,int k,int l,int r,int v)
	{
		if(b<=l||r<=a) return;
		if(a<=l&&r<=b)
		{
			seg[k].mn+=v;
			add[k]+=v;
		}
		else
		{
			update(a,b,k*2+1,l,(l+r)/2,v);
			update(a,b,k*2+2,(l+r)/2,r,v);
			make(k);
		}
	}
	void update(int a,int b,int v)
	{
		update(a,b,0,0,mum,v);
	}
	int get()
	{
		if(seg[0].mn!=0) return 0;
		return seg[0].cnt;
	}
};
segtree seg;
vector <int> vec[SIZE];
vector <int> add[SIZE];
int id[SIZE],ch[SIZE];
int ans[SIZE],cnt[SIZE];
int nw;

void dfs(int v=0,int p=-1)
{
	id[v]=nw++;
	for(int i=0;i<vec[v].size();i++)
	{
		int to=vec[v][i];
		if(to!=p) dfs(to,v);
	}
	ch[v]=nw;
}
void solve(int v=0,int p=-1)
{
	for(int i=0;i<add[v].size();i++)
	{
		int to=add[v][i];
		if(cnt[v]==0) seg.update(id[v],ch[v],1);
		if(cnt[to]==0) seg.update(id[to],ch[to],1);
		cnt[v]++;cnt[to]++;
	}
	ans[v]=seg.get();
	for(int i=0;i<vec[v].size();i++)
	{
		int to=vec[v][i];
		if(to!=p) solve(to,v);
	}
	for(int i=0;i<add[v].size();i++)
	{
		int to=add[v][i];
		cnt[v]--;cnt[to]--;
		if(cnt[v]==0) seg.update(id[v],ch[v],-1);
		if(cnt[to]==0) seg.update(id[to],ch[to],-1);
	}
}
int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	for(int i=0;i<n-1;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);a--;b--;
		vec[a].push_back(b);
		vec[b].push_back(a);
	}
	for(int i=0;i<m;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);a--;b--;
		add[a].push_back(b);
		add[b].push_back(a);
	}
	dfs();
	seg.init(n);
	solve();
	for(int i=0;i<n;i++)
	{
		if(i!=0) printf(" ");
		ans[i]=n-ans[i];
		printf("%d",max(0,ans[i]-1));
	}puts("");
	return 0;
}


#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cfloat>
#include <numeric>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;

const int oo = 0x3f3f3f3f;
const double eps = 1e-9;

#define sz(c) int((c).size())
#define all(c) (c).begin(), (c).end()
#define FOR(i,a,b) for (int i = (a); i < (b); i++)
#define FORD(i,a,b) for (int i = int(b)-1; i >= (a); i--)
#define FORIT(i,c) for(__typeof__((c).begin()) i=(c).begin(); i!=(c).end(); i++)
#define mp make_pair
#define pb push_back

#define MAXN (100 * 1024)

int N, K;

vi iadj[MAXN];

vi adj[MAXN];
int cnt[MAXN];
int par[MAXN];
int new2orig[MAXN];
int orig2new[MAXN];
int ID = 0;

int result[MAXN];

set<int> activator[MAXN];
bool active[MAXN];

int bit[MAXN];

void bitadd(int i, int v) {
	for (++i; i <= N+1; i += i&-i) bit[i] += v;
}

int get_cumu(int i) {
	int res = 0;
	for (++i; i; i -= i&-i) res += bit[i];
	return res;
}

int get_int(int a, int b) {
	return get_cumu(b) - get_cumu(a-1);
}
/*
int idfs(int n, int p = -1) {
	int id = ID++;
	orig2new[n] = id;
	new2orig[id] = n;

	cnt[id] = 1;
	par[id] = p;
	adj[id].clear();

	for (const auto &e : iadj[n]) {
		if (e == p) continue;
		cnt[id] += idfs(e, n);
		adj[id].pb(orig2new[e]);
	}

	return cnt[id];
}
*/
int idfs(int orignode, int origpar = 0) {
	int node = ID++;
	orig2new[orignode] = node;
	new2orig[node] = orignode;

	cnt[node] = 1;
	par[node] = orig2new[origpar];
	adj[node].clear();

	for (const auto &origto : iadj[orignode]) {
		if (origto == origpar) continue;
		cnt[node] += idfs(origto, orignode);
		adj[node].pb(orig2new[origto]);
	}

	return cnt[node];
}

void dfs(int n) {
	vector<pii> cleanup;
	for (const auto &e : activator[n]) {
		int k = e;
		while (k > -1) {
			if (active[k]) { k = -2; break; }
			k = par[k];
		}
		if (k == -2) continue;
		int sum = cnt[e] - get_int(e, e+cnt[e]-1);
		bitadd(e, sum);
		active[e] = true;
		cleanup.pb(mp(e,sum));
	}

	result[new2orig[n]] = get_cumu(N);

	for (const auto &e : adj[n])
		dfs(e);

	for (const auto &e : cleanup) {
		bitadd(e.first, -e.second);
		active[e.first] = false;
	}
}

int main() {
	cin >> N >> K;

	fill_n(bit, N+10, 0);
	fill_n(par, N+10, -1);

	FOR(i,0,N-1) {
		int a, b; cin >> a >> b;
		iadj[a].pb(b);
		iadj[b].pb(a);
	}

	orig2new[0] = -1;
	idfs(1);

	FOR(i,0,K) {
		int a, b; cin >> a >> b;
		a = orig2new[a];
		b = orig2new[b];
		activator[a].insert(a);
		activator[a].insert(b);
		activator[b].insert(a);
		activator[b].insert(b);
	}

	dfs(orig2new[1]);

	FOR(i,1,N+1) {
		if (i > 1) cout << " ";
		cout << max(0, result[i]-1);
	}
	cout << endl;
}


#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cfloat>
#include <numeric>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;

const int oo = 0x3f3f3f3f;
const double eps = 1e-9;

#define sz(c) int((c).size())
#define all(c) (c).begin(), (c).end()
#define FOR(i,a,b) for (int i = (a); i < (b); i++)
#define FORD(i,a,b) for (int i = int(b)-1; i >= (a); i--)
#define FORIT(i,c) for(__typeof__((c).begin()) i=(c).begin(); i!=(c).end(); i++)
#define mp make_pair
#define pb push_back

#define MAXN (100 * 1024)

struct ENTRY {
	int todo;
	int v;
	ENTRY() : todo(0), v(0) {}
};
ENTRY segt_active[4*MAXN];
ENTRY segt_cnt[4*MAXN];

int all_in_one(ENTRY *segt, int p, int i, int j, int a, int b, int v = 0) {
	if (b < i || j < a) return 0;
	if (a <= i && j <= b) {
		segt[p].v += (segt[p].todo + v) * (j-i+1);
		segt[p].todo = 0;
		return segt[p].v;
	}

	int p1 = 2*p+1;
	int p2 = 2*p+2;
	segt[p1].todo += segt[p].todo;
	segt[p2].todo += segt[p].todo;
	segt[p].todo = 0;

	int ii = (i+j)/2;
	int jj = ii+1;
	int ret = all_in_one(segt, p1, i, ii, a, b, v)
	        + all_in_one(segt, p2, jj, j, a, b, v);

	segt[p].v = segt[p1].v + segt[p1].todo * (ii-i+1)
	          + segt[p2].v + segt[p2].todo * (j-jj+1);

	return ret;
}

int N, K;

vi iadj[MAXN];

vi adj[MAXN];
int cnt[MAXN];
int par[MAXN];
int new2orig[MAXN];
int orig2new[MAXN];
int ID = 0;

int result[MAXN];

set<int> activator[MAXN];

int idfs(int orignode, int origpar = 0) {
	int node = ID++;
	orig2new[orignode] = node;
	new2orig[node] = orignode;

	cnt[node] = 1;
	par[node] = orig2new[origpar];
	adj[node].clear();

	for (const auto &origto : iadj[orignode]) {
		if (origto == origpar) continue;
		cnt[node] += idfs(origto, orignode);
		adj[node].pb(orig2new[origto]);
	}

	return cnt[node];
}

void dfs(int n) {
	vector<pii> cleanup;
	for (const auto &anode : activator[n]) {
		int anode_end = anode + cnt[anode] - 1;

		if (all_in_one(segt_active, 0,0,N, anode, anode, 0) > 0) continue;

		int add = cnt[anode] - all_in_one(segt_cnt, 0,0,N, anode, anode_end, 0);

		all_in_one(segt_active, 0,0,N, anode, anode_end, 1);
		all_in_one(segt_cnt, 0,0,N, anode, anode, add);
		cleanup.pb(mp(anode, add));
	}

	result[n] = all_in_one(segt_cnt, 0,0,N, 0, N, 0);

	for (const auto &to : adj[n])
		dfs(to);

	for (const auto &e : cleanup) {
		int anode = e.first, add = e.second;
		int anode_end = anode + cnt[anode] - 1;
		all_in_one(segt_active, 0,0,N, anode, anode_end, -1);
		all_in_one(segt_cnt, 0,0,N, anode, anode, -add);
	}
}

int main() {
	cin >> N >> K;

	FOR(i,0,N-1) {
		int a, b; cin >> a >> b;
		iadj[a].pb(b);
		iadj[b].pb(a);
	}

	orig2new[0] = -1;
	idfs(1);

	FOR(i,0,K) {
		int a, b; cin >> a >> b;
		a = orig2new[a];
		b = orig2new[b];
		activator[a].insert(a);
		activator[a].insert(b);
		activator[b].insert(a);
		activator[b].insert(b);
	}

	dfs(orig2new[1]);

	FOR(i,1,N+1) {
		if (i > 1) cout << " ";
		cout << max(0, result[orig2new[i]]-1);
	}
	cout << endl;
}


#include <bitset>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cfloat>
#include <numeric>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;

const int oo = 0x3f3f3f3f;
const double eps = 1e-9;

#define sz(c) int((c).size())
#define all(c) (c).begin(), (c).end()
#define FOR(i,a,b) for (int i = (a); i < (b); i++)
#define FORD(i,a,b) for (int i = int(b)-1; i >= (a); i--)
#define FORIT(i,c) for(__typeof__((c).begin()) i=(c).begin(); i!=(c).end(); i++)
#define mp make_pair
#define pb push_back

#define MAXN (100 * 1024)

typedef bitset<MAXN> bs;

int N, K;

vi iadj[MAXN];

vi adj[MAXN];
int cnt[MAXN];
int par[MAXN];
int new2orig[MAXN];
int orig2new[MAXN];
int ID = 0;

int result[MAXN];

set<int> activator[MAXN];
bs bset[MAXN];

int bit[MAXN];

void bitadd(int i, int v) {
	for (++i; i <= N+1; i += i&-i) bit[i] += v;
}

int get_cumu(int i) {
	int res = 0;
	for (++i; i; i -= i&-i) res += bit[i];
	return res;
}

int get_int(int a, int b) {
	return get_cumu(b) - get_cumu(a-1);
}

int idfs(int n, int p = -1) {
	int id = ID++;
	orig2new[n] = id;
	new2orig[id] = n;

	cnt[id] = 1;
	par[id] = p;
	adj[id].clear();
	bset[id].reset();
	bset[id].set(id);

	for (const auto &e : iadj[n]) {
		if (e == p) continue;
		cnt[id] += idfs(e, n);
		adj[id].pb(orig2new[e]);
		bset[id] |= bset[orig2new[e]];
	}

	return cnt[id];
}

void dfs(int n, bs ta) {
	vector<pii> cleanup;
	for (const auto &e : activator[n]) {
		if ((ta & bset[e]) == bset[e]) continue;
		ta |= bset[e];
		int sum = cnt[e] - get_int(e, e+cnt[e]-1);
		bitadd(e, sum);
		cleanup.pb(mp(e,sum));
	}

	result[new2orig[n]] = get_cumu(N);

	for (const auto &e : adj[n])
		dfs(e, ta);

	for (const auto &e : cleanup)
		bitadd(e.first, -e.second);
}

int main() {
	cin >> N >> K;

	fill_n(bit, N+10, 0);

	FOR(i,0,N-1) {
		int a, b; cin >> a >> b;
		iadj[a].pb(b);
		iadj[b].pb(a);
	}

	idfs(1);

	FOR(i,0,K) {
		int a, b; cin >> a >> b;
		a = orig2new[a];
		b = orig2new[b];
		activator[a].insert(a);
		activator[a].insert(b);
		activator[b].insert(a);
		activator[b].insert(b);
	}

	dfs(orig2new[1], bs());

	FOR(i,1,N+1) {
		if (i > 1) cout << " ";
		cout << max(0, result[i]-1);
	}
	cout << endl;
}


#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cfloat>
#include <numeric>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;

const int oo = 0x3f3f3f3f;
const double eps = 1e-9;

#define sz(c) int((c).size())
#define all(c) (c).begin(), (c).end()
#define FOR(i,a,b) for (int i = (a); i < (b); i++)
#define FORD(i,a,b) for (int i = int(b)-1; i >= (a); i--)
#define FORIT(i,c) for(__typeof__((c).begin()) i=(c).begin(); i!=(c).end(); i++)
#define mp make_pair
#define pb push_back

#define MAXN (100 * 1024)

struct ENTRY {
	int todo;
	int v;
	ENTRY() : todo(0), v(0) {}
};
ENTRY segt_active[4*MAXN];
ENTRY segt_cnt[4*MAXN];

int segt_update(ENTRY *segt, int p, int i, int j, int a, int b, int v = 0) {
	if (b < i || j < a) return 0;
	if (a <= i && j <= b) {
		segt[p].todo += v;
		return segt[p].v + segt[p].todo * (j-i+1);
	}

	int p1 = 2*p+1;
	int p2 = 2*p+2;
	segt[p1].todo += segt[p].todo;
	segt[p2].todo += segt[p].todo;
	segt[p].todo = 0;

	int ii = (i+j)/2;
	int jj = ii+1;
	int ret = segt_update(segt, p1, i, ii, a, b, v)
	        + segt_update(segt, p2, jj, j, a, b, v);

	segt[p].v = segt[p1].v + segt[p1].todo * (ii-i+1)
	          + segt[p2].v + segt[p2].todo * (j-jj+1);

	return ret;
}

int N, K;

vi iadj[MAXN];

vi adj[MAXN];
int cnt[MAXN];
int par[MAXN];
int new2orig[MAXN];
int orig2new[MAXN];
int ID = 0;

int result[MAXN];

set<int> activator[MAXN];

int idfs(int orignode, int origpar = 0) {
	int node = ID++;
	orig2new[orignode] = node;
	new2orig[node] = orignode;

	cnt[node] = 1;
	par[node] = orig2new[origpar];
	adj[node].clear();

	for (const auto &origto : iadj[orignode]) {
		if (origto == origpar) continue;
		cnt[node] += idfs(origto, orignode);
		adj[node].pb(orig2new[origto]);
	}

	return cnt[node];
}

void dfs(int n) {
	vector<pii> cleanup;
	for (const auto &anode : activator[n]) {
		int anode_end = anode + cnt[anode] - 1;

		if (segt_update(segt_active, 0,0,N, anode, anode, 0) > 0) continue;

		int add = cnt[anode] - segt_update(segt_cnt, 0,0,N, anode, anode_end, 0);

		segt_update(segt_active, 0,0,N, anode, anode_end, 1);
		segt_update(segt_cnt, 0,0,N, anode, anode, add);
		cleanup.pb(mp(anode, add));
	}

	result[n] = segt_update(segt_cnt, 0,0,N, 0, N, 0);

	for (const auto &to : adj[n])
		dfs(to);

	for (const auto &e : cleanup) {
		int anode = e.first, add = e.second;
		int anode_end = anode + cnt[anode] - 1;
		segt_update(segt_active, 0,0,N, anode, anode_end, -1);
		segt_update(segt_cnt, 0,0,N, anode, anode, -add);
	}
}

int main() {
	cin >> N >> K;

	FOR(i,0,N-1) {
		int a, b; cin >> a >> b;
		iadj[a].pb(b);
		iadj[b].pb(a);
	}

	orig2new[0] = -1;
	idfs(1);

	FOR(i,0,K) {
		int a, b; cin >> a >> b;
		a = orig2new[a];
		b = orig2new[b];
		activator[a].insert(a);
		activator[a].insert(b);
		activator[b].insert(a);
		activator[b].insert(b);
	}

	dfs(orig2new[1]);

	FOR(i,1,N+1) {
		if (i > 1) cout << " ";
		cout << max(0, result[orig2new[i]]-1);
	}
	cout << endl;
}


#include <bitset>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cfloat>
#include <numeric>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;

const int oo = 0x3f3f3f3f;
const double eps = 1e-9;

#define sz(c) int((c).size())
#define all(c) (c).begin(), (c).end()
#define FOR(i,a,b) for (int i = (a); i < (b); i++)
#define FORD(i,a,b) for (int i = int(b)-1; i >= (a); i--)
#define FORIT(i,c) for(__typeof__((c).begin()) i=(c).begin(); i!=(c).end(); i++)
#define mp make_pair
#define pb push_back

#define MAXN (100 * 1024)

typedef bitset<MAXN> bs;

int N, K;

vi iadj[MAXN];

vi adj[MAXN];
int cnt[MAXN];
int par[MAXN];
int new2orig[MAXN];
int orig2new[MAXN];
int ID = 0;

int result[MAXN];

set<int> activator[MAXN];

int bit[MAXN];

void bitadd(int i, int v) {
	for (++i; i <= N+1; i += i&-i) bit[i] += v;
}

int get_cumu(int i) {
	int res = 0;
	for (++i; i; i -= i&-i) res += bit[i];
	return res;
}

int get_int(int a, int b) {
	return get_cumu(b) - get_cumu(a-1);
}

int idfs(int n, int p = -1) {
	int id = ID++;
	orig2new[n] = id;
	new2orig[id] = n;

	cnt[id] = 1;
	par[id] = p;
	adj[id].clear();

	for (const auto &e : iadj[n]) {
		if (e == p) continue;
		cnt[id] += idfs(e, n);
		adj[id].pb(orig2new[e]);
	}

	return cnt[id];
}

void dfs(int n, bs ta) {
	vector<pii> cleanup;
	for (const auto &e : activator[n]) {
		bs eset;
		FOR(i,0,cnt[e]) eset.set(e+i);
		if ((ta & eset) == eset) continue;
		ta |= eset;
		int sum = cnt[e] - get_int(e, e+cnt[e]-1);
		bitadd(e, sum);
		cleanup.pb(mp(e,sum));
	}

	result[new2orig[n]] = get_cumu(N);

	for (const auto &e : adj[n])
		dfs(e, ta);

	for (const auto &e : cleanup)
		bitadd(e.first, -e.second);
}

int main() {
	cin >> N >> K;

	fill_n(bit, N+10, 0);

	FOR(i,0,N-1) {
		int a, b; cin >> a >> b;
		iadj[a].pb(b);
		iadj[b].pb(a);
	}

	idfs(1);

	FOR(i,0,K) {
		int a, b; cin >> a >> b;
		a = orig2new[a];
		b = orig2new[b];
		activator[a].insert(a);
		activator[a].insert(b);
		activator[b].insert(a);
		activator[b].insert(b);
	}

	dfs(orig2new[1], bs());

	FOR(i,1,N+1) {
		if (i > 1) cout << " ";
		cout << max(0, result[i]-1);
	}
	cout << endl;
}


#include <iostream>
#include <algorithm>
#include <cmath>
#include <assert.h>
#include <stdio.h>
#include <ctime>
#include <cstdlib>
#include <utility>
#include <string.h>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>

#define INF (1<<30)
#define pii pair<int,int>
#define pll pair<long long,long long>
#define eps 1e-9

#ifdef ONLINE_JUDGE
#define debug(args...)
#else
#define debug(args...) fprintf(stderr,args)
#endif

using namespace std;

int Tmin[400400];
int Tqnt[400400];
int lazy[400400];

void create(int init,int fim,int p){

	Tqnt[p] = fim-init+1;
	int mid = (init+fim)/2;
	if(init != fim)
		create(init,mid,2*p),
		create(mid+1,fim,2*p+1);
}

void refresh(int init,int fim,int p){

	Tmin[p] += lazy[p];
	if(init != fim)
		lazy[2*p] += lazy[p],
		lazy[2*p+1] += lazy[p];
	lazy[p] = 0;

}

void calc(int p){

	if(Tmin[2*p] == Tmin[2*p+1])
		Tmin[p] = Tmin[2*p],
		Tqnt[p] = Tqnt[2*p] + Tqnt[2*p+1];

	if(Tmin[2*p] < Tmin[2*p+1])
		Tmin[p] = Tmin[2*p],
		Tqnt[p] = Tqnt[2*p];

	if(Tmin[2*p] > Tmin[2*p+1])
		Tmin[p] = Tmin[2*p+1],
		Tqnt[p] = Tqnt[2*p+1];

}

int query(int init,int fim,int p,int qx,int qy){

	refresh(init,fim,p);

	if(init > qy || fim < qx)
		return 0;

	if(init >= qx && fim <= qy)
		return Tmin[p] ? (fim-init+1) : (fim-init+1-Tqnt[p]);

	int mid = (init+fim)/2;
	int ret = query(init,mid,2*p,qx,qy) + query(mid+1,fim,2*p+1,qx,qy);

	calc(p);
	return ret;
}

void update(int init,int fim,int p,int upx,int upy,int val){

	refresh(init,fim,p);

	if(init > upy || fim < upx)
		return;

	if(init >= upx && fim <= upy){
		lazy[p] += val;
		refresh(init,fim,p);
		return;
	}

	int mid = (init+fim)/2;

	update(init,mid,2*p,upx,upy,val);
	update(mid+1,fim,2*p+1,upx,upy,val);

	calc(p);

}

vector<int> L[100100];
vector<int> upd[100100];

int n,m;
int a[100100];
int b[100100];
int pre[100100];
int ans[100100];
int cont = 0;

void dfs(int x,int p){

	pre[x] = cont++;
	a[x] = pre[x];
	b[x] = pre[x];

	for(vector<int> :: iterator it = L[x].begin(); it < L[x].end(); it++)
		if(*it != p){
			dfs(*it,x);
			a[x] = min(a[x], a[*it]);
			b[x] = max(b[x], b[*it]);
		}

	debug("%d~%d\n",a[x],b[x]);

}

void dfs2(int x,int p){

	for(vector<int> :: iterator it = upd[x].begin(); it < upd[x].end(); it++){
		update(0,n-1,1,a[x],b[x],1);
		update(0,n-1,1,a[*it],b[*it],1);
		debug("up %d~%d\n",a[x],b[x]);
		debug("up %d~%d\n",a[*it],b[*it]);
	}

	ans[x] = query(0,n-1,1,0,n-1);

	for(vector<int> :: iterator it = L[x].begin(); it < L[x].end(); it++)
		if(*it != p)
			dfs2(*it,x);

	for(vector<int> :: iterator it = upd[x].begin(); it < upd[x].end(); it++){
		update(0,n-1,1,a[x],b[x],-1);
		update(0,n-1,1,a[*it],b[*it],-1);
	}

}

main(){

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

		for(int i=1;i<n;i++){
			int x,y;
			scanf("%d%d",&x,&y);
			x--,y--;
			L[x].push_back(y);
			L[y].push_back(x);
		}

		create(0,n-1,1);
		dfs(0,0);

		for(int i=0;i<m;i++){

			int x,y;
			scanf("%d%d",&x,&y);
			x--,y--;

			upd[x].push_back(y);
			upd[y].push_back(x);

		}

		dfs2(0,0);

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

		printf("\n");

}


#include <functional>/*{{{*/
#include <algorithm>
#include <iostream>
#include <sstream>
#include <numeric>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <cstdio>
#include <vector>
#include <math.h>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
using namespace std;typedef long long ll;typedef long double real;void run();int main(){ios::sync_with_stdio(0);run();}/*}}}*/

struct seg_t{
  seg_t *c[2];
  int n,sum;

  seg_t(int n,bool rec=true):n(n),sum(0){
    if (n==1 or not rec) return;
    c[0]=c[1]=new seg_t(n/2);
  }

  seg_t *insert(int l,int r){
    if (sum==n or r<=0 or l>=n) return this;
    seg_t *res;
    if (l<=0 and r>=n){
      if (sum==n) return this;
      res=new seg_t(n,false);
      res->sum=n;
    }else{
      seg_t *a=c[0]->insert(l,r);
      seg_t *b=c[1]->insert(l-n/2,r-n/2);
      if (a==c[0] and b==c[1]) return this;
      res=new seg_t(n,false);
      res->c[0]=a;
      res->c[1]=b;
      res->sum=a->sum+b->sum;
    }
    return res;
  }
};

vector<int> edge[100000];
vector<int> link[100000];
int res[1000000];
int lef[1000000];
int rgt[1000000];

void build(int i,int p,int x){
  lef[i]=x; rgt[i]=x+1;
  for (int j: edge[i]){
    if (j!=p){
      build(j,i,rgt[i]);
      rgt[i]=rgt[j]+1;
    }
  }
}

void dfs(int x,int p,seg_t *tree){
  if (not link[x].empty()){
    tree=tree->insert(lef[x],rgt[x]+1);
  }
  for (int y: link[x]){
    tree=tree->insert(lef[y],rgt[y]+1);
  }
  res[x]=tree->sum;
  for (int y: edge[x]){
    if (y!=p){
      dfs(y,x,tree);
    }
  }
}

void run(){
  int n,m; cin>>n>>m;

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

  for (int i=0; i<m; i++){
    int a,b; cin>>a>>b; --a,--b;
    link[a].push_back(b); link[b].push_back(a);
  }

  build(0,-1,0);
  seg_t root(1<<18);
  dfs(0,-1,&root);

  for (int i=0; i<n; i++){
    cout<<max(0,res[i]/2-1)<<(i+1==n?'\n':' ');
  }
}


#define _CRT_SECURE_NO_WARNINGS
#pragma comment(linker, "/STACK:1000000000")
#include <iostream>
#include <algorithm>
#include <memory.h>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <complex>
#include <string>
#include <bitset>
#include <vector>
#include <cstdio>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef complex < double > cd;

const bool db = false;

#define mp make_pair
#define pb push_back
#define ppb pop_back
#define sd second
#define fs first

#define inf 1000000007
#define nmax 100010
#define mmax 100010
#define eps 1e-6

int ord[nmax], pt;
int l[nmax], r[nmax];
vector < int > gr[nmax];
vector < pair < int, int > > v[nmax];
int n, m, x, y, ans[nmax];
int t[4 * nmax], s[4 * nmax];

void dfs(int v, int p) {
	ord[++pt] = v;
	l[v] = pt;
	for(int i = 0; i < gr[v].size(); ++i) {
		int to = gr[v][i];
		if(to == p) continue;
		dfs(to, v);
	}
	r[v] = pt;
}

void build(int v, int l, int r) {
	if(l != r) {
		int m = (l + r) / 2;
		build(v + v, l, m);
		build(v + v + 1, m + 1, r);
	}
	t[v] = r - l + 1;
}

void add(int v, int L, int R, int l, int r, int val) {
	if(L == l && r == R) {
		s[v] += val;
		if(s[v] != 0) {
			t[v] = 0;
		} else {
			if(L != R) {
				t[v] = t[v + v] + t[v + v + 1];
			} else {
				t[v] = 1;
			}
		}
		return;
	}
	int M = (L + R) >> 1;
	if(r <= M) add(v + v, L, M, l, r, val);
	else if(l > M) add(v + v + 1, M + 1, R, l, r, val);
	else {
		add(v + v, L, M, l, M, val);
		add(v + v + 1, M + 1, R, M + 1, r, val);
	}
	t[v] = (s[v] ? 0 : t[v + v] + t[v + v + 1]);
}

int main() {
	//freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
	//freopen("censor.in", "r", stdin); freopen("censor.out", "w", stdout);
	scanf("%d%d", &n, &m);
	for(int i = 1; i < n; ++i) {
		scanf("%d%d", &x, &y);
		gr[x].pb(y); gr[y].pb(x);
	}
	dfs(1, 0);
	build(1, 1, n);
	for(int i = 1; i <= m; ++i) {
		scanf("%d%d", &x, &y);
		v[l[x]].pb(mp(x, y)); v[l[y]].pb(mp(x, y));
		v[r[x] + 1].pb(mp(-x, y)); v[r[y] + 1].pb(mp(-x, y));
	}
	for(int i = 1; i <= n; ++i) {
		for(int j = 0; j < v[i].size(); ++j) {
			int x = v[i][j].fs, y = v[i][j].sd, inc = 1;
			if(x < 0) x = -x, inc = -inc;
			add(1, 1, n, l[x], r[x], inc);
			add(1, 1, n, l[y], r[y], inc);
		}
		add(1, 1, n, i, i, 1);
		ans[ord[i]] = n - 1 - t[1];
		add(1, 1, n, i, i, -1);
	}
	for(int i = 1; i <= n; ++i) {
		printf("%d%c", ans[i], i == n ? '\n' : ' ');
	}
	getchar(); getchar();
	return 0;
}


#include <iostream>
#include <cstdio>
#include <string.h>
#include <string>
#include <algorithm>
#include <math.h>
#include <vector>
using namespace std;

const int maxn = 100000 + 10;
struct node
{
	int l, r, x, y, d, num;
} tr[maxn * 2];
int n, m, tot;
vector <int> gr[maxn];
vector <int> a[maxn];
int fir[maxn], sec[maxn], ans[maxn];

void dfs(int u, int p)
{
	fir[u] = ++tot;
	for (vector<int>::iterator iter = gr[u].begin(); iter != gr[u].end(); iter++)
		if (*iter != p)
			dfs(*iter, u);
	sec[u] = tot;
}

void build(int x, int y)
{
	int t = ++tot;
	tr[t].x = x, tr[t].y = y;
	tr[t].num = tr[t].d = 0;
	if (x == y) {
		tr[t].l = tr[t].r = 0;
	} else {
		tr[t].l = tot + 1;
		build(x, (x+y)/2);
		tr[t].r = tot + 1;
		build((x+y)/2+1, y);
	}
}

void update(int t)
{
	if (tr[t].d > 0) tr[t].num = tr[t].y - tr[t].x + 1;
	else {
		if (tr[t].x == tr[t].y) tr[t].num = 0;
		else tr[t].num = tr[tr[t].l].num + tr[tr[t].r].num;
	}
}

void add(int t, int X, int Y, int d)
{
	if (X <= tr[t].x && tr[t].y <= Y) {
		tr[t].d += d;
		update(t);
	} else {
		int mid = (tr[t].x + tr[t].y) / 2;
		if (X <= mid) add(tr[t].l, X, Y, d);
		if (Y > mid) add(tr[t].r, X, Y, d);
		update(t);
	}
}

void dodfs(int u, int p)
{
	for (vector<int>::iterator iter = a[u].begin(); iter != a[u].end(); iter++) {
		add(1, fir[*iter], sec[*iter], 1);
		add(1, fir[u], sec[u], 1);
	}

	ans[u] = tr[1].num;
	for (vector<int>::iterator iter = gr[u].begin(); iter != gr[u].end(); iter++)
		if (*iter != p)
			dodfs(*iter, u);

	for (vector<int>::iterator iter = a[u].begin(); iter != a[u].end(); iter++) {
		add(1, fir[*iter], sec[*iter], -1);
		add(1, fir[u], sec[u], -1);
	}
}

int main()
{
	int x, y;
	while (scanf("%d%d", &n, &m)!=EOF) {
		memset(ans, 0, sizeof(ans));
		for (int i = 1; i <= n; i++)
			gr[i].clear();
		for (int i = 1; i != n; i++) {
			scanf("%d%d", &x, &y);
			gr[x].push_back(y);
			gr[y].push_back(x);
		}
		tot = 0;
		dfs(1, 0);
		for (int i = 0; i != m; i++) {
			scanf("%d%d", &x, &y);
			a[x].push_back(y);
			a[y].push_back(x);
		}
		tot = 0;
		build(1, n);
		dodfs(1, 0);
		for (int i = 1; i <= n; i++) {
			printf("%d ", max(0, ans[i] - 1));
		}
		printf("\n");
	}
	return 0;
}


#include <iostream>
#include <cstdio>
#include <string.h>
#include <string>
#include <algorithm>
#include <math.h>
#include <vector>
using namespace std;

const int maxn = 100000 + 10;
struct node
{
	int l, r, x, y, d, num;
} tr[maxn * 2];
int n, m, tot;
vector <int> gr[maxn];
vector <int> a[maxn];
int fir[maxn], sec[maxn], ans[maxn];

void dfs(int u, int p)
{
	cout << u << " " << p << endl;
	fir[u] = ++tot;
	for (vector<int>::iterator iter = gr[u].begin(); iter != gr[u].end(); iter++)
		if (*iter != p)
			dfs(*iter, u);
	sec[u] = tot;
}

void build(int x, int y)
{
	int t = ++tot;
	tr[t].x = x, tr[t].y = y;
	tr[t].num = tr[t].d = 0;
	if (x == y) {
		tr[t].l = tr[t].r = 0;
	} else {
		tr[t].l = tot + 1;
		build(x, (x+y)/2);
		tr[t].r = tot + 1;
		build((x+y)/2+1, y);
	}
}

void update(int t)
{
	if (tr[t].d > 0) tr[t].num = tr[t].y - tr[t].x + 1;
	else {
		if (tr[t].x == tr[t].y) tr[t].num = 0;
		else tr[t].num = tr[tr[t].l].num + tr[tr[t].r].num;
	}
}

void add(int t, int X, int Y, int d)
{
	if (X <= tr[t].x && tr[t].y <= Y) {
		tr[t].d += d;
		update(t);
	} else {
		int mid = (tr[t].x + tr[t].y) / 2;
		if (X <= mid) add(tr[t].l, X, Y, d);
		if (Y > mid) add(tr[t].r, X, Y, d);
		update(t);
	}
}

void dodfs(int u, int p)
{
	for (vector<int>::iterator iter = a[u].begin(); iter != a[u].end(); iter++) {
		add(1, fir[*iter], sec[*iter], 1);
		add(1, fir[u], sec[u], 1);
	}

	ans[u] = tr[1].num;
	for (vector<int>::iterator iter = gr[u].begin(); iter != gr[u].end(); iter++)
		if (*iter != p)
			dodfs(*iter, u);

	for (vector<int>::iterator iter = a[u].begin(); iter != a[u].end(); iter++) {
		add(1, fir[*iter], sec[*iter], -1);
		add(1, fir[u], sec[u], -1);
	}
}

int main()
{
	int x, y;
	while (scanf("%d%d", &n, &m)!=EOF) {
		memset(ans, 0, sizeof(ans));
		for (int i = 1; i <= n; i++)
			gr[i].clear();
		for (int i = 1; i != n; i++) {
			scanf("%d%d", &x, &y);
			gr[x].push_back(y);
			gr[y].push_back(x);
		}
		tot = 0;
		dfs(1, 0);
		for (int i = 0; i != m; i++) {
			scanf("%d%d", &x, &y);
			a[x].push_back(y);
			a[y].push_back(x);
		}
		tot = 0;
		build(1, n);
		dodfs(1, 0);
		for (int i = 1; i <= n; i++) {
			printf("%d ", max(0, ans[i] - 1));
		}
		printf("\n");
	}
	return 0;
}


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

typedef pair<int, int> pii;

#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define rep(i,n)  FOR(i,0,n)

struct segtree{
    int *lazy, *mi, *cnt;
    int sz;

    segtree(int n){
	for(sz = 1; sz < n; sz *= 2);
	lazy = new int[sz * 2 - 1];
	mi = new int[sz * 2 - 1];
	cnt = new int[sz * 2 - 1];
    }

    void init(){ init(0, 0, sz); }
    void add(int a, int b, int x){ add(a, b, x, 0, 0, sz); }
    pii query(int a, int b){ return query(a, b, 0, 0, sz); }

    void init(int k, int l, int r){
	lazy[k] = mi[k] = 0;
	cnt[k] = r - l;
	if(k < sz - 1){
	    init(k * 2 + 1, l, (l + r) / 2);
	    init(k * 2 + 2, (l + r) / 2, r);
	}
    }

    inline void spread(int k){
	if(lazy[k] == 0) return ;
	mi[k] += lazy[k];
	if(k < sz - 1){
	    lazy[k * 2 + 1] += lazy[k];
	    lazy[k * 2 + 2] += lazy[k];
	}
	lazy[k] = 0;
    }

    inline void upd(int k){
	cnt[k] = 0;
	mi[k] = min(mi[k * 2 + 1], mi[k * 2 + 2]);
	if(mi[k * 2 + 1] == mi[k]) cnt[k] += cnt[k * 2 + 1];
	if(mi[k * 2 + 2] == mi[k]) cnt[k] += cnt[k * 2 + 2];
    }

    void add(int a, int b, int x, int k, int l, int r){
	spread(k);
	if(r <= a || b <= l) return ;
	if(a <= l && r <= b){ lazy[k] += x; spread(k); return ; }
	add(a, b, x, k * 2 + 1, l, (l + r) / 2);
	add(a, b, x, k * 2 + 2, (l + r) / 2, r);
	upd(k);
    }

    pii query(int a, int b, int k, int l, int r){
	spread(k);
	if(r <= a || b <= l) return mp(0, INT_MAX);
	if(a <= l && r <= b) return mp(cnt[k], mi[k]);
	pii lc = query(a, b, k * 2 + 1, l, (l + r) / 2);
	pii rc = query(a, b, k * 2 + 2, (l + r) / 2, r);

	pii ret = mp(0, INT_MAX);
	if(lc.se <= rc.se) ret = lc;
	if(rc.se <= lc.se){
	    ret.se = rc.se;
	    ret.fi += rc.fi;
	}
	return ret;
    }
};

int n, m;
segtree *t;
vector<int> g[100010];
vector<int> op[100010];
int in[100010], out[100010];
int ans[100010];
int now;

inline void tour(int v, int p){
    in[v] = now++;
    for(int &to : g[v]) if(to != p) tour(to, v);
    out[v] = now;
}

void calc(int v, int p){
    bool f = false;

    for(int &x : op[v]){
	t->add(in[x], out[x], 1);
	if(!f){
	    f = true;
	    t->add(in[v], out[v], 1);
	}
    }

    pii ret = t->query(0, n);
    if(ret.se > 0) ans[v] = n;
    else ans[v] = n - ret.fi;
    if(ans[v]) --ans[v];

    for(int &to : g[v]) if(to != p) calc(to, v);

    for(int &x : op[v])
	t->add(in[x], out[x], -1);

    if(f) t->add(in[v], out[v], -1);
}

int main(){
    scanf("%d %d", &n, &m);

    rep(i, n - 1){
	int a, b;
	scanf("%d %d", &a, &b); --a; --b;
	g[a].pb(b);
	g[b].pb(a);
    }

    rep(i, m){
	int a, b;
	scanf("%d %d", &a, &b); --a; --b;
	op[a].pb(b); op[b].pb(a);
    }

    tour(0, -1);
    t = new segtree(n);
    t->init();
    calc(0, -1);
    rep(i, n) printf("%d%c", ans[i], i == n - 1 ? '\n' : ' ');

    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; ++i)

const int
	MAXV = 1 << 17;

int V, Q;
vector< int > G[MAXV], queries[MAXV];
int dfsNum;
int dfsLo[MAXV];
int dfsHi[MAXV];
int answer[MAXV];

struct node
{
	int sum, cov;
} T[2 * MAXV];

void update(int x, int lo, int hi, int from, int to, int delta)
{
	if (lo > hi || lo > to || hi < from)
		return ;

	if (lo >= from && hi <= to)
	{
		T[x].sum += delta;
	}
	else
	{
		int mid = (lo + hi) / 2;
		update(2 * x, lo, mid, from, to, delta);
		update(2 * x + 1, mid + 1, hi, from, to, delta);
	}

	if (T[x].sum > 0)
		T[x].cov = (hi - lo + 1);
	else
		if (lo == hi)
			T[x].cov = 0;
		else
			T[x].cov = T[2 * x].cov + T[2 * x + 1].cov;
}

void update(int u, int delta)
{
	update(1, 0, V - 1, dfsLo[u], dfsHi[u], delta);
}

void preDfs(int u, int from = -1)
{
	dfsLo[u]= dfsNum;
	for (int v : G[u]) if (v != from)
		preDfs(v, u);
	dfsHi[u]= dfsNum++;
}

void dfs(int u, int from = -1)
{
	if (!queries[u].empty())
		update(u, +1);
	for (int q : queries[u])
		update(q, +1);

	answer[u] = T[1].cov;

	for (int v : G[u]) if (v != from)
		dfs(v, u);

	if (!queries[u].empty())
		update(u, -1);
	for (int q : queries[u])
		update(q, -1);
}

int main()
{
	std::ios::sync_with_stdio(0);

	cin >> V >> Q;

	REP(i, V - 1)
	{
		int u, v;
		cin >> u >> v;
		--u;
		--v;
		G[u].push_back(v);
		G[v].push_back(u);
	}

	REP(i, Q)
	{
		int u, v;
		cin >> u >> v;
		--u;
		--v;
		queries[u].push_back(v);
		queries[v].push_back(u);
	}

	preDfs(0);
	dfs(0);

	REP(i, V)
		cout << max(0, answer[i] - 1) << " ";

	cout << endl;

	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; ++i)

const int
	MAXV = 1 << 17;

int V, Q;
vector< int > G[MAXV], queries[MAXV];
int dfsNum;
int dfsLo[MAXV];
int dfsHi[MAXV];
int answer[MAXV];

struct node
{
	int sum, cov;
} T[2 * MAXV];

void update(int x, int lo, int hi, int from, int to, int delta)
{
	if (lo > hi || lo > to || hi < from)
		return ;

	if (lo >= from && hi <= to)
	{
		T[x].sum += delta;
	}
	else
	{
		int mid = (lo + hi) / 2;
		update(2 * x, lo, mid, from, to, delta);
		update(2 * x + 1, mid + 1, hi, from, to, delta);
	}

	if (T[x].sum > 0)
		T[x].cov = (hi - lo + 1);
	else
		if (lo == hi)
			T[x].cov = 0;
		else
			T[x].cov = T[2 * x].cov + T[2 * x + 1].cov;
}

void update(int u, int delta)
{
	update(1, 0, V - 1, dfsLo[u], dfsHi[u], delta);
}

void preDfs(int u, int from = -1)
{
	dfsLo[u]= dfsNum;
	for (int v : G[u]) if (v != from)
		preDfs(v, u);
	dfsHi[u]= dfsNum++;
}

void dfs(int u, int from = -1)
{
	if (!queries[u].empty())
		update(u, +1);
	for (int q : queries[u])
		update(q, +1);

	answer[u] = T[1].cov;

	for (int v : G[u]) if (v != from)
		dfs(v, u);

	if (!queries[u].empty())
		update(u, -1);
	for (int q : queries[u])
		update(q, -1);
}

int main()
{
	cin >> V >> Q;

	REP(i, V - 1)
	{
		int u, v;
		cin >> u >> v;
		--u;
		--v;
		G[u].push_back(v);
		G[v].push_back(u);
	}

	REP(i, Q)
	{
		int u, v;
		cin >> u >> v;
		--u;
		--v;
		queries[u].push_back(v);
		queries[v].push_back(u);
	}

	preDfs(0);
	dfs(0);

	REP(i, V)
		cout << max(0, answer[i] - 1) << " ";

	cout << endl;

	return 0;
}


// Alfonso Peterssen (mukel)
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; ++i)

const int
	MAXV = 1 << 17;

int V, Q;
vector< int > G[MAXV], queries[MAXV];
int dfsNum;
int dfsLo[MAXV];
int dfsHi[MAXV];
int answer[MAXV];

struct node
{
	int sum, cov;
} T[2 * MAXV];

void update(int x, int lo, int hi, int from, int to, int delta)
{
	if (lo > hi || lo > to || hi < from)
		return ;

	if (lo >= from && hi <= to)
	{
		T[x].sum += delta;
	}
	else
	{
		int mid = (lo + hi) / 2;
		update(2 * x, lo, mid, from, to, delta);
		update(2 * x + 1, mid + 1, hi, from, to, delta);
	}

	if (T[x].sum > 0)
		T[x].cov = (hi - lo + 1);
	else
		if (lo == hi)
			T[x].cov = 0;
		else
			T[x].cov = T[2 * x].cov + T[2 * x + 1].cov;
}

void update(int u, int delta)
{
	update(1, 0, V - 1, dfsLo[u], dfsHi[u], delta);
}

void preDfs(int u, int from = -1)
{
	dfsLo[u]= dfsNum;
	for (int v : G[u]) if (v != from)
		preDfs(v, u);
	dfsHi[u]= dfsNum++;
}

void dfs(int u, int from = -1)
{
	if (!queries[u].empty())
		update(u, +1);
	for (int q : queries[u])
		update(q, +1);

	answer[u] = T[1].cov;

	for (int v : G[u]) if (v != from)
		dfs(v, u);

	if (!queries[u].empty())
		update(u, -1);
	for (int q : queries[u])
		update(q, -1);
}

int main()
{
	std::ios::sync_with_stdio(0);

	cin >> V >> Q;

	REP(i, V - 1)
	{
		int u, v;
		cin >> u >> v;
		--u;
		--v;
		G[u].push_back(v);
		G[v].push_back(u);
	}

	REP(i, Q)
	{
		int u, v;
		cin >> u >> v;
		--u;
		--v;
		queries[u].push_back(v);
		queries[v].push_back(u);
	}

	preDfs(0);
	dfs(0);

	REP(i, V)
		cout << max(0, answer[i] - 1) << " ";

	cout << endl;

	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<string>
#include<bitset>
#include<iomanip>
#include<iostream>
#include<cmath>
using namespace std;
#define rep(i,x,y) for(i=x;i<=y;i++)
#define _rep(i,x,y) for(i=x;i>=y;i--)
#define REP(i,x,y) for(int i=(x);i<=(y);i++)
#define _REP(i,x,y) for(int i=(x);i>=(y);i--)
#define CL(S,x) memset(S,x,sizeof(S))
#define CP(S1,S2) memcpy(S1,S2,sizeof(S2))
#define ALL(x,S) for(__typeof((S).end()) x=S.begin();x!=S.end();x++)
#define pb push_back
#define IN insert
#define ER erase
#define BE begin()
#define ED end()
#define LB lower_bound
#define UB upper_bound
#define mp make_pair
#define fi first
#define se second
#define upmin(x,y) x=min(x,y)
#define upmax(x,y) x=max(x,y)
#define COUT(S,x) cout<<fixed<<setprecision(x)<<S<<endl
template<class T> inline void read(T&x){bool fu=0;char c;for(c=getchar();c<=32;c=getchar());if(c=='-')fu=1,c=getchar();for(x=0;c>32;c=getchar())x=x*10+c-'0';if(fu)x=-x;};
template<class T> inline void read(T&x,T&y){read(x);read(y);}
template<class T> inline void read(T&x,T&y,T&z){read(x);read(y);read(z);}
template<class T> inline void read(T&x,T&y,T&z,T&q){read(x);read(y);read(z);read(q);}

inline char getc(){char c;for(c=getchar();c<=32;c=getchar());return c;}

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;

const int N=100010;
int n,m,i,j,k,l,p,x,y,res;
vector<int> e[N];
pii a[N<<1];
int st[N],ed[N],li[N],ans[N];

vector<pii> S[N];

void dfs(int i,int f)
{
	st[i]=++st[0];li[st[0]]=i;
	for(int k=0;k<e[i].size();k++)
	{
		int u=e[i][k];if(u==f)continue;
		dfs(u,i);
	}
	ed[i]=st[0];
}

struct sgt
{
	int add[N<<2];pii s[N<<2];
	void padd(int i,int t){add[i]+=t;s[i].fi+=t;}
	void D(int i){if(add[i]==0)return;	padd(i*2,add[i]);	padd(i*2+1,add[i]);	add[i]=0;}
	void U(int i){s[i]=s[i*2];if(s[i*2+1].fi<s[i].fi)s[i]=s[i*2+1];else s[i].se+=(s[i*2+1].fi==s[i].fi)*s[i*2+1].se;}
	void F(int i,int x,int y,int l,int r,int z)
	{
		if(y<l||x>r)return;
		if(x>=l&&y<=r){padd(i,z);if(s[i].fi==0)res+=s[i].se;return;}
		D(i);F(i*2,x,(x+y)/2,l,r,z);F(i*2+1,(x+y)/2+1,y,l,r,z);U(i);
	}
	void B(int i,int x,int y)
	{
		if(x!=y)B(i*2,x,(x+y)/2),B(i*2+1,(x+y)/2+1,y),U(i);
		else s[i].se=1;
	}
}T;

int cf(int x){return x>m?x-m:x+m;}

int main()
{
    //freopen("1.in","r",stdin);freopen("1.out","w",stdout);
	read(n,m);
	rep(i,1,n-1)read(x,y),e[x].pb(y),e[y].pb(x);
	dfs(1,0);

	T.B(1,1,n);

	rep(i,1,m)
	{
		read(x,y);
		a[i]=mp(st[x],ed[x]);	S[st[x]].pb(mp(i,1));S[ed[x]+1].pb(mp(i,-1));
		a[i+m]=mp(st[y],ed[y]);	S[st[y]].pb(mp(i+m,1));S[ed[y]+1].pb(mp(i+m,-1));
	}

	rep(i,1,n)
	{
		for(int k=0;k<S[i].size();k++)
		{
			p=S[i][k].fi;
			res=0;
			//printf("%d %d %d\n",i,p,S[i][k].se);
			T.F(1,1,n,a[p].fi,a[p].se,S[i][k].se);
			T.F(1,1,n,a[cf(p)].fi,a[cf(p)].se,S[i][k].se);
		}
		ans[li[i]]=n-T.s[1].se*(T.s[1].fi==0);
	}
	rep(i,1,n)printf("%d ",max(0,ans[i]-1));printf("\n");

    return 0;
}


#include<algorithm>
#include<cassert>
#include<complex>
#include<map>
#include<iomanip>
#include<sstream>
#include<queue>
#include<set>
#include<string>
#include<vector>
#include<iostream>
#include<cstring>
#include<cstdio>
#define FOR(i, a, b) for(int i =(a); i <=(b); ++i)
#define FORD(i, a, b) for(int i = (a); i >= (b); --i)
#define fup FOR
#define fdo FORD
#define REP(i, n) for(int i = 0;i <(n); ++i)
#define VAR(v, i) __typeof(i) v=(i)
#define FORE(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i)
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define siz SZ
#define CLR(x) memset((x), 0, sizeof(x))
#define PB push_back
#define MP make_pair
#define FI first
#define SE second
#define X FI
#define Y SE.FI
#define Z SE.SE
#define SQR(a) ((a)*(a))
#define DE 1
#define E(x) {if (DE)cerr <<#x <<" = " <<x <<endl; }
#define E2(x, y) {if (DE)cerr <<#x <<" = " <<x << ", " << #y << " = " << y << endl; }
#define E3(x, y, z) {if (DE)cerr <<#x <<" = " <<x << ", " << #y << " = " << y << ", " << #z << " = " << z << endl; }
#define E4(x, y, z, u) {if (DE)cerr <<#x <<" = " <<x << ", " << #y << " = " << y << ", " << #z << " = " << z << ", " << #u << " = " << u << endl; }
#define E5(x, y, z, u, v) {if (DE)cerr <<#x <<" = " <<x << ", " << #y << " = " << y << ", " << #z << " = " << z << ", " << #u << " = " << u << ", " << #v << " = " << v << endl; }
#define E6(x, y, z, u, v, o) {if (DE)cerr <<#x <<" = " <<x << ", " << #y << " = " << y << ", " << #z << " = " << z << ", " << #u << " = " << u << ", " << #v << " = " << v << ", " << #o << " = " << o << endl; }
#define Ev(x) {if (DE) {cerr <<#x <<" = "; FORE(it, (x)) cerr <<*it <<", "; cout <<endl; }}

using namespace std;

typedef long long LL;
typedef long double LD;
typedef pair<int, int> P;
typedef pair<int, P> PP;
typedef vector<int> VI;
const LL INF64 = ((LL)1E18);
const int INF=1E9+7;
template<class C> void mini(C&a4, C b4) { a4 = min(a4, b4); }
template<class C> void maxi(C&a4, C b4) { a4 = max(a4, b4); }
template<typename T1, typename T2> ostream& operator<< (ostream &out, pair<T1, T2> pair) { out << "(" << pair.FI << ", " << pair.SE << ")"; return out; }

const int base = 1 << 19;
struct count_0_ltree {
    int dod[2 * base + 6], ile[2 * base + 6];
    void add(int l, int r, int v, int x = 1, int ll = 1, int rr = base) {
        if(r < ll || rr < l) return;
        if(l <= ll && rr <= r) { //przedzial basowy
            dod[x] += v;
            if (dod[x]) ile[x] = 0;
            else
            if (x >= base) {
                ile[x] = 1;
            } else {
                ile[x] = ile[x * 2] + ile[x * 2 + 1];
            }
        } else { //nadprzedzial
            add(l, r, v, x+x, ll, (ll+rr)/2);
            add(l, r, v, x+x+1, (ll+rr+1)/2, rr);
            ile[x] = (ile[x * 2] + ile[x * 2 + 1]) * (dod[x] == 0);
            //update
        }
    }
    int ile_zero() {
        if (dod[1]) return 0;
        else return ile[1];
    }

    void init() {
        CLR(dod);
        fup(i, base, 2 * base) ile[i] = 1;
        fdo(i, base - 1, 1) ile[i] = ile[i * 2] + ile[i * 2];
    }
};
count_0_ltree tree;
#define maxn 100005
int n, m, numer, res[maxn];
VI t[maxn], dod[maxn];
P inter[maxn];

void go(int act, int papa = -1) {
    inter[act].FI = ++numer;
    FORE(it, t[act]) if (*it != papa) go(*it, act);
    inter[act].SE = numer;
}

void go2(int act, int papa = -1) {
    FORE(it, dod[act]) {
        tree.add(inter[*it].FI, inter[*it].SE, 1);
        tree.add(inter[act].FI, inter[act].SE, 1);
    }
    res[act] = base - tree.ile_zero();
    FORE(it, t[act]) if (*it != papa) go2(*it, act);

    FORE(it, dod[act]) {
        tree.add(inter[*it].FI, inter[*it].SE, -1);
        tree.add(inter[act].FI, inter[act].SE, -1);
    }
}

int main(){
    ios_base::sync_with_stdio(false);
    tree.init();
    cin >> n >> m;
    fup(i, 1, n - 1) {
        int a, b; cin >> a >> b;
        t[a].PB(b); t[b].PB(a);
    }

    go(1);
    fup(i, 1, m) {
        int a, b;
        cin >> a >> b;
        dod[a].PB(b);
        dod[b].PB(a);
    }
    go2(1);
    fup(i, 1, n) cout << (res[i]?res[i]-1:0) << " "; cout << endl;
    return 0;
}


#include <cassert>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
#include <complex>
using namespace std;

// begin insert defines
template <class T> void PA(T x[], int n) {for (int i = 0; i < n; ++i) cout << x[i] << " "; cout << endl;}
typedef pair<int, int> PII;
#define Rep(i,n) for(int n_ = (n), i = 0; i< n_; ++i)
template <class T> void PV(T x) {for(__typeof__((x).begin()) i = (x).begin(); i != (x).end(); ++i) cout << *i << " "; cout << endl;}
#define ND second
#define FS first
#define MP make_pair
#define PB push_back
typedef vector<int> VRI;
#define VR vector

// end insert defines

const int N = 100000;

VRI lnk[N];
VRI L, R;
int n, m;
int en;

struct Seg
{
    int lc, rc, l, r;
    int c, s;
}seg[N * 4];

int segn;

void eulerPath(int now, int fth)
{
    L[now] = en++;
    for (auto &v: lnk[now])
        if (v != fth)
            eulerPath(v, now);
    R[now] = en++;
}

int seg_init(int l, int r)
{
    int p = segn++;
    Seg &ns = seg[p];
    ns.l = l, ns.r = r;
    ns.c = 0;
    ns.s = 0;
    if (l == r) return p;
    int mid = (l + r) / 2;
    ns.lc = seg_init(l, mid);
    ns.rc = seg_init(mid + 1, r);
    return p;
}

void update(Seg &ns, Seg &ls, Seg &rs)
{
    ns.s = ls.c ? (ls.r - ls.l + 1) : ls.s;
    ns.s += rs.c ? (rs.r - rs.l + 1) : rs.s;
}

void seg_ins(int p, int l, int r, int v)
{
    Seg &ns = seg[p];
    int mid = (ns.l + ns.r) / 2;
    if (l <= ns.l && ns.r <= r) {
        ns.c += v;
        return ;
    }
    if (l <= mid) seg_ins(ns.lc, l, r, v);
    if (r > mid) seg_ins(ns.rc, l, r, v);
    update(ns, seg[ns.lc], seg[ns.rc]);
}

VR<PII> op[N];
int ans[N];

void dfs(int now, int fth)
{
    for (const PII &opi: op[now]) {
        seg_ins(0, L[opi.FS], R[opi.FS], 1);
        seg_ins(0, L[opi.ND], R[opi.ND], 1);
    }
    ans[now] = seg[0].c ? n * 2 : seg[0].s;
    ans[now] /= 2;
    if (ans[now]) ans[now]--;
    for (auto &v: lnk[now])
        if (v != fth)
            dfs(v, now);
    for (const PII &opi: op[now]) {
        seg_ins(0, L[opi.FS], R[opi.FS], -1);
        seg_ins(0, L[opi.ND], R[opi.ND], -1);
    }
}

int main(int argc, char *argv[])
{
    cin >> n >> m;
    Rep(i, n - 1) {
        int u, v;
        cin >> u >> v;
        u--, v--;
        lnk[u].PB(v);
        lnk[v].PB(u);
    }
    L.resize(n);
    R.resize(n);
    en = 0;
    eulerPath(0, -1);

    segn = 0;
    seg_init(0, n * 2 - 1);

    while (m-->0) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        op[a].PB(MP(a, b));
        op[b].PB(MP(a, b));
    }
    dfs(0, -1);
    PA(ans, n);
    return 0;
}


#include <cassert>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
#include <complex>
using namespace std;

// begin insert defines
template <class T> void PA(T x[], int n) {for (int i = 0; i < n; ++i) cout << x[i] << " "; cout << endl;}
typedef pair<int, int> PII;
#define Rep(i,n) for(int n_ = (n), i = 0; i< n_; ++i)
template <class T> void PV(T x) {for(__typeof__((x).begin()) i = (x).begin(); i != (x).end(); ++i) cout << *i << " "; cout << endl;}
#define ND second
#define FS first
#define MP make_pair
#define PB push_back
typedef vector<int> VRI;
#define VR vector

// end insert defines

const int N = 100000;

VRI lnk[N];
VRI L, R;
int n, m;
int en;

struct Seg
{
    int lc, rc, l, r;
    int c, s;
}seg[N * 4];

int segn;

void eulerPath(int now, int fth)
{
    L[now] = en++;
    for (auto &v: lnk[now])
        if (v != fth)
            eulerPath(v, now);
    R[now] = en++;
}

int seg_init(int l, int r)
{
    int p = segn++;
    Seg &ns = seg[p];
    ns.l = l, ns.r = r;
    ns.c = 0;
    ns.s = 0;
    if (l == r) return p;
    int mid = (l + r) / 2;
    ns.lc = seg_init(l, mid);
    ns.rc = seg_init(mid + 1, r);
    return p;
}

void update(Seg &ns, Seg &ls, Seg &rs)
{
    ns.s = ls.c ? (ls.r - ls.l + 1) : ls.s;
    ns.s += rs.c ? (rs.r - rs.l + 1) : rs.s;
}

void seg_ins(int p, int l, int r, int v)
{
    Seg &ns = seg[p];
    int mid = (ns.l + ns.r) / 2;
    if (l <= ns.l && ns.r <= r) {
        ns.c += v;
        return ;
    }
    if (l <= mid) seg_ins(ns.lc, l, r, v);
    if (r > mid) seg_ins(ns.rc, l, r, v);
    update(ns, seg[ns.lc], seg[ns.rc]);
}

VR<PII> op[N];
int ans[N];

void dfs(int now, int fth)
{
    for (const PII &opi: op[now]) {
        seg_ins(0, L[opi.FS], R[opi.FS], 1);
        seg_ins(0, L[opi.ND], R[opi.ND], 1);
    }
    ans[now] = seg[0].c ? segn : seg[0].s;
    ans[now] /= 2;
    if (ans[now]) ans[now]--;
    for (auto &v: lnk[now])
        if (v != fth)
            dfs(v, now);
    for (const PII &opi: op[now]) {
        seg_ins(0, L[opi.FS], R[opi.FS], -1);
        seg_ins(0, L[opi.ND], R[opi.ND], -1);
    }
}

int main(int argc, char *argv[])
{
    cin >> n >> m;
    Rep(i, n - 1) {
        int u, v;
        cin >> u >> v;
        u--, v--;
        lnk[u].PB(v);
        lnk[v].PB(u);
    }
    L.resize(n);
    R.resize(n);
    en = 0;
    eulerPath(0, -1);

    segn = 0;
    seg_init(0, n * 2 - 1);

    while (m-->0) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        op[a].PB(MP(a, b));
        op[b].PB(MP(a, b));
    }
    dfs(0, -1);
    PA(ans, n);
    return 0;
}


#include<iostream>
#include<vector>

#define PB push_back
#define MP make_pair
#define F first
#define S second
using namespace std;

const int MAXN = 1e5, SEG = 4e5;
int l[MAXN], r[MAXN], sum[SEG], lazy[SEG], DFSNUM, ans[MAXN];
bool mark[MAXN];
vector<int> v[MAXN];
int n, m;
vector<pair<int, int> > seg[MAXN];

void DFS(int n)
{
	mark[n] = true;
	l[n] = DFSNUM;
	DFSNUM++;
	for(int x : v[n])
		if(!mark[x])
			DFS(x);
	r[n] = DFSNUM;
}

void add(int ql, int qr, int val, int x = 1, int l = 0, int r = n)
{
	if(ql == qr)
		return;
	if(ql <= l && r <= qr)
	{
		lazy[x] += val;
		if(lazy[x] == 0 && val == -1)
			sum[x] = sum[2 * x] + sum[2 * x + 1];
		if(lazy[x] == 1 && val == 1)
			sum[x] = r - l;
		return;
	}
	int mid = (l + r) / 2;
	if(ql < mid)
		add(ql, qr, val, 2 * x, l, mid);
	if(qr > mid)
		add(ql, qr, val, 2 * x + 1, mid, r);
	if(lazy[x] == 0)
		sum[x] = sum[2 * x] + sum[2 * x + 1];
}

void DFS2(int n)
{
	mark[n] = true;
	for(auto p : seg[n])
		add(p.F, p.S, 1);
	ans[n] = sum[1];
	for(int x : v[n])
		if(!mark[x])
			DFS2(x);
	for(auto p : seg[n])
		add(p.F, p.S, -1);
}

int main()
{
	cin >> n >> m;
	for(int i = 0; i < n - 1; i++)
	{
		int a, b;
		cin >> a >> b;
		a--, b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	DFS(0);
	while(m--)
	{
		int a, b;
		cin >> a >> b;
		a--, b--;
		seg[a].PB(MP(l[b], r[b]));
		seg[b].PB(MP(l[a], r[a]));
	}
	for(int i = 0; i < n; i++)
		if(seg[i].size())
			seg[i].PB(MP(l[i] + 1, r[i]));
	fill(mark, mark + MAXN, 0);
	cout << "PASS" << endl;
	DFS2(0);
	for(int i = 0; i < n; i++)
		cout << ans[i] << ' ';
	cout << endl;
	return 0;
}


#include<iostream>
#include<vector>

#define PB push_back
#define MP make_pair
#define F first
#define S second
using namespace std;

const int MAXN = 1e5, SEG = 4e5;
int l[MAXN], r[MAXN], sum[SEG], lazy[SEG], DFSNUM, ans[MAXN];
bool mark[MAXN];
vector<int> v[MAXN];
int n, m;
vector<pair<int, int> > seg[MAXN];

void DFS(int n)
{
	mark[n] = true;
	l[n] = DFSNUM;
	DFSNUM++;
	for(int x : v[n])
		if(!mark[x])
			DFS(x);
	r[n] = DFSNUM;
}

void add(int ql, int qr, int val, int x = 1, int l = 0, int r = n)
{
	if(ql <= l && r <= qr)
	{
		lazy[x] += val;
		if(lazy[x] == 0 && val == -1)
			sum[x] = sum[2 * x] + sum[2 * x + 1];
		if(lazy[x] == 1 && val == 1)
			sum[x] = r - l;
		return;
	}
	int mid = (l + r) / 2;
	if(ql < mid)
		add(ql, qr, val, 2 * x, l, mid);
	if(qr > mid)
		add(ql, qr, val, 2 * x + 1, mid, r);
	if(lazy[x] == 0)
		sum[x] = sum[2 * x] + sum[2 * x + 1];
}

void DFS2(int n)
{
	mark[n] = true;
	for(auto p : seg[n])
		add(p.F, p.S, 1);
	ans[n] = sum[1];
	for(int x : v[n])
		if(!mark[x])
			DFS2(x);
	for(auto p : seg[n])
		add(p.F, p.S, -1);
}

int main()
{
	cin >> n >> m;
	for(int i = 0; i < n - 1; i++)
	{
		int a, b;
		cin >> a >> b;
		a--, b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	DFS(0);
	while(m--)
	{
		int a, b;
		cin >> a >> b;
		a--, b--;
		seg[a].PB(MP(l[b], r[b]));
		seg[b].PB(MP(l[a], r[a]));
	}
	for(int i = 0; i < n; i++)
		if(seg[i].size())
			seg[i].PB(MP(l[i] + 1, r[i]));
	fill(mark, mark + MAXN, 0);
	DFS2(0);
	for(int i = 0; i < n; i++)
		cout << ans[i] << ' ';
	cout << endl;
	return 0;
}


#include<iostream>
#include<vector>

#define PB push_back
#define MP make_pair
#define F first
#define S second
using namespace std;

const int MAXN = 1e5, SEG = 4e5;
int l[MAXN], r[MAXN], sum[SEG], lazy[SEG], DFSNUM, ans[MAXN];
bool mark[MAXN];
vector<int> v[MAXN];
int n, m;
vector<pair<int, int> > seg[MAXN];

void DFS(int n)
{
	mark[n] = true;
	l[n] = DFSNUM;
	DFSNUM++;
	for(int x : v[n])
		if(!mark[x])
			DFS(x);
	r[n] = DFSNUM;
}

void add(int ql, int qr, int val, int x = 1, int l = 0, int r = n)
{
	if(ql == qr)
		return;
	if(ql <= l && r <= qr)
	{
		lazy[x] += val;
		if(lazy[x] == 0 && val == -1)
			sum[x] = sum[2 * x] + sum[2 * x + 1];
		if(lazy[x] == 1 && val == 1)
			sum[x] = r - l;
		return;
	}
	int mid = (l + r) / 2;
	if(ql < mid)
		add(ql, qr, val, 2 * x, l, mid);
	if(qr > mid)
		add(ql, qr, val, 2 * x + 1, mid, r);
	if(lazy[x] == 0)
		sum[x] = sum[2 * x] + sum[2 * x + 1];
}

void DFS2(int n)
{
	mark[n] = true;
	for(auto p : seg[n])
		add(p.F, p.S, 1);
	ans[n] = sum[1];
	for(int x : v[n])
		if(!mark[x])
			DFS2(x);
	for(auto p : seg[n])
		add(p.F, p.S, -1);
}

int main()
{
	cin >> n >> m;
	for(int i = 0; i < n - 1; i++)
	{
		int a, b;
		cin >> a >> b;
		a--, b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	DFS(0);
	while(m--)
	{
		int a, b;
		cin >> a >> b;
		a--, b--;
		seg[a].PB(MP(l[b], r[b]));
		seg[b].PB(MP(l[a], r[a]));
	}
	for(int i = 0; i < n; i++)
		if(seg[i].size())
			seg[i].PB(MP(l[i], r[i]));
	fill(mark, mark + MAXN, 0);
	DFS2(0);
	for(int i = 0; i < n; i++)
		cout << max(0, ans[i] - 1) << ' ';
	cout << endl;
	return 0;
}