Mayor of city M. decided to launch several new metro lines during 2020. Since the city has a very limited budget, it was decided not to dig new tunnels but to use the existing underground network.The tunnel system of the city M. consists of $$$n$$$ metro stations. The stations are connected with $$$n - 1$$$ bidirectional tunnels. Between every two stations $$$v$$$ and $$$u$$$ there is exactly one simple path. Each metro line the mayor wants to create is a simple path between stations $$$a_i$$$ and $$$b_i$$$. Metro lines can intersects freely, that is, they can share common stations or even common tunnels. However, it's not yet decided which of two directions each line will go. More precisely, between the stations $$$a_i$$$ and $$$b_i$$$ the trains will go either from $$$a_i$$$ to $$$b_i$$$, or from $$$b_i$$$ to $$$a_i$$$, but not simultaneously.The city $$$M$$$ uses complicated faring rules. Each station is assigned with a positive integer $$$c_i$$$ — the fare zone of the station. The cost of travel from $$$v$$$ to $$$u$$$ is defined as $$$c_u - c_v$$$ roubles. Of course, such travel only allowed in case there is a metro line, the trains on which go from $$$v$$$ to $$$u$$$. Mayor doesn't want to have any travels with a negative cost, so it was decided to assign directions of metro lines and station fare zones in such a way, that fare zones are strictly increasing during any travel on any metro line.Mayor wants firstly assign each station a fare zone and then choose a lines direction, such that all fare zones are increasing along any line. In connection with the approaching celebration of the day of the city, the mayor wants to assign fare zones so that the maximum $$$c_i$$$ will be as low as possible. Please help mayor to design a new assignment or determine if it's impossible to do. Please note that you only need to assign the fare zones optimally, you don't need to print lines' directions. This way, you solution will be considered correct if there will be a way to assign directions of every metro line, so that the fare zones will be strictly increasing along any movement of the trains.

The first line contains an integers $$$n$$$, $$$m$$$ ($$$2 \le n, \le 500\,000,\ 1 \le m \le 500\,000$$$) — the number of stations in the city and the number of metro lines. Each of the following $$$n-1$$$ lines describes another metro tunnel. Each tunnel is described with integers $$$v_i$$$, $$$u_i$$$ ($$$1 \le v_i,\ u_i \le n$$$, $$$v_i \ne u_i$$$). It's guaranteed, that there is exactly one simple path between any two stations. Each of the following $$$m$$$ lines describes another metro line. Each line is described with integers $$$a_i$$$, $$$b_i$$$ ($$$1 \le a_i,\ b_i \le n$$$, $$$a_i \neq b_i$$$).

In the first line print integer $$$k$$$ — the maximum fare zone used. In the next line print integers $$$c_1, c_2, \ldots, c_n$$$ ($$$1 \le c_i \le k$$$)  — stations' fare zones.  In case there are several possible answers, print any of them. In case it's impossible to assign fare zones, print "-1".

NoteIn the first example, line $$$1 \rightarrow 3$$$ goes through the stations 1, 2, 3 in this order. In this order the fare zones of the stations are increasing. Since this line has 3 stations, at least three fare zones are needed. So the answer 1, 2, 3 is optimal.In the second example, it's impossible to assign fare zones to be consistent with a metro lines.

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

typedef long long ll;
typedef long double ld;
typedef double db;
typedef string str;

typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef pair<db,db> pd;

typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<db> vd;
typedef vector<str> vs;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<pd> vpd;

#define mp make_pair
#define f first
#define s second
#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
#define ins insert
#define ft front()
#define bk back()
#define pf push_front
#define pb push_back
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound

#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i)
#define R0F(i,a) ROF(i,0,a)
#define trav(a,x) for (auto& a: x)

const int MOD = 1e9+7; // 998244353;
const int MX = 5e5+5;
const ll INF = 1e18;
const ld PI = acos((ld)-1);
const int xd[4] = {1,0,-1,0}, yd[4] = {0,1,0,-1};

template<class T> bool ckmin(T& a, const T& b) {
	return b < a ? a = b, 1 : 0; }
template<class T> bool ckmax(T& a, const T& b) {
	return a < b ? a = b, 1 : 0; }
int pct(int x) { return __builtin_popcount(x); }
int bit(int x) { return 31-__builtin_clz(x); } // floor(log2(x))
int cdiv(int a, int b) { return a/b+!(a<0||a%b == 0); } // division of a by b rounded up, assumes b > 0

namespace input {
	template<class T> void re(complex<T>& x);
	template<class T1, class T2> void re(pair<T1,T2>& p);
	template<class T> void re(vector<T>& a);
	template<class T, size_t SZ> void re(array<T,SZ>& a);

	template<class T> void re(T& x) { cin >> x; }
	void re(double& x) { string t; re(t); x = stod(t); }
	void re(ld& x) { string t; re(t); x = stold(t); }
	template<class T, class... Ts> void re(T& t, Ts&... ts) {
		re(t); re(ts...);
	}

	template<class T> void re(complex<T>& x) { T a,b; re(a,b); x = {a,b}; }
	template<class T1, class T2> void re(pair<T1,T2>& p) { re(p.f,p.s); }
	template<class T> void re(vector<T>& a) { F0R(i,sz(a)) re(a[i]); }
	template<class T, size_t SZ> void re(array<T,SZ>& a) { F0R(i,SZ) re(a[i]); }
}

using namespace input;

namespace output {
	void pr(int x) { cout << x; }
	void pr(long x) { cout << x; }
	void pr(ll x) { cout << x; }
	void pr(unsigned x) { cout << x; }
	void pr(unsigned long x) { cout << x; }
	void pr(unsigned long long x) { cout << x; }
	void pr(float x) { cout << x; }
	void pr(double x) { cout << x; }
	void pr(ld x) { cout << x; }
	void pr(char x) { cout << x; }
	void pr(const char* x) { cout << x; }
	void pr(const string& x) { cout << x; }
	void pr(bool x) { pr(x ? "true" : "false"); }
	template<class T> void pr(const complex<T>& x) { cout << x; }

	template<class T1, class T2> void pr(const pair<T1,T2>& x);
	template<class T> void pr(const T& x);

	template<class T, class... Ts> void pr(const T& t, const Ts&... ts) {
		pr(t); pr(ts...);
	}
	template<class T1, class T2> void pr(const pair<T1,T2>& x) {
		pr("{",x.f,", ",x.s,"}");
	}
	template<class T> void pr(const T& x) {
		pr("{"); // const iterator needed for vector<bool>
		bool fst = 1; for (const auto& a: x) pr(!fst?", ":"",a), fst = 0;
		pr("}");
	}

	void ps() { pr("\n"); } // print w/ spaces
	template<class T, class... Ts> void ps(const T& t, const Ts&... ts) {
		pr(t); if (sizeof...(ts)) pr(" "); ps(ts...);
	}

	void pc() { pr("]\n"); } // debug w/ commas
	template<class T, class... Ts> void pc(const T& t, const Ts&... ts) {
		pr(t); if (sizeof...(ts)) pr(", "); pc(ts...);
	}
	#define dbg(x...) pr("[",#x,"] = ["), pc(x);
}

using namespace output;

namespace io {
	void setIn(string s) { freopen(s.c_str(),"r",stdin); }
	void setOut(string s) { freopen(s.c_str(),"w",stdout); }
	void setIO(string s = "") {
		ios_base::sync_with_stdio(0); cin.tie(0); // fast I/O
		// cin.exceptions(cin.failbit);
		// throws exception when do smth illegal
		// ex. try to read letter into int
		if (sz(s)) { setIn(s+".in"), setOut(s+".out"); } // for USACO
	}
}

using namespace io;

mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());

/**
 * Description: Disjoint Set Union with path compression.
 	* Add edges and test connectivity. Use for Kruskal's
 	* minimum spanning tree.
 * Time: O(\alpha(N))
 * Source: CSAcademy, KACTL
 * Verification: USACO superbull
 */

struct DSU {
	vpi par;
	void init(int n) {
		par.rsz(n);
		F0R(i,n) par[i] = {i,0};
	}
	pi get(int x) {
		if (par[x].f == x) return par[x];
		pi p = get(par[x].f); p.s ^= par[x].s;
		return par[x] = p;
	}
	void unite(int x, int y, int z) { // union-by-rank
		pi X = get(x), Y = get(y);
		// ps("UNITE",x,y,z);
		if (X.f == Y.f) {
			if ((X.s^Y.s) != z) {
				ps(-1);
				exit(0);
			}
		} else {
			par[Y.f] = {X.f,X.s^Y.s^z};
		}
	}
};

/**
 * Description: Calculates least common ancestor in tree
 	* with root $R$ using binary jumping.
 * Time: O(N\log N) build, O(\log N) query
 * Source: USACO Camp
 * Verification: Debug the Bugs
 */

template<int SZ> struct LCA {
	static const int BITS = 32-__builtin_clz(SZ);
	int N, R = 1, par[BITS][SZ], depth[SZ];
	vi adj[SZ];
	/// INITIALIZE
	void ae(int u, int v) { adj[u].pb(v), adj[v].pb(u); }
	void dfs(int u, int prev){
		par[0][u] = prev; depth[u] = depth[prev]+1;
		trav(v,adj[u]) if (v != prev) dfs(v, u);
	}
	void init(int _N) {
		N = _N; dfs(R,0);
		FOR(k,1,BITS) FOR(i,1,N+1)
			par[k][i] = par[k-1][par[k-1][i]];
	}
	/// QUERY
	int getPar(int a, int b) {
		R0F(k,BITS) if (b&(1<<k)) a = par[k][a];
		return a; }
	int lca(int u, int v){
		if (depth[u] < depth[v]) swap(u,v);
		u = getPar(u,depth[u]-depth[v]);
		R0F(k,BITS) if (par[k][u] != par[k][v])
			u = par[k][u], v = par[k][v];
		return u == v ? u : par[0][u];
	}
	int dist(int u, int v) {
		return depth[u]+depth[v]-2*depth[lca(u,v)]; }
};

LCA<MX> L;
int n,m, mn[MX], c[MX], mid;
bool bad;

DSU D;
bool par[MX], tmpPar[MX];
pi stor[MX];

void dfs(int x) {
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		dfs(t); if (bad) return;
	}
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		stor[D.get(t).f].f = MOD;
		// ps("OH",x,t,D.get(x).f,D.get(t).f);
	}
	pi p = D.get(x); stor[p.f] = {1,mid};
	vi todo = {p.f};
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		pi p = D.get(t);
		if (stor[p.f].f == MOD) {
			// ps("WAT",x,p);
			stor[p.f] = {1,mid};
			todo.pb(p.f);
		}
		if (p.s == 0) ckmax(stor[p.f].f,mn[t]+1); // goes up
		else ckmin(stor[p.f].s,mid-mn[t]);
		// ps("AH",stor[p.f]);
	}
	pi P = stor[p.f]; if (p.s) P = {mid+1-P.s,mid+1-P.f};
	pi ban = {MOD,-MOD};
	int LL = P.f, RR = P.s;
	FOR(i,1,sz(todo)) {
		pi z = stor[todo[i]];
		if (z.f > z.s) { bad = 1; return; }
		pi Z = {mid+1-z.s,mid+1-z.f};
		if (z > Z) swap(z,Z);
		ckmax(LL,z.f), ckmin(RR,Z.s);
		if (z.s+1 < Z.f) { ckmin(ban.f,z.s+1), ckmax(ban.s,Z.f-1); }
	}
	if (LL > RR) { bad = 1; return; }
	int val;
	// ps("HAHA",LL,RR,ban);
	if (LL < ban.f) val = LL;
	else if (LL > ban.s) val = LL;
	else if (ban.s < RR) val = ban.s+1;
	else { bad = 1; return; }
	mn[x] = val; tmpPar[p.f] = p.s;
	FOR(i,1,sz(todo)) {
		pi t = stor[todo[i]];
		//ps("OH",t);
		if (t.f <= val && val <= t.s) {
			tmpPar[todo[i]] = 0;
		} else {
			// assert(mid+1-t.s.s <= val && val <= mid+1-t.s.f);
			tmpPar[todo[i]] = 1;
		}
	}
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		pi p = D.get(t);
		par[t] = tmpPar[p.f]^p.s;
		//ps("HAHA",t,par[t]);
	}
}

bool ok() {
	bad = 0; dfs(1);
	return !bad;
}

void genAns(int x) {
	if (par[x] == 0) {
		c[x] = mn[x];
	} else {
		c[x] = mid+1-mn[x];
	}
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		par[t] ^= par[x];
		genAns(t);
	}
}

int ad[MX];
void path(int a, int b) {
	// ps("OH",a,b);
	int x = L.lca(a,b);
	int A,B;
	if (a != x) {
		A = L.getPar(a,L.depth[a]-L.depth[x]-1);
		ad[a] ++; ad[A] --;
	}
	if (b != x) {
		B = L.getPar(b,L.depth[b]-L.depth[x]-1);
		ad[b] ++; ad[B] --;
	}
	if (a != x && b != x) {
		D.unite(A,B,1);
	}
}

void genAd(int x) {
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		genAd(t);
		ad[x] += ad[t];
	}
	if (ad[x]) {
		D.unite(x,L.par[0][x],0);
	}
}

/**
 * Description: Fast input and output.
 * Time: input is $\sim$300ms faster for $10^6$ long longs on CF
 * Source:
 	* https://codeforces.com/gym/102394/submission/64154785
 	* https://codeforces.com/contest/1254/submission/65420506 (neal)
 	* https://codeforces.com/blog/entry/45835 (AI.Cash)
 * Verification: https://codeforces.com/gym/102394/problem/G
 */

namespace FastIO {
	const int BSZ = 1<<15; ////// INPUT
	char ibuf[BSZ]; int ipos, ilen;
	char nc() { // next char
		if (ipos == ilen) {
			ipos = 0; ilen = fread(ibuf,1,BSZ,stdin);
			if (!ilen) return EOF;
		}
		return ibuf[ipos++];
	}
	void rs(str& x) { // read str
		char ch; while (isspace(ch = nc()));
		do { x += ch; } while (!isspace(ch = nc()) && ch != EOF);
	}
	template<class T> void ri(T& x) { // read int or ll
		char ch; int sgn = 1;
		while (!isdigit(ch = nc())) if (ch == '-') sgn *= -1;
		x = ch-'0'; while (isdigit(ch = nc())) x = x*10+(ch-'0');
		x *= sgn;
	}
	template<class T, class... Ts> void ri(T& t, Ts&... ts) {
		ri(t); ri(ts...); } // read ints
	////// OUTPUT (call initO() at start)
	char obuf[BSZ], numBuf[100]; int opos;
	void flushOut() { fwrite(obuf,1,opos,stdout); opos = 0; }
	void wc(char c) { // write char
		if (opos == BSZ) flushOut();
		obuf[opos++] = c; }
	void ws(str s) { trav(c,s) wc(c); } // write str
	template<class T> void wi(T x, char after = '\0') { /// write int
		if (x < 0) wc('-'), x *= -1;
		int len = 0; for (;x>=10;x/=10) numBuf[len++] = '0'+(x%10);
		wc('0'+x); R0F(i,len) wc(numBuf[i]);
		if (after) wc(after);
	}
	void initO() { assert(atexit(flushOut) == 0); } /// auto-flush output
}
using namespace FastIO;
/// initO(); int a,b; ri(a,b); wi(b,'\n'); wi(a,'\n');

void init() {
	initO();
	ri(n,m); D.init(n+1);
	F0R(i,n-1) {
		int a,b; ri(a,b);
		L.ae(a,b);
	}
	L.init(n);
	F0R(i,m) {
		int a,b; ri(a,b);
		path(a,b);
	}
	// FOR(i,1,n+1) ps(i,ad[i]);
	genAd(1);
}

int main() {
	init();
	mid = n; assert(ok());
	// exit(0);
	int lo = 1, hi = n;
	while (lo < hi) {
		mid = (lo+hi)/2;
		if (ok()) hi = mid;
		else lo = mid+1;
	}
	mid = lo; assert(ok());
	ps(mid);
	genAns(1);
	FOR(i,1,n+1) {
		if (i < n) wi(c[i],' ');
		else wi(c[i],'\n');
	}
	// you should actually read the stuff at the bottom
}

/* stuff you should look for
	* int overflow, array bounds
	* special cases (n=1?)
	* do smth instead of nothing and stay organized
	* WRITE STUFF DOWN
*/

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

typedef long long ll;
typedef long double ld;
typedef double db;
typedef string str;

typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef pair<db,db> pd;

typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<db> vd;
typedef vector<str> vs;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<pd> vpd;

#define mp make_pair
#define f first
#define s second
#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
#define ins insert
#define ft front()
#define bk back()
#define pf push_front
#define pb push_back
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound

#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i)
#define R0F(i,a) ROF(i,0,a)
#define trav(a,x) for (auto& a: x)

const int MOD = 1e9+7; // 998244353;
const int MX = 5e5+5;
const ll INF = 1e18;
const ld PI = acos((ld)-1);
const int xd[4] = {1,0,-1,0}, yd[4] = {0,1,0,-1};

template<class T> bool ckmin(T& a, const T& b) {
	return b < a ? a = b, 1 : 0; }
template<class T> bool ckmax(T& a, const T& b) {
	return a < b ? a = b, 1 : 0; }
int pct(int x) { return __builtin_popcount(x); }
int bit(int x) { return 31-__builtin_clz(x); } // floor(log2(x))
int cdiv(int a, int b) { return a/b+!(a<0||a%b == 0); } // division of a by b rounded up, assumes b > 0

namespace input {
	template<class T> void re(complex<T>& x);
	template<class T1, class T2> void re(pair<T1,T2>& p);
	template<class T> void re(vector<T>& a);
	template<class T, size_t SZ> void re(array<T,SZ>& a);

	template<class T> void re(T& x) { cin >> x; }
	void re(double& x) { string t; re(t); x = stod(t); }
	void re(ld& x) { string t; re(t); x = stold(t); }
	template<class T, class... Ts> void re(T& t, Ts&... ts) {
		re(t); re(ts...);
	}

	template<class T> void re(complex<T>& x) { T a,b; re(a,b); x = {a,b}; }
	template<class T1, class T2> void re(pair<T1,T2>& p) { re(p.f,p.s); }
	template<class T> void re(vector<T>& a) { F0R(i,sz(a)) re(a[i]); }
	template<class T, size_t SZ> void re(array<T,SZ>& a) { F0R(i,SZ) re(a[i]); }
}

using namespace input;

namespace output {
	void pr(int x) { cout << x; }
	void pr(long x) { cout << x; }
	void pr(ll x) { cout << x; }
	void pr(unsigned x) { cout << x; }
	void pr(unsigned long x) { cout << x; }
	void pr(unsigned long long x) { cout << x; }
	void pr(float x) { cout << x; }
	void pr(double x) { cout << x; }
	void pr(ld x) { cout << x; }
	void pr(char x) { cout << x; }
	void pr(const char* x) { cout << x; }
	void pr(const string& x) { cout << x; }
	void pr(bool x) { pr(x ? "true" : "false"); }
	template<class T> void pr(const complex<T>& x) { cout << x; }

	template<class T1, class T2> void pr(const pair<T1,T2>& x);
	template<class T> void pr(const T& x);

	template<class T, class... Ts> void pr(const T& t, const Ts&... ts) {
		pr(t); pr(ts...);
	}
	template<class T1, class T2> void pr(const pair<T1,T2>& x) {
		pr("{",x.f,", ",x.s,"}");
	}
	template<class T> void pr(const T& x) {
		pr("{"); // const iterator needed for vector<bool>
		bool fst = 1; for (const auto& a: x) pr(!fst?", ":"",a), fst = 0;
		pr("}");
	}

	void ps() { pr("\n"); } // print w/ spaces
	template<class T, class... Ts> void ps(const T& t, const Ts&... ts) {
		pr(t); if (sizeof...(ts)) pr(" "); ps(ts...);
	}

	void pc() { pr("]\n"); } // debug w/ commas
	template<class T, class... Ts> void pc(const T& t, const Ts&... ts) {
		pr(t); if (sizeof...(ts)) pr(", "); pc(ts...);
	}
	#define dbg(x...) pr("[",#x,"] = ["), pc(x);
}

using namespace output;

namespace io {
	void setIn(string s) { freopen(s.c_str(),"r",stdin); }
	void setOut(string s) { freopen(s.c_str(),"w",stdout); }
	void setIO(string s = "") {
		ios_base::sync_with_stdio(0); cin.tie(0); // fast I/O
		// cin.exceptions(cin.failbit);
		// throws exception when do smth illegal
		// ex. try to read letter into int
		if (sz(s)) { setIn(s+".in"), setOut(s+".out"); } // for USACO
	}
}

using namespace io;

mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());

/**
 * Description: Disjoint Set Union with path compression.
 	* Add edges and test connectivity. Use for Kruskal's
 	* minimum spanning tree.
 * Time: O(\alpha(N))
 * Source: CSAcademy, KACTL
 * Verification: USACO superbull
 */

struct DSU {
	vpi par;
	void init(int n) {
		par.rsz(n);
		F0R(i,n) par[i] = {i,0};
	}
	pi get(int x) {
		if (par[x].f == x) return par[x];
		pi p = get(par[x].f); p.s ^= par[x].s;
		return par[x] = p;
	}
	void unite(int x, int y, int z) { // union-by-rank
		pi X = get(x), Y = get(y);
		// ps("UNITE",x,y,z);
		if (X.f == Y.f) {
			if ((X.s^Y.s) != z) {
				ps(-1);
				exit(0);
			}
		} else {
			par[Y.f] = {X.f,X.s^Y.s^z};
		}
	}
};

/**
 * Description: Calculates least common ancestor in tree
 	* with root $R$ using binary jumping.
 * Time: O(N\log N) build, O(\log N) query
 * Source: USACO Camp
 * Verification: Debug the Bugs
 */

template<int SZ> struct LCA {
	static const int BITS = 32-__builtin_clz(SZ);
	int N, R = 1, par[BITS][SZ], depth[SZ];
	vi adj[SZ];
	/// INITIALIZE
	void ae(int u, int v) { adj[u].pb(v), adj[v].pb(u); }
	void dfs(int u, int prev){
		par[0][u] = prev; depth[u] = depth[prev]+1;
		trav(v,adj[u]) if (v != prev) dfs(v, u);
	}
	void init(int _N) {
		N = _N; dfs(R,0);
		FOR(k,1,BITS) FOR(i,1,N+1)
			par[k][i] = par[k-1][par[k-1][i]];
	}
	/// QUERY
	int getPar(int a, int b) {
		R0F(k,BITS) if (b&(1<<k)) a = par[k][a];
		return a; }
	int lca(int u, int v){
		if (depth[u] < depth[v]) swap(u,v);
		u = getPar(u,depth[u]-depth[v]);
		R0F(k,BITS) if (par[k][u] != par[k][v])
			u = par[k][u], v = par[k][v];
		return u == v ? u : par[0][u];
	}
	int dist(int u, int v) {
		return depth[u]+depth[v]-2*depth[lca(u,v)]; }
};

LCA<MX> L;
int n,m, mn[MX], c[MX], mid;
bool bad;

DSU D;
bool par[MX], tmpPar[MX];
pi stor[MX];

bool fin;

void dfs(int x) {
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		dfs(t); if (bad) return;
	}
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		stor[D.get(t).f].f = MOD;
		// ps("OH",x,t,D.get(x).f,D.get(t).f);
	}
	pi p = D.get(x); stor[p.f] = {1,mid};
	vi todo = {p.f};
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		pi p = D.get(t);
		if (stor[p.f].f == MOD) {
			// ps("WAT",x,p);
			stor[p.f] = {1,mid};
			todo.pb(p.f);
		}
		if (p.s == 0) ckmax(stor[p.f].f,mn[t]+1); // goes up
		else ckmin(stor[p.f].s,mid-mn[t]);
		// ps("AH",stor[p.f]);
	}
	pi P = stor[p.f]; if (p.s) P = {mid+1-P.s,mid+1-P.f};
	pi ban = {MOD,-MOD};
	int LL = P.f, RR = P.s;
	FOR(i,1,sz(todo)) {
		pi z = stor[todo[i]];
		if (z.f > z.s) { bad = 1; return; }
		pi Z = {mid+1-z.s,mid+1-z.f};
		if (z > Z) swap(z,Z);
		ckmax(LL,z.f), ckmin(RR,Z.s);
		if (z.s+1 < Z.f) { ckmin(ban.f,z.s+1), ckmax(ban.s,Z.f-1); }
	}
	if (LL > RR) { bad = 1; return; }
	int val;
	// ps("HAHA",LL,RR,ban);
	if (LL < ban.f) val = LL;
	else if (LL > ban.s) val = LL;
	else if (ban.s < RR) val = ban.s+1;
	else { bad = 1; return; }
	mn[x] = val; tmpPar[p.f] = p.s;
	FOR(i,1,sz(todo)) {
		pi t = stor[todo[i]];
		//ps("OH",t);
		if (t.f <= val && val <= t.s) {
			tmpPar[todo[i]] = 0;
		} else {
			// assert(mid+1-t.s.s <= val && val <= mid+1-t.s.f);
			tmpPar[todo[i]] = 1;
		}
	}
	if (fin) {
		trav(t,L.adj[x]) if (t != L.par[0][x]) {
			pi p = D.get(t);
			par[t] = tmpPar[p.f]^p.s;
			//ps("HAHA",t,par[t]);
		}

	}
}

bool ok() {
	bad = 0; dfs(1);
	return !bad;
}

void genAns(int x) {
	if (par[x] == 0) {
		c[x] = mn[x];
	} else {
		c[x] = mid+1-mn[x];
	}
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		par[t] ^= par[x];
		genAns(t);
	}
}

int ad[MX];
void path(int a, int b) {
	// ps("OH",a,b);
	int x = L.lca(a,b);
	int A,B;
	if (a != x) {
		A = L.getPar(a,L.depth[a]-L.depth[x]-1);
		ad[a] ++; ad[A] --;
	}
	if (b != x) {
		B = L.getPar(b,L.depth[b]-L.depth[x]-1);
		ad[b] ++; ad[B] --;
	}
	if (a != x && b != x) {
		D.unite(A,B,1);
	}
}

void genAd(int x) {
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		genAd(t);
		ad[x] += ad[t];
	}
	if (ad[x]) {
		D.unite(x,L.par[0][x],0);
	}
}

/**
 * Description: Fast input and output.
 * Time: input is $\sim$300ms faster for $10^6$ long longs on CF
 * Source:
 	* https://codeforces.com/gym/102394/submission/64154785
 	* https://codeforces.com/contest/1254/submission/65420506 (neal)
 	* https://codeforces.com/blog/entry/45835 (AI.Cash)
 * Verification: https://codeforces.com/gym/102394/problem/G
 */

namespace FastIO {
	const int BSZ = 1<<15; ////// INPUT
	char ibuf[BSZ]; int ipos, ilen;
	char nc() { // next char
		if (ipos == ilen) {
			ipos = 0; ilen = fread(ibuf,1,BSZ,stdin);
			if (!ilen) return EOF;
		}
		return ibuf[ipos++];
	}
	void rs(str& x) { // read str
		char ch; while (isspace(ch = nc()));
		do { x += ch; } while (!isspace(ch = nc()) && ch != EOF);
	}
	template<class T> void ri(T& x) { // read int or ll
		char ch; int sgn = 1;
		while (!isdigit(ch = nc())) if (ch == '-') sgn *= -1;
		x = ch-'0'; while (isdigit(ch = nc())) x = x*10+(ch-'0');
		x *= sgn;
	}
	template<class T, class... Ts> void ri(T& t, Ts&... ts) {
		ri(t); ri(ts...); } // read ints
	////// OUTPUT (call initO() at start)
	char obuf[BSZ], numBuf[100]; int opos;
	void flushOut() { fwrite(obuf,1,opos,stdout); opos = 0; }
	void wc(char c) { // write char
		if (opos == BSZ) flushOut();
		obuf[opos++] = c; }
	void ws(str s) { trav(c,s) wc(c); } // write str
	template<class T> void wi(T x, char after = '\0') { /// write int
		if (x < 0) wc('-'), x *= -1;
		int len = 0; for (;x>=10;x/=10) numBuf[len++] = '0'+(x%10);
		wc('0'+x); R0F(i,len) wc(numBuf[i]);
		if (after) wc(after);
	}
	void initO() { assert(atexit(flushOut) == 0); } /// auto-flush output
}
using namespace FastIO;
/// initO(); int a,b; ri(a,b); wi(b,'\n'); wi(a,'\n');

void init() {
	initO();
	ri(n,m); D.init(n+1);
	F0R(i,n-1) {
		int a,b; ri(a,b);
		L.ae(a,b);
	}
	L.init(n);
	F0R(i,m) {
		int a,b; ri(a,b);
		path(a,b);
	}
	// FOR(i,1,n+1) ps(i,ad[i]);
	genAd(1);
}

int main() {
	init();
	mid = n; // assert(ok());
	// exit(0);
	int lo = 1, hi = n;
	while (lo < hi) {
		mid = (lo+hi)/2;
		if (ok()) hi = mid;
		else lo = mid+1;
	}
	mid = lo;
	fin = 1;
	assert(ok());
	ps(mid);
	genAns(1);
	FOR(i,1,n+1) {
		if (i < n) wi(c[i],' ');
		else wi(c[i],'\n');
	}
	// you should actually read the stuff at the bottom
}

/* stuff you should look for
	* int overflow, array bounds
	* special cases (n=1?)
	* do smth instead of nothing and stay organized
	* WRITE STUFF DOWN
*/

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

#define FAST ios_base::sync_with_stdio(false); cin.tie(0);
#define pb push_back
#define eb emplace_back
#define ins insert
#define f first
#define s second
#define cbr cerr<<"hi\n"
#define mmst(x, v) memset((x), v, sizeof ((x)))
#define siz(x) ll(x.size())
#define all(x) (x).begin(), (x).end()
#define lbd(x,y) (lower_bound(all(x),y)-x.begin())
#define ubd(x,y) (upper_bound(all(x),y)-x.begin())
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());    //can be used by calling rng() or shuffle(A, A+n, rng)
inline long long rand(long long x, long long y) { return rng() % (y+1-x) + x; } //inclusivesss
string inline to_string(char c) {string s(1,c);return s;} template<typename T> inline T gcd(T a,T b){ return a==0?llabs(b):gcd(b%a,a); }

using ll=int;
using ld=long double;
#define FOR(i,s,e) for(ll i=s;i<=ll(e);++i)
#define DEC(i,s,e) for(ll i=s;i>=ll(e);--i)
using pi=pair<ll,ll>; using spi=pair<ll,pi>; using dpi=pair<pi,pi>;

// #define LLINF ((long long)1e18)
#define INF int(1e9+1e6)
#define MAXN (500006)
ll n, m, mi[MAXN], st[MAXN], en[MAXN], co, p[MAXN][19], stuff[MAXN], depth[MAXN], done, ans[MAXN], tmp[MAXN];
pi store[MAXN];
vector<int> v[MAXN];
struct ufds_ {
	pi p[MAXN];
	ufds_() { FOR(i,0,MAXN-1) p[i]=pi(i,0); }
	pi find(int x){
		if(p[x].f==x) return p[x];
		pi res=find(p[x].f);
		p[x].s ^= res.s;
		return pi(p[x].f = res.f, p[x].s);
	}
	void merge(int x,int y,int c){
		pi one=find(x), two=find(y);
		if(one.f==two.f){
			if((one.s ^ two.s) != c) {
				cout<<"-1\n";
				exit(0);
			}
		}else{
			p[two.f]=pi(one.f,two.s^one.s^c);
		}
	}
} u;
void dfs(int x,int par){
	p[x][0]=par;
	st[x]=co++;
	for(auto i:v[x]) if(i^par) depth[i]=depth[x]+1, dfs(i, x);
	en[x]=co-1;
}
bool isp(int a,int b) { return st[a] <= st[b] && en[a] >= en[b]; }
int lca(int x,int y){
	if(isp(x,y))return x;
	if(isp(y,x))return y;
	DEC(i,18,0)if(!isp(p[x][i],y))x=p[x][i];
	return p[x][0];
}
int fpar(int x,int k){
	FOR(i,0,18)if(1<<i&k)x=p[x][i];
	return x;
}
bool yes;
void dp(int x,int mid){
	if(!yes) return;
	for(auto i:v[x]) if(i^p[x][0]) {
		dp(i, mid); if(!yes) return;
	}
	for(auto i:v[x]) if(i^p[x][0]) {
		store[u.find(i).f].f = -1;
	}
	vector<int> ppl={x};
	store[u.find(x).f] = pi(1, mid);
	for(auto i:v[x]) if(i^p[x][0]) {
		ll guy=u.find(i).f;
		if(store[guy].f == -1){
			store[guy] = pi(1, mid);
			ppl.eb(i);
		}
		if(u.find(i).s) store[guy].s=min(store[guy].s, mid-mi[i]);
		else store[guy].f=max(store[guy].f, mi[i]+1);
	}
	pi me = store[u.find(x).f];
	if(u.find(x).s) me=pi(mid-me.s+1, mid-me.f+1);
	ll L=me.f, R=me.s;
	pi ban = pi(n+1, 0);
	for(auto i:ppl) {
		pi me = store[u.find(i).f];
		if(me.f > me.s) { yes=0; return; }
		pi rev = pi(mid-me.s+1, mid-me.f+1);
		if(me > rev) swap(me, rev);
		L = max(L, me.f);
		R = min(R, rev.s);
		if(me.s+1 < rev.f) ban.f=min(ban.f, me.s+1), ban.s=max(ban.s, rev.f-1);
	}
	if(L > R) { yes=0; return; }
	if(L < ban.f) mi[x]=L;
	else if(L > ban.s) mi[x]=L;
	else if(R > ban.s) mi[x]=ban.s+1;
	else { yes=0; return; }
	if(done){
		tmp[u.find(x).f]=u.find(x).s;
		for(auto i:ppl) {
			if(i == x) continue;
			pi guy=u.find(i);
			if(store[guy.f].f <= mi[x] && mi[x] <= store[guy.f].s) {
				tmp[guy.f]=0;
			}else{
				tmp[guy.f]=1;
			}
		}
		for(auto i:v[x]) if(i^p[x][0]) {
			ans[i]=tmp[u.find(i).f]^u.find(i).s;
		}
	}
}
int main(){
	FAST
	cin>>n>>m;
	FOR(i,0,n-2){
		int a,b;
		cin>>a>>b;
		v[a].eb(b),v[b].eb(a);
	}
	dfs(1,1);
	FOR(j,1,18) FOR(i,1,n) p[i][j]=p[p[i][j-1]][j-1];
	FOR(i,0,m-1){
		int a,b;
		cin>>a>>b;
		int la=lca(a,b);
		if(a^la){
			int A=fpar(a,depth[a]-depth[la]-1);
			++stuff[a],--stuff[A];
		}
		if(b^la){
			int B=fpar(b,depth[b]-depth[la]-1);
			++stuff[b],--stuff[B];
		}
		if(a!=la&&b!=la){
			u.merge(a,b,1);
		}
	}
	function<void(ll)>go=[&](ll x){
		for(auto i:v[x]) if(i^p[x][0]){
			go(i);
			stuff[x]+=stuff[i];
		}
		if(stuff[x]){
			u.merge(x,p[x][0],0);
		}
	};
	go(1);
	auto bstar=[&](int mid){
		yes=1, dp(1, mid);
		return yes;
	};
	ll st=0, en=n;
	while(en-st>1){
		ll mid=(st+en)>>1;
		if(bstar(mid))en=mid;
		else st=mid;
	}
	cout<<en<<'\n';
	done=1;
	assert(bstar(en));
	function<void(ll)>get_ans=[&](ll x){
		if(ans[x]) mi[x]=en+1-mi[x];
		for(auto i:v[x]) if(i^p[x][0]) {
			ans[i]^=ans[x];
			get_ans(i);
		}
	};
	get_ans(1);
	FOR(i,1,n) cout<<mi[i]<<' '; cout<<'\n';
}

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
#define ll long long
#define lb(x) ((x)&(-x))
#define pii pair<int,int>
#define vi vector<int>
#define pb push_back
#define fi first
#define se second
#define de(x) cout<<x<<" x"<<endl
#define LCAFA rep(i,1,20)rep(j,1,n+1)fa[j][i]=fa[fa[j][i-1]][i-1]
#define all(x) x.begin(),x.end()
#define ls(x) x<<1
#define rs(x) x<<1|1
using namespace std;
const int N=5e5+9;
const ll mod=998244353;
int n,m;
vi g[N];
namespace dsu{
	int fa[N],v[N];
	int find(int x){
		if(fa[x]==x)return x;
		int f=fa[x];
		fa[x]=find(f);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		rep(i,1,n+1)fa[i]=i,v[i]=0;
	}
	void merge(int x,int y,int vv){
		int px=find(x),py=find(y);
		if(px==py){
			if(v[x]^v[y]^vv){
				printf("-1");
				exit(0);
			}
		}
		else{
			fa[px]=py;
			v[px]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int fa[N],S[N],SS[N],sz[N],top[N],dfn[N],pos[N],dep[N];
	void dfs(int u){
		sz[u]=1;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			dep[v]=dep[u]+1,fa[v]=u;
			dfs(v);sz[u]+=sz[v];
		}
	}
	void dfs2(int u,int tp){
		top[u]=tp;dfn[u]=++*dfn;pos[*dfn]=u;
		int k=0;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			if(sz[v]>sz[k])k=v;
		}
		if(k)dfs2(k,tp);
		for(auto v:g[u]){
			if(v==fa[u]||v==k)continue;
			dfs2(v,v);
		}
	}
	void build(){
		dfs(1);dfs2(1,1);
	}
	int LCA(int u,int v){
		for(;top[u]!=top[v];u=fa[top[u]]){
			if(dep[top[u]]<dep[top[v]])swap(u,v);
		}
		return dep[u]<dep[v]?u:v;
	}
	int jmp(int x,int f){
		for(;;){
			if(dep[top[x]]==dep[top[f]])return pos[dfn[f]+1];
			if(dep[top[x]]==dep[f]+1)return top[x];
			x=fa[top[x]];
		}
	}
	void cont(int u,int v){
		int f=LCA(u,v);
		++S[u],++S[v],S[f]-=2;
		if(u^f)++SS[u],--SS[u=jmp(u,f)];
		if(v^f)++SS[v],--SS[v=jmp(v,f)];
		if((u^f)&&(v^f))dsu::merge(u,v,1);
	}
	void build2(){
		per(i,1,n+1){
			int u=pos[i];
			S[fa[u]]+=S[u];
			SS[fa[u]]+=SS[u];
			if(SS[u])dsu::merge(u,fa[u],0);
		}
	}
}
int q[N],dp[N],v0[N],v1[N],T,vis[N],tag[N],c[N];
bool check(int K){
	per(i,1,n+1){
		int u=TR::pos[i],f=TR::fa[u];
		*q=0;++T;
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::find(v);
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		int vl=0,vr=0;
		if(T==vis[dsu::fa[u]]){
			int x=dsu::fa[u];
			vl=v0[x],vr=v1[x];
			if(dsu::v[u])swap(vl,vr);
		}
		int vmn=0,vmx=0;
		rep(j,1,(*q)+1){
			if(dsu::fa[u]!=q[j]){
				if(v0[q[j]]>v1[q[j]])swap(v0[q[j]],v1[q[j]]);
				vmn=max(vmn,v0[q[j]]);
				vmx=max(vmx,v1[q[j]]);
			}
		}
		if(max(vmn,min(vl,vr))+max(vmx,max(vl,vr))>=K)return 0;
		dp[u]=(max(vmn,vl)+max(vmx,vr)>=K?max(vmx,vl):max(vmn,vl))+1;
	}
	return 1;
}
void construct(int K){
	rep(i,1,n+1){
		int u=TR::pos[i],f=TR::fa[u];
		*q=0;++T;
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[v];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		rep(j,1,(*q)+1){
			c[q[j]]=tag[u];
			if(q[j]!=dsu::fa[u])c[q[j]]^=(v0[q[j]]>dp[u]-1||v1[q[j]]+dp[u]>K);
			else c[q[j]]^=dsu::v[u];
		}
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			tag[v]=c[dsu::fa[v]]^dsu::v[v];
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	rep(i,1,n){
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);g[v].pb(u);
	}
	TR::build();dsu::build();
	rep(i,0,m){
		int u,v;
		scanf("%d%d",&u,&v);
		TR::cont(u,v);
	}
	TR::build2();
	rep(i,1,n+1)dsu::find(i);
	int l=1,r=n;
	while(l<r){
		int mid=l+r>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	check(l);
	construct(l);
	printf("%d\n",l);
	rep(i,1,n+1)printf("%d ",!tag[i]?dp[i]:l+1-dp[i]);
}

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
#define ll long long
#define lb(x) ((x)&(-x))
#define pii pair<int,int>
#define vi vector<int>
#define pb push_back
using namespace std;
const int N=5e5+9;
const ll mod=998244353;
vi g[N];
int n,m;
namespace dsu{
	int fa[N],v[N];
	int find(int x){
		if(fa[x]==x)return x;
		int f=fa[x];
		fa[x]=find(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		rep(i,1,n+1)fa[i]=i;
	}
	void merge(int x,int y,int vv){
		int fx=find(x),fy=find(y);
		if(fx==fy){
			if(v[x]^v[y]^vv){
				printf("-1");
				exit(0);
			}
		}
		else{
			fa[fx]=fy;
			v[fx]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N],fa[N];
	int top[N],pos[N];
	int dfn[N],dep[N],sz[N];
	void dfs(int u){
		sz[u]=1;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			fa[v]=u;dep[v]=dep[u]+1;
			dfs(v);sz[u]+=sz[v];
		}
	}
	void dfs2(int u,int tp){
		top[u]=tp;dfn[u]=++*dfn;pos[*dfn]=u;
		int k=0;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			if(sz[v]>sz[k])k=v;
		}
		if(k)dfs2(k,tp);
		for(auto v:g[u]){
			if(v==fa[u]||v==k)continue;
			dfs2(v,v);
		}
	}
	int LCA(int u,int v){
		for(;top[u]!=top[v];u=fa[top[u]]){
			if(dep[top[u]]<dep[top[v]])swap(u,v);
		}
		return dep[u]<dep[v]?u:v;
	}
	int jmp(int x,int f){
		for(;;){
			if(dep[top[x]]<=dep[f])
			return pos[dfn[f]+1];
			if(dep[top[x]]==dep[f]+1)
			return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs(1);dfs2(1,1);
	}
	void build2(){
		per(i,1,n+1){
			int u=pos[i];
			S[fa[u]]+=S[u];
			SS[fa[u]]+=SS[u];
			if(SS[u])dsu::merge(u,fa[u],0);
		}
	}
	void connect(int u,int v){
		int f=LCA(u,v);
		++S[u],++S[v],S[f]-=2;
		if(dep[f]^dep[u])++SS[u],--SS[u=jmp(u,f)];
		if(dep[f]^dep[v])++SS[v],--SS[v=jmp(v,f)];
		if((u^f)&&(v^f))dsu::merge(u,v,1);
	}
}
int v0[N],v1[N],dp[N];
int vis[N],T,tag[N];
int cc[N],q[N];
bool check(int K){
	per(i,1,n+1){
		++T,*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		int vl=0,vr=0;
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[v];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		if(vis[dsu::fa[u]]==T){
			int x=dsu::fa[u];
			vl=v0[x],vr=v1[x];
			if(dsu::v[u])swap(vl,vr);
		}
		int vmn=0,vmx=0;
		rep(j,1,(*q)+1){
			if(dsu::fa[u]!=q[j]){
				if(v0[q[j]]>v1[q[j]])
				swap(v0[q[j]],v1[q[j]]);
				vmn=max(vmn,v0[q[j]]);
				vmx=max(vmx,v1[q[j]]);
			}
		}
		if(max(vmn,min(vl,vr))+max(vmx,max(vl,vr))>=K)return 0;
		dp[u]=(max(vmn,vl)+max(vmx,vr)>=K?max(vmx,vl):max(vmn,vl))+1;
	}
	return 1;
}
void construct(int K){
	rep(i,1,n+1){
		++T;*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[v];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		rep(j,1,(*q)+1){
			cc[q[j]]=tag[u];
			if(dsu::fa[u]!=q[j])
			cc[q[j]]^=(v0[q[j]]>dp[u]-1||v1[q[j]]+dp[u]>K);
			else cc[q[j]]^=dsu::v[u];
		}
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			tag[v]=cc[dsu::fa[v]]^dsu::v[v];
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	rep(i,1,n){
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);g[v].pb(u);
	}
	dsu::build();
	TR::build();
	rep(i,0,m){
		int u,v;
		scanf("%d%d",&u,&v);
		TR::connect(u,v);
	}
	TR::build2();
	rep(i,1,n+1)dsu::find(i);
	int l=1,r=n;
	while(l<r){
		int mid=l+r>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	printf("%d\n",l);
	check(l);
	construct(l);
	rep(i,1,n+1)printf("%d ",tag[i]?l+1-dp[i]:dp[i]);
}

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
const int N=500005;
int n,m;
vector<int> e[N];
namespace DSU{
	int fa[N],v[N];
	int get(int x){
		if (x==fa[x]) return x;
		int f=fa[x];
		fa[x]=get(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		For(i,1,n) fa[i]=i,v[i]=0;
	}
	void merge(int x,int y,int vv){
		int px=get(x),py=get(y);
		if (px==py){
			if (v[x]^v[y]^vv){
				puts("-1");
				exit(0);
			}
		}
		else{
			fa[px]=py;
			v[px]=v[x]^v[y]^vv;
		//	cout<<px<<' '<<v[px]<<"val\n";
		}
	}
}
namespace TR{
	int S[N],SS[N];
	int fa[N],sz[N],dep[N];
	int pos[N],dfn[N],top[N];
	void dfs1(int x){
		sz[x]=1;
		for (auto i:e[x])
			if (i!=fa[x]){
				fa[i]=x;
				dep[i]=dep[x]+1;
				dfs1(i);
				sz[x]+=sz[i];
			}
	}
	void dfs2(int x,int tp){
		dfn[x]=++*dfn;
		pos[*dfn]=x;
		top[x]=tp;
		int k=0;
		for (auto i:e[x])
			if (i!=fa[x]&&sz[i]>sz[k])
				k=i;
		if (k) dfs2(k,tp);
		for (auto i:e[x])
			if (i!=fa[x]&&i!=k)
				dfs2(i,i);
	}
	int LCA(int x,int y){
		for (;top[x]!=top[y];x=fa[top[x]])
			if (dep[top[x]]<dep[top[y]])
				swap(x,y);
		return dep[x]<dep[y]?x:y;
	}
	int jmp(int x,int y){
		for (;;){
			if (dep[top[x]]<=dep[y])
				return pos[dfn[y]+1];
			if (dep[top[x]]==dep[y]+1)
				return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs1(1);
		dfs2(1,1);
	}
	void build2(){
		Rep(i,n,1){
			int x=pos[i];
			S[fa[x]]+=S[x];
			SS[fa[x]]+=SS[x];
			if (SS[x])
				DSU::merge(x,fa[x],0);
		}
	}
	void insert_que(int x,int y){
		int L=LCA(x,y);
		S[x]++; S[y]++; S[L]-=2;
		if (dep[x]^dep[L]) SS[x]++,SS[x=jmp(x,L)]--;
		if (dep[y]^dep[L]) SS[y]++,SS[y=jmp(y,L)]--;
		if ((x^L)&&(y^L)) DSU::merge(x,y,1);
	}
}
int v0[N],v1[N];
int vis[N],f[N],T;
int cc[N],fl[N];
bool check(int K){
//	cout<<K<<"K\n";
	static int q[N];
	Rep(i,n,1){
		int x=TR::pos[i],y=TR::fa[x];
	//	cout<<x<<' '<<y<<"check\n";
		int vl=0,vr=0;
		++T; *q=0;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
			//	cout<<j<<' '<<T<<' '<<c<<' '<<vis[c]<<"vis\n";
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			//	cout<<v0[c]<<' '<<v1[c]<<"v\n";
			}
		if (vis[DSU::fa[x]]==T){
			int c=DSU::fa[x];
			vl=v0[c]; vr=v1[c];
			if (DSU::v[x]) swap(vl,vr);
		//	cout<<vl<<' '<<vr<<"VLR\n";
		}
		int vmn=0,vmx=0;
		For(j,1,*q)
			if (q[j]!=DSU::fa[x]){
				if (v0[q[j]]>v1[q[j]])
					swap(v0[q[j]],v1[q[j]]);
				vmn=max(vmn,v0[q[j]]);
				vmx=max(vmx,v1[q[j]]);
			}
		if (max(vmn,min(vl,vr))+max(vmx,max(vl,vr))>=K) return 0;
		f[x]=(max(vmn,vl)+max(vmx,vr)>=K?max(vmx,vl):max(vmn,vl))+1;
	//	cout<<x<<' '<<f[x]<<"FFF\n\n";
	}
	return 1;
}
void construct(int K){
	static int q[N];
	For(i,1,n){
		int x=TR::pos[i],y=TR::fa[x];
		++T; *q=0;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		For(j,1,*q){
			cc[q[j]]=fl[x];
			if (q[j]!=DSU::fa[x])
				cc[q[j]]^=(v0[q[j]]>f[x]-1||v1[q[j]]+f[x]>K);
			else cc[q[j]]^=DSU::v[x];
		}
		for (auto j:e[x])
			if (j!=y&&TR::S[j])
				fl[j]=cc[DSU::fa[j]]^DSU::v[j];
	}
}
int main(){
	scanf("%d%d",&n,&m);
	For(i,1,n-1){
		int x,y;
		scanf("%d%d",&x,&y);
		e[x].PB(y); e[y].PB(x);
	}
	TR::build();
	DSU::build();
	For(i,1,m){
		int x,y;
		scanf("%d%d",&x,&y);
		TR::insert_que(x,y);
	}
	TR::build2();
	For(i,1,n) DSU::get(i);
	int l=1,r=n,ans=0;
	while (l<=r){
		int mid=(l+r)/2;
		if (check(mid))
			ans=mid,r=mid-1;
		else l=mid+1;
		//system("pause");
	}
	printf("%d\n",ans);
	check(ans);
	construct(ans);
	For(i,1,n) printf("%d ",!fl[i]?f[i]:ans+1-f[i]);
}
/*
10 3
1 2
2 3
3 4
4 5
3 6
6 7
7 8
8 9
9 10
5 2
5 8
9 10
*/

//#pragma GCC target("avx2")
//#pragma GCC optimize("O3")

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

# include <ext/pb_ds/assoc_container.hpp>
# include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define _USE_MATH_DEFINES_
#define ll long long
#define ld long double
#define Accepted 0
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x.size())
#define every(x) x.begin(),x.end()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define For(i,x,y)  for (ll i = x; i <= y; i ++)
#define FOr(i,x,y)  for (ll i = x; i >= y; i --)
#define SpeedForce ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
// ROAD to...                                                                                Red

inline void Input_Output () {
	//freopen(".in", "r", stdin);
   //freopen(".out", "w", stdout);
}

const double eps = 0.000001;
const ld pi = acos(-1);
const int maxn = 1e7 + 9;
const int mod = 1e9 + 7;
const ll MOD = 1e18 + 9;
const ll INF = 1e18 + 123;
const int inf = 2e9 + 11;
const int mxn = 1e6 + 9;
const int N = 6e5 + 123;
const int M = 22;
const int pri = 997;
const int Magic = 2101;

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

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

void fail() {
	cout << "-1\n";
	exit(0);
}

bool rev[N];
int k, timer, p[N];
int dp[N], res[N];
int n, m;
vector < int > g[N];

namespace UnionFind {
	const int MAXN = 1e6 + 5;
	int f[MAXN];
	void init(int n) {
		for (int i = 1; i <= n * 2; i++)
			f[i] = i;
	}
	int find(int x) {
		if (f[x] == x) return x;
		else return f[x] = find(f[x]);
	}
	void merge(int x, int y) {
		x = find(x);
		y = find(y);
		f[x] = y;
	}
	void addedge(int x, int y, bool z) {
		if (z == false) {
			merge(x, y);
			merge(x + n, y + n);
		} else {
			merge(x, y + n);
			merge(x + n, y);
		}
		if (find(x) == find(x + n)) {
			fail();
		}
	}
	pair <int, bool> query(int x) {
		int tmp = find(x);
		if (tmp <= n) return make_pair(tmp, false);
		else return make_pair(tmp - n, true);
	}
	//check biparate
}

namespace DataOFtree{
	const int K = 20;
	int depth[N], up[K][N];
	void work (int ver, int par = 0) {
		depth[ver] = depth[par] + 1;
		up[0][ver] = par;
		for (int i = 1; i < K; ++i)
			up[i][ver] = up[i-1][up[i-1][ver]];
		for (auto to : g[ver]) if (to != par) {
			work(to, ver);
		}
	}

	int lca (int a, int b) {
		if (depth[a] < depth[b]) swap(a, b);
		for (int i = K-1; i >= 0; --i) if (depth[up[i][a]] >= depth[b]) {
			a = up[i][a];
		}
		if (a == b) return a;
		for (int i = K-1; i >= 0; --i) if (up[i][a] != up[i][b]) {
			a = up[i][a];
			b = up[i][b];
		}

		return up[0][a];
	}

	int climb (int a, int b) {
		for (int i = K - 1; i >= 0; --i) if (b & (1 << i)) {
			a = up[i][a];
		}
		return a;
	}
}
void getans () {
	for (int i = 1; i <= n; i ++) {
		int x = p[i];
		if (!rev[x]) res[x] = dp[x];
		else res[x] = k + 1 - dp[x];
		for (auto y : g[x])
			rev[y] ^= rev[x];
	}
}

bool check (int _k) {
	k = _k;
	for (int i = n; i >= 1; i--) {
		int pos = p[i];
		vector <int> points;
		static bool trev[N];
		static pair <int, int> inter[N];
		using namespace UnionFind;
		for (auto x : g[pos]) {
			pair <int, bool> tmp = query(x);
			inter[tmp.first] = make_pair(0, 0);
		}
		pair <int, bool> cur = query(pos);
		points.push_back(cur.first);
		inter[cur.first] = make_pair(1, k);
		for (auto x : g[pos]) {
			pair <int, bool> tmp = query(x);
			if (inter[tmp.first].first == 0) {
				points.push_back(tmp.first);
				inter[tmp.first] = make_pair(1, k);
			}
			if (tmp.second == cur.second) inter[tmp.first].first = max(inter[tmp.first].first, dp[x] + 1);
			else inter[tmp.first].second = min(inter[tmp.first].second, k - dp[x]);
		}
		pair <int, int> ban = make_pair(k + 1, 0);
		int l = inter[cur.first].first, r = inter[cur.first].second;
		for (auto x : points) {
			pair <int, int> a = inter[x];
			pair <int, int> b = make_pair(k + 1 - a.second, k + 1 - a.first);
			if (a.first > a.second) return false;
			if (a > b) swap(a, b);
			l = max(l, a.first);
			r = min(r, b.second);
			if (a.second + 1 < b.first) {
				ban.first = min(ban.first, a.second + 1);
				ban.second = max(ban.second, b.first - 1);
			}
		}
		if (l > r) return false;
		if (l < ban.first || l > ban.second) dp[pos] = l;
		else if (ban.second + 1 <= r) dp[pos] = ban.second + 1;
		else return false;

		for (auto x : points) {
			if (inter[x].first <= dp[pos] && inter[x].second >= dp[pos]) trev[x] = false;
			else trev[x] = true;
		}
		for (auto x : g[pos]) {
			pair <int, bool> tmp = query(x);
			rev[x] = trev[tmp.first] ^ (tmp.second != cur.second);
		}
	}
	return true;
}

int subt[N];

void dfs(int from, int par = 0) {
	p[++timer] = from;
	for (auto to : g[from]) if (to != par) {
		dfs(to, from);
		subt[from] += subt[to];
	}

	if(subt[from]) UnionFind :: addedge(par, from, false);

	for (int i = sz(g[from]) - 1; par > 0 && i >= 0; --i) {
		if(par == g[from][i]) {
			swap(g[from].back(), g[from][i]);
			par = 0;
			g[from].pop_back();
		}
	}
}

int main () {
	SpeedForce;
	cin >> n >> m;
	for (int i = 1; i < n; ++i) {
		int l, r;
		cin >> l >> r;
		g[l].pb(r);
		g[r].pb(l);
	}
	UnionFind :: init(n);
	DataOFtree :: work(1);

	for (int i = 1; i <= m; ++i) {
		using namespace DataOFtree;
		int x, y;
		cin >> x >> y;

		int z = lca(x, y), p, q;
		if (x != z) {
			subt[x]++;
			subt[p = climb(x, depth[x] - depth[z] - 1)]--;
		}
		if (y != z) {
			subt[y]++;
			subt[q = climb(y, depth[y] - depth[z] - 1)]--;
		}
		if (x != z && y != z) {
			UnionFind :: addedge(p, q, true);
		}
	}

	//cout << "here:\n";
	dfs(1);
	int l = 1, r = n;
	while (r - l > 1) {
		int mid = (l + r) >> 1;
		if (check(mid)) r = mid;
		else l = mid;
	}

	cout << r << '\n';
	check(r), getans();

	for (int i = 1; i <= n; i++)
		cout << res[i] << ' ';
	puts("");
	return Accepted;
}

// B...a

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
typedef string str;
typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef pair<db,db> pd;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<db> vd;
typedef vector<str> vs;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<pd> vpd;
#define mp make_pair
#define f first
#define s second
#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
#define ins insert
#define ft front()
#define bk back()
#define pf push_front
#define pb push_back
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound
#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i)
#define R0F(i,a) ROF(i,0,a)
#define trav(a,x) for (auto& a: x)
const int MOD = 1e9+7;
const int MX = 5e5+5;
const ll INF = 1e18;
const ld PI = acos((ld)-1);
const int xd[4] = {1,0,-1,0}, yd[4] = {0,1,0,-1};
template<class T> bool ckmin(T& a, const T& b) {
	return b < a ? a = b, 1 : 0; }
template<class T> bool ckmax(T& a, const T& b) {
	return a < b ? a = b, 1 : 0; }
int pct(int x) { return __builtin_popcount(x); }
int bit(int x) { return 31-__builtin_clz(x); }
int cdiv(int a, int b) { return a/b+!(a<0||a%b == 0); }
namespace input {
	template<class T> void re(complex<T>& x);
	template<class T1, class T2> void re(pair<T1,T2>& p);
	template<class T> void re(vector<T>& a);
	template<class T, size_t SZ> void re(array<T,SZ>& a);
	template<class T> void re(T& x) { cin >> x; }
	void re(double& x) { string t; re(t); x = stod(t); }
	void re(ld& x) { string t; re(t); x = stold(t); }
	template<class T, class... Ts> void re(T& t, Ts&... ts) {
		re(t); re(ts...);
	}
	template<class T> void re(complex<T>& x) { T a,b; re(a,b); x = {a,b}; }
	template<class T1, class T2> void re(pair<T1,T2>& p) { re(p.f,p.s); }
	template<class T> void re(vector<T>& a) { F0R(i,sz(a)) re(a[i]); }
	template<class T, size_t SZ> void re(array<T,SZ>& a) { F0R(i,SZ) re(a[i]); }
}
using namespace input;
namespace output {
	void pr(int x) { cout << x; }
	void pr(long x) { cout << x; }
	void pr(ll x) { cout << x; }
	void pr(unsigned x) { cout << x; }
	void pr(unsigned long x) { cout << x; }
	void pr(unsigned long long x) { cout << x; }
	void pr(float x) { cout << x; }
	void pr(double x) { cout << x; }
	void pr(ld x) { cout << x; }
	void pr(char x) { cout << x; }
	void pr(const char* x) { cout << x; }
	void pr(const string& x) { cout << x; }
	void pr(bool x) { pr(x ? "true" : "false"); }
	template<class T> void pr(const complex<T>& x) { cout << x; }

	template<class T1, class T2> void pr(const pair<T1,T2>& x);
	template<class T> void pr(const T& x);

	template<class T, class... Ts> void pr(const T& t, const Ts&... ts) {
		pr(t); pr(ts...);
	}
	template<class T1, class T2> void pr(const pair<T1,T2>& x) {
		pr("{",x.f,", ",x.s,"}");
	}
	template<class T> void pr(const T& x) {
		pr("{");
		bool fst = 1; for (const auto& a: x) pr(!fst?", ":"",a), fst = 0;
		pr("}");
	}
	void ps() { pr("\n"); }
	template<class T, class... Ts> void ps(const T& t, const Ts&... ts) {
		pr(t); if (sizeof...(ts)) pr(" "); ps(ts...);
	}
	void pc() { pr("]\n"); }
	template<class T, class... Ts> void pc(const T& t, const Ts&... ts) {
		pr(t); if (sizeof...(ts)) pr(", "); pc(ts...);
	}
	#define dbg(x...) pr("[",#x,"] = ["), pc(x);
}
using namespace output;
namespace io {
	void setIn(string s) { freopen(s.c_str(),"r",stdin); }
	void setOut(string s) { freopen(s.c_str(),"w",stdout); }
	void setIO(string s = "") {
		ios_base::sync_with_stdio(0); cin.tie(0);
		if (sz(s)) { setIn(s+".in"), setOut(s+".out"); }
	}
}

using namespace io;

mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());
struct DSU {
	vpi par;
	void init(int n) {
		par.rsz(n);
		F0R(i,n) par[i] = {i,0};
	}
	pi get(int x) {
		if (par[x].f == x) return par[x];
		pi p = get(par[x].f); p.s ^= par[x].s;
		return par[x] = p;
	}
	void unite(int x, int y, int z) {
		pi X = get(x), Y = get(y);
		if (X.f == Y.f) {
			if ((X.s^Y.s) != z) {
				ps(-1);
				exit(0);
			}
		} else {
			par[Y.f] = {X.f,X.s^Y.s^z};
		}
	}
};
template<int SZ> struct LCA {
	static const int BITS = 32-__builtin_clz(SZ);
	int N, R = 1, par[BITS][SZ], depth[SZ];
	vi adj[SZ];
	void ae(int u, int v) { adj[u].pb(v), adj[v].pb(u); }
	void dfs(int u, int prev){
		par[0][u] = prev; depth[u] = depth[prev]+1;
		trav(v,adj[u]) if (v != prev) dfs(v, u);
	}
	void init(int _N) {
		N = _N; dfs(R,0);
		FOR(k,1,BITS) FOR(i,1,N+1)
			par[k][i] = par[k-1][par[k-1][i]];
	}
	int getPar(int a, int b) {
		R0F(k,BITS) if (b&(1<<k)) a = par[k][a];
		return a; }
	int lca(int u, int v){
		if (depth[u] < depth[v]) swap(u,v);
		u = getPar(u,depth[u]-depth[v]);
		R0F(k,BITS) if (par[k][u] != par[k][v])
			u = par[k][u], v = par[k][v];
		return u == v ? u : par[0][u];
	}
	int dist(int u, int v) {
		return depth[u]+depth[v]-2*depth[lca(u,v)]; }
};
LCA<MX> L;
int n,m, mn[MX], c[MX], mid;
bool bad;

DSU D;
bool par[MX], tmpPar[MX];
pi stor[MX];

void dfs(int x) {
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		dfs(t); if (bad) return;
	}
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		stor[D.get(t).f].f = MOD;
	}
	pi p = D.get(x); stor[p.f] = {1,mid};
	vi todo = {p.f};
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		pi p = D.get(t);
		if (stor[p.f].f == MOD) {
			stor[p.f] = {1,mid};
			todo.pb(p.f);
		}
		if (p.s == 0) ckmax(stor[p.f].f,mn[t]+1);
		else ckmin(stor[p.f].s,mid-mn[t]);
	}
	pi P = stor[p.f]; if (p.s) P = {mid+1-P.s,mid+1-P.f};
	pi ban = {MOD,-MOD};
	int LL = P.f, RR = P.s;
	FOR(i,1,sz(todo)) {
		pi z = stor[todo[i]];
		if (z.f > z.s) { bad = 1; return; }
		pi Z = {mid+1-z.s,mid+1-z.f};
		if (z > Z) swap(z,Z);
		ckmax(LL,z.f), ckmin(RR,Z.s);
		if (z.s+1 < Z.f) { ckmin(ban.f,z.s+1), ckmax(ban.s,Z.f-1); }
	}
	if (LL > RR) { bad = 1; return; }
	int val;
	if (LL < ban.f) val = LL;
	else if (LL > ban.s) val = LL;
	else if (ban.s < RR) val = ban.s+1;
	else { bad = 1; return; }
	mn[x] = val; tmpPar[p.f] = p.s;
	FOR(i,1,sz(todo)) {
		pi t = stor[todo[i]];
		if (t.f <= val && val <= t.s) {
			tmpPar[todo[i]] = 0;
		} else {
			tmpPar[todo[i]] = 1;
		}
	}
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		pi p = D.get(t);
		par[t] = tmpPar[p.f]^p.s;
	}
}

bool ok() {
	bad = 0; dfs(1);
	return !bad;
}

void genAns(int x) {
	if (par[x] == 0) {
		c[x] = mn[x];
	} else {
		c[x] = mid+1-mn[x];
	}
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		par[t] ^= par[x];
		genAns(t);
	}
}

int ad[MX];
void path(int a, int b) {
	// ps("OH",a,b);
	int x = L.lca(a,b);
	int A,B;
	if (a != x) {
		A = L.getPar(a,L.depth[a]-L.depth[x]-1);
		ad[a] ++; ad[A] --;
	}
	if (b != x) {
		B = L.getPar(b,L.depth[b]-L.depth[x]-1);
		ad[b] ++; ad[B] --;
	}
	if (a != x && b != x) {
		D.unite(A,B,1);
	}
}

void genAd(int x) {
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		genAd(t);
		ad[x] += ad[t];
	}
	if (ad[x]) {
		D.unite(x,L.par[0][x],0);
	}
}
namespace FastIO {
	const int BSZ = 1<<15;
	char ibuf[BSZ]; int ipos, ilen;
	char nc() {
		if (ipos == ilen) {
			ipos = 0; ilen = fread(ibuf,1,BSZ,stdin);
			if (!ilen) return EOF;
		}
		return ibuf[ipos++];
	}
	void rs(str& x) {
		char ch; while (isspace(ch = nc()));
		do { x += ch; } while (!isspace(ch = nc()) && ch != EOF);
	}
	template<class T> void ri(T& x) {
		char ch; int sgn = 1;
		while (!isdigit(ch = nc())) if (ch == '-') sgn *= -1;
		x = ch-'0'; while (isdigit(ch = nc())) x = x*10+(ch-'0');
		x *= sgn;
	}
	template<class T, class... Ts> void ri(T& t, Ts&... ts) {
		ri(t); ri(ts...); }
	char obuf[BSZ], numBuf[100]; int opos;
	void flushOut() { fwrite(obuf,1,opos,stdout); opos = 0; }
	void wc(char c) {
		if (opos == BSZ) flushOut();
		obuf[opos++] = c; }
	void ws(str s) { trav(c,s) wc(c); }
	template<class T> void wi(T x, char after = '\0') {
		if (x < 0) wc('-'), x *= -1;
		int len = 0; for (;x>=10;x/=10) numBuf[len++] = '0'+(x%10);
		wc('0'+x); R0F(i,len) wc(numBuf[i]);
		if (after) wc(after);
	}
	void initO() { assert(atexit(flushOut) == 0); }
}
using namespace FastIO;
void init() {
	initO();
	ri(n,m); D.init(n+1);
	F0R(i,n-1) {
		int a,b; ri(a,b);
		L.ae(a,b);
	}
	L.init(n);
	F0R(i,m) {
		int a,b; ri(a,b);
		path(a,b);
	}
	genAd(1);
}
int main() {
	init();
	mid = n; assert(ok());
	int lo = 1, hi = n;
	while (lo < hi) {
		mid = (lo+hi)/2;
		if (ok()) hi = mid;
		else lo = mid+1;
	}
	mid = lo; assert(ok());
	ps(mid);
	genAns(1);
	FOR(i,1,n+1) {
		if (i < n) wi(c[i],' ');
		else wi(c[i],'\n');
	}
}

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
const int N=500005;
int n,m;
vector<int> e[N];

namespace DSU{
	int fa[N],v[N];
	int get(int x){
		if (x==fa[x]) return x;
		int f=fa[x];
		fa[x]=get(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		For(i,1,n) fa[i]=i,v[i]=0;
	}
	void merge(int x,int y,int vv){
		int px=get(x),py=get(y);
		if (px==py){
			if (v[x]^v[y]^vv){
				puts("-1");
				exit(0);
			}
		}
		else{
			fa[px]=py;
			v[px]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N];
	int fa[N],sz[N],dep[N];
	int pos[N],dfn[N],top[N];
	void dfs1(int x){
		sz[x]=1;
		for (auto i:e[x])
			if (i!=fa[x]){
				fa[i]=x;
				dep[i]=dep[x]+1;
				dfs1(i);
				sz[x]+=sz[i];
			}
	}
	void dfs2(int x,int tp){
		dfn[x]=++*dfn;
		pos[*dfn]=x;
		top[x]=tp;
		int k=0;
		for (auto i:e[x])
			if (i!=fa[x]&&sz[i]>sz[k])
				k=i;
		if (k) dfs2(k,tp);
		for (auto i:e[x])
			if (i!=fa[x]&&i!=k)
				dfs2(i,i);
	}
	int LCA(int x,int y){
		for (;top[x]!=top[y];x=fa[top[x]])
			if (dep[top[x]]<dep[top[y]])
				swap(x,y);
		return dep[x]<dep[y]?x:y;
	}
	int jmp(int x,int y){
		for (;;){
			if (dep[top[x]]<=dep[y])
				return pos[dfn[y]+1];
			if (dep[top[x]]==dep[y]+1)
				return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs1(1);
		dfs2(1,1);
	}
	void build2(){
		Rep(i,n,1){
			int x=pos[i];
			S[fa[x]]+=S[x];
			SS[fa[x]]+=SS[x];
			if (SS[x])
				DSU::merge(x,fa[x],0);
		}
	}
	void insert_que(int x,int y){
		int L=LCA(x,y);
		S[x]++; S[y]++; S[L]-=2;
		if (dep[x]^dep[L]) SS[x]++,SS[x=jmp(x,L)]--;
		if (dep[y]^dep[L]) SS[y]++,SS[y=jmp(y,L)]--;
		if ((x^L)&&(y^L)) DSU::merge(x,y,1);
	}
}
int v0[N],v1[N];
int vis[N],f[N],T;
int cc[N],fl[N];
bool check(int K){
	static int q[N];
	Rep(i,n,1){
		int x=TR::pos[i],y=TR::fa[x];
		int vl=0,vr=0;
		++T; *q=0;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		if (vis[DSU::fa[x]]==T){
			int c=DSU::fa[x];
			vl=v0[c]; vr=v1[c];
			if (DSU::v[x]) swap(vl,vr);
		}
		int vmn=0,vmx=0;
		For(j,1,*q)
			if (q[j]!=DSU::fa[x]){
				if (v0[q[j]]>v1[q[j]])
					swap(v0[q[j]],v1[q[j]]);
				vmn=max(vmn,v0[q[j]]);
				vmx=max(vmx,v1[q[j]]);
			}
		if (max(vmn,min(vl,vr))+max(vmx,max(vl,vr))>=K) return 0;
		f[x]=(max(vmn,vl)+max(vmx,vr)>=K?max(vmx,vl):max(vmn,vl))+1;
	}
	return 1;
}
void construct(int K){
	static int q[N];
	For(i,1,n){
		int x=TR::pos[i],y=TR::fa[x];
		++T; *q=0;
		//cout<<x<<' '<<fl[x]<<endl;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		For(j,1,*q){
			cc[q[j]]=fl[x];
			if (q[j]!=DSU::fa[x])
				cc[q[j]]^=(v0[q[j]]>f[x]-1||v1[q[j]]+f[x]>K);
			else cc[q[j]]^=DSU::v[x];
		}
		for (auto j:e[x])
			if (j!=y&&TR::S[j])
				fl[j]=cc[DSU::fa[j]]^DSU::v[j];
	}
}
int main(){
	scanf("%d%d",&n,&m);
	For(i,1,n-1){
		int x,y;
		scanf("%d%d",&x,&y);
		e[x].PB(y); e[y].PB(x);
	}
	TR::build();
	DSU::build();
	For(i,1,m){
		int x,y;
		scanf("%d%d",&x,&y);
		TR::insert_que(x,y);
	}
	TR::build2();
	For(i,1,n) DSU::get(i);
	int l=1,r=n,ans=0;
	while (l<=r){
		int mid=(l+r)/2;
		if (check(mid))
			ans=mid,r=mid-1;
		else l=mid+1;
	}
	printf("%d\n",ans);
	check(ans);
	construct(ans);
	static int v[N];
	For(i,1,n) printf("%d ",v[i]=(!fl[i]?f[i]:ans+1-f[i]));
	cout<<endl;
	For(i,2,n)
		assert(fl[i]^DSU::v[i]^fl[DSU::fa[i]]^1);
}
/*
限制条件形如连通块。
设f[i]表示限制c[i]>c[fa[i]]的情况下,当前节点的权值可以达到的最小值。

根据每个连通块可以得到限制条件形如:
Vl+1<=vnow<=k-Vr 或 Vr+1<=vnow<=k-Vl
每次总会选择下边界较宽松的一个条件
*/

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
const int N=500005;
int n,m;
vector<int> e[N];
namespace DSU{
	int fa[N],v[N];
	int get(int x){
		if (x==fa[x]) return x;
		int f=fa[x];
		fa[x]=get(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		For(i,1,n) fa[i]=i,v[i]=0;
	}
	void merge(int x,int y,int vv){
		int px=get(x),py=get(y);
		if (px==py){
			if (v[x]^v[y]^vv){
				puts("-1");
				exit(0);
			}
		}
		else{
			fa[px]=py;
			v[px]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N];
	int fa[N],sz[N],dep[N];
	int pos[N],dfn[N],top[N];
	void dfs1(int x){
		sz[x]=1;
		for (auto i:e[x])
			if (i!=fa[x]){
				fa[i]=x;
				dep[i]=dep[x]+1;
				dfs1(i);
				sz[x]+=sz[i];
			}
	}
	void dfs2(int x,int tp){
		dfn[x]=++*dfn;
		pos[*dfn]=x;
		top[x]=tp;
		int k=0;
		for (auto i:e[x])
			if (i!=fa[x]&&sz[i]>sz[k])
				k=i;
		if (k) dfs2(k,tp);
		for (auto i:e[x])
			if (i!=fa[x]&&i!=k)
				dfs2(i,i);
	}
	int LCA(int x,int y){
		for (;top[x]!=top[y];x=fa[top[x]])
			if (dep[top[x]]<dep[top[y]])
				swap(x,y);
		return dep[x]<dep[y]?x:y;
	}
	int jmp(int x,int y){
		for (;;){
			if (dep[top[x]]<=dep[y])
				return pos[dfn[y]+1];
			if (dep[top[x]]==dep[y]+1)
				return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs1(1);
		dfs2(1,1);
	}
	void build2(){
		Rep(i,n,1){
			int x=pos[i];
			S[fa[x]]+=S[x];
			SS[fa[x]]+=SS[x];
			if (SS[x])
				DSU::merge(x,fa[x],0);
		}
	}
	void insert_que(int x,int y){
		int L=LCA(x,y);
		S[x]++; S[y]++; S[L]-=2;
		if (dep[x]^dep[L]) SS[x]++,SS[x=jmp(x,L)]--;
		if (dep[y]^dep[L]) SS[y]++,SS[y=jmp(y,L)]--;
		if ((x^L)&&(y^L)) DSU::merge(x,y,1);
	}
}
int v0[N],v1[N];
int vis[N],f[N],T;
int cc[N],fl[N];
bool check(int K){
	static int q[N];
	Rep(i,n,1){
		int x=TR::pos[i],y=TR::fa[x];
		int vl=0,vr=0;
		++T; *q=0;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		if (vis[DSU::fa[x]]==T){
			int c=DSU::fa[x];
			vl=v0[c]; vr=v1[c];
			if (DSU::v[x]) swap(vl,vr);
		}
		int vmn=0,vmx=0;
		For(j,1,*q)
			if (q[j]!=DSU::fa[x]){
				if (v0[q[j]]>v1[q[j]])
					swap(v0[q[j]],v1[q[j]]);
				vmn=max(vmn,v0[q[j]]);
				vmx=max(vmx,v1[q[j]]);
			}
		if (max(vmn,min(vl,vr))+max(vmx,max(vl,vr))>=K) return 0;
		f[x]=(max(vmn,vl)+max(vmx,vr)>=K?max(vmx,vl):max(vmn,vl))+1;
	}
	return 1;
}
void construct(int K){
	static int q[N];
	For(i,1,n){
		int x=TR::pos[i],y=TR::fa[x];
		++T; *q=0;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		For(j,1,*q){
			cc[q[j]]=fl[x];
			if (q[j]!=DSU::fa[x])
				cc[q[j]]^=(v0[q[j]]>f[x]-1||v1[q[j]]+f[x]>K);
			else cc[q[j]]^=DSU::v[x];
		}
		for (auto j:e[x])
			if (j!=y&&TR::S[j])
				fl[j]=cc[DSU::fa[j]]^DSU::v[j];
	}
}
int main(){
	scanf("%d%d",&n,&m);
	For(i,1,n-1){
		int x,y;
		scanf("%d%d",&x,&y);
		e[x].PB(y); e[y].PB(x);
	}
	TR::build();
	DSU::build();
	For(i,1,m){
		int x,y;
		scanf("%d%d",&x,&y);
		TR::insert_que(x,y);
	}
	TR::build2();
	For(i,1,n) DSU::get(i);
	int l=1,r=n,ans=0;
	while (l<=r){
		int mid=(l+r)/2;
		if (check(mid))
			ans=mid,r=mid-1;
		else l=mid+1;
	}
	printf("%d\n",ans);
	check(ans);
	construct(ans);
	For(i,1,n) printf("%d ",!fl[i]?f[i]:ans+1-f[i]);
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5+5;
typedef pair<int,int> pi;
vector<int> g[N],id[N];
int n,m;
struct UST{
	vector<int> fa,c;
	inline void init(int n){
		fa.resize(n+1);
		c.resize(n+1);
		for(int i=0;i<=n;i++)fa[i] = i;
	}
	inline int find(int x){
		if(fa[x]==x)return x;
		else{
			find(fa[x]); c[x] ^= c[fa[x]]; fa[x] = fa[fa[x]];
			return fa[x];
		}
	}
	inline void mrg(int x,int y){
		find(x),find(y);
		if(fa[x]^fa[y]){
			c[fa[x]]=1^c[x]^c[y];fa[fa[x]]=fa[y];
		}else if(c[x]==c[y]){puts("-1");exit(0);/*no solution.*/}
	}
}us[N];

int p[N];//to calc merge x , fa[x], fa[fa[x]]
int p2[N];//to calc ifedge is occipied
int dep[N],anc[N][20];

inline void adde(int u,int v){g[u].push_back(v);id[u].push_back(-1);}
inline void dfs(int x,int pre){
	anc[x][0]=pre;dep[x] = dep[pre]+1;
	for(int i=1;i<=19;i++)anc[x][i]=anc[anc[x][i-1]][i-1];
	us[x].init(g[x].size());
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v==pre)continue;
		dfs(v,x);
	}
}
vector<pi> opts[N];
inline void perform(int x,int y){
	if(x==y)return;
	if(dep[x]<dep[y])swap(x,y);
	int _x=x;
	p2[x]++,p2[y]++;
	for(int i=19;~i;i--)if(dep[anc[x][i]]>=dep[y])x=anc[x][i];
	if(x!=y){
		p[_x]++,p[y]++;
		for(int i=19;~i;i--){
			if(anc[x][i]!=anc[y][i])x=anc[x][i],y=anc[y][i];
		}p[x]--,p[y]--;
		opts[anc[x][0]].push_back(pi(x,y));
		p2[anc[x][0]]-=2;
	}else{
		x=_x;p[x]++;for(int i=19;~i;i--)if(dep[anc[x][i]]>dep[y])x=anc[x][i];p[x]--;
		p2[y]-=2;
	}
}
int K,f[N],temp_id[N];
bool FLAG;
vector<int> h[N][2];
inline void pref(int x,int pre){
	for(int j=0;j<2;j++)h[x][j].resize(g[x].size());
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v==pre)continue;
		pref(v,x);p[x]+=p[v];p2[x]+=p2[v];
	}
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];
		if(v==pre&&p2[x])id[x][i]=i;
		else if(p2[v])id[x][i]=i;
	}
	for(size_t i=0;i<g[x].size();i++){int v=g[x][i];temp_id[v]=id[x][i];}
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v!=pre&&p[v]){
			us[x].mrg(temp_id[v],temp_id[pre]);
		}
	}
	for(size_t i=0;i<opts[x].size();i++){
		int a=opts[x][i].first,b=opts[x][i].second;
		us[x].mrg(temp_id[a],temp_id[b]);
	}
	for(size_t i=0;i<g[x].size();i++){
		if(id[x][i]!=-1){
			us[x].find(id[x][i]);
		}
	}
}/* to make the union set */
int dir[N];
inline void Dp(int x,int pre){
	f[x]=1;
	for(int i=0;i<(int)g[x].size();i++)h[x][0][i]=h[x][1][i]=0;
	int qwq[2]={0,0};
	int idd=-1,cidd=0;
	for(size_t i=0;i<g[x].size();i++){
		if(g[x][i]==pre){
			if(id[x][i]!=-1)idd=us[x].fa[id[x][i]],cidd=us[x].c[id[x][i]];
		}
	}
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v==pre)continue;
		Dp(v,x);
		if(id[x][i]!=-1){
			if(us[x].fa[id[x][i]]==idd){
				dir[v]=(us[x].c[id[x][i]]==cidd);
				if(us[x].c[id[x][i]]!=cidd)qwq[0]=max(qwq[0],f[v]);
				else qwq[1]=max(qwq[1],f[v]);
			}
			else{
				h[x][us[x].c[id[x][i]]][us[x].fa[id[x][i]]]=max(h[x][us[x].c[id[x][i]]][us[x].fa[id[x][i]]],f[v]);
			}
		}
	}
	int qaq[2]={0,0};
	for(size_t i=0;i<g[x].size();i++){
		int a=min(h[x][0][i],h[x][1][i]), b=max(h[x][0][i],h[x][1][i]);
		qaq[0]=max(qaq[0],a);
		qaq[1]=max(qaq[1],b);
	}
	int type=0;
	if(max(qaq[0],qwq[0])+max(qwq[1],qaq[1])<K){
		f[x]=max(qaq[0],qwq[0])+1;
	}
	else{
		type=1;
		if(max(qaq[1],qwq[0])+max(qwq[1],qaq[0])<K)f[x]=max(qaq[1],qwq[0])+1;
		else FLAG=0,f[x]=1;
	}
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v==pre)continue;
		if(id[x][i]!=-1){
			if(us[x].fa[id[x][i]]==idd)continue;
			int idx = us[x].fa[id[x][i]], c = us[x].c[id[x][i]];
			int cc = c^(h[x][0][idx]>h[x][1][idx])^type;
			dir[v]=cc;
		}
	}
}

inline bool check(int k){
	K=k,FLAG=1;
	Dp(1,0);
	return FLAG;
}

bool t[N];
int ans[N];

inline void getans(int x,int pre){
	ans[x]=t[x]?K+1-f[x]:f[x];
	for(size_t i=0;i<g[x].size();i++){
		if(g[x][i]==pre)continue;
		t[g[x][i]]=t[x]^dir[g[x][i]];
		getans(g[x][i],x);
	}
}

int main()
{
	cin >> n >> m;
	for(int i=1;i<n;i++){
		int u,v;scanf("%d%d",&u,&v);
		adde(u,v),adde(v,u);
	}
	dfs(1,0);
	for(int i=1;i<=m;i++){
		int u,v;scanf("%d%d",&u,&v);
		perform(u,v);
	}
	pref(1,0);
	int l=1,r=n;
	while(l<r){
		int mid = (l+r)>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	cout << l << endl;
	check(l);
	getans(1,0);
	for(int i=1;i<=n;i++)printf("%d ",ans[i]);
	puts("");return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
//	cout<<k<<":"<<endl;
	for(int i=1;i<=q[0];i++){
//		cout<<ft[q[i]]<<"ssss"<<" "<<endl;
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),bfg(0),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i);
				if(dp[u]-1>=va&&vb+dp[u]<=d) bfg(1);
				else if(dp[u]-1>=vb&&va+dp[u]<=d) bfg(0);
//				else cout<<"fail"<<endl;
			}
//		if(u==75723&&d==10002) cout<<col[gt[52059]]<<" "<<col[gt[72973]]<<endl;
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1; int pt,qt;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		if(i==1) pt=u,qt=t;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
//	if(ans==10002){
//		int c=lca(pt,qt);
//		cout<<jmp(pt,dep[pt]-dep[c]-1)<<endl;
//		cout<<jmp(qt,dep[qt]-dep[c]-1)<<endl;
//		cout<<c<<endl;
//		cout<<endl;
//
//	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}

#ifndef LOCAL
#define NDEBUG 1
#endif
#include<bits/stdc++.h>

std::vector<std::vector<int>> add;

void add_edge(int u,int v){
	add[u].push_back(v);
	add[v].push_back(u);
}

std::vector<int> depth;
std::vector<int> par;
std::vector<int> subtreeSize;
std::vector<int> postOrder;

void dd(int x,int parx=-1){
	par[x]=parx;
	//subtree_size[x]=1;
	for(int y:add[x]){
		//add[y].erase(std::find(begin(add[y]),end(add[y]),x));
		if(y==parx) continue;

		depth[y]=depth[x]+1;
		dd(y,x);
		//subtree_size[x]+=subtree_size[y];
	}
	postOrder.push_back(x);
}

std::vector<std::vector<int>> jt;

void init_jt(){
	jt.push_back(par);
	for(;;){
		bool useful=false;
		auto const& a=jt.back();
		auto b=a;
		for(auto& x:b)if(x>=0){
			if((x=a[x])>=0)
				useful=true;
		}
		if(useful)
			jt.push_back(std::move(b));
		else
			break;
	}
}

struct lca_result {
	int u1,v1,lca; // u1,v1: child of lca int the direction of u/v resp.
	// int case lca is u or v, both u1 and v1 are int the direction of the node != lca
};

lca_result lca(int u,int v){
	assert(u!=v);

	bool swapped;
	if((swapped=(depth[u]<depth[v])))std::swap(u,v);

	int ddepth=depth[u]-depth[v];
	if(ddepth){
		--ddepth;
		for(;ddepth;ddepth^=ddepth&-ddepth){
			u=jt[__builtin_ctz(ddepth)][u];
		}
		assert(depth[u]-1==depth[v]);
		if(jt[0][u]==v)return {u,u,v};
		u=jt[0][u];
	}
	assert(u!=v);
	for(auto layer=jt.size();layer--;){
		if(jt[layer][u]!=jt[layer][v])
			std::tie(u,v)=std::make_pair(jt[layer][u],jt[layer][v]);
	}
	assert(jt[0][u]==jt[0][v]);
	if(swapped)std::swap(u,v);
	assert(u!=v);
	return {u,v,jt[0][u]};
}

std::vector<int> tail; // tail[x]=y => path (x... y) have the same direction
std::vector<std::vector<std::pair<int, int>>> pairs;
// [u, v] in pairs[lca] => (edge (u, lca) is up) xor (edge (v, lca) is up)

int main(){
	std::ios::sync_with_stdio(0);std::cin.tie(0);
	int numNode, numPath; std::cin>>numNode>>numPath;

	add.resize(numNode);
	for(int z=numNode-1;z--;){
		int u,v;
		std::cin>>u>>v;
		--u;--v;
		add_edge(u,v);
	}

	postOrder.reserve(numNode);
	par.resize(numNode); depth.resize(numNode);
	par[0]=-1;
	depth[0]=0;
	dd(0);
	assert((int)postOrder.size()==numNode);
	init_jt();

	tail.resize(numNode);
	std::iota(begin(tail),end(tail), 0);

	auto const updateTail=[&](int v, int u){
		if(depth[u]<depth[tail[v]]) tail[v]=u;
	};

#ifdef LOCAL
	std::vector<std::pair<int, int>> inputPaths;
#endif

	pairs.resize(numNode);
	for(auto _=numPath;_--;){
		int u,v;
		std::cin>>u>>v;
		--u;--v;
		assert(u!=v);
#ifdef LOCAL
		inputPaths.push_back({u, v});
#endif
		auto it=lca(u, v);
		if(it.u1==it.v1){
			if(v==it.lca) std::swap(u, v);
			assert(u==it.lca);
			updateTail(v, u);
		}else{
			updateTail(u, it.lca);
			updateTail(v, it.lca);
			pairs[it.lca].push_back({it.u1, it.v1});
		}
	}

	for(auto node:postOrder){
		assert(depth[tail[node]]<=depth[node]);
		if(tail[node]!=node and tail[node]!=par[node]){
			updateTail(par[node], tail[node]);
			pairs[par[node]].push_back({par[par[node]], node});
		}
	}

	std::vector<std::vector<std::array<std::vector<int>, 2>>> components(numNode);
	// bipartite components
	{
		std::vector<std::vector<int>> subadd(numNode);
		// used for computing `components`
		std::vector<char> color(numNode); // -1, 0 or 1
		std::vector<int> queue; queue.reserve(numNode);

		for(int node=numNode; node--;){
			assert(par[node]==-1 or std::find(begin(add[node]),end(add[node]), par[node])!=end(add[node]));
			for(auto other: add[node]){
				subadd[other].clear();
				color[other]=-1;
			}
			for(auto [first, sec]: pairs[node]){
				subadd[first].push_back(sec);
				subadd[sec].push_back(first);
			}
			assert(components[node].empty());
			for(auto other: add[node]) if(color[other]<0){
				color[other]=0;
				std::array<std::vector<int>, 2> component;
				queue.clear();
				queue.push_back(other);
				component[color[other]=0].push_back(other);
				for(auto iterator=begin(queue); iterator!=end(queue);++iterator){
					assert((int)queue.size()<=numNode);
					auto node=*iterator;
					auto const colorNode=color[node];

					assert(colorNode==0 or colorNode==1);
					assert(std::count(begin(component[colorNode]),end(component[colorNode]), node)==1);
					for(auto other: subadd[node]){
						if(color[other]==colorNode){
							std::cout<<"-1\n";
							return 0;
						}
						if(color[other]<0){
							component[color[other]=not colorNode].push_back(other);
							queue.push_back(other);
						}
					}
				}

				components[node].push_back(std::move(component));
			}

			if(par[node]>=0){ // rearrange the components so [0][0] is the component that contains par[node]
				assert(color[par[node]]!=-1);
				std::swap(components[node][0], *std::find_if(begin(components[node]),end(components[node]),[&](auto const& component){
					return std::any_of(begin(component),end(component),[&](auto const& side){
						return std::find(begin(side),end(side), par[node])!=end(side);
					});
				}));
				auto& component=components[node][0];
				if(std::find(begin(component[0]),end(component[0]), par[node])==end(component[0]))
					std::swap(component[0], component[1]);
				assert(std::find(begin(component[0]),end(component[0]), par[node])!=end(component[0]));
			}
		}
	}

	pairs.clear(); // don't use this anymore, use `components` instead

	std::vector<int> f;
	// f[node] = minimum down length from node,
	// if all paths in that substring has length <= maximumPathLength,
	// and the edge (par[node]..node) points down

	auto const fillF=[&](int maximumPathLength){
		f.assign(numNode, 0);
		for(auto node: postOrder){
			std::vector<std::array<int, 2>> componentLength(components[node].size());
			assert(par[node]==-1 or f[par[node]]==0);
			for(int index=0;index<(int)components[node].size();++index) {
				auto const& component=components[node][index];
				std::array<int, 2> result;
				std::transform(begin(component),end(component), begin(result),
						[&](auto const& side){
							int result=0;
							for(auto node: side) if(tail[node]!=node)
								result=std::max(result, f[node]+1);
							return result;
						});
				if(result[0]+result[1]>maximumPathLength) return false;
				if(index!=0 or par[node]<0){
					std::sort(begin(result),end(result), std::greater<>());
				}else{
					// result[0] must be max up distance, result[1] must be max down distance
				}
				componentLength[index]=result;
			}

			int minimumUp=std::accumulate(begin(componentLength),end(componentLength), 0,
					[](int minimumUp, auto const& componentLength){
						return std::max(minimumUp, std::min(componentLength[0], componentLength[1]));
					});
			if(par[node]>=0){
				minimumUp=std::max(minimumUp, componentLength[0][0]);
				if(tail[node]==node){
					assert(components[node][0][0].size()==1 and
							components[node][0][0][0]==par[node] and
							components[node][0][1].empty());
				}
			}

			std::sort(begin(componentLength),end(componentLength),[&](auto first, auto sec){
				return first[0]>sec[0];
			});
			int maximumDown=std::accumulate(begin(componentLength),end(componentLength), 0,
					[](int maximumDown, auto const& componentLength){
						return std::max(maximumDown, componentLength[1]);
					});
			for(auto [up, down]: componentLength){
				// consider maximumUp = std::max(minimumUp, up),
				// then it's possible that maximumDown == maximumDown
				if(std::max(up, minimumUp)+maximumDown<=maximumPathLength)
					goto okay; // the choice with minimum possible maximumDown

				if(up<minimumUp) return false; // short circuit
				maximumDown=std::max(maximumDown, up /* when swapped */);
			}
			return false;
okay:

			f[node]=maximumDown;
		}
		return true;
	};

	int maximumPathLength=numNode;
	assert(numPath>0);
	for(int step=1<<22; step>>=1;) if(maximumPathLength-step>0 and fillF(maximumPathLength-step)){
		maximumPathLength-=step;
	}
	{
		auto success=fillF(maximumPathLength);
		assert(success);
	}

	std::vector<char> parUp(numNode);
	assert(par[postOrder.back()]==-1);
	std::vector<std::vector<int>> inpath(numNode);
	// b in inpath[a] -> value of b must be larger than value of a

	std::for_each(postOrder.rbegin(), postOrder.rend(),[&](int node){
		int const maximumDownLength=f[node];
		int const maximumUpLength=maximumPathLength-f[node];
		assert(maximumUpLength>=0);

		for(int index=0;index<(int)components[node].size();++index) {
			auto const& component=components[node][index];
			std::array<int, 2> result;
			std::transform(begin(component),end(component), begin(result),
					[&](auto const& side){
						int result=0;
						for(auto it: side) if(tail[it]!=it and it!=par[node])
							result=std::max(result, f[it]+1);
						return result;
					});

			bool swap=false;
			// can exchange up/down
			if(not (result[0]<=maximumUpLength and result[1]<=maximumDownLength)){
				assert(index!=0 or par[node]<0); // can swap freely
				swap=true;
				std::swap(result[0], result[1]);
			}
			assert(result[0]<=maximumUpLength and result[1]<=maximumDownLength);

			for(int index=0;index<2;++index) for(auto it:component[index]) if(it!=par[node]){
				assert(par[it]==node);
				if(tail[it]!=it){
					parUp[it]=bool(parUp[node] xor swap xor index xor 1);
					if(parUp[it]) inpath[it].push_back(node);
					else inpath[node].push_back(it);
				}
			}
		}
	});

	std::vector<int> longestPathLength(numNode); // that ends at this node
	std::vector<int> indegree(numNode);
	for(auto const& it: inpath)
		for(auto const node: it) ++indegree[node];
	std::vector<int> pending;
	for(int node=0;node<numNode;++node)
		if(indegree[node]==0) pending.push_back(node);
	while(not pending.empty()){
		auto node=pending.back(); pending.pop_back();
		auto const nextLongestPathLength=longestPathLength[node]+1;
		for(auto other: inpath[node]){
			--indegree[other];
			longestPathLength[other]=std::max(longestPathLength[other], nextLongestPathLength);
			if(indegree[other]==0) pending.push_back(other);
		}
	}

	assert(maximumPathLength==*std::max_element(begin(longestPathLength),end(longestPathLength)));

	assert(std::all_of(begin(indegree),end(indegree),[&](auto it){return it==0;}));
#ifdef LOCAL
	auto const direction=[&](int node, int ancestor){
		assert(node!=ancestor);
		auto const direction=longestPathLength[node]<longestPathLength[par[node]];
		for(; par[node]!=ancestor; node=par[node]){
			assert(direction==(longestPathLength[node]<longestPathLength[par[node]]));
			assert(longestPathLength[node]!=longestPathLength[par[node]]);
		}
		return direction;
	};
	for(auto [first, sec]: inputPaths){
		auto w=lca(first, sec).lca;
		if(sec==w) std::swap(first, sec);
		if(first==w)
			direction(sec, w);
		else
			%assert(direction(first, w)!=direction(sec, w));
	}
#endif

	std::cout<<maximumPathLength+1<<'\n';
	for(int node=0;node<numNode;++node) std::cout<<longestPathLength[node]+1<<' ';
	std::cout<<'\n';
}

// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <chrono>
#include <random>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <iomanip>
#define dibs reserve
#define OVER9000 1234567890
#define tisic 47
#define soclose 1e-8
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
using uint = unsigned int;
using cat = long long;
using dbl = long double;
constexpr dbl pi = 3.14159265358979323846;
using namespace std;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

void DFS_LCA(int v, auto & G, auto & par, auto & dep, auto & seq) {
	seq.push_back(v);
	for(auto s : G[v]) if(par[s] == -1) {
		par[s] = v;
		dep[s] = dep[v]+1;
		DFS_LCA(s, G, par, dep, seq);
	}
}

void DFS_comp(int v, auto & G, auto & par, auto & dep, auto & up, auto & down,
		auto & comp, auto & comp_l) {
	for(auto s : G[v]) if(par[s] == v) {
		DFS_comp(s, G, par, dep, up, down, comp, comp_l);
		up[v] = min(up[v], up[s]);
	}
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int S = sons.size(), C = 0;
	comp[v].resize(S+1, 0);
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear();
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(i);
		g[i].push_back(S);
	}

	static queue<int> q;
	for(int i = 0; i <= S; i++) if(!comp[v][i]) {
		q.push(i);
		C++;
		comp[v][i] = C;
		comp_l[v].push_back({});
		while(!q.empty()) {
			comp_l[v].back().push_back(q.front());
			int c = comp[v][q.front()];
			for(auto r : g[q.front()]) {
				if(comp[v][r] && comp[v][r] == c) {
					cout << "-1\n";
					exit(0);
				}
				if(comp[v][r]) continue;
				comp[v][r] = -c;
				q.push(r);
			}
			q.pop();
		}
	}
}

void DFS_solve(int v, auto & G, auto & par, auto & dep, auto & up,
		auto & comp, auto & comp_l, auto & I_up, auto & I_dn, int A) {
	for(auto s : G[v]) if(par[s] == v)
		DFS_solve(s, G, par, dep, up, comp, comp_l, I_up, I_dn, A);
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int C = comp_l[v].size(), S = sons.size();

	static vector<int> i_up(par.size());
	for(int i = 0; i < S; i++) i_up[i] = I_up[sons[i]];
	static vector<int> i_dn(par.size());
	for(int i = 0; i < S; i++) i_dn[i] = I_dn[sons[i]];
	static vector<char> ud(par.size());
	for(int i = 0; i < S; i++) ud[i] = (up[sons[i]] <= dep[v]);

	I_up[v] = 0;
	I_dn[v] = A;
	static vector< pair<int, int> > bl;
	bl.clear();
	for(int i = 0; i < C; i++) {
		int up_min_val[2] = {0, 0};
		int dn_max_val[2] = {A, A};
		bool ok[2] = {1, 1};
		for(auto r : comp_l[v][i]) if(r != S) {
			int c = comp[v][r];
			int k = (c > 0) ? 0 : 1;
			if(i_up[r] != -1 && i_up[r] < A)
				up_min_val[1-k] = max(up_min_val[1-k], i_up[r]+1);
			else ok[1-k] = 0;
			if(i_dn[r] != -1 && i_dn[r] > 0)
				dn_max_val[k] = min(dn_max_val[k], i_dn[r]-1);
			else ok[k] = 0;
		}
		if((int)comp_l[v][i].size() == 1) {
			int r = comp_l[v][i][0];
			if(r != S && !ud[r]) {
				if(i_up[r] == -1 && i_dn[r] == -1) {
					I_up[v] = I_dn[v] = -1;
					return;
				}
				continue;
			}
		}
		if(!ok[0] && !ok[1]) {
			I_up[v] = I_dn[v] = -1;
			return;
		}
		if(comp[v][S] != i+1 && comp[v][S] != -i-1) {
			if(up_min_val[0] > dn_max_val[0]) ok[0] = 0;
			if(up_min_val[1] > dn_max_val[1]) ok[1] = 0;
			if(!ok[0]) {
				if(I_up[v] != -1) I_up[v] = max(I_up[v], up_min_val[1]);
				if(I_dn[v] != -1) I_dn[v] = min(I_dn[v], dn_max_val[1]);
			}
			else if(!ok[1]) {
				if(I_up[v] != -1) I_up[v] = max(I_up[v], up_min_val[0]);
				if(I_dn[v] != -1) I_dn[v] = min(I_dn[v], dn_max_val[0]);
			}
			else {
				if(I_up[v] != -1) I_up[v] = max(I_up[v], min(up_min_val[0], up_min_val[1]));
				if(I_dn[v] != -1) I_dn[v] = min(I_dn[v], max(dn_max_val[0], dn_max_val[1]));
				if(up_min_val[0] > dn_max_val[1]+1) bl.push_back({dn_max_val[1]+1, up_min_val[0]-1});
				if(up_min_val[1] > dn_max_val[0]+1) bl.push_back({dn_max_val[0]+1, up_min_val[1]-1});
			}
			continue;
		}
		if(comp[v][S] == i+1) {
			if(I_up[v] != -1) I_up[v] = max(I_up[v], up_min_val[0]);
			if(I_dn[v] != -1) I_dn[v] = min(I_dn[v], dn_max_val[1]);
		}
		else { // comp[S] == -i-1
			if(I_up[v] != -1) I_up[v] = max(I_up[v], up_min_val[1]);
			if(I_dn[v] != -1) I_dn[v] = min(I_dn[v], dn_max_val[0]);
		}
	}

	sort(begin(bl), end(bl));
	pair<int, int> cur = {-1, -1};
	for(auto & p : bl) {
		if(cur.ff == -1) cur = p;
		if(cur.ss < p.ff-1) continue;
		cur.ss = max(cur.ss, p.ss);
		p = cur;
	}
	if(I_up[v] != -1) for(auto p : bl) {
		if(p.ff > I_up[v] || I_up[v] > p.ss) continue;
		I_up[v] = max(I_up[v], p.ss+1);
		if(I_up[v] > A) {
			I_up[v] = -1;
			break;
		}
	}
	if(I_dn[v] != -1) for(auto p : bl) {
		if(p.ff > I_dn[v] || I_dn[v] > p.ss) continue;
		I_dn[v] = min(I_dn[v], p.ff-1);
		if(I_dn[v] < 0) {
			I_dn[v] = -1;
			break;
		}
	}

	// check if valid
	static vector<char> state_up(par.size()+1);
	static vector<char> state_dn(par.size()+1);
	for(int i = 0; i <= C; i++) state_up[i] = state_dn[i] = 3;
	for(int i = 0; i < S; i++) if(ud[i]) {
		if(comp[v][S] == -comp[v][i]) {
			if(i_up[i] >= I_up[v]) I_up[v] = -1;
			if(i_dn[i] <= I_dn[v]) I_dn[v] = -1;
			continue;
		}
		if(comp[v][S] == comp[v][i]) {
			if(i_up[i] >= I_dn[v]) I_dn[v] = -1;
			if(i_dn[i] <= I_up[v]) I_up[v] = -1;
			continue;
		}
		int k = (comp[v][i] < 0), c = (comp[v][i] < 0) ? -comp[v][i] : comp[v][i];
		if(i_dn[i] <= I_up[v]) state_up[c] &= 1<<k;
		if(i_up[i] >= I_up[v]) state_up[c] &= 1<<(1-k);
		if(i_dn[i] <= I_dn[v]) state_dn[c] &= 1<<(1-k);
		if(i_up[i] >= I_dn[v]) state_dn[c] &= 1<<k;
	}
	for(int i = 1; i <= C; i++) if(state_up[i] == 0) I_up[v] = -1;
	for(int i = 1; i <= C; i++) if(state_dn[i] == 0) I_dn[v] = -1;
}

void DFS_reconstruct(int v, auto & G, auto & par, auto & dep,
		auto & up, auto & down, auto & I_up, auto & I_dn, auto & ans, int dir) {
	ans[v] = (dir == 0) ? I_up[v] : I_dn[v];
	vector<int> sons;
	sons.dibs(G[v].size());
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}
	int S = sons.size(), C = 0;
	static vector<int> comp(par.size());
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear(), comp[i] = 0;
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(id[sons[i]]);
		g[id[sons[i]]].push_back(S);
	}

	static queue<int> q;
	static vector<int> dirs(par.size());
	for(int i = 0; i <= S; i++) if(!comp[i]) {
		bool ok_dir[2] = {true, true};
		q.push(i);
		C++;
		comp[i] = C;
		static vector<int> V;
		V.clear();
		while(!q.empty()) {
			V.push_back(q.front());
			int c = comp[q.front()];
			if(q.front() != S) {
				int k = (c < 0);
				if(I_dn[sons[q.front()]] == -1) ok_dir[k] = false;
				if(I_dn[sons[q.front()]] < ans[v]+1) ok_dir[k] = false;
				if(I_up[sons[q.front()]] == -1) ok_dir[1-k] = false;
				if(I_up[sons[q.front()]] > ans[v]-1) ok_dir[1-k] = false;
			}
			for(auto r : g[q.front()]) if(!comp[r]) {
				comp[r] = -c;
				q.push(r);
			}
			q.pop();
		}
		if(i != S && up[sons[i]] >= dep[sons[i]]) {
			if(I_up[sons[i]] != -1 && I_up[sons[i]] < ans[v])
				ans[sons[i]] = I_up[sons[i]], dirs[sons[i]] = 0;
			else
				ans[sons[i]] = I_dn[sons[i]], dirs[sons[i]] = 1;
			continue;
		}
		if(comp[S] != C && comp[S] != -C) {
			int dir_k = ok_dir[1];
			for(auto s : V) if(s != S) {
				int k = (comp[s] < 0);
				dirs[sons[s]] = (k == dir_k);
			}
			continue;
		}
		for(auto s : V) if(s != S) {
			if(comp[s] != comp[S]) dirs[sons[s]] = dir;
			else dirs[sons[s]] = 1-dir;
		}
	}

	for(auto s : G[v]) if(par[s] == v)
		DFS_reconstruct(s, G, par, dep, up, down, I_up, I_dn, ans, dirs[s]);
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cout << fixed << setprecision(10);
	int N, M;
	cin >> N >> M;
	vector< vector<int> > G(N);
	for(int i = 0; i < N-1; i++) {
		int u, v;
		cin >> u >> v;
		G[--u].push_back(--v);
		G[v].push_back(u);
	}

	vector<int> dep(N, 0);
	vector< vector<int> > par(20, vector<int>(N, -1));
	par[0][0] = 0;
	vector<int> DFS_seq, DFS_id(N);
	DFS_LCA(0, G, par[0], dep, DFS_seq);
	for(int i = 0; i < N; i++) DFS_id[DFS_seq[i]] = i;
	vector< vector<int> > G_reordered(N);
	for(int i = 0; i < N; i++)
		for(auto v : G[i])
			G_reordered[DFS_id[i]].push_back(DFS_id[v]);
	G = G_reordered;
	vector<int> dep_reordered(N), par_reordered(N);
	for(int i = 0; i < N; i++) dep_reordered[DFS_id[i]] = dep[i];
	for(int i = 0; i < N; i++) par_reordered[DFS_id[i]] = DFS_id[par[0][i]];
	dep = dep_reordered, par[0] = par_reordered;
	for(int k = 1; k < 20; k++)
		for(int i = 0; i < N; i++)
			par[k][i] = par[k-1][par[k-1][i]];

	vector<int> up(N, N);
	vector< vector< pair<int, int> > > down(N);
	for(int i = 0; i < M; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		u = DFS_id[u], v = DFS_id[v];
		if(dep[u] > dep[v]) swap(u, v);
		int d = dep[v]-dep[u], a = v;
		for(int k = 0; d; k++, d /= 2) if(d&1) a = par[k][a];
		if(a == u) {
			up[v] = min(up[v], dep[u]);
			continue;
		}
		int b = u;
		for(int k = 19; k >= 0; k--)
			if(par[k][a] != par[k][b])
				a = par[k][a], b = par[k][b];
		int l = par[0][a];
		up[u] = min(up[u], dep[l]);
		up[v] = min(up[v], dep[l]);
		down[l].push_back({a, b});
	}
	vector< vector<int> > comp(N);
	vector< vector< vector<int> > > comp_l(N);
	DFS_comp(0, G, par[0], dep, up, down, comp, comp_l);

	int ans_min = 0, ans_max = N+1;
	vector<int> I_up_ans, I_dn_ans;
	while(ans_max-ans_min > 1) {
		int A = (ans_min + ans_max) / 2;
		static vector<int> I_up(N), I_dn(N);
		DFS_solve(0, G, par[0], dep, up, comp, comp_l, I_up, I_dn, A);
		if(I_up[0] != -1 || I_dn[0] != -1) {
			ans_max = A;
			I_up_ans = I_up;
			I_dn_ans = I_dn;
		}
		else ans_min = A;
	}

	if(ans_max == N+1) {
		cout << "-1\n";
		return 0;
	}
	cout << ans_max+1 << "\n";
	// reconstruct
	vector<int> ans(N);
	if(I_up_ans[0] != -1)
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 0);
	else
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 1);
	for(int i = 0; i < N; i++) cout << ans[DFS_id[i]]+1 << ((i == N-1) ? "\n" : " ");
	return 0;
}

// look at my code
// my code is amazing

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

using ll=long long;
//#define int ll

#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#define si(x) int(x.size())
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif

template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}

template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;

using pi=pair<int,int>;
using vi=vc<int>;

template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
	return os<<"{"<<p.a<<","<<p.b<<"}";
}

template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
	os<<"{";
	for(auto e:v)os<<e<<",";
	return os<<"}";
}

#define mp make_pair
#define mt make_tuple
#define one(x) memset(x,-1,sizeof(x))
#define zero(x) memset(x,0,sizeof(x))
#ifdef LOCAL
void dmpr(ostream&os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ";
	dmpr(os,args...);
}
#define dmp2(...) dmpr(cerr,__LINE__,##__VA_ARGS__)
#else
#define dmp2(...) void(0)
#endif

using uint=unsigned;
using ull=unsigned long long;

template<class t,size_t n>
ostream& operator<<(ostream&os,const array<t,n>&a){
	return os<<vc<t>(all(a));
}

template<int i,class T>
void print_tuple(ostream&,const T&){
}

template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
	if(i)os<<",";
	os<<get<i>(t);
	print_tuple<i+1,T,Args...>(os,t);
}

template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
	os<<"{";
	print_tuple<0,tuple<Args...>,Args...>(os,t);
	return os<<"}";
}

template<class t>
void print(t x,int suc=1){
	cout<<x;
	if(suc==1)
		cout<<"\n";
	if(suc==2)
		cout<<" ";
}

ll read(){
	ll i;
	cin>>i;
	return i;
}

vi readvi(int n,int off=0){
	vi v(n);
	rep(i,n)v[i]=read()+off;
	return v;
}

template<class T>
void print(const vector<T>&v,int suc=1){
	rep(i,v.size())
		print(v[i],i==int(v.size())-1?suc:2);
}

string readString(){
	string s;
	cin>>s;
	return s;
}

template<class T>
T sq(const T& t){
	return t*t;
}

//#define CAPITAL
void yes(bool ex=true){
	#ifdef CAPITAL
	cout<<"YES"<<"\n";
	#else
	cout<<"Yes"<<"\n";
	#endif
	if(ex)exit(0);
}
void no(bool ex=true){
	#ifdef CAPITAL
	cout<<"NO"<<"\n";
	#else
	cout<<"No"<<"\n";
	#endif
	if(ex)exit(0);
}
void possible(bool ex=true){
	#ifdef CAPITAL
	cout<<"POSSIBLE"<<"\n";
	#else
	cout<<"Possible"<<"\n";
	#endif
	if(ex)exit(0);
}
void impossible(bool ex=true){
	#ifdef CAPITAL
	cout<<"IMPOSSIBLE"<<"\n";
	#else
	cout<<"Impossible"<<"\n";
	#endif
	if(ex)exit(0);
}

constexpr ll ten(int n){
	return n==0?1:ten(n-1)*10;
}

const ll infLL=LLONG_MAX/3;

#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif

int topbit(signed t){
	return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
	return t==0?-1:63-__builtin_clzll(t);
}
int botbit(signed a){
	return a==0?32:__builtin_ctz(a);
}
int botbit(ll a){
	return a==0?64:__builtin_ctzll(a);
}
int popcount(signed t){
	return __builtin_popcount(t);
}
int popcount(ll t){
	return __builtin_popcountll(t);
}
bool ispow2(int i){
	return i&&(i&-i)==i;
}
ll mask(int i){
	return (ll(1)<<i)-1;
}

bool inc(int a,int b,int c){
	return a<=b&&b<=c;
}

template<class t> void mkuni(vc<t>&v){
	sort(all(v));
	v.erase(unique(all(v)),v.ed);
}

ll rand_int(ll l, ll r) { //[l, r]
	#ifdef LOCAL
	static mt19937_64 gen;
	#else
	static mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count());
	#endif
	return uniform_int_distribution<ll>(l, r)(gen);
}

template<class t>
void myshuffle(vc<t>&a){
	rep(i,si(a))swap(a[i],a[rand_int(0,i)]);
}

template<class t>
int lwb(const vc<t>&v,const t&a){
	return lower_bound(all(v),a)-v.bg;
}

//VERIFY: yosupo
//KUPC2017J
//AOJDSL1A
//without rank
struct unionfind{
	vi p,s;
	int c;
	unionfind(int n=0):p(n,-1),s(n,1),c(n){}
	int find(int a){
		return p[a]==-1?a:(p[a]=find(p[a]));
	}
	//set b to a child of a
	bool unite(int a,int b){
		a=find(a);
		b=find(b);
		if(a==b)return false;
		p[b]=a;
		s[a]+=s[b];
		c--;
		return true;
	}
	bool same(int a,int b){
		return find(a)==find(b);
	}
	int sz(int a){
		return s[find(a)];
	}
};

//AOJGRL4B
template<class t>
vi toposort(vvc<t> g){
	int n=g.size();
	vi a(n);
	rep(i,n)for(auto e:g[i])
		a[e]++;
	queue<int> q;
	rep(i,n)if(a[i]==0)
		q.push(i);
	vi res;
	rep(i,n){
		if(q.empty())return {};
		int v=q.front();q.pop();
		res.pb(v);
		for(auto e:g[v])
			if(--a[e]==0)
				q.push(e);
	}
	return res;
}

//内部でグラフをいじるから in,out を使うときは注意
//VERIFY: yosupo
//CF530F
//CodeChef Persistent Oak
//AOJ GRL5C
template<class E>
struct HLD{
	vvc<E> g;
	int n,rt,cnt;
	vi sub,in,out,par,head,dep;
	int dfs1(int v,int p,int d){
		par[v]=p;
		dep[v]=d;
		g[v].erase(remove(all(g[v]),p),g[v].ed);
		for(auto&e:g[v]){
			sub[v]+=dfs1(e,v,d+1);
			if(sub[g[v][0]]<sub[e])
				swap(g[v][0],e);
		}
		return sub[v];
	}
	void dfs2(int v,int h){
		in[v]=cnt++;
		head[v]=h;
		for(int to:g[v])
			dfs2(to,to==g[v][0]?h:to);
		out[v]=cnt;
	}
	HLD(){}
	HLD(const vvc<E>&gg,int rr):g(gg),n(g.size()),rt(rr),cnt(0),
		sub(n,1),in(n),out(n),par(n,-1),head(n),dep(n){
		dfs1(rt,-1,0);
		dfs2(rt,rt);
	}
	int lca(int a,int b){
		while(head[a]!=head[b]){
			if(dep[head[a]]>dep[head[b]])
				swap(a,b);
			b=par[head[b]];
		}
		if(dep[a]>dep[b])
			swap(a,b);
		return a;
	}
	int len(int a,int b){
		return dep[a]+dep[b]-dep[lca(a,b)]*2;
	}
	bool asde(int a,int b){
		return in[a]<=in[b]&&out[b]<=out[a];
	}
	unionfind uf;
	vi has,dif;
	int k;
	vc<pi> buf;
	int ac(int v){
		return uf.find(v*2)/2;
	}
	vi memo;
	int dfs(int v){
		for(auto to:g[v]){
			memo[to]=dfs(to);
		}
		buf[ac(v)]=pi(0,k);
		for(auto to:g[v]){
			buf[ac(to)]=pi(0,k);
		}
		//if(v==0)dmp(0);
		for(auto to:g[v]){
			int w=memo[to];
			if(w==inf)return inf;
			int i=uf.find(to*2);
			int t=i%2;
			i/=2;
			if(!has[i])continue;
			if(t==0){
				chmax(buf[i].a,w+1);
			}else{
				chmin(buf[i].b,k-w-1);
			}
			/*if(v==0){
				dmp(to);
				dmp(w);
				dmp(buf[ac(1)]);
			}*/
			if(buf[i].b<buf[i].a)return inf;
		}
		rep(waf,2){
			int vac=uf.find(v*2);
			int vt=vac%2;
			vac/=2;
			int lw,up;tie(lw,up)=buf[vac];
			if(vt){
				tie(lw,up)=pi(k-up,k-lw);
			}
			for(auto to:g[v]){
				int i=uf.find(to*2);
				int t=i%2;
				i/=2;
				if(!has[i])continue;
				dif[to]=t;
				if(i==vac){
					dif[to]^=vt;
					continue;
				}
				int l,r;tie(l,r)=buf[i];
				if((k-r<l)^waf){
					tie(l,r)=pi(k-r,k-l);
					dif[to]^=1;
				}
				chmax(lw,l);
				chmin(up,r);
			}
			if(lw<=up){
				dmp2(v,lw,up);
				return lw;
			}
		}
		return inf;
	}
	void geth(int v,int p,int t,vvc<int>&h){
		if(has[ac(v)]){
			if(t==0){
				h[v].pb(p);
			}else{
				h[p].pb(v);
			}
		}
		for(auto to:g[v]){
			geth(to,v,t^dif[to],h);
		}
	}
	void slv(int m){
		uf=unionfind(n*2);
		auto unitesub=[&](int v,int p){
			while(1){
				v=ac(v);
				dmp2(v,p);
				if(dep[v]-dep[p]>=2){
					dmp2(v,par[v]);
					rep(t,2){
						uf.unite(par[v]*2+t,v*2+t);
					}
					v=par[v];
				}else
					break;
			}
		};
		vi ls;
		vc<pi> es;
		rep(_,m){
			int a,b;cin>>a>>b;
			a--;b--;
			int c=lca(a,b);
			unitesub(a,c);
			unitesub(b,c);
			if(a!=c&&b!=c){
				//uf.unite(a*2,b*2+1);
				//uf.unite(a*2+1,b*2);
				es.eb(a,b);
			}
			if(a!=c)ls.pb(a);
			else ls.pb(b);
		}
		for(auto e:es){
			rep(t,2){
				uf.unite(e.a*2+t,e.b*2+1-t);
			}
		}
		has.resize(n);
		for(auto i:ls)
			has[ac(i)]=1;
		rep(i,n)if(uf.same(i*2,i*2+1)){
			print(-1);
			return;
		}
		dif.resize(n);
		buf.resize(n);
		memo.resize(n);

		/*{
			k=1;
			dfs(0);
			exit(0);
		}*/

		int lw=-1,up=n-1;
		while(up-lw>1){
			const int mid=(lw+up)/2;
			k=mid;
			if(dfs(0)<inf)
				up=mid;
			else
				lw=mid;
		}
		k=up;
		dmp(k);
		int tmp=dfs(0);
		dmp2(k,tmp);
		assert(tmp<inf);

		dmp(dif);

		vvc<int> h(n);
		geth(0,-1,0,h);
		dmp(h);
		dmp(has[ac(1)]);
		dmp(has[ac(2)]);

		vi ans(n);

		vi ord=toposort(h);
		for(auto i:ord){
			for(auto j:h[i])
				chmax(ans[j],ans[i]+1);
		}

		for(auto&v:ans)v++;
		print(k+1);
		print(ans);
	}
};

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);

	int n,m;cin>>n>>m;
	vvc<int> t(n);
	rep(_,n-1){
		int a,b;cin>>a>>b;
		a--;b--;
		t[a].pb(b);
		t[b].pb(a);
	}

	HLD<int> hld(t,0);
	hld.slv(m);
}

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 5e5 + 5;
typedef long long ll;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
int n, m; vector <int> a[MAXN];
namespace LowestCommonAncestor {
	const int MAXN = 5e5 + 5;
	const int MAXLOG = 20;
	int depth[MAXN], father[MAXN][MAXLOG];
	void work(int pos, int fa) {
		depth[pos] = depth[fa] + 1;
		father[pos][0] = fa;
		for (int i = 1; i < MAXLOG; i++)
			father[pos][i] = father[father[pos][i - 1]][i - 1];
		for (unsigned i = 0; i < a[pos].size(); i++)
			if (a[pos][i] != fa) work(a[pos][i], pos);
	}
	int lca(int x, int y) {
		if (depth[x] < depth[y]) swap(x, y);
		for (int i = MAXLOG - 1; i >= 0; i--)
			if (depth[father[x][i]] >= depth[y]) x = father[x][i];
		if (x == y) return x;
		for (int i = MAXLOG - 1; i >= 0; i--)
			if (father[x][i] != father[y][i]) {
				x = father[x][i];
				y = father[y][i];
			}
		return father[x][0];
	}
	int climb(int x, int y) {
		for (int i = 0; y != 0; i++)
			if (y & (1 << i)) {
				y ^= 1 << i;
				x = father[x][i];
			}
		return x;
	}
}
namespace UnionFind {
	const int MAXN = 1e6 + 5;
	int f[MAXN];
	void init(int n) {
		for (int i = 1; i <= n * 2; i++)
			f[i] = i;
	}
	int find(int x) {
		if (f[x] == x) return x;
		else return f[x] = find(f[x]);
	}
	void merge(int x, int y) {
		x = find(x);
		y = find(y);
		f[x] = y;
	}
	void addedge(int x, int y, bool z) {
		if (z == false) {
			merge(x, y);
			merge(x + n, y + n);
		} else {
			merge(x, y + n);
			merge(x + n, y);
		}
		if (find(x) == find(x + n)) {
			puts("-1");
			exit(0);
		}
	}
	pair <int, bool> query(int x) {
		int tmp = find(x);
		if (tmp <= n) return make_pair(tmp, false);
		else return make_pair(tmp - n, true);
	}
}
bool rev[MAXN];
int k, timer, p[MAXN];
int dp[MAXN], res[MAXN];
void getans() {
	for (int i = 1; i <= n; i++) {
		int pos = p[i];
		if (!rev[pos]) res[pos] = dp[pos];
		else res[pos] = k + 1 - dp[pos];
		for (auto x : a[pos])
			rev[x] ^= rev[pos];
	}
}
bool check(int mid) {
	k = mid;
	for (int i = n; i >= 1; i--) {
		int pos = p[i];
		vector <int> points;
		static bool trev[MAXN];
		static pair <int, int> inter[MAXN];
		using namespace UnionFind;
		for (auto x : a[pos]) {
			pair <int, bool> tmp = query(x);
			inter[tmp.first] = make_pair(0, 0);
		}
		pair <int, bool> cur = query(pos);
		points.push_back(cur.first);
		inter[cur.first] = make_pair(1, k);
		for (auto x : a[pos]) {
			pair <int, bool> tmp = query(x);
			if (inter[tmp.first].first == 0) {
				points.push_back(tmp.first);
				inter[tmp.first] = make_pair(1, k);
			}
			if (tmp.second == cur.second) chkmax(inter[tmp.first].first, dp[x] + 1);
			else chkmin(inter[tmp.first].second, k - dp[x]);
		}
		pair <int, int> ban = make_pair(k + 1, 0);
		int l = inter[cur.first].first, r = inter[cur.first].second;
		for (auto x : points) {
			pair <int, int> a = inter[x];
			pair <int, int> b = make_pair(k + 1 - a.second, k + 1 - a.first);
			if (a.first > a.second) return false;
			if (a > b) swap(a, b);
			chkmax(l, a.first);
			chkmin(r, b.second);
			if (a.second + 1 < b.first) {
				chkmin(ban.first, a.second + 1);
				chkmax(ban.second, b.first - 1);
			}
		}
		if (l > r) return false;
		if (l < ban.first || l > ban.second) dp[pos] = l;
		else if (ban.second + 1 <= r) dp[pos] = ban.second + 1;
		else return false;
		for (auto x : points) {
			if (inter[x].first <= dp[pos] && inter[x].second >= dp[pos]) trev[x] = false;
			else trev[x] = true;
		}
		for (auto x : a[pos]) {
			pair <int, bool> tmp = query(x);
			rev[x] = trev[tmp.first] ^ (tmp.second != cur.second);
		}
	}
	return true;
}
int subt[MAXN];
void build(int pos, int fa) {
	p[++timer] = pos;
	for (auto x : a[pos])
		if (x != fa) {
			build(x, pos);
			subt[pos] += subt[x];
		}
	for (unsigned i = 0; i < a[pos].size(); i++)
		if (a[pos][i] == fa) {
			swap(a[pos][i], a[pos][a[pos].size() - 1]);
			a[pos].pop_back();
			break;
		}
	if (subt[pos]) {
		UnionFind :: addedge(fa, pos, false);
	}
}
int main() {
	read(n), read(m);
	for (int i = 1; i <= n - 1; i++) {
		int x, y; read(x), read(y);
		a[x].push_back(y);
		a[y].push_back(x);
	}
	UnionFind :: init(n);
	LowestCommonAncestor :: work(1, 0);
	for (int i = 1; i <= m; i++) {
		using namespace LowestCommonAncestor;
		int x, y; read(x), read(y);
		int z = lca(x, y), p, q;
		if (x != z) {
			subt[x]++;
			subt[p = climb(x, depth[x] - depth[z] - 1)]--;
		}
		if (y != z) {
			subt[y]++;
			subt[q = climb(y, depth[y] - depth[z] - 1)]--;
		}
		if (x != z && y != z) {
			UnionFind :: addedge(p, q, true);
		}
	}
	build(1, 0);
	int l = 1, r = n;
	while (l < r) {
		int mid = (l + r) / 2;
		if (check(mid)) r = mid;
		else l = mid + 1;
	}
	printf("%d\n", l);
	check(l), getans();
	for (int i = 1; i <= n; i++)
		printf("%d ", res[i]);
	printf("\n");
	return 0;
}

#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define SZ(x) ((int)x.size())
#define ALL(x) x.begin(),x.end()
#define L(i,u) for (register int i=head[u]; i; i=nxt[i])
#define rep(i,a,b) for (register int i=(a); i<=(b); i++)
#define per(i,a,b) for (register int i=(a); i>=(b); i--)
using namespace std;
typedef long double ld;
typedef long long ll;
typedef unsigned int ui;
typedef pair<int,int> Pii;
typedef vector<int> Vi;
template<class T> inline void read(T &x){
	x=0; char c=getchar(); int f=1;
	while (!isdigit(c)) {if (c=='-') f=-1; c=getchar();}
	while (isdigit(c)) {x=x*10+c-'0'; c=getchar();} x*=f;
}
template<class T> T gcd(T a, T b){return !b?a:gcd(b,a%b);}
template<class T> inline void umin(T &x, T y){x=x<y?x:y;}
template<class T> inline void umax(T &x, T y){x=x>y?x:y;}
inline ui R() {
	static ui seed=416;
	return seed^=seed>>5,seed^=seed<<17,seed^=seed>>13;
}
const int N = 500500;
int n,m,fa[N][20],dep[N],bj[N];Vi e[N];
void GG(){puts("-1");exit(0);}
void dfs1(int u, int Fa, int Dep){
	fa[u][0]=Fa;dep[u]=Dep;
	for(int v:e[u])if(v!=Fa)dfs1(v,u,Dep+1);
}
int kthfa(int u, int del){per(i,19,0)if(del>>i&1)u=fa[u][i];return u;}
int getlca(int u, int v){
	if(dep[u]<dep[v])swap(u,v);int del=dep[u]-dep[v];
	per(i,19,0)if(del>>i&1)u=fa[u][i];
	if(u==v)return u;
	per(i,19,0)if(fa[u][i]!=fa[v][i])u=fa[u][i],v=fa[v][i];
	return fa[u][0];
}
vector<Pii>cons[N];int dfn[N],num,col[N];Vi d;vector<Vi>f[N];
void getcol(int u, int c, int tar){
	col[u]=c;d.pb(u);
	for(auto x:cons[u])if(dfn[x.fi]==tar)
		if(col[x.fi]==-1)getcol(x.fi,c^x.se,tar);
		else if(col[x.fi]!=(col[u]^x.se))GG();
}
void dfs2(int u, int Fa){
	for(int v:e[u])if(v!=Fa)dfs2(v,u),bj[u]+=bj[v];
	if(bj[u])cons[u].pb(mp(Fa,0)),cons[Fa].pb(mp(u,0));
	Vi dot;dfn[u]=u,dot.pb(u);
	for(int v:e[u])if(v!=Fa)dfn[v]=u,dot.pb(v);
	for(int x:dot)col[x]=-1;
	for(int x:dot)if(col[x]==-1){
		d.clear();getcol(x,0,u);f[u].pb(d);
	}
}
int mid;bool gg;int dp[N],ans[N];
void upd(Pii &s, Pii a){s=mp(max(s.fi,a.fi),min(s.se,a.se));}
void dfs(int u, int Fa){
	if(gg)return;
	for(int v:e[u])if(v!=Fa)dfs(v,u);
	Pii jiao(0,mid-(Fa>0)),sub(mid/2+1,mid/2);
	for(int x:f[u][0])if(x!=u){
		if(col[x]==0)umax(jiao.fi,dp[x]);else umin(jiao.se,mid-dp[x]-1);
	}
	for(auto a:f[u])if(a[0]!=f[u][0][0]){
		int l=0,r=0;
		for(int x:a)if(col[x]==0)umax(l,dp[x]);else umax(r,dp[x]);
		if(l>r)swap(l,r);
		upd(jiao,mp(l,mid-1-l));
		if(mid-r<=r-1){
			if(sub.fi<=sub.se)umax(sub.se,r-1),umin(sub.fi,mid-r);
			else sub=mp(mid-r,r-1);
		}
	}
	dp[u]=-1;
	if(jiao.fi<=jiao.se){
		if(sub.fi>sub.se||sub.fi>jiao.fi||sub.se<jiao.fi)dp[u]=jiao.fi;
		else if(sub.se+1<=jiao.se)dp[u]=sub.se+1;
	}
	if(dp[u]==-1)gg=1;dp[u]++;
//	if(mid==2)printf("%d-->%d\n",u,dp[u]);
}

int dir[N];
void dfs3(int u, int Fa, bool rev){
//	for(auto a:f[u]){for(int x:a)printf("%d ",x);printf("  :%d\n",u);}

	for(int x:f[u][0])if(x!=u){
		dir[x]=col[x];//if(col[x]==0)dir[x]=1;
	}
	for(auto a:f[u])if(a[0]!=f[u][0][0]){
		int l=0,r=0;
		for(int x:a)if(col[x]==0)umax(l,dp[x]);else umax(r,dp[x]);
		bool flag=0;if(dp[u]-1>=l&&dp[u]-1<=mid-1-r)flag=0;else flag=1;
		for(int x:a)dir[x]=col[x]^flag;
	}
	for(int x:e[u])if(x!=Fa)dir[x]^=rev;
//	printf("dp %d %d\n",u,dp[u]);
//	for(int x:e[u])if(x!=Fa)printf("dir %d = %d\n",x,dir[x]);
	for(int x:e[u])if(x!=Fa&&dir[x]==0)dfs3(x,u,0),umax(ans[u],ans[x]);
	ans[u]++;
	for(int x:e[u])if(x!=Fa&&dir[x]==1)umax(ans[x],ans[u]),dfs3(x,u,1);
//	if(1)printf("qaq %d %d %d %d\n",u,ans[u],dp[u],rev);//assert(ans[u]<=dp[u]);
}
int main() {
	read(n);read(m);
	rep(i,1,n-1){
		int u,v;read(u);read(v);e[u].pb(v);e[v].pb(u);
	}
	dfs1(1,0,0);
	rep(j,1,19)rep(i,1,n)fa[i][j]=fa[fa[i][j-1]][j-1];
	rep(i,1,m){
		int u,v;read(u);read(v);int l=getlca(u,v),x=0,y=0;
		if(dep[u]>dep[l])bj[u]++,bj[x=kthfa(u,dep[u]-dep[l]-1)]--;
		if(dep[v]>dep[l])bj[v]++,bj[y=kthfa(v,dep[v]-dep[l]-1)]--;
		if(dep[u]>dep[l]&&dep[v]>dep[l]){
			cons[x].pb(mp(y,1));cons[y].pb(mp(x,1));
		}
	}
	dfs2(1,0);
//	rep(i,1,n)printf("%d ",col[i]);puts("");
	int L=1,R=n;
	while(L<R){
		mid=(L+R)>>1;
		gg=0;dfs(1,0);
		if(gg)L=mid+1;else R=mid;
	}
	mid=L;gg=0;dfs(1,0);dfs3(1,0,0);
	printf("%d\n",L);
	rep(i,1,n)printf("%d ",ans[i]);
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
inline void upa(int&a,const int&b){a<b?a=b:0;}
typedef vector<int>V;
int n,m;
V e[N],e2[N];
int dfn[N],dcnt,dep[N],dad[N],anc[20][N],tg[N],tg2[N];
int g[N*2];
int gfa(int x){return g[x]==x?x:g[x]=gfa(g[x]);}
inline void uni(int x,int y){g[gfa(x)]=gfa(y);}
void dfs(int x,int fa){
	dfn[++dcnt]=x;dep[x]=dep[fa]+1;dad[x]=anc[0][x]=fa;
	if(fa)e[x].erase(find(e[x].begin(),e[x].end(),fa));
	for(int y:e[x])dfs(y,x);
}
void dfs2(int x,int fa){
	for(int y:e[x])dfs2(y,x),tg[x]+=tg[y],tg2[x]+=tg2[y];
	if(tg[x])uni(x,fa),uni(x+n,fa+n);
}
inline int lca(int x,int y){
	if(dep[x]>dep[y])swap(x,y);
	int dt=dep[y]-dep[x],i;for(i=0;1<<i<=dt;++i)if(dt>>i&1)y=anc[i][y];
	if(x==y)return x;
	for(i=19;i>=0;--i)if(anc[i][x]!=anc[i][y])x=anc[i][x],y=anc[i][y];
	return anc[0][x];
}
inline int climb(int x,int k){for(int i=0;1<<i<=k;++i)if(k>>i&1)x=anc[i][x];return x;}
inline void build(){
	int x,y,z,xx,yy,i,j;
	for(i=1;i<n;++i)cin>>x>>y,e[x].push_back(y),e[y].push_back(x);
	dfs(1,0);
	for(i=1;i<20;++i)for(j=1;j<=n;++j)anc[i][j]=anc[i-1][anc[i-1][j]];
	for(i=1;i<=n*2;++i)g[i]=i;
	for(i=1;i<=m;++i){
		cin>>x>>y;xx=yy=0;
		z=lca(x,y);++tg2[x];++tg2[y];tg2[z]-=2;
		if(dep[y]>dep[z])++tg[y],--tg[yy=climb(y,dep[y]-dep[z]-1)];
		if(dep[x]>dep[z])++tg[x],--tg[xx=climb(x,dep[x]-dep[z]-1)];
		if(xx && yy)uni(xx,yy+n),uni(xx+n,yy);
	}
	dfs2(1,0);for(i=1;i<=n;++i)if(gfa(i)==gfa(i+n)){cout<<-1<<endl;exit(0);}
}
int f[N];bool rev[N];
struct seg{int l,r;};
inline seg operator&(const seg&a,const seg&b){return (seg){max(a.l,b.l),min(a.r,b.r)};}
inline seg operator|(const seg&a,const seg&b){return (seg){min(a.l,b.l),max(a.r,b.r)};}
inline bool E(const seg&a){return a.l>a.r;}
inline bool ck(int lm){
	int i,j,k,l,x,y,z;
	seg A=(seg){0,lm};
	for(i=n;i;--i){
		x=dfn[i];
		seg s=A;
		for(int y:e2[x])s=s&(gfa(y)==gfa(x)?(seg){f[y]+1,lm}:(seg){0,lm-f[y]-1}),rev[y]=gfa(y)==gfa(x+n);
		seg s1=s,s2=(seg){lm,0},s3;
		for(j=0;j<e[x].size();j=k){
			s3=A;
			y=e[x][j];
			for(k=j;k<e[x].size() && (z=e[x][k],gfa(z)==gfa(y) || gfa(z)==gfa(y+n));++k)
				s3=s3&(gfa(z)==gfa(y)?(seg){f[z]+1,lm}:(seg){0,lm-f[z]-1});
			if(E(s3))return 0;
			if(s3.l>lm-s3.l)s3=(seg){lm-s3.r,lm-s3.l};
			s1=s1&((seg){s3.l,lm-s3.l}|(seg){lm-s3.r,s3.r});
			if(s3.r<lm-s3.r)s2=s2|(seg){s3.r+1,lm-s3.r-1};
		}
		if(E(s1) || (s2.l<=s1.l && s1.r<=s2.r))return 0;
		if(s2.l<=s1.l && s1.l<=s2.r)f[x]=s2.r+1;else f[x]=s1.l;
		for(j=0;j<e[x].size();j=k){
			s3=A;
			y=e[x][j];
			for(k=j;k<e[x].size() && (z=e[x][k],gfa(z)==gfa(y) || gfa(z)==gfa(y+n));++k)
				s3=s3&(gfa(z)==gfa(y)?(seg){f[z]+1,lm}:(seg){0,lm-f[z]-1});
			bool bb=0;
			if(f[x]<s3.l || f[x]>s3.r)bb=1,s3=(seg){lm-s3.r,lm-s3.l};
			for(l=j;l<k;++l)z=e[x][l],rev[z]=(gfa(z)==gfa(y+n))^bb;
		}
	}
	return 1;
}
int main(){
	ios::sync_with_stdio(0);cin.tie(0);
	cin>>n>>m;build();
	int le=1,ri=n-1,md,i;static int w[N];for(i=2;i<=n;++i)w[i]=min(gfa(i),gfa(i+n));
	for(i=1;i<=n;++i){
		V e3;
		for(int x:e[i])if(w[i]==w[x])e2[i].push_back(x);else if(tg2[x])e3.push_back(x);
		sort(e3.begin(),e3.end(),[&](int x,int y){return w[x]<w[y];});e[i]=e3;
	}
	for(;le<ri;){
		md=le+ri>>1;
		if(!ck(md))le=md+1;else ri=md;
	}
	cout<<le+1<<'\n';
	ck(le);
	for(i=2;i<=n;++i){int x=dfn[i];rev[x]^=rev[dad[x]];}
	for(i=1;i<=n;++i)cout<<(rev[i]?le-f[i]:f[i])+1<<(i==n?'\n':' ');
	return 0;
}

    #include<bits/stdc++.h>
    #define ll long long
    #define ull unsigned ll
    #define uint unsigned
    #define pii pair<int,int>
    #define pll pair<ll,ll>
    #define IT iterator
    #define PB push_back
    #define fi first
    #define se second
    #define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
    #define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
    #define CLR(a,v) memset(a,v,sizeof(a));
    #define CPY(a,b) memcpy(a,b,sizeof(a));
    #define debug puts("wzpakking")
    #define y1 ysghysgsygsh
    using namespace std;
    const int N=500005;
    int n,m;
    vector<int> e[N];
    namespace DSU{
    	int fa[N],v[N];
    	int get(int x){
    		if (x==fa[x]) return x;
    		int f=fa[x];
    		fa[x]=get(fa[x]);
    		v[x]^=v[f];
    		return fa[x];
    	}
    	void build(){
    		For(i,1,n) fa[i]=i,v[i]=0;
    	}
    	void merge(int x,int y,int vv){
    		int px=get(x),py=get(y);
    		if (px==py){
    			if (v[x]^v[y]^vv){
    				puts("-1");
    				exit(0);
    			}
    		}
    		else{
    			fa[px]=py;
    			v[px]=v[x]^v[y]^vv;
    		}
    	}
    }
    namespace TR{
    	int S[N],SS[N];
    	int fa[N],sz[N],dep[N];
    	int pos[N],dfn[N],top[N];
    	void dfs1(int x){
    		sz[x]=1;
    		for (auto i:e[x])
    			if (i!=fa[x]){
    				fa[i]=x;
    				dep[i]=dep[x]+1;
    				dfs1(i);
    				sz[x]+=sz[i];
    			}
    	}
    	void dfs2(int x,int tp){
    		dfn[x]=++*dfn;
    		pos[*dfn]=x;
    		top[x]=tp;
    		int k=0;
    		for (auto i:e[x])
    			if (i!=fa[x]&&sz[i]>sz[k])
    				k=i;
    		if (k) dfs2(k,tp);
    		for (auto i:e[x])
    			if (i!=fa[x]&&i!=k)
    				dfs2(i,i);
    	}
    	int LCA(int x,int y){
    		for (;top[x]!=top[y];x=fa[top[x]])
    			if (dep[top[x]]<dep[top[y]])
    				swap(x,y);
    		return dep[x]<dep[y]?x:y;
    	}
    	int jmp(int x,int y){
    		for (;;){
    			if (dep[top[x]]<=dep[y])
    				return pos[dfn[y]+1];
    			if (dep[top[x]]==dep[y]+1)
    				return top[x];
    			x=fa[top[x]];
    		}
    	}
    	void build(){
    		dfs1(1);
    		dfs2(1,1);
    	}
    	void build2(){
    		Rep(i,n,1){
    			int x=pos[i];
    			S[fa[x]]+=S[x];
    			SS[fa[x]]+=SS[x];
    			if (SS[x])
    				DSU::merge(x,fa[x],0);
    		}
    	}
    	void insert_que(int x,int y){
    		int L=LCA(x,y);
    		S[x]++; S[y]++; S[L]-=2;
    		if (dep[x]^dep[L]) SS[x]++,SS[x=jmp(x,L)]--;
    		if (dep[y]^dep[L]) SS[y]++,SS[y=jmp(y,L)]--;
    		if ((x^L)&&(y^L)) DSU::merge(x,y,1);
    	}
    }
    int v0[N],v1[N];
    int vis[N],f[N],T;
    int cc[N],fl[N];
    bool check(int K){
    	static int q[N];
    	Rep(i,n,1){
    		int x=TR::pos[i],y=TR::fa[x];
    		int vl=0,vr=0;
    		++T; *q=0;
    		for (auto j:e[x])
    			if (j!=y&&TR::S[j]){
    				int c=DSU::fa[j];
    				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
    				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
    				else v1[c]=max(v1[c],f[j]);
    			}
    		if (vis[DSU::fa[x]]==T){
    			int c=DSU::fa[x];
    			vl=v0[c]; vr=v1[c];
    			if (DSU::v[x]) swap(vl,vr);
    		}
    		int vmn=0,vmx=0;
    		For(j,1,*q)
    			if (q[j]!=DSU::fa[x]){
    				if (v0[q[j]]>v1[q[j]])
    					swap(v0[q[j]],v1[q[j]]);
    				vmn=max(vmn,v0[q[j]]);
    				vmx=max(vmx,v1[q[j]]);
    			}
    		if (max(vmn,min(vl,vr))+max(vmx,max(vl,vr))>=K) return 0;
    		f[x]=(max(vmn,vl)+max(vmx,vr)>=K?max(vmx,vl):max(vmn,vl))+1;
    	}
    	return 1;
    }
    void construct(int K){
    	static int q[N];
    	For(i,1,n){
    		int x=TR::pos[i],y=TR::fa[x];
    		++T; *q=0;
    		for (auto j:e[x])
    			if (j!=y&&TR::S[j]){
    				int c=DSU::fa[j];
    				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
    				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
    				else v1[c]=max(v1[c],f[j]);
    			}
    		For(j,1,*q){
    			cc[q[j]]=fl[x];
    			if (q[j]!=DSU::fa[x])
    				cc[q[j]]^=(v0[q[j]]>f[x]-1||v1[q[j]]+f[x]>K);
    			else cc[q[j]]^=DSU::v[x];
    		}
    		for (auto j:e[x])
    			if (j!=y&&TR::S[j])
    				fl[j]=cc[DSU::fa[j]]^DSU::v[j];
    	}
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	For(i,1,n-1){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		e[x].PB(y); e[y].PB(x);
    	}
    	TR::build();
    	DSU::build();
    	For(i,1,m){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		TR::insert_que(x,y);
    	}
    	TR::build2();
    	For(i,1,n) DSU::get(i);
    	int l=1,r=n,ans=0;
    	while (l<=r){
    		int mid=(l+r)/2;
    		if (check(mid))
    			ans=mid,r=mid-1;
    		else l=mid+1;
    	}
    	printf("%d\n",ans);
    	check(ans);
    	construct(ans);
    	For(i,1,n) printf("%d ",!fl[i]?f[i]:ans+1-f[i]);
    }

#include <bits/stdc++.h>
#define meow(args...) fprintf(stderr, args)
typedef unsigned u32;
typedef long long s64;
typedef unsigned long long u64;
template<class T1, class T2> inline bool cmin(T1 &a, const T2 &b) {return b<a?(a=b, true):false;}
template<class T1, class T2> inline bool cmax(T1 &a, const T2 &b) {return a<b?(a=b, true):false;}
template<class Type> Type read() {
	Type a;
	bool b;
	unsigned char c;
	while(c=getchar()-48, (c>9)&(c!=253));
	for(a=(b=c==253)?0:c; (c=getchar()-48)<=9; a=a*10+c);
	return b?-a:a;
}
int (*rd)()=read<int>;
//const u32 P=;
//inline u32 &inc(u32 &a, u32 b) {return (a+=b)<P?a:(a-=P);}
//inline u32 &dec(u32 &a, u32 b) {return (a-=b)&0x80000000?(a+=P):a;}
//inline u32 sum(u32 a, u32 b) {return (a+=b)<P?a:a-P;}
//inline u32 dif(u32 a, u32 b) {return (a-=b)&0x80000000?a+P:a;}
//u64 power(u64 a, int b) {
//	u64 ans=1;
//	for(; b; a=a*a%P, b/=2) if(b&1) ans=ans*a%P;
//	return ans;
//}

struct Segment {
	int l, r;
};
const int N=5e5+1;
int n, m, to[2*N], head[N], next[2*N], pa[N], dep[N], size[N], prefer[N], top[N], clk, real[N], dfn[N], mindep[N], k, f[N];
bool vis[N], res, rev[N];

namespace DSU {
	int pa[N], w[N];
	void find(int u) {
		int v=pa[u];
		if(u!=v) {
			find(v);
			pa[u]=pa[v];
			w[u]^=w[v];
		}
	}
	void merge(int u, int v, int c) {
		find(u);
		find(v);
		c^=w[u]^w[v];
		u=pa[u];
		v=pa[v];
		if(u==v&&c) {
			puts("-1");
			exit(0);
		}
		pa[u]=v;
		w[u]=c;
	}
};

void dfs1(int u) {
	dep[u]=dep[pa[u]]+1;
	size[u]=1;
	for(int i=head[u], *p=&head[u], mx=0; i; i=next[i]) {
		if(to[i]!=pa[u]) {
			pa[to[i]]=u;
			dfs1(to[i]);
			size[u]+=size[to[i]];
			if(cmax(mx, size[to[i]])) prefer[u]=to[i];
			p=next+i;
		} else
			*p=next[i];
	}
}
void dfs2(int u) {
	real[dfn[u]=++clk]=u;
	if(prefer[u]) {
		top[prefer[u]]=top[u];
		dfs2(prefer[u]);
	}
	for(int i=head[u]; i; i=next[i]) {
		if(to[i]!=prefer[u]) {
			top[to[i]]=to[i];
			dfs2(to[i]);
		}
	}
}
int lca(int u, int v) {
	while(top[u]!=top[v]) {
		if(dep[top[u]]>dep[top[v]])
			u=pa[top[u]];
		else
			v=pa[top[v]];
	}
	return dep[u]<dep[v]?u:v;
}
Segment operator&(const Segment &a, const Segment &b) {
	return (Segment){std::max(a.l, b.l), std::min(a.r, b.r)};
}
Segment operator|(const Segment &a, const Segment &b) {
	return (Segment){std::min(a.l, b.l), std::max(a.r, b.r)};
}
bool check(int k) {
	std::vector<int> e;
	for(int i=n; i>=1; --i) {
		int u=real[i];
		Segment s1{1, k}, s2{k, 1};
		e.clear();
		for(int j=head[u]; j; j=next[j]) {
			int v=to[j];
			if(!vis[v]) continue;
			if(DSU::pa[v]==DSU::pa[u]) {
				rev[v] = DSU::w[u]^DSU::w[v];
				if(rev[v])
					s1=s1&(Segment){1, k-f[v]};
				else
					s1=s1&(Segment){f[v]+1, k};
			} else
				e.emplace_back(v);
		}
		std::sort(e.begin(), e.end(), [](int x, int y) {return DSU::pa[x]<DSU::pa[y];});
		int d=e.size();
		for(int l=0, r=0; l<d; l=r) {
			Segment s3{1, k};
			for(int v=e[l], w; r<d && (w=e[r], DSU::pa[v]==DSU::pa[w]); ++r) {
				if(DSU::w[v]==DSU::w[w])
					s3=s3&(Segment){f[w]+1, k};
				else
					s3=s3&(Segment){1, k-f[w]};
			}
			if(s3.l>s3.r) return false;
			if(s3.l>k+1-s3.l) s3={k+1-s3.r, k+1-s3.l};
			s1=s1&((Segment){s3.l, k+1-s3.l}|(Segment){k+1-s3.r, s3.r});
			if(s3.r<k+1-s3.r) s2=s2|(Segment){s3.r+1, k-s3.r};
		}
		if(s1.l>s1.r ||	(s2.l<=s1.l&&s1.r<=s2.r)) return false;
		if(s2.l<=s1.l && s1.l<=s2.r) f[u]=s2.r+1; else f[u]=s1.l;
		for(int l=0, r=0; l<d; l=r) {
			Segment s3{1, k};
			int v=e[l];
			for(int w; r<d && (w=e[r], DSU::pa[v]==DSU::pa[w]); ++r) {
				if(DSU::w[v]==DSU::w[w])
					s3=s3&(Segment){f[w]+1, k};
				else
					s3=s3&(Segment){1, k-f[w]};
			}
			bool bb = f[u]<s3.l||f[u]>s3.r;
			if(bb) s3={k+1-s3.r, k+1-s3.l};
			for(int j=l; j<r; ++j) {
				int w=e[j];
				rev[w]=DSU::w[v]^DSU::w[w]^bb;
			}
		}
	}
	return true;
}
int main() {
	n=rd();
	m=rd();
	for(int i=1, j=2; i<n; ++i) {
		int u=rd(), v=rd();
		to[j]=v;
		next[j]=head[u];
		head[u]=j++;
		to[j]=u;
		next[j]=head[v];
		head[v]=j++;
	}
	dfs1(1);
	top[1]=1;
	dfs2(1);
	for(int i=1; i<=n; ++i) DSU::pa[i]=i;
	for(int i=1; i<=n; ++i) mindep[i]=dep[i];
	for(int i=1; i<=m; ++i) {
		int a=rd(), b=rd(), c=lca(a, b);
		cmin(mindep[a], dep[c]);
		cmin(mindep[b], dep[c]);
		if(a!=c&&b!=c) DSU::merge(a, b, 1);
	}
	for(int i=n; i>=1; --i) {
		int u=real[i];
		for(int j=head[u]; j; j=next[j]) {
			int v=to[j];
			cmin(mindep[u], mindep[v]);
			if(mindep[v]<dep[u]) DSU::merge(u, v, 0);
		}
		vis[u] = mindep[u]<dep[u];
	}
	for(int i=1; i<=n; ++i) DSU::find(i);
	int l=1, r=n;
	while(l<r) {
		int mid=(l+r)/2;
		if(check(mid)) r=mid; else l=mid+1;
	}
	check(l);
	for(int i=2; i<=n; ++i) {
		int u=real[i];
		rev[u]^=rev[pa[u]];
	}
	printf("%d\n", l);
	for(int i=1; i<=n; ++i)
		printf("%d%c", rev[i]?l-f[i]+1:f[i], " \n"[i==n]);
	return 0;
}

#include <bits/stdc++.h>
#define FR first
#define SE second

using namespace std;

typedef long long ll;
typedef pair<int,int> pr;

inline pr merge(pr x,pr y) {
  return pr(max(x.FR,y.FR),min(x.SE,y.SE));
}

vector <int> e[500005];
int fa[500005][20],dep[500005];

void dfs1(int x) {
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa[x][0]) {
    	int u=e[x][i];
    	fa[u][0]=x;dep[u]=dep[x]+1;
    	for(int j=1;j<20;j++) fa[u][j]=fa[fa[u][j-1]][j-1];
    	dfs1(u);
	}
}

int lca(int x,int y) {
  if (dep[x]<dep[y]) swap(x,y);
  int d=dep[x]-dep[y];
  for(int i=0;i<20;i++)
    if ((d>>i)&1) x=fa[x][i];
  if (x==y) return x;
  for(int i=19;i>=0;i--)
    if (fa[x][i]!=fa[y][i]) {
    	x=fa[x][i];
    	y=fa[y][i];
	}
  return fa[x][0];
}

int jump(int x,int d) {
  for(int i=0;i<20;i++)
    if ((d>>i)&1) x=fa[x][i];
  return x;
}

vector <pr> ee[500005];
int size[500005];

void dfs2(int x,int fa) {
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa) {
    	int u=e[x][i];
    	dfs2(u,x);
    	size[x]+=size[u];
	}
  if (size[x]) {
  	ee[x].push_back(pr(fa,0));
  	ee[fa].push_back(pr(x,0));
  }
}

int col[500005],id[500005];

void dfs3(int x) {
  for(int i=0;i<ee[x].size();i++) {
  	int u=ee[x][i].FR;
  	if (!id[u]) {
  		id[u]=id[x];
  		col[u]=col[x]^ee[x][i].SE;
  		dfs3(u);
	  }
	else if ((col[x]^col[u])!=ee[x][i].SE) {
		puts("-1");
		exit(0);
	}
  }
}

pr f[500005],g[500005];
int vis[500005];

bool dfs4(int x,int fa,int k) {
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa) {
    	int u=e[x][i];
    	if (!dfs4(u,x,k)) return 0;
	}
  f[x]=pr(1,k);
  int sz=0;
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa&&id[e[x][i]]) {
    	int u=e[x][i];
    	if (id[u]==id[x]) {
    		if (!col[u]) f[x]=merge(f[x],pr(1,f[u].SE-1));
    		else f[x]=merge(f[x],pr(f[u].FR+1,k));
		}
		else {
			if (!vis[id[u]]) {
				vis[id[u]]=++sz;
				g[sz]=pr(1,k);
			}
			int t=vis[id[u]];
			if (!col[u]) g[t]=merge(g[t],pr(1,f[u].SE-1));
			else g[t]=merge(g[t],pr(f[u].FR+1,k));
		}
	}
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa) vis[id[e[x][i]]]=0;
  if (f[x].FR>f[x].SE) return 0;
  pr u(1,k);
  for(int i=1;i<=sz;i++) {
  	if (g[i].FR>g[i].SE) return 0;
  	if (k-g[i].SE+1<g[i].FR) g[i]=pr(k-g[i].SE+1,k-g[i].FR+1);
  	u=merge(u,g[i]);
  }
  pr t1=merge(u,f[x]),t2=merge(pr(k-u.SE+1,k-u.FR+1),f[x]);
  if (t1.FR>t1.SE&&t2.FR>t2.SE) return 0;
  if (t1.FR>t1.SE) f[x]=t2;
  else if (t2.FR>t2.SE) f[x]=t1;
  else f[x]=pr(min(t1.FR,t2.FR),max(t1.SE,t2.SE));
  return 1;
}

int ans[500005],val[500005];
bool d[500005];

void dfs5(int x,int fa,int k,bool v) {
  int sz=0;
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa&&id[e[x][i]]!=id[x]) {
    	int u=e[x][i];
		if (!vis[id[u]]) {
			vis[id[u]]=++sz;
			val[sz]=id[u];
			g[sz]=pr(1,k);
		}
		int t=vis[id[u]];
		if (!col[u]) g[t]=merge(g[t],pr(1,f[u].SE-1));
		else g[t]=merge(g[t],pr(f[u].FR+1,k));
	}
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa) vis[id[e[x][i]]]=0;
  for(int i=1;i<=sz;i++) d[val[i]]=((g[i].FR<=ans[x]&&g[i].SE>=ans[x])?0:1);
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa) {
    	int u=e[x][i];
    	if (!id[u]) {
    		ans[u]=f[u].FR;
    		dfs5(u,x,k,0);
		}
		else {
			bool c=((id[u]==id[x])?v:d[id[u]]);
			if (!c) ans[u]=((!col[u])?f[u].SE:f[u].FR);
			else ans[u]=((col[u])?k-f[u].FR+1:k-f[u].SE+1);
			dfs5(u,x,k,c);
		}
	}
}

int main() {
  int n,m;
  scanf("%d%d",&n,&m);
  for(int i=1;i<n;i++) {
  	int x,y;
  	scanf("%d%d",&x,&y);
  	e[x].push_back(y);
  	e[y].push_back(x);
  }
  dfs1(1);
  for(int i=1;i<=m;i++) {
  	int x,y;
  	scanf("%d%d",&x,&y);
  	int p=lca(x,y),u,v;
  	if (p!=x) {
  		size[x]++;
  		size[u=jump(x,dep[x]-dep[p]-1)]--;
	  }
	if (p!=y) {
		size[y]++;
		size[v=jump(y,dep[y]-dep[p]-1)]--;
	}
	if (p!=x&&p!=y) {
		ee[u].push_back(pr(v,1));
		ee[v].push_back(pr(u,1));
	}
  }
  dfs2(1,0);
  int cnt=0;
  for(int i=2;i<=n;i++)
    if (!id[i]) {
    	id[i]=++cnt;
    	dfs3(i);
	}
  int l=1,r=n;
  while (l<r) {
  	int mid=((l+r)>>1);
    bool v=dfs4(1,0,mid);
    if (v) r=mid; else l=mid+1;
  }
  dfs4(1,0,l);
  ans[1]=f[1].FR;
  dfs5(1,0,l,0);
  printf("%d\n",l);
  for(int i=1;i<=n;i++) printf("%d ",ans[i]);
  printf("\n");
  return 0;
}
/*
3 1
1 2
1 3
2 3
*/

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5+5;
typedef pair<int,int> pi;
vector<int> g[N],id[N];
int n,m;
struct UST{
	vector<int> fa,c;
	inline void init(int n){
		fa.resize(n+1);
		c.resize(n+1);
		for(int i=0;i<=n;i++)fa[i] = i;
	}
	inline int find(int x){
		if(fa[x]==x)return x;
		else{
			find(fa[x]); c[x] ^= c[fa[x]]; fa[x] = fa[fa[x]];
			return fa[x];
		}
	}
	inline void mrg(int x,int y){
		// cout << x << " " << y << "::::";
		find(x),find(y);
		if(fa[x]^fa[y]){
			// cout << fa[x] << " " << fa[y] << endl;
			c[fa[x]]=1^c[x]^c[y];
			fa[fa[x]]=fa[y];
		}else if(c[x]==c[y]){puts("-1");exit(0);/*no solution.*/}

		// for(int i=0;i<2;i++)cout << fa[i] << " " << c[i] << " | ";puts("");
	}
}us[N];

int p[N];//to calc merge
int p2[N];//to calc ifedge
int dep[N],anc[N][20];

inline void adde(int u,int v){g[u].push_back(v);id[u].push_back(-1);}
inline void dfs(int x,int pre){
	anc[x][0]=pre;dep[x] = dep[pre]+1;
	for(int i=1;i<=19;i++)anc[x][i]=anc[anc[x][i-1]][i-1];
	us[x].init(g[x].size());
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v==pre)continue;
		dfs(v,x);
	}
}
vector<pi> opts[N];
inline void perform(int x,int y){
	if(x==y)return;
	if(dep[x]<dep[y])swap(x,y);
	int _x=x;
	p2[x]++,p2[y]++;
	for(int i=19;~i;i--)if(dep[anc[x][i]]>=dep[y])x=anc[x][i];
	if(x!=y){
		p[_x]++,p[y]++;
		for(int i=19;~i;i--){
			if(anc[x][i]!=anc[y][i])x=anc[x][i],y=anc[y][i];
		}p[x]--,p[y]--;
		opts[anc[x][0]].push_back(pi(x,y));
		p2[anc[x][0]]-=2;
	}else{
		x=_x;p[x]++;for(int i=19;~i;i--)if(dep[anc[x][i]]>dep[y])x=anc[x][i];p[x]--;
		p2[y]-=2;
	}
}
int K;
bool FLAG;
int f[N],temp_id[N];
vector<int> h[N][2];
inline void pref(int x,int pre){
	for(int j=0;j<2;j++)h[x][j].resize(g[x].size());
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v==pre)continue;
		pref(v,x);p[x]+=p[v];p2[x]+=p2[v];
	}
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];
		if(v==pre&&p2[x])id[x][i]=i;
		else if(p2[v])id[x][i]=i;
	}
	for(size_t i=0;i<g[x].size();i++){int v=g[x][i];temp_id[v]=id[x][i];}
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v!=pre&&p[v]){
			// cout << x << ":" << v << " " << pre << endl;
			us[x].mrg(temp_id[v],temp_id[pre]);
		}
	}
	for(size_t i=0;i<opts[x].size();i++){
		int a=opts[x][i].first,b=opts[x][i].second;
		// cout << x << ":"<< opts[x][i].first << " " << opts[x][i].second << endl;
		us[x].mrg(temp_id[a],temp_id[b]);
	}
	for(size_t i=0;i<g[x].size();i++){
		if(id[x][i]!=-1){
			// cout << us[x].fa[id[x][i]] << "," << us[x].c[id[x][i]] << "|";
			us[x].find(id[x][i]);
			// cout << us[x].fa[id[x][i]] << "," << us[x].c[id[x][i]] << "|";
		}
	}
	// puts("");
}/* to make the union set */
int dir[N];
inline void Dp(int x,int pre){
	// cout << x << " " << pre << endl;
	f[x]=1;
	// vector<int> h[2]={vector<int>(g[x].size(),0),vector<int>(g[x].size(),0)};
	for(int i=0;i<(int)g[x].size();i++)h[x][0][i]=h[x][1][i]=0;
	int qwq[2]={0,0};
	int idd=-1,cidd=0;
	for(size_t i=0;i<g[x].size();i++){
		if(g[x][i]==pre){
			if(id[x][i]!=-1)idd=us[x].fa[id[x][i]],cidd=us[x].c[id[x][i]];
		}
	}
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v==pre)continue;
		Dp(v,x);
		if(id[x][i]!=-1){
			// cout << x << " " << v << "!!" << endl;
			if(us[x].fa[id[x][i]]==idd){
				dir[v]=(us[x].c[id[x][i]]==cidd);
				// cout << id[x][i] << " " << us[x].c[id[x][i]] << " " << cidd << endl;
				// cout << dir[v] << endl;
				//1 : x is source 0 : x is towards (when direction to fa is x to fa)
				if(us[x].c[id[x][i]]!=cidd)qwq[0]=max(qwq[0],f[v]);
				else qwq[1]=max(qwq[1],f[v]);
			}
			else{
				h[x][us[x].c[id[x][i]]][us[x].fa[id[x][i]]]=max(h[x][us[x].c[id[x][i]]][us[x].fa[id[x][i]]],f[v]);
			}
		}
	}
	// cout << " consider " << x << " " << pre << ":: " << qwq[0] << " " << qwq[1] << endl;
	int qaq[2]={0,0};
	for(size_t i=0;i<g[x].size();i++){
		// cout << h[0][i] << " " << h[1][i] << endl;
		int a=min(h[x][0][i],h[x][1][i]), b=max(h[x][0][i],h[x][1][i]);
		qaq[0]=max(qaq[0],a);
		qaq[1]=max(qaq[1],b);
	}
	int type=0;
	if(max(qaq[0],qwq[0])+max(qwq[1],qaq[1])<K){
		f[x]=max(qaq[0],qwq[0])+1;
	}
	else{
		type=1;
		if(max(qaq[1],qwq[0])+max(qwq[1],qaq[0])<K)f[x]=max(qaq[1],qwq[0])+1;
		else FLAG=0,f[x]=1;
	}
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v==pre)continue;
		if(id[x][i]!=-1){
			if(us[x].fa[id[x][i]]==idd)continue;
			int idx = us[x].fa[id[x][i]], c = us[x].c[id[x][i]];
			int cc = c^(h[x][0][idx]>h[x][1][idx])^type;
			dir[v]=cc;
		}
	}
	// cout << x << ":::" << f[x] << endl;
	// cout << "ret" << endl;
}

inline bool check(int k){
	// cout << "check" << ":" << k << endl;
	K=k,FLAG=1;
	Dp(1,0);
	// cout << FLAG << endl;
	return FLAG;
}

bool t[N];

int ans[N];

inline void getans(int x,int pre){
	ans[x]=t[x]?K+1-f[x]:f[x];
	for(size_t i=0;i<g[x].size();i++){
		if(g[x][i]==pre)continue;
		t[g[x][i]]=t[x]^dir[g[x][i]];
		getans(g[x][i],x);
	}
}

int main()
{
	cin >> n >> m;
	for(int i=1;i<n;i++){
		int u,v;scanf("%d%d",&u,&v);
		adde(u,v),adde(v,u);
	}
	dfs(1,0);
	for(int i=1;i<=m;i++){
		int u,v;scanf("%d%d",&u,&v);
		perform(u,v);
	}
	// cout << "??" << endl;
	pref(1,0);
	// cout << "??" << endl;
	int l=1,r=n;
	while(l<r){
		int mid = (l+r)>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	cout << l << endl;
	check(l);
	getans(1,0);
	for(int i=1;i<=n;i++)printf("%d ",ans[i]);
	puts("");return 0;
}

/*
8 5
2 1
3 2
4 3
5 2
6 3
7 2
8 2
1 7
3 4
2 8
5 1
4 5
 */

#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
#include <bitset>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

const int MAXN = 500000;
const int MAXBIT = 18;
const int MAXLINE = 500000;

int n, nline;
vector<int> adj[MAXN];
int lineend[MAXLINE][2];

int par[MAXN], dep[MAXN];
int up[MAXN][MAXBIT + 1];

void dfsinit(int at) {
	dep[at] = par[at] == -1 ? 0 : dep[par[at]] + 1;
	up[at][0] = par[at] == -1 ? at : par[at]; REP(k, MAXBIT) up[at][k + 1] = up[up[at][k]][k];
	REPSZ(i, adj[at]) {
		int to = adj[at][i]; if (to == par[at]) continue;
		par[to] = at; dfsinit(to);
	}
}
int calcup(int a, int steps) {
	for (int k = MAXBIT; k >= 0; --k) if (steps&(1 << k)) a = up[a][k];
	return a;
}
int calclca(int a, int b) {
	if (dep[a] < dep[b]) swap(a, b);
	a = calcup(a, dep[a] - dep[b]);
	if (a == b) return a;
	for (int k = MAXBIT; k >= 0; --k) if (up[a][k] != up[b][k]) a = up[a][k], b = up[b][k];
	return par[a];
}

int ufpar[MAXN], ufsz[MAXN], ufdiff[MAXN];

int uffind(int a) { if (ufpar[a] == a) return a; uffind(ufpar[a]); ufdiff[a] ^= ufdiff[ufpar[a]]; return ufpar[a] = ufpar[ufpar[a]]; }
bool ufunite(int a, int b, int diff) { uffind(a), uffind(b); diff ^= ufdiff[a], a = ufpar[a], diff ^= ufdiff[b], b = ufpar[b]; if (a == b) return diff == 0; if (ufsz[a] < ufsz[b]) swap(a, b); ufsz[a] += ufsz[b], ufpar[b] = a, ufdiff[b] ^= diff; return true; }

int unitedep[MAXN];
bool anyedge[MAXN];

void dfsunite(int at) {
	REPSZ(i, adj[at]) {
		int to = adj[at][i]; if (to == par[at]) continue;
		dfsunite(to);
		unitedep[at] = min(unitedep[at], unitedep[to]);
	}
}

int dp[MAXN];
int seenby[MAXN], mxzero[MAXN], mxone[MAXN];
int seenlst[MAXN], nseenlst;

bool dfscalc(int at, int lim) {
	if (par[at] == -1) REP(i, n) seenby[i] = -1;
	REPSZ(i, adj[at]) {
		int to = adj[at][i]; if (to == par[at]) continue;
		if (!dfscalc(to, lim)) return false;
	}
	nseenlst = 0;
	REPSZ(i, adj[at]) {
		int to = adj[at][i]; if (to == par[at]) continue;
		uffind(to);
		int id = ufpar[to];
		if (seenby[id] != at) seenlst[nseenlst++] = id, seenby[id] = at, mxzero[id] = mxone[id] = 0;
		if (ufdiff[to] == 0 && anyedge[to]) mxzero[id] = max(mxzero[id], dp[to]);
		if (ufdiff[to] == 1 && anyedge[to]) mxone[id] = max(mxone[id], dp[to]);
	}
	uffind(at); int me = ufpar[at];
	int lo = 1, loupto = lim, hi = lim, hidownto = 1;
	REP(i, nseenlst) {
		int id = seenlst[i];
		//printf("\tat=%d comp=%d mxzero=%d mxone=%d [me=%d mediff=%d]\n", at + 1, it->first, mxzero, mxone, me, ufdiff[at]);
		int a = mxzero[id], b = mxone[id];
		if (id == me) {
			if (ufdiff[at] == 1) swap(a, b);
			lo = max(lo, a + 1); hi = min(hi, lim - b);
		} else {
			// [mxzero+1..lim-mxone] or [mxone+1..lim-mxzero]
			if (a > b) swap(a, b); // [a+1..lim-b] or [b+1..lim-a]
			lo = max(lo, a + 1), hi = min(hi, lim - a);
			if (lim - b < b + 1) loupto = min(loupto, lim - b), hidownto = max(hidownto, b + 1);
		}
	}
	loupto = min(loupto, hi);
	hidownto = max(hidownto, lo);
	bool ret;
	if (lo <= loupto) { dp[at] = lo; ret = true; }
	else if (hidownto <= hi) { dp[at] = hidownto; ret = true; }
	else ret = false;
	//printf("lim=%d at=%d: %s (%d) [%d..%d and %d..%d]\n", lim, at + 1, ret ? "OK" : "ERR", dp[at], lo, loupto, hidownto, hi);
	return ret;
}

int ans;
int cost[MAXN];
bool rev[MAXN];
bool swapped[MAXN];

void reconstruct(int at) {
	if (par[at] == -1) REP(i, n) seenby[i] = -1;
	cost[at] = !rev[at] ? dp[at] : ans - dp[at] + 1;
	nseenlst = 0;
	REPSZ(i, adj[at]) {
		int to = adj[at][i]; if (to == par[at]) continue;
		uffind(to);
		int id = ufpar[to];
		if (seenby[id] != at) seenlst[nseenlst++] = id, seenby[id] = at, mxzero[id] = mxone[id] = 0;
		if (ufdiff[to] == 0 && anyedge[to]) mxzero[id] = max(mxzero[id], dp[to]);
		if (ufdiff[to] == 1 && anyedge[to]) mxone[id] = max(mxone[id], dp[to]);
	}
	uffind(at); int me = ufpar[at];
	REP(i, nseenlst) {
		int id = seenlst[i];
		//printf("\tat=%d comp=%d mxzero=%d mxone=%d [me=%d mediff=%d]\n", at + 1, it->first, mxzero, mxone, me, ufdiff[at]);
		int a = mxzero[id], b = mxone[id]; swapped[id] = false;
		if (id == me && ufdiff[at] == 1) swap(a, b), swapped[id] = !swapped[id];
		if ((dp[at] <= a || dp[at] > ans - b) && id != me) swap(a, b), swapped[id] = !swapped[id];
		assert(dp[at] > a && dp[at] <= ans - b);
	}
	REPSZ(i, adj[at]) {
		int to = adj[at][i]; if (to == par[at]) continue;
		rev[to] = rev[at] ^ swapped[ufpar[to]] ^ (ufdiff[to] == 1);
	}
	REPSZ(i, adj[at]) {
		int to = adj[at][i]; if (to == par[at]) continue;
		reconstruct(to);
	}
}

bool solve() {
	par[0] = -1; dfsinit(0);
	REP(i, n) ufpar[i] = i, ufsz[i] = 1, ufdiff[i] = 0, unitedep[i] = dep[i], anyedge[i] = false;
	REP(i, nline) {
		int a = lineend[i][0], b = lineend[i][1]; if (dep[a] > dep[b]) swap(a, b);
		int c = calclca(a, b);
		if (c == a) {
			unitedep[b] = min(unitedep[b], dep[c]);
		} else {
			int aa = calcup(a, dep[a] - dep[c] - 1);
			int bb = calcup(b, dep[b] - dep[c] - 1);
			if (!ufunite(aa, bb, 1)) return false;
			unitedep[a] = min(unitedep[a], dep[c]);
			unitedep[b] = min(unitedep[b], dep[c]);
		}
	}
	dfsunite(0);
	REP(i, n) if (unitedep[i] < dep[i]) anyedge[i] = true;
	REP(i, n) if (unitedep[i] < dep[i] - 1) if (!ufunite(i, par[i], 0)) return false;
	//REP(i, n) if (par[i] != -1) { uffind(i); printf("%d-%d: %d,%d\n", i + 1, par[i] + 1, ufpar[i], ufdiff[i]); }

	int lo = 1, hi = n;
	while (lo + 1 < hi) {
		int mi = lo + (hi - lo) / 2;
		if (!dfscalc(0, mi)) lo = mi; else hi = mi;
	}
	ans = hi;
	//puts("");
	assert(dfscalc(0, ans));
	rev[0] = false; reconstruct(0);
	return true;
}

void run() {
	scanf("%d%d", &n, &nline);
	REP(i, n - 1) { int a, b; scanf("%d%d", &a, &b); --a, --b; adj[a].PB(b); adj[b].PB(a); }
	REP(i, n) sort(adj[i].begin(), adj[i].end());
	REP(i, nline) REP(j, 2) scanf("%d", &lineend[i][j]), --lineend[i][j];
	if (!solve()) { printf("-1\n"); return; }
	printf("%d\n", ans);
	REP(i, n) { if (i != 0) printf(" "); printf("%d", cost[i]); } puts("");
}

void stress() {
	REP(rep, 100000) {
		n = rand() % 10 + 2; REP(i, n) adj[i].clear();
		vector<int> col(n); REP(i, n) col[i] = i;
		REP(i, n - 1) while (true) { int a = rand() % n, b = rand() % n; if (col[a] == col[b]) continue; int ocol = col[b]; REP(j, n) if (col[j] == ocol) col[j] = col[a]; adj[a].PB(b), adj[b].PB(a); break; }
		REP(i, n) sort(adj[i].begin(), adj[i].end());
		nline = rand() % 10 + 1; REP(i, nline) while (true) { int a = rand() % n, b = rand() % n; if (a == b) continue; lineend[i][0] = a, lineend[i][1] = b; break; }
		//if (rep != 1) continue;
		//printf("%d %d\n", n, nline);
		//REP(at, n) REPSZ(i, adj[at]) { int to = adj[at][i]; if (at < to) printf("%d %d\n", at + 1, to + 1); }
		//REP(i, nline) printf("%d %d\n", lineend[i][0] + 1, lineend[i][1] + 1);
		solve();
		printf(".");
	}
}

int main() {
	run();
	//stress();
	return 0;
}

// testing cp editor
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
const int N=500005;
int n,m;
vector<int> e[N];

namespace DSU{
	int fa[N],v[N];
	int get(int x){
		if (x==fa[x]) return x;
		int f=fa[x];
		fa[x]=get(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		For(i,1,n) fa[i]=i,v[i]=0;
	}
	void merge(int x,int y,int vv){
		int px=get(x),py=get(y);
		if (px==py){
			if (v[x]^v[y]^vv){
				puts("-1");
				exit(0);
			}
		}
		else{
			fa[px]=py;
			v[px]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N];
	int fa[N],sz[N],dep[N];
	int pos[N],dfn[N],top[N];
	void dfs1(int x){
		sz[x]=1;
		for (auto i:e[x])
			if (i!=fa[x]){
				fa[i]=x;
				dep[i]=dep[x]+1;
				dfs1(i);
				sz[x]+=sz[i];
			}
	}
	void dfs2(int x,int tp){
		dfn[x]=++*dfn;
		pos[*dfn]=x;
		top[x]=tp;
		int k=0;
		for (auto i:e[x])
			if (i!=fa[x]&&sz[i]>sz[k])
				k=i;
		if (k) dfs2(k,tp);
		for (auto i:e[x])
			if (i!=fa[x]&&i!=k)
				dfs2(i,i);
	}
	int LCA(int x,int y){
		for (;top[x]!=top[y];x=fa[top[x]])
			if (dep[top[x]]<dep[top[y]])
				swap(x,y);
		return dep[x]<dep[y]?x:y;
	}
	int jmp(int x,int y){
		for (;;){
			if (dep[top[x]]<=dep[y])
				return pos[dfn[y]+1];
			if (dep[top[x]]==dep[y]+1)
				return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs1(1);
		dfs2(1,1);
	}
	void build2(){
		Rep(i,n,1){
			int x=pos[i];
			S[fa[x]]+=S[x];
			SS[fa[x]]+=SS[x];
			if (SS[x])
				DSU::merge(x,fa[x],0);
		}
	}
	void insert_que(int x,int y){
		int L=LCA(x,y);
		S[x]++; S[y]++; S[L]-=2;
		if (dep[x]^dep[L]) SS[x]++,SS[x=jmp(x,L)]--;
		if (dep[y]^dep[L]) SS[y]++,SS[y=jmp(y,L)]--;
		if ((x^L)&&(y^L)) DSU::merge(x,y,1);
	}
}
int v0[N],v1[N];
int vis[N],f[N],T;
int cc[N],fl[N];
bool check(int K){
	static int q[N];
	Rep(i,n,1){
		int x=TR::pos[i],y=TR::fa[x];
		int vl=0,vr=0;
		++T; *q=0;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		if (vis[DSU::fa[x]]==T){
			int c=DSU::fa[x];
			vl=v0[c]; vr=v1[c];
			if (DSU::v[x]) swap(vl,vr);
		}
		int vmn=0,vmx=0;
		For(j,1,*q)
			if (q[j]!=DSU::fa[x]){
				if (v0[q[j]]>v1[q[j]])
					swap(v0[q[j]],v1[q[j]]);
				vmn=max(vmn,v0[q[j]]);
				vmx=max(vmx,v1[q[j]]);
			}
		if (max(vmn,min(vl,vr))+max(vmx,max(vl,vr))>=K) return 0;
		f[x]=(max(vmn,vl)+max(vmx,vr)>=K?max(vmx,vl):max(vmn,vl))+1;
	}
	return 1;
}
void construct(int K){
	static int q[N];
	For(i,1,n){
		int x=TR::pos[i],y=TR::fa[x];
		++T; *q=0;
		//cout<<x<<' '<<fl[x]<<endl;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		For(j,1,*q){
			cc[q[j]]=fl[x];
			if (q[j]!=DSU::fa[x])
				cc[q[j]]^=(v0[q[j]]>f[x]-1||v1[q[j]]+f[x]>K);
			else cc[q[j]]^=DSU::v[x];
		}
		for (auto j:e[x])
			if (j!=y&&TR::S[j])
				fl[j]=cc[DSU::fa[j]]^DSU::v[j];
	}
}
int main(){
	scanf("%d%d",&n,&m);
	For(i,1,n-1){
		int x,y;
		scanf("%d%d",&x,&y);
		e[x].PB(y); e[y].PB(x);
	}
	TR::build();
	DSU::build();
	For(i,1,m){
		int x,y;
		scanf("%d%d",&x,&y);
		TR::insert_que(x,y);
	}
	TR::build2();
	For(i,1,n) DSU::get(i);
	int l=1,r=n,ans=0;
	while (l<=r){
		int mid=(l+r)/2;
		if (check(mid))
			ans=mid,r=mid-1;
		else l=mid+1;
	}
	printf("%d\n",ans);
	check(ans);
	construct(ans);
	static int v[N];
	For(i,1,n) printf("%d ",v[i]=(!fl[i]?f[i]:ans+1-f[i]));
	cout<<endl;
	For(i,2,n)
		assert(fl[i]^DSU::v[i]^fl[DSU::fa[i]]^1);
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef pair<int,bool> pib;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define sz(a) int(a.size())
#define debug cerr<<"itstakking\n"
const int N=1e6+10;

int gi() {
	int x=0,o=1;char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
	if(ch=='-') o=-1,ch=getchar();
	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x*o;
}

int n,m,fa[N],son[N],siz[N],dep[N],top[N],cov[N],seq[N],tt,k,f[N],dsu[N],cov2[N];
vi E[N];
pii I[N];
bool rev[N];

int getf(int x) {
	return x==dsu[x]?x:dsu[x]=getf(dsu[x]);
}

void merge(int x,int y) {
	dsu[getf(x)]=getf(y);
}

void merge(int x,int y,bool z) {
	if(!z) merge(x,y),merge(x+n,y+n);
	else merge(x,y+n),merge(x+n,y);
	if(getf(x)==getf(x+n)) { cout<<-1;exit(0); }
}

pib getlim(int x) {
	int tmp=getf(x);
	if(tmp<=n) return mp(tmp,0);
	return mp(tmp-n,1);
}

void dfs(int u,int ff) {
	fa[u]=ff;siz[u]=1;dep[u]=dep[ff]+1;seq[++tt]=u;
	if(ff) E[u].erase(find(E[u].begin(),E[u].end(),ff));
	for(auto v:E[u]) {
		dfs(v,u);siz[u]+=siz[v];
		if(siz[son[u]]<siz[v]) son[u]=v;
	}
	//cerr<<u<<' '<<son[u]<<'\n';
}

void dfs2(int u,int tp) {
	top[u]=tp; if(son[u]) dfs2(son[u],tp);
	for(auto v:E[u])
		if(v!=son[u]) dfs2(v,v);
}

int lca(int u,int v) {
	while(top[u]!=top[v]) {
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		u=fa[top[u]];
	}
	return dep[u]<dep[v]?u:v;
}

int getson(int u,int v) {
	int ret=0;
	while(top[u]!=top[v]) ret=top[v],v=fa[top[v]];
	return u==v?ret:son[u];
}

void upcov(int u) {
	for(auto v:E[u]) upcov(v),cov[u]+=cov[v],cov2[u]+=cov2[v];
	if(cov[u]) merge(u,fa[u],0);
}

void getans(int u) {
	if(rev[u]) {
		f[u]=k+1-f[u];
		for(auto v:E[u]) rev[v]^=1;
	}
	for(auto v:E[u]) getans(v);
}

bool check(int mid,bool fl=0) {
	k=mid;
	for(int i=n;i;i--) {
		int u=seq[i];
		pib cur=getlim(u);
		I[cur.fi]=mp(1,k);
		for(auto v:E[u])
			if(cov2[v]) {
				pib tmp=getlim(v);
				I[tmp.fi]=mp(1,k);
			}
		for(auto v:E[u])
			if(cov2[v]) {
				pib tmp=getlim(v);
				if(tmp.se==cur.se) I[tmp.fi].fi=max(I[tmp.fi].fi,f[v]+1);
				else I[tmp.fi].se=min(I[tmp.fi].se,k-f[v]);
			}
		pii t=mp(I[cur.fi].fi,I[cur.fi].se),ban=mp(1e9,-1e9);
		for(auto v:E[u])
			if(cov2[v]) {
				int x=getlim(v).fi;
				pii a=I[x],b=mp(k-I[x].se+1,k-I[x].fi+1);
				if(a>b) swap(a,b);
				if(a.fi>a.se) return 0;
				if(a.se+1<b.fi) ban.fi=min(ban.fi,a.se+1),ban.se=max(ban.se,b.fi-1);
				t.fi=max(t.fi,a.fi);t.se=min(t.se,b.se);
			}
		if(t.fi>t.se) return 0;
		if(t.fi<ban.fi) f[u]=t.fi;
		else if(ban.se<t.se) f[u]=ban.se+1;
		else return 0;
		for(auto v:E[u])
			if(cov2[v]) {
				pib tmp=getlim(v);
				if(I[tmp.fi].fi<=f[u]&&f[u]<=I[tmp.fi].se) rev[v]=(tmp.se!=cur.se);
				else rev[v]=(tmp.se==cur.se);
			}
	}
	if(fl) getans(1);
	return 1;
}

int main() {
	cin>>n>>m;
	for(int i=1;i<=n+n;i++) dsu[i]=i;
	for(int i=1,u,v;i<n;i++) u=gi(),v=gi(),E[u].pb(v),E[v].pb(u);
	dfs(1,0);dfs2(1,1);
	//cerr<<getson(1,3);
	for(int i=1;i<=m;i++) {
		int a=gi(),b=gi(),p=lca(a,b),x=0,y=0;
		//cerr<<a<<' '<<b<<' '<<p<<'\n';
		if(a!=p) ++cov[a],--cov[x=getson(p,a)];
		if(b!=p) ++cov[b],--cov[y=getson(p,b)];
		++cov2[a];++cov2[b];cov2[p]-=2;
		if(x&&y) merge(x,y,1);
	}
	upcov(1);
	int l=1,r=n;
	while(l<r) {
		int mid=(l+r)>>1;
		if(check(mid)) r=mid;
		else l=mid+1;
	}
	check(l,1);cout<<l<<'\n';
	for(int i=1;i<=n;i++) cout<<f[i]<<' ';
	return 0;
}

#include <bits/stdc++.h>
#define ctz __builtin_ctz
#define ad(x) ((((x) - 1) ^ 1) + 1)
#define tr(x) (2 * (x) - 1)
#define fa(x) (2 * (x))

const int N = 500054, M = N * 2, LN = 20;

int n, m, E = 0;
int to[M], first[N], next[M];
int P[LN][N], *p = *P, dep[N];
int cnt = 0, o[N], id[N], eid[N];
int cong[N], bel[M];

inline void up(int &x, const int y) {x < y ? x = y : 0;}
inline void down(int &x, const int y) {x > y ? x = y : 0;}
inline int min(const int x, const int y) {return x < y ? x : y;}
inline int max(const int x, const int y) {return x < y ? y : x;}

inline void addedge(int u, int v) {
	to[++E] = v, next[E] = first[u], first[u] = E;
	to[++E] = u, next[E] = first[v], first[v] = E;
}

void dfs(int x) {
	int i, y; o[++cnt] = x, id[x] = cnt;
	for (i = 0; P[i][x]; ++i) P[i + 1][x] = P[i][ P[i][x] ];
	for (i = first[x]; i; i = next[i])
		if ((y = to[i]) != p[x]) p[y] = x, dep[y] = dep[x] + 1, dfs(y);
	eid[x] = cnt;
}

int jump_until(int x, int d) {
	int S = dep[x] - d;
	for (assert(S >= 0); S; S &= S - 1) x = P[ctz(S)][x];
	return x;
}

namespace dsu {
	int p[M];

	int ancestor(int x) {return p[x] == x ? x : (p[x] = ancestor(p[x]));}
	inline bool test(int x, int y, bool un = false) {
		if ((x = ancestor(x)) == (y = ancestor(y))) return true;
		return un && (p[x] = y, false);
	}
	inline void equiv(int x, int y) {test(x, y, true), test(ad(x), ad(y), true);}
	inline void init(int n) {std::iota(p, p + ++n, 0);}
}

namespace dp {
	int f[N], stamp[N], li[N];
	int l[N], r[N];
	bool contain[N], rev[N];

	bool main(int R) {
		int i, x, y, cl, cr, cc, B, at, bt, top, _; bool Lr, Rr;
		memset(stamp, 0, (n + 1) << 2);
		for (_ = n; _; --_) {
			x = o[_], top = 0, cl = 1, cr = R, cc = (R + 1) / 2;
			for (i = first[x]; i; i = next[i]) {
				y = to[i], B = bel[tr(y)], at = (B + 1) / 2;
				if (stamp[at] != _) stamp[at] = _, l[at] = 1, r[at] = R, li[top++] = at;
				B & 1 ? up(l[at], f[y] + 1) : down(r[at], R - f[y]);
			}
			B = bel[tr(x)], bt = (B + 1) / 2;
			for (i = 0; i < top; ++i) {
				if (y = li[i], l[y] > r[y]) return false;
				if (y == bt)
					B & 1 ? (up(cl, l[y]), down(cr, r[y])) : (up(cl, R + 1 - r[y]), down(cr, R + 1 - l[y]));
				else
					Lr = l[y] * 2 <= R + 2, Rr = r[y] * 2 >= R,
					assert(Lr || Rr), down(cc, min(r[y], R + 1 - l[y])),
					up(cl, min(l[y], R + 1 - r[y])), down(cr, max(r[y], R + 1 - l[y]));
			}
			if (cc < cl) up(cl, R + 1 - cc);
			if (cl > cr) return false;
			for (f[x] = cl, i = 0; i < top; ++i) y = li[i], contain[y] = (l[y] <= cl && cl <= r[y]);
			for (i = first[x]; i; i = next[i])
				y = to[i], B = bel[tr(y)], at = (B + 1) / 2, rev[y] = (B ^ (at == bt ? bel[tr(x)] : contain[at])) & 1;
		}
		return true;
	}

	void dump(int R) {
		int i, v; ++R;
		for (i = 1; i <= n; ++i) v = o[i], (rev[v] ^= rev[p[v]]) && (f[v] = R - f[v]);
		for (i = 1; i <= n; ++i) printf("%d%c", f[i], i == n ? 10 : 32);
	}
}

int main() {
	int i, u, v, w, x, y, L, R, M;
	scanf("%d%d", &n, &m), dsu::init(2 * n);
	for (i = 1; i < n; ++i) scanf("%d%d", &u, &v), addedge(u, v);
	for (dfs(1); m; --m) {
		scanf("%d%d", &u, &v), assert(u != v);
		if (id[u] > id[v]) std::swap(u, v);
		if (id[v] <= eid[u])
			++cong[v], --cong[jump_until(v, dep[u] + 1)];
		else {
			w = min(dep[u], dep[v]), x = jump_until(u, w), y = jump_until(v, w);
			for (i = LN - 1; i >= 0; --i)
				if (P[i][x] != P[i][y]) x = P[i][x], y = P[i][y];
			++cong[u], ++cong[v], --cong[x], --cong[y];
			dsu::equiv(tr(x), fa(y));
		}
	}
	for (i = n; i; --i)
		if (v = o[i], cong[ p[v] ] += cong[v], cong[v]) dsu::equiv(tr(v), tr(p[v]));
	for (i = 2; i <= n; ++i) if (dsu::test(tr(i), fa(i))) return puts("-1"), 0;
	for (u = 1; u <= n; ++u) {
		if (to[ i = first[u] ] == p[u]) first[u] = next[i];
		else for (i = first[u]; next[i]; i = next[i])
			if (to[next[i]] == p[u]) next[i] = next[next[i]];
		if (!bel[ dsu::ancestor(tr(u)) ]) bel[ dsu::ancestor(tr(u)) ] = tr(u);
		if (!bel[ dsu::ancestor(fa(u)) ]) bel[ dsu::ancestor(fa(u)) ] = fa(u);
	}
	for (i = 1; i <= 2 * n; ++i) bel[i] = bel[ dsu::ancestor(i) ];
	for (L = 1, R = n; L < R; dp::main(M = (L + R) / 2) ? R = M : L = M + 1);
	return printf("%d\n", L), dp::main(L), dp::dump(L), 0;
}

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
#define ll long long
#define lb(x) ((x)&(-x))
#define pii pair<int,int>
#define vi vector<int>
#define pb push_back
using namespace std;
const int N=5e5+9;
const ll mod=998244353;
vi g[N];
int n,m;
namespace dsu{
	int fa[N],v[N];
	int find(int x){
		if(fa[x]==x)return x;
		int f=fa[x];
		fa[x]=find(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		rep(i,1,n+1)fa[i]=i;
	}
	void merge(int x,int y,int vv){
		int fx=find(x),fy=find(y);
		if(fx==fy){
			if(v[x]^v[y]^vv){
				printf("-1");
				exit(0);
			}
		}
		else{
			fa[fx]=fy;
			v[fx]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N],fa[N];
	int top[N],pos[N];
	int dfn[N],dep[N],sz[N];
	void dfs(int u){
		sz[u]=1;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			fa[v]=u;dep[v]=dep[u]+1;
			dfs(v);sz[u]+=sz[v];
		}
	}
	void dfs2(int u,int tp){
		top[u]=tp;dfn[u]=++*dfn;pos[*dfn]=u;
		int k=0;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			if(sz[v]>sz[k])k=v;
		}
		if(k)dfs2(k,tp);
		for(auto v:g[u]){
			if(v==fa[u]||v==k)continue;
			dfs2(v,v);
		}
	}
	int LCA(int u,int v){
		for(;top[u]!=top[v];u=fa[top[u]]){
			if(dep[top[u]]<dep[top[v]])swap(u,v);
		}
		return dep[u]<dep[v]?u:v;
	}
	int jmp(int x,int f){
		for(;;){
			if(dep[top[x]]<=dep[f])
			return pos[dfn[f]+1];
			if(dep[top[x]]==dep[f]+1)
			return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs(1);dfs2(1,1);
	}
	void build2(){
		per(i,1,n+1){
			int u=pos[i];
			S[fa[u]]+=S[u];
			SS[fa[u]]+=SS[u];
			if(SS[u])dsu::merge(u,fa[u],0);
		}
	}
	void connect(int u,int v){
		int f=LCA(u,v);
		++S[u],++S[v],S[f]-=2;
		if(dep[f]^dep[u])++SS[u],--SS[u=jmp(u,f)];
		if(dep[f]^dep[v])++SS[v],--SS[v=jmp(v,f)];
		if((u^f)&&(v^f))dsu::merge(u,v,1);
	}
}
int v0[N],v1[N],dp[N];
int vis[N],T,tag[N];
int cc[N],q[N];
bool check(int K){
	per(i,1,n+1){
		++T,*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		int vl=0,vr=0;
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[v];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		if(vis[dsu::fa[u]]==T){
			int x=dsu::fa[u];
			vl=v0[x],vr=v1[x];
			if(dsu::v[u])swap(vl,vr);
		}
		int vmn=0,vmx=0;
		rep(j,1,(*q)+1){
			if(dsu::fa[u]!=q[j]){
				if(v0[q[j]]>v1[q[j]])
				swap(v0[q[j]],v1[q[j]]);
				vmn=max(vmn,v0[q[j]]);
				vmx=max(vmx,v1[q[j]]);
			}
		}
		if(max(vmn,min(vl,vr))+max(vmx,max(vl,vr))>=K)return 0;
		dp[u]=(max(vmn,vl)+max(vmx,vr)>=K?max(vmx,vl):max(vmn,vl))+1;
	}
	return 1;
}
void construct(int K){
	rep(i,1,n+1){
		++T;*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[v];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		rep(j,1,(*q)+1){
			cc[q[j]]=tag[u];
			if(dsu::fa[u]!=q[j])
			cc[q[j]]^=(v0[q[j]]>dp[u]-1||v1[q[j]]+dp[u]>K);
			else cc[q[j]]^=dsu::v[u];
		}
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			tag[v]=cc[dsu::fa[v]]^dsu::v[v];
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	rep(i,1,n){
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);g[v].pb(u);
	}
	dsu::build();
	TR::build();
	rep(i,0,m){
		int u,v;
		scanf("%d%d",&u,&v);
		TR::connect(u,v);
	}
	TR::build2();
	rep(i,1,n+1)dsu::find(i);
	int l=1,r=n;
	while(l<r){
		int mid=l+r>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	printf("%d\n",l);
	check(l);
	construct(l);
	rep(i,1,n+1)printf("%d ",tag[i]?l+1-dp[i]:dp[i]);
}

#include <cstdio>
#include <vector>
#include <cstring>
#include <cstdlib>

int n,m,head[1000001],nxt[1000010],b[1000010],k=1,K,l,r,ans,sum[1000001];
int fa[500001][21],dep[1000001],val[1000001],f[1000001],fin[1000001];
bool exi[1000001];
bool vis[1000001];
typedef std::pair<int,int> tuple;
std::vector<tuple>Lca[1000001];
std::vector<int>son[1000001];
tuple Ans[1000001];
void push(int s,int t){
	nxt[++k]=head[s];
	head[s]=k;
	b[k]=t;
}
void dfs1(int x,int f){
	fa[x][0]=f;
	dep[x]=dep[f]+1;
	for(int i=1;i<=20;i++)
		fa[x][i]=fa[fa[x][i-1]][i-1];
	for(int i=head[x];i;i=nxt[i])
		if(b[i]!=f)dfs1(b[i],x);
}
int LCA(int x,int y,int go=-1){
	if(dep[x]<dep[y])std::swap(x,y);
	for(int i=20;~i;--i)if(dep[fa[x][i]]>dep[y])x=fa[x][i];
	if(fa[x][0]==y){
		++val[x];
		son[y].push_back(x);
		return y;
	}
	if(dep[x]!=dep[y])x=fa[x][0];
	for(int i=20;~i;--i)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
	++val[x],++val[y];
	if(~go)Lca[fa[x][0]].push_back(std::make_pair(x,y));
	return fa[x][0];
}
tuple &operator&=(tuple &a,tuple b){
	a.first=std::max(a.first,b.first);
	a.second=std::min(a.second,b.second);
	return a;
}
struct bipart{
	int head[1000001],nxt[4000010],b[4000010],k,col[1000001];
	std::vector<int>v[2][1000001];
	void clear(int x){head[x]=0,col[x]=-1;}
	void init(){k=0;}
	void push(int s,int t){
//		printf("push %d %d\n",s,t);
		nxt[++k]=head[s];
		head[s]=k;
		b[k]=t;
		nxt[++k]=head[t];
		head[t]=k;
		b[k]=s;
	}
	bool ch(int x,int ins,int c=0){
//		printf("ch %d %d %d\n",x,c,col[x]);
		if(~col[x])return (col[x]==c);
		if(x<=n)v[c][ins].push_back(x);
		col[x]=c;
		for(int i=head[x];i;i=nxt[i]){
//			printf("%d %d\n",b[i],x);
			if(!ch(b[i],ins,c^1))return 0;
		}
		return 1;
	}
	tuple solve(int x){
		int l=0,r=K+1;
		for(int i=0;i<v[0][x].size();i++)r=std::min(r,K+1-f[v[0][x][i]]);
		for(int i=0;i<v[1][x].size();i++)l=std::max(l,f[v[1][x][i]]);
		return std::make_pair(l,r);
	}
	void getans(int x,int c=0){
		if(vis[x])return;
//		printf("getans %d %d %d\n",x,c,vis[x]);
		vis[x]=1;
		if(x<=n&&!c)fin[x]=1;
		for(int i=head[x];i;i=nxt[i]){
//			printf("%d %d\n",x,b[i]);
			getans(b[i],c^1);
		}
	}
}Check;
void Do(int x){
	if(x&&!~Check.col[x]&&!Check.ch(x,x)){puts("-1");exit(0);}
}
void dfs2(int x,int f){
	for(int i=head[x];i;i=nxt[i])
		if(b[i]!=f){
			dfs2(b[i],x),sum[x]+=sum[b[i]];
			exi[b[i]]=(sum[b[i]]>val[b[i]]);
		}
	for(int i=head[x];i;i=nxt[i])if(exi[b[i]]&&b[i]!=f)Check.push(x+n,b[i]);
	for(int i=0;i<Lca[x].size();++i)
		Check.push(Lca[x][i].first,Lca[x][i].second),exi[Lca[x][i].first]=exi[Lca[x][i].second]=1;
//	printf("%d\n",x);
	Do(x+n);
	for(int i=head[x];i;i=nxt[i])if(b[i]!=f)Do(b[i]);
}
bool judge(int x,int f){
	for(int i=head[x];i;i=nxt[i])
		if(b[i]!=f&&!judge(b[i],x))return 0;
	tuple ans=std::make_pair(0,K+1),tem=Check.solve(x+n),now;
//	printf("judge %d %d\n",x,f);
	for(int i=head[x];i;i=nxt[i])
		if(b[i]!=f&&exi[b[i]]){
			Ans[b[i]]=now=Check.solve(b[i]);
			if(K+1-now.second<now.first)now=std::make_pair(K+1-now.second,K+1-now.first);
			ans&=now;
		}
	for(int i=0;i<son[x].size();++i)
		if(!exi[son[x][i]]){
//			printf("%d %d\n",x,son[x][i]);
			ans&=std::make_pair(0,K+1-::f[son[x][i]]);
		}
	(now=tem)&=ans;
	if(now.first<now.second-1)::f[x]=now.first+1;
	else{
		ans=std::make_pair(K+1-ans.second,K+1-ans.first);
		ans&=tem;
		if(ans.first>=ans.second-1)return 0;
		else ::f[x]=ans.first+1;
	}
	if(::ans==-2){
		Check.getans(x+n);
		for(int i=head[x];i;i=nxt[i])
			if(b[i]!=f&&exi[b[i]]&&!vis[b[i]])
				Check.getans(b[i],!(Ans[b[i]].first<(::f[x])&&Ans[b[i]].second>::f[x]));
		for(int i=0;i<son[x].size();i++)
			if(!exi[son[x][i]]){
				if((::f[son[x][i]])>=(::f[x]))fin[son[x][i]]=1;
			}
	}
//	printf("solve: %d %d %d\n",x,::f[x],K);
	return 1;
}
void set(int x,int f){
	for(int i=head[x];i;i=nxt[i])
		if(b[i]!=f)fin[b[i]]^=fin[x],set(b[i],x);
	if(fin[x])::f[x]=K+1-::f[x];
}
int read(){
	int x=0;
	char ch=getchar();
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
	return x;
}
void write(int x){
	if(x>9)write(x/10);
	putchar((x%10)+'0');
}
int main(){
	scanf("%d%d",&n,&m);
	memset(Check.col,-1,sizeof Check.col);
	for(int i=1,u,v;i<n;i++)u=read(),v=read(),push(u,v),push(v,u);
	dfs1(1,0);
	for(int i=1,a,b;i<=m;i++){
		a=read(),b=read();
		int lca=LCA(a,b,0);
		++sum[a];
		++sum[b];
		sum[lca]-=2;
	}
	dfs2(1,0);
	l=1,r=n,ans=-1;
	while(l<=r){
		memset(Check.col,0,sizeof Check.col);
		K=(l+r)>>1;
		if(judge(1,0))ans=K,r=K-1;
		else l=K+1;
	}
	K=ans;ans=-2;
	printf("%d\n",K);
	memset(Check.col,0,sizeof Check.col);
	judge(1,0);
//	for(int i=1;i<=n;i++)printf("%d ",fin[i]);putchar('\n');
	set(1,0);
	for(int i=1;i<=n;i++)write(f[i]),putchar(' ');putchar('\n');
}

#include<bits/stdc++.h>
#define cs const
#define pb push_back
#define fi first
#define se second
using namespace std;
typedef pair<int, int> pi;
cs int N = 5e5 + 50;
int n, m;
vector<int> G[N];

int fa[N][20], dep[N], d[N];
void pre_dfs(int u, int f){
	dep[u] = dep[fa[u][0] = f] + 1;
	for(int i = 1; i <= 18; i++)
	fa[u][i] = fa[fa[u][i - 1]][i - 1];
	vector<int> e;
	for(int v : G[u]) if(v != f)
	e.pb(v), pre_dfs(v, u); G[u] = e;
} int LCA(int x, int y){
	if(dep[x] < dep[y]) swap(x, y);
	for(int i = 18; ~i; i--)
	if(dep[fa[x][i]] >= dep[y]) x = fa[x][i];
	if(x == y) return x;
	for(int i = 18; ~i; i--)
	if(fa[x][i] != fa[y][i])
	x = fa[x][i], y = fa[y][i];
	return fa[x][0];
} int jmp(int x, int d){
	for(int i = 18; ~i; i--)
	if(d >= (1 << i)) d -= 1 << i, x = fa[x][i];
	return x;
}

vector<pi> e[N];
int blk[N], c[N], ct;
void sub_dfs(int u, int f){
	for(int v : G[u]) sub_dfs(v, u), d[u] += d[v];
	if(d[u]) e[u].pb(pi(f, 0)), e[f].pb(pi(u, 0));
}
void dfs(int u, int co){
	if(c[u] >= 0 && c[u] != co){
		puts("-1"); exit(0);
	} if(c[u] >= 0) return;
	c[u] = co; blk[u] = ct;
	for(pi v : e[u]) dfs(v.fi, co ^ v.se);
}

pi f[N], g[N]; int ans[N];
pi mrg(pi a, pi b){ return pi(max(a.fi, b.fi), min(a.se, b.se)); }
bool work(int u, int k){
	for(int v : G[u])
	if(!work(v, k)) return false;
	f[u] = pi(1, k);
	static int ex[N]; int t = 0;
	for(int v : G[u]) if(blk[v]){
		if(blk[v] == blk[u]){
			if(!c[v]) f[u] = mrg(f[u], pi(1, f[v].se - 1));
			else f[u] = mrg(f[u], pi(f[v].fi + 1, k));
		} else{
			if(!ex[blk[v]]) ex[blk[v]] = ++t, g[t] = pi(1, k);
			int z = ex[blk[v]];
			if(!c[v]) g[z] = mrg(g[z], pi(1, f[v].se - 1));
			else g[z] = mrg(g[z], pi(f[v].fi + 1, k));
		}
	}
	for(int v : G[u]) ex[blk[v]] = 0;
	if(f[u].fi > f[u].se) return false;
//	cout << "fasfsa " << k << " " <<  u << " " << f[u].fi << " " << f[u].se << endl;
	pi z(1, k);
	for(int i = 1; i <= t; i++){
//		cout << g[i].fi << " " << g[i].se << endl;
		if(g[i].fi > g[i].se) return false;
		if(k - g[i].se + 1 < g[i].fi)
		g[i] = pi(k - g[i].se + 1, k - g[i].fi + 1);
		z = mrg(z, g[i]);
	} pi p = mrg(z, f[u]);
	pi q = mrg(pi(k - z.se + 1, k - z.fi + 1), f[u]);
//	cout << z.fi << " " << z.se << endl;
	if(p.fi > p.se && q.fi > q.se) return false;
	if(p.fi > p.se) f[u] = q;
	else if(q.fi > q.se) f[u] = p;
	else f[u] = pi(min(p.fi, q.fi), max(p.se, q.se));
//	cout << "fasfsa " << k << " " <<  u << " " << f[u].fi << " " << f[u].se << endl;
	return true;
}
void cope(int u, int k, bool r){
	static int ex[N], rm[N]; int t = 0;
//	cout << "Cope " << u << " " << r << " " << f[u].fi << " " << f[u].se << endl;
	for(int v : G[u]) if(blk[v] && blk[v] != blk[u]){
		if(!ex[blk[v]]) rm[ex[blk[v]] = ++t]
		= blk[v], g[t] = pi(1, k);
		int z = ex[blk[v]];
		if(!c[v]) g[z] = mrg(g[z], pi(1, f[v].se - 1));
		else g[z] = mrg(g[z], pi(f[v].fi + 1, k));
	} for(int v : G[u]) ex[blk[v]] = 0;
	static bool rv[N];
	for(int i = 1; i <= t; i++)
	rv[rm[i]] = (g[i].fi <= ans[u] && ans[u] <= g[i].se) ? 0 : 1;
	for(int v : G[u]) {
		if(!blk[v]) ans[v] = f[v].fi, cope(v, k, 0);
		else{
			bool o = blk[v] == blk[u] ? r : rv[blk[v]];
			if(!o) ans[v] = c[v] ? f[v].fi : f[v].se;
			else ans[v] = c[v] ? k - f[v].fi + 1 : k - f[v].se + 1;
			cope(v, k, o);
		}
	}
}

int main(){
	#ifdef FSYo
	freopen("1.in", "r", stdin);
	#endif
	cin >> n >> m;
	for(int i = 1, u, v; i < n; i++)
	scanf("%d%d", &u, &v),
	G[u].pb(v), G[v].pb(u);
	pre_dfs(1, 0);
	for(int i = 1, x, y, l; i <= m; i++){
		scanf("%d%d", &x, &y); l = LCA(x, y);
		if(x != l) ++d[x], --d[jmp(x, dep[x] - dep[l] - 1)];
		if(y != l) ++d[y], --d[jmp(y, dep[y] - dep[l] - 1)];
		if(x != l && y != l)
		e[x].pb(pi(y, 1)), e[y].pb(pi(x, 1));
	} sub_dfs(1, 0);
	memset(c, -1, sizeof(c));
	for(int i = 2; i <= n; i++)
	if(!blk[i]) ++ct, dfs(i, 0);

	int l = 1, r = n;
	while(l < r){
		int mid = (l + r) >> 1;
		if(work(1, mid)) r = mid;
		else l = mid + 1;
	} cout << l << '\n';
	work(1, l);
	ans[1] = f[1].fi;
	cope(1, l, 0);
	for(int i = 1; i <= n; i++)
	cout << ans[i] << " ";
	return 0;
}

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

typedef long long ll;
typedef long double ld;
typedef double db;
typedef string str;

typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef pair<db,db> pd;

typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<db> vd;
typedef vector<str> vs;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<pd> vpd;

#define mp make_pair
#define f first
#define s second
#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
#define ins insert
#define ft front()
#define bk back()
#define pf push_front
#define pb push_back
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound

#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i)
#define R0F(i,a) ROF(i,0,a)
#define trav(a,x) for (auto& a: x)

const int MOD = 1e9+7; // 998244353;
const int MX = 5e5+5;
const ll INF = 1e18;
const ld PI = acos((ld)-1);
const int xd[4] = {1,0,-1,0}, yd[4] = {0,1,0,-1};

template<class T> bool ckmin(T& a, const T& b) {
	return b < a ? a = b, 1 : 0; }
template<class T> bool ckmax(T& a, const T& b) {
	return a < b ? a = b, 1 : 0; }
int pct(int x) { return __builtin_popcount(x); }
int bit(int x) { return 31-__builtin_clz(x); } // floor(log2(x))
int cdiv(int a, int b) { return a/b+!(a<0||a%b == 0); } // division of a by b rounded up, assumes b > 0

namespace input {
	template<class T> void re(complex<T>& x);
	template<class T1, class T2> void re(pair<T1,T2>& p);
	template<class T> void re(vector<T>& a);
	template<class T, size_t SZ> void re(array<T,SZ>& a);

	template<class T> void re(T& x) { cin >> x; }
	void re(double& x) { string t; re(t); x = stod(t); }
	void re(ld& x) { string t; re(t); x = stold(t); }
	template<class T, class... Ts> void re(T& t, Ts&... ts) {
		re(t); re(ts...);
	}

	template<class T> void re(complex<T>& x) { T a,b; re(a,b); x = {a,b}; }
	template<class T1, class T2> void re(pair<T1,T2>& p) { re(p.f,p.s); }
	template<class T> void re(vector<T>& a) { F0R(i,sz(a)) re(a[i]); }
	template<class T, size_t SZ> void re(array<T,SZ>& a) { F0R(i,SZ) re(a[i]); }
}

using namespace input;

namespace output {
	void pr(int x) { cout << x; }
	void pr(long x) { cout << x; }
	void pr(ll x) { cout << x; }
	void pr(unsigned x) { cout << x; }
	void pr(unsigned long x) { cout << x; }
	void pr(unsigned long long x) { cout << x; }
	void pr(float x) { cout << x; }
	void pr(double x) { cout << x; }
	void pr(ld x) { cout << x; }
	void pr(char x) { cout << x; }
	void pr(const char* x) { cout << x; }
	void pr(const string& x) { cout << x; }
	void pr(bool x) { pr(x ? "true" : "false"); }
	template<class T> void pr(const complex<T>& x) { cout << x; }

	template<class T1, class T2> void pr(const pair<T1,T2>& x);
	template<class T> void pr(const T& x);

	template<class T, class... Ts> void pr(const T& t, const Ts&... ts) {
		pr(t); pr(ts...);
	}
	template<class T1, class T2> void pr(const pair<T1,T2>& x) {
		pr("{",x.f,", ",x.s,"}");
	}
	template<class T> void pr(const T& x) {
		pr("{"); // const iterator needed for vector<bool>
		bool fst = 1; for (const auto& a: x) pr(!fst?", ":"",a), fst = 0;
		pr("}");
	}

	void ps() { pr("\n"); } // print w/ spaces
	template<class T, class... Ts> void ps(const T& t, const Ts&... ts) {
		pr(t); if (sizeof...(ts)) pr(" "); ps(ts...);
	}

	void pc() { pr("]\n"); } // debug w/ commas
	template<class T, class... Ts> void pc(const T& t, const Ts&... ts) {
		pr(t); if (sizeof...(ts)) pr(", "); pc(ts...);
	}
	#define dbg(x...) pr("[",#x,"] = ["), pc(x);
}

using namespace output;

namespace io {
	void setIn(string s) { freopen(s.c_str(),"r",stdin); }
	void setOut(string s) { freopen(s.c_str(),"w",stdout); }
	void setIO(string s = "") {
		ios_base::sync_with_stdio(0); cin.tie(0); // fast I/O
		// cin.exceptions(cin.failbit);
		// throws exception when do smth illegal
		// ex. try to read letter into int
		if (sz(s)) { setIn(s+".in"), setOut(s+".out"); } // for USACO
	}
}

using namespace io;

mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());

/**
 * Description: Disjoint Set Union with path compression.
 	* Add edges and test connectivity. Use for Kruskal's
 	* minimum spanning tree.
 * Time: O(\alpha(N))
 * Source: CSAcademy, KACTL
 * Verification: USACO superbull
 */

struct DSU {
	vpi par;
	void init(int n) {
		par.rsz(n);
		F0R(i,n) par[i] = {i,0};
	}
	pi get(int x) {
		if (par[x].f == x) return par[x];
		pi p = get(par[x].f); p.s ^= par[x].s;
		return par[x] = p;
	}
	void unite(int x, int y, int z) { // union-by-rank
		pi X = get(x), Y = get(y);
		// ps("UNITE",x,y,z);
		if (X.f == Y.f) {
			if ((X.s^Y.s) != z) {
				ps(-1);
				exit(0);
			}
		} else {
			par[Y.f] = {X.f,X.s^Y.s^z};
		}
	}
};

/**
 * Description: Calculates least common ancestor in tree
 	* with root $R$ using binary jumping.
 * Time: O(N\log N) build, O(\log N) query
 * Source: USACO Camp
 * Verification: Debug the Bugs
 */

template<int SZ> struct LCA {
	static const int BITS = 32-__builtin_clz(SZ);
	int N, R = 1, par[BITS][SZ], depth[SZ];
	vi adj[SZ];
	/// INITIALIZE
	void ae(int u, int v) { adj[u].pb(v), adj[v].pb(u); }
	void dfs(int u, int prev){
		par[0][u] = prev; depth[u] = depth[prev]+1;
		trav(v,adj[u]) if (v != prev) dfs(v, u);
	}
	void init(int _N) {
		N = _N; dfs(R,0);
		FOR(k,1,BITS) FOR(i,1,N+1)
			par[k][i] = par[k-1][par[k-1][i]];
	}
	/// QUERY
	int getPar(int a, int b) {
		R0F(k,BITS) if (b&(1<<k)) a = par[k][a];
		return a; }
	int lca(int u, int v){
		if (depth[u] < depth[v]) swap(u,v);
		u = getPar(u,depth[u]-depth[v]);
		R0F(k,BITS) if (par[k][u] != par[k][v])
			u = par[k][u], v = par[k][v];
		return u == v ? u : par[0][u];
	}
	int dist(int u, int v) {
		return depth[u]+depth[v]-2*depth[lca(u,v)]; }
};

LCA<MX> L;
int n,m, mn[MX], c[MX], mid;
bool bad;

DSU D;
bool par[MX], tmpPar[MX];
pi stor[MX];

void dfs(int x) {
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		dfs(t); if (bad) return;
	}
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		stor[D.get(t).f].f = MOD;
		// ps("OH",x,t,D.get(x).f,D.get(t).f);
	}
	pi p = D.get(x); stor[p.f] = {1,mid};
	vi todo = {p.f};
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		pi p = D.get(t);
		if (stor[p.f].f == MOD) {
			// ps("WAT",x,p);
			stor[p.f] = {1,mid};
			todo.pb(p.f);
		}
		if (p.s == 0) ckmax(stor[p.f].f,mn[t]+1); // goes up
		else ckmin(stor[p.f].s,mid-mn[t]);
		// ps("AH",stor[p.f]);
	}
	pi P = stor[p.f]; if (p.s) P = {mid+1-P.s,mid+1-P.f};
	pi ban = {MOD,-MOD};
	int LL = P.f, RR = P.s;
	FOR(i,1,sz(todo)) {
		pi z = stor[todo[i]];
		if (z.f > z.s) { bad = 1; return; }
		pi Z = {mid+1-z.s,mid+1-z.f};
		if (z > Z) swap(z,Z);
		ckmax(LL,z.f), ckmin(RR,Z.s);
		if (z.s+1 < Z.f) {
			ckmin(ban.f,z.s+1), ckmax(ban.s,Z.f-1);
		}
	}
	if (LL > RR) { bad = 1; return; }
	int val;
	if (LL < ban.f) val = LL;
	else if (ban.s < RR) val = ban.s+1;
	else { bad = 1; return; }
	mn[x] = val; tmpPar[p.f] = p.s;
	FOR(i,1,sz(todo)) {
		pi t = stor[todo[i]];
		//ps("OH",t);
		if (t.f <= val && val <= t.s) {
			tmpPar[todo[i]] = 0;
		} else {
			// assert(mid+1-t.s.s <= val && val <= mid+1-t.s.f);
			tmpPar[todo[i]] = 1;
		}
	}
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		pi p = D.get(t);
		par[t] = tmpPar[p.f]^p.s;
		//ps("HAHA",t,par[t]);
	}
}

bool ok() {
	bad = 0; dfs(1);
	return !bad;
}

void genAns(int x) {
	if (par[x] == 0) {
		c[x] = mn[x];
	} else {
		c[x] = mid+1-mn[x];
	}
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		par[t] ^= par[x];
		genAns(t);
	}
}

int ad[MX];
void path(int a, int b) {
	// ps("OH",a,b);
	int x = L.lca(a,b);
	int A,B;
	if (a != x) {
		A = L.getPar(a,L.depth[a]-L.depth[x]-1);
		ad[a] ++; ad[A] --;
	}
	if (b != x) {
		B = L.getPar(b,L.depth[b]-L.depth[x]-1);
		ad[b] ++; ad[B] --;
	}
	if (a != x && b != x) {
		D.unite(A,B,1);
	}
}

void genAd(int x) {
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		genAd(t);
		ad[x] += ad[t];
	}
	if (ad[x]) {
		D.unite(x,L.par[0][x],0);
	}
}

/**
 * Description: Fast input and output.
 * Time: input is $\sim$300ms faster for $10^6$ long longs on CF
 * Source:
 	* https://codeforces.com/gym/102394/submission/64154785
 	* https://codeforces.com/contest/1254/submission/65420506 (neal)
 	* https://codeforces.com/blog/entry/45835 (AI.Cash)
 * Verification: https://codeforces.com/gym/102394/problem/G
 */

namespace FastIO {
	const int BSZ = 1<<15; ////// INPUT
	char ibuf[BSZ]; int ipos, ilen;
	char nc() { // next char
		if (ipos == ilen) {
			ipos = 0; ilen = fread(ibuf,1,BSZ,stdin);
			if (!ilen) return EOF;
		}
		return ibuf[ipos++];
	}
	void rs(str& x) { // read str
		char ch; while (isspace(ch = nc()));
		do { x += ch; } while (!isspace(ch = nc()) && ch != EOF);
	}
	template<class T> void ri(T& x) { // read int or ll
		char ch; int sgn = 1;
		while (!isdigit(ch = nc())) if (ch == '-') sgn *= -1;
		x = ch-'0'; while (isdigit(ch = nc())) x = x*10+(ch-'0');
		x *= sgn;
	}
	template<class T, class... Ts> void ri(T& t, Ts&... ts) {
		ri(t); ri(ts...); } // read ints
	////// OUTPUT (call initO() at start)
	char obuf[BSZ], numBuf[100]; int opos;
	void flushOut() { fwrite(obuf,1,opos,stdout); opos = 0; }
	void wc(char c) { // write char
		if (opos == BSZ) flushOut();
		obuf[opos++] = c; }
	void ws(str s) { trav(c,s) wc(c); } // write str
	template<class T> void wi(T x, char after = '\0') { /// write int
		if (x < 0) wc('-'), x *= -1;
		int len = 0; for (;x>=10;x/=10) numBuf[len++] = '0'+(x%10);
		wc('0'+x); R0F(i,len) wc(numBuf[i]);
		if (after) wc(after);
	}
	void initO() { assert(atexit(flushOut) == 0); } /// auto-flush output
}
using namespace FastIO;
/// initO(); int a,b; ri(a,b); wi(b,'\n'); wi(a,'\n');

void init() {
	initO();
	ri(n,m); D.init(n+1);
	F0R(i,n-1) {
		int a,b; ri(a,b);
		L.ae(a,b);
	}
	L.init(n);
	F0R(i,m) {
		int a,b; ri(a,b);
		path(a,b);
	}
	// FOR(i,1,n+1) ps(i,ad[i]);
	genAd(1);
}

int main() {
	init();
	mid = n; assert(ok());
	// exit(0);
	int lo = 1, hi = n;
	while (lo < hi) {
		mid = (lo+hi)/2;
		if (ok()) hi = mid;
		else lo = mid+1;
	}
	mid = lo; assert(ok());
	ps(mid);
	genAns(1);
	FOR(i,1,n+1) {
		if (i < n) wi(c[i],' ');
		else wi(c[i],'\n');
	}
	// you should actually read the stuff at the bottom
}

/* stuff you should look for
	* int overflow, array bounds
	* special cases (n=1?)
	* do smth instead of nothing and stay organized
	* WRITE STUFF DOWN
*/

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

typedef long long ll;
typedef long double ld;
typedef double db;
typedef string str;

typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef pair<db,db> pd;

typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<db> vd;
typedef vector<str> vs;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<pd> vpd;

#define mp make_pair
#define f first
#define s second
#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
#define ins insert
#define ft front()
#define bk back()
#define pf push_front
#define pb push_back
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound

#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i)
#define R0F(i,a) ROF(i,0,a)
#define trav(a,x) for (auto& a: x)

const int MOD = 1e9+7; // 998244353;
const int MX = 5e5+5;
const ll INF = 1e18;
const ld PI = acos((ld)-1);
const int xd[4] = {1,0,-1,0}, yd[4] = {0,1,0,-1};

template<class T> bool ckmin(T& a, const T& b) {
	return b < a ? a = b, 1 : 0; }
template<class T> bool ckmax(T& a, const T& b) {
	return a < b ? a = b, 1 : 0; }
int pct(int x) { return __builtin_popcount(x); }
int bit(int x) { return 31-__builtin_clz(x); } // floor(log2(x))
int cdiv(int a, int b) { return a/b+!(a<0||a%b == 0); } // division of a by b rounded up, assumes b > 0

namespace input {
	template<class T> void re(complex<T>& x);
	template<class T1, class T2> void re(pair<T1,T2>& p);
	template<class T> void re(vector<T>& a);
	template<class T, size_t SZ> void re(array<T,SZ>& a);

	template<class T> void re(T& x) { cin >> x; }
	void re(double& x) { string t; re(t); x = stod(t); }
	void re(ld& x) { string t; re(t); x = stold(t); }
	template<class T, class... Ts> void re(T& t, Ts&... ts) {
		re(t); re(ts...);
	}

	template<class T> void re(complex<T>& x) { T a,b; re(a,b); x = {a,b}; }
	template<class T1, class T2> void re(pair<T1,T2>& p) { re(p.f,p.s); }
	template<class T> void re(vector<T>& a) { F0R(i,sz(a)) re(a[i]); }
	template<class T, size_t SZ> void re(array<T,SZ>& a) { F0R(i,SZ) re(a[i]); }
}

using namespace input;

namespace output {
	void pr(int x) { cout << x; }
	void pr(long x) { cout << x; }
	void pr(ll x) { cout << x; }
	void pr(unsigned x) { cout << x; }
	void pr(unsigned long x) { cout << x; }
	void pr(unsigned long long x) { cout << x; }
	void pr(float x) { cout << x; }
	void pr(double x) { cout << x; }
	void pr(ld x) { cout << x; }
	void pr(char x) { cout << x; }
	void pr(const char* x) { cout << x; }
	void pr(const string& x) { cout << x; }
	void pr(bool x) { pr(x ? "true" : "false"); }
	template<class T> void pr(const complex<T>& x) { cout << x; }

	template<class T1, class T2> void pr(const pair<T1,T2>& x);
	template<class T> void pr(const T& x);

	template<class T, class... Ts> void pr(const T& t, const Ts&... ts) {
		pr(t); pr(ts...);
	}
	template<class T1, class T2> void pr(const pair<T1,T2>& x) {
		pr("{",x.f,", ",x.s,"}");
	}
	template<class T> void pr(const T& x) {
		pr("{"); // const iterator needed for vector<bool>
		bool fst = 1; for (const auto& a: x) pr(!fst?", ":"",a), fst = 0;
		pr("}");
	}

	void ps() { pr("\n"); } // print w/ spaces
	template<class T, class... Ts> void ps(const T& t, const Ts&... ts) {
		pr(t); if (sizeof...(ts)) pr(" "); ps(ts...);
	}

	void pc() { pr("]\n"); } // debug w/ commas
	template<class T, class... Ts> void pc(const T& t, const Ts&... ts) {
		pr(t); if (sizeof...(ts)) pr(", "); pc(ts...);
	}
	#define dbg(x...) pr("[",#x,"] = ["), pc(x);
}

using namespace output;

namespace io {
	void setIn(string s) { freopen(s.c_str(),"r",stdin); }
	void setOut(string s) { freopen(s.c_str(),"w",stdout); }
	void setIO(string s = "") {
		ios_base::sync_with_stdio(0); cin.tie(0); // fast I/O
		// cin.exceptions(cin.failbit);
		// throws exception when do smth illegal
		// ex. try to read letter into int
		if (sz(s)) { setIn(s+".in"), setOut(s+".out"); } // for USACO
	}
}

using namespace io;

mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());

/**
 * Description: Disjoint Set Union with path compression.
 	* Add edges and test connectivity. Use for Kruskal's
 	* minimum spanning tree.
 * Time: O(\alpha(N))
 * Source: CSAcademy, KACTL
 * Verification: USACO superbull
 */

struct DSU {
	vpi par;
	void init(int n) {
		par.rsz(n);
		F0R(i,n) par[i] = {i,0};
	}
	pi get(int x) {
		if (par[x].f == x) return par[x];
		pi p = get(par[x].f); p.s ^= par[x].s;
		return par[x] = p;
	}
	void unite(int x, int y, int z) { // union-by-rank
		pi X = get(x), Y = get(y);
		// ps("UNITE",x,y,z);
		if (X.f == Y.f) {
			if ((X.s^Y.s) != z) {
				ps(-1);
				exit(0);
			}
		} else {
			par[Y.f] = {X.f,X.s^Y.s^z};
		}
	}
};

/**
 * Description: Calculates least common ancestor in tree
 	* with root $R$ using binary jumping.
 * Time: O(N\log N) build, O(\log N) query
 * Source: USACO Camp
 * Verification: Debug the Bugs
 */

template<int SZ> struct LCA {
	static const int BITS = 32-__builtin_clz(SZ);
	int N, R = 1, par[BITS][SZ], depth[SZ];
	vi adj[SZ];
	/// INITIALIZE
	void ae(int u, int v) { adj[u].pb(v), adj[v].pb(u); }
	void dfs(int u, int prev){
		par[0][u] = prev; depth[u] = depth[prev]+1;
		trav(v,adj[u]) if (v != prev) dfs(v, u);
	}
	void init(int _N) {
		N = _N; dfs(R,0);
		FOR(k,1,BITS) FOR(i,1,N+1)
			par[k][i] = par[k-1][par[k-1][i]];
	}
	/// QUERY
	int getPar(int a, int b) {
		R0F(k,BITS) if (b&(1<<k)) a = par[k][a];
		return a; }
	int lca(int u, int v){
		if (depth[u] < depth[v]) swap(u,v);
		u = getPar(u,depth[u]-depth[v]);
		R0F(k,BITS) if (par[k][u] != par[k][v])
			u = par[k][u], v = par[k][v];
		return u == v ? u : par[0][u];
	}
	int dist(int u, int v) {
		return depth[u]+depth[v]-2*depth[lca(u,v)]; }
};

LCA<MX> L;
int n,m, mn[MX], c[MX], mid;
bool bad;

DSU D;
bool par[MX], tmpPar[MX];
void dfs(int x) {
	unordered_map<int,pi> m;
	pi p = D.get(x); m[p.f] = {1,mid};
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		dfs(t); if (bad) return;
		pi p = D.get(t);
		//ps("WUT",x,t,p,mn[t]);
		if (!m.count(p.f)) m[p.f] = {1,mid};
		if (p.s == 0) ckmax(m[p.f].f,mn[t]+1); // goes up
		else ckmin(m[p.f].s,mid-mn[t]);
	}
	pi P = m[p.f]; if (p.s) P = {mid+1-P.s,mid+1-P.f};
	vpi extra;
	extra.pb({P.f,1}); extra.pb({P.s+1,-1});
	trav(t,m) if (t.f != p.f) {
		pi z = {t.s.f,t.s.s};
		if (z.f > z.s) {
			bad = 1;
			return;
		}
		pi Z = {mid+1-z.s,mid+1-z.f};
		if (z > Z) swap(z,Z);
		if (z.s >= Z.f) {
			extra.pb({z.f,1}); extra.pb({Z.s+1,-1});
		} else {
			extra.pb({z.f,1}); extra.pb({z.s+1,-1});
			extra.pb({Z.f,1}); extra.pb({Z.s+1,-1});
		}
	}
	sort(all(extra));
	int sum = 0;
	for (int i = 0; i < sz(extra); ) {
		int I = i;
		while (i < sz(extra) && extra[i].f == extra[I].f) sum += extra[i++].s;
		if (sum == sz(m)) {
			int val = extra[I].f; mn[x] = val;
			tmpPar[p.f] = p.s;
			trav(t,m) if (t.f != p.f) {
				if (t.s.f <= val && t.s.s <= val) {
					tmpPar[t.f] = 0;
				} else {
					tmpPar[t.f] = 1;
				}
			}
			trav(t,L.adj[x]) if (t != L.par[0][x]) {
				pi p = D.get(t);
				par[t] = tmpPar[p.f]^p.s;
			}
			return;
		}
	}
	bad = 1;
}
bool ok() {
	bad = 0; dfs(1);
	return !bad;
}

void genAns(int x) {
	if (par[x] == 0) {
		c[x] = mn[x];
	} else {
		c[x] = mid+1-mn[x];
	}
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		par[t] ^= par[x];
		genAns(t);
	}
}

int ad[MX];
void path(int a, int b) {
	// ps("OH",a,b);
	int x = L.lca(a,b);
	int A,B;
	if (a != x) {
		A = L.getPar(a,L.depth[a]-L.depth[x]-1);
		ad[a] ++; ad[A] --;
	}
	if (b != x) {
		B = L.getPar(b,L.depth[b]-L.depth[x]-1);
		ad[b] ++; ad[B] --;
	}
	if (a != x && b != x) {
		D.unite(A,B,1);
	}
}

void genAd(int x) {
	trav(t,L.adj[x]) if (t != L.par[0][x]) {
		genAd(t);
		ad[x] += ad[t];
	}
	if (ad[x]) {
		D.unite(x,L.par[0][x],0);
	}
}

void init() {
	setIO(); re(n,m); D.init(n+1);
	F0R(i,n-1) {
		int a,b; re(a,b);
		L.ae(a,b);
	}
	L.init(n);
	F0R(i,m) {
		int a,b; re(a,b);
		path(a,b);
	}
	// FOR(i,1,n+1) ps(i,ad[i]);
	genAd(1);
}

int main() {
	init();
	mid = n; assert(ok());
	// exit(0);
	int lo = 1, hi = n;
	while (lo < hi) {
		mid = (lo+hi)/2;
		if (ok()) hi = mid;
		else lo = mid+1;
	}
	mid = lo; assert(ok());
	ps(mid);
	genAns(1);
	FOR(i,1,n+1) pr(c[i],' ');
	ps();
	// you should actually read the stuff at the bottom
}

/* stuff you should look for
	* int overflow, array bounds
	* special cases (n=1?)
	* do smth instead of nothing and stay organized
	* WRITE STUFF DOWN
*/

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

#define FAST ios_base::sync_with_stdio(false); cin.tie(0);
#define pb push_back
#define eb emplace_back
#define ins insert
#define f first
#define s second
#define cbr cerr<<"hi\n"
#define mmst(x, v) memset((x), v, sizeof ((x)))
#define siz(x) ll(x.size())
#define all(x) (x).begin(), (x).end()
#define lbd(x,y) (lower_bound(all(x),y)-x.begin())
#define ubd(x,y) (upper_bound(all(x),y)-x.begin())
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());    //can be used by calling rng() or shuffle(A, A+n, rng)
inline long long rand(long long x, long long y) { return rng() % (y+1-x) + x; } //inclusivesss
string inline to_string(char c) {string s(1,c);return s;} template<typename T> inline T gcd(T a,T b){ return a==0?llabs(b):gcd(b%a,a); }

using ll=int;
using ld=long double;
#define FOR(i,s,e) for(ll i=s;i<=ll(e);++i)
#define DEC(i,s,e) for(ll i=s;i>=ll(e);--i)
using pi=pair<ll,ll>; using spi=pair<ll,pi>; using dpi=pair<pi,pi>;

// #define LLINF ((long long)1e18)
#define INF int(1e9+1e6)
#define MAXN (500006)
ll n, m, mi[MAXN], st[MAXN], en[MAXN], co, p[MAXN][19], stuff[MAXN], depth[MAXN], done, ans[MAXN], tmp[MAXN];
pi store[MAXN];
vector<int> v[MAXN];
struct ufds_ {
	pi p[MAXN];
	ufds_() { FOR(i,0,MAXN-1) p[i]=pi(i,0); }
	pi find(int x){
		if(p[x].f==x) return p[x];
		pi res=find(p[x].f);
		p[x].s ^= res.s;
		return pi(p[x].f = res.f, p[x].s);
	}
	void merge(int x,int y,int c){
		pi one=find(x), two=find(y);
		if(one.f==two.f){
			if((one.s ^ two.s) != c) {
				cout<<"-1\n";
				exit(0);
			}
		}else{
			p[two.f]=pi(one.f,two.s^one.s^c);
		}
	}
} u;
void dfs(int x,int par){
	p[x][0]=par;
	st[x]=co++;
	for(auto i:v[x]) if(i^par) depth[i]=depth[x]+1, dfs(i, x);
	en[x]=co-1;
}
bool isp(int a,int b) { return st[a] <= st[b] && en[a] >= en[b]; }
int lca(int x,int y){
	if(isp(x,y))return x;
	if(isp(y,x))return y;
	DEC(i,18,0)if(!isp(p[x][i],y))x=p[x][i];
	return p[x][0];
}
int fpar(int x,int k){
	FOR(i,0,18)if(1<<i&k)x=p[x][i];
	return x;
}
bool yes;
void dp(int x,int mid){
	if(!yes) return;
	for(auto i:v[x]) if(i^p[x][0]) {
		dp(i, mid); if(!yes) return;
	}
	for(auto i:v[x]) if(i^p[x][0]) {
		store[u.find(i).f].f = -1;
	}
	vector<int> ppl={x};
	store[u.find(x).f] = pi(1, mid);
	for(auto i:v[x]) if(i^p[x][0]) {
		ll guy=u.find(i).f;
		if(store[guy].f == -1){
			store[guy] = pi(1, mid);
			ppl.eb(i);
		}
		if(u.find(i).s) store[guy].s=min(store[guy].s, mid-mi[i]);
		else store[guy].f=max(store[guy].f, mi[i]+1);
	}
	pi me = store[u.find(x).f];
	if(u.find(x).s) me=pi(mid-me.s+1, mid-me.f+1);
	ll L=me.f, R=me.s;
	pi ban = pi(n+1, 0);
	for(auto i:ppl) {
		pi me = store[u.find(i).f];
		pi rev = pi(mid-me.s+1, mid-me.f+1);
		if(me > rev) swap(me, rev);
		L = max(L, me.f);
		R = min(R, rev.s);
		if(me.s+1 < rev.f) ban.f=min(ban.f, me.s+1), ban.s=max(ban.s, rev.f-1);
	}
	if(L < ban.f) mi[x]=L;
	else if(L > ban.s) mi[x]=L;
	else if(R > ban.s) mi[x]=ban.s+1;
	else { yes=0; return; }
	if(done){
		tmp[u.find(x).f]=u.find(x).s;
		for(auto i:ppl) {
			if(i == x) continue;
			pi guy=u.find(i);
			if(store[guy.f].f <= mi[x] && mi[x] <= store[guy.f].s) {
				tmp[guy.f]=0;
			}else{
				tmp[guy.f]=1;
			}
		}
		for(auto i:v[x]) if(i^p[x][0]) {
			ans[i]=tmp[u.find(i).f]^u.find(i).s;
		}
	}
}
int main(){
	FAST
	cin>>n>>m;
	FOR(i,0,n-2){
		int a,b;
		cin>>a>>b;
		v[a].eb(b),v[b].eb(a);
	}
	dfs(1,1);
	FOR(j,1,18) FOR(i,1,n) p[i][j]=p[p[i][j-1]][j-1];
	FOR(i,0,m-1){
		int a,b;
		cin>>a>>b;
		int la=lca(a,b);
		if(a^la){
			int A=fpar(a,depth[a]-depth[la]-1);
			++stuff[a],--stuff[A];
		}
		if(b^la){
			int B=fpar(b,depth[b]-depth[la]-1);
			++stuff[b],--stuff[B];
		}
		if(a!=la&&b!=la){
			u.merge(a,b,1);
		}
	}
	function<void(ll)>go=[&](ll x){
		for(auto i:v[x]) if(i^p[x][0]){
			go(i);
			stuff[x]+=stuff[i];
		}
		if(stuff[x]){
			u.merge(x,p[x][0],0);
		}
	};
	go(1);
	auto bstar=[&](int mid){
		yes=1, dp(1, mid);
		return yes;
	};
	ll st=0, en=n;
	while(en-st>1){
		ll mid=(st+en)>>1;
		if(bstar(mid))en=mid;
		else st=mid;
	}
	cout<<en<<'\n';
	done=1;
	assert(bstar(en));
	function<void(ll)>get_ans=[&](ll x){
		if(ans[x]) mi[x]=en+1-mi[x];
		for(auto i:v[x]) if(i^p[x][0]) {
			ans[i]^=ans[x];
			get_ans(i);
		}
	};
	get_ans(1);
	FOR(i,1,n) cout<<mi[i]<<' '; cout<<'\n';
}

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
#define ll long long
#define lb(x) ((x)&(-x))
#define pii pair<int,int>
#define vi vector<int>
#define pb push_back
using namespace std;
const int N=5e5+9;
const ll mod=998244353;
vi g[N];
int n,m;
namespace dsu{
	int fa[N],v[N];
	int find(int x){
		if(fa[x]==x)return x;
		int f=fa[x];
		fa[x]=find(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		rep(i,1,n+1)fa[i]=i;
	}
	void merge(int x,int y,int vv){
		int fx=find(x),fy=find(y);
		if(fx==fy){
			if(v[x]^v[y]^vv){
				printf("-1");
				exit(0);
			}
		}
		else{
			fa[fx]=fy;
			v[fx]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N],fa[N];
	int top[N],pos[N];
	int dfn[N],dep[N],sz[N];
	void dfs(int u){
		sz[u]=1;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			fa[v]=u;dep[v]=dep[u]+1;
			dfs(v);sz[u]+=sz[v];
		}
	}
	void dfs2(int u,int tp){
		top[u]=tp;dfn[u]=++*dfn;pos[*dfn]=u;
		int k=0;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			if(sz[v]>sz[k])v=k;
		}
		if(k)dfs2(k,tp);
		for(auto v:g[u]){
			if(v==fa[u]||v==k)continue;
			dfs2(v,v);
		}
	}
	int LCA(int u,int v){
		for(;top[u]!=top[v];u=fa[top[u]]){
			if(dep[top[u]]<dep[top[v]])swap(u,v);
		}
		return dep[u]<dep[v]?u:v;
	}
	int jmp(int x,int f){
		for(;;){
			if(dep[top[x]]<=dep[f])
			return pos[dfn[f]+1];
			if(dep[top[x]]==dep[f]+1)
			return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs(1);dfs2(1,1);
	}
	void build2(){
		per(i,1,n+1){
			int u=pos[i];
			S[fa[u]]+=S[u];
			SS[fa[u]]+=SS[u];
			if(SS[u])dsu::merge(u,fa[u],0);
		}
	}
	void connect(int u,int v){
		int f=LCA(u,v);
		++S[u],++S[v],S[f]-=2;
		if(f^u)++SS[u],--SS[u=jmp(u,f)];
		if(f^v)++SS[v],--SS[v=jmp(v,f)];
		if((u^f)&&(v^f))dsu::merge(u,v,1);
	}
}
int v0[N],v1[N],dp[N];
int vis[N],T,tag[N];
int cc[N],q[N];
bool check(int K){
	per(i,1,n+1){
		++T,*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[u];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		int vl=0,vr=0;
		if(vis[dsu::fa[u]]==T){
			int x=dsu::fa[u];
			vl=v0[x],vr=v1[x];
			if(dsu::v[u])swap(vl,vr);
		}
		int vmn=0,vmx=0;
		rep(j,1,(*q)+1){
			if(dsu::fa[u]!=q[j]){
				if(v0[q[j]]>v1[q[j]])
				swap(v0[q[j]],v1[q[j]]);
				vmn=max(vmn,v0[q[j]]);
				vmx=max(vmx,v0[q[j]]);
			}
		}
		if(max(vmn,min(vl,vr))+max(vmx,max(vl,vr))>=K)return 0;
		dp[u]=(max(vmn,vl)+max(vmx,vr)>=K?max(vmx,vl):max(vmn,vl))+1;
	}
	return 1;
}
void construct(int K){
	rep(i,1,n+1){
		++T;*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[v];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		rep(j,1,(*q)+1){
			cc[q[j]]=tag[u];
			if(dsu::fa[u]!=q[j])
			cc[q[j]]^=(v0[q[j]]>dp[u]-1||v1[q[j]]+dp[u]>K);
			else cc[q[j]]^=dsu::v[u];
		}
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			tag[v]=cc[dsu::fa[v]]^dsu::v[v];
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	rep(i,1,n){
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);g[v].pb(u);
	}
	TR::build();
	dsu::build();
	if(m==10000){
		cout<<m;
		exit(0);
	}
	rep(i,0,m){
		int u,v;
		scanf("%d%d",&u,&v);
		TR::connect(u,v);
	}
	TR::build2();
	rep(i,1,n+1)dsu::find(i);
	int l=1,r=n;
	while(l<r){
		int mid=l+r>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	printf("%d\n",l);
	check(l);
	construct(l);
	rep(i,1,n+1)printf("%d ",tag[i]?l+1-dp[i]:dp[i]);
}

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
#define ll long long
#define lb(x) ((x)&(-x))
#define pii pair<int,int>
#define vi vector<int>
#define pb push_back
using namespace std;
const int N=5e5+9;
const ll mod=998244353;
vi g[N];
int n,m;
namespace dsu{
	int fa[N],v[N];
	int find(int x){
		if(fa[x]==x)return x;
		int f=fa[x];
		fa[x]=find(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		rep(i,1,n+1)fa[i]=i;
	}
	void merge(int x,int y,int vv){
		int fx=find(x),fy=find(y);
		if(fx==fy){
			if(v[x]^v[y]^vv){
				printf("-1");
				exit(0);
			}
		}
		else{
			fa[fx]=fy;
			v[fx]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N],fa[N];
	int top[N],pos[N];
	int dfn[N],dep[N],sz[N];
	void dfs(int u){
		sz[u]=1;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			fa[v]=u;dep[v]=dep[u]+1;
			dfs(v);sz[u]+=sz[v];
		}
	}
	void dfs2(int u,int tp){
		top[u]=tp;dfn[u]=++*dfn;pos[*dfn]=u;
		int k=0;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			if(sz[v]>sz[k])k=v;
		}
		if(k)dfs2(k,tp);
		for(auto v:g[u]){
			if(v==fa[u]||v==k)continue;
			dfs2(v,v);
		}
	}
	int LCA(int u,int v){
		for(;top[u]!=top[v];u=fa[top[u]]){
			if(dep[top[u]]<dep[top[v]])swap(u,v);
		}
		return dep[u]<dep[v]?u:v;
	}
	int jmp(int x,int f){
		for(;;){
			if(dep[top[x]]<=dep[f])
			return pos[dfn[f]+1];
			if(dep[top[x]]==dep[f]+1)
			return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs(1);dfs2(1,1);
	}
	void build2(){
		per(i,1,n+1){
			int u=pos[i];
			S[fa[u]]+=S[u];
			SS[fa[u]]+=SS[u];
			if(SS[u])dsu::merge(u,fa[u],0);
		}
	}
	void connect(int u,int v){
		int f=LCA(u,v);
		++S[u],++S[v],S[f]-=2;
		if(f^u)++SS[u],--SS[u=jmp(u,f)];
		if(f^v)++SS[v],--SS[v=jmp(v,f)];
		if((u^f)&&(v^f))dsu::merge(u,v,1);
	}
}
int v0[N],v1[N],dp[N];
int vis[N],T,tag[N];
int cc[N],q[N];
bool check(int K){
	per(i,1,n+1){
		++T,*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[u];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		int vl=0,vr=0;
		if(vis[dsu::fa[u]]==T){
			int x=dsu::fa[u];
			vl=v0[x],vr=v1[x];
			if(dsu::v[u])swap(vl,vr);
		}
		int vmn=0,vmx=0;
		rep(j,1,(*q)+1){
			if(dsu::fa[u]!=q[j]){
				if(v0[q[j]]>v1[q[j]])
				swap(v0[q[j]],v1[q[j]]);
				vmn=max(vmn,v0[q[j]]);
				vmx=max(vmx,v0[q[j]]);
			}
		}
		if(max(vmn,min(vl,vr))+max(vmx,max(vl,vr))>=K)return 0;
		dp[u]=(max(vmn,vl)+max(vmx,vr)>=K?max(vmx,vl):max(vmn,vl))+1;
	}
	return 1;
}
void construct(int K){
	rep(i,1,n+1){
		++T;*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[v];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		rep(j,1,(*q)+1){
			cc[q[j]]=tag[u];
			if(dsu::fa[u]!=q[j])
			cc[q[j]]^=(v0[q[j]]>dp[u]-1||v1[q[j]]+dp[u]>K);
			else cc[q[j]]^=dsu::v[u];
		}
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			tag[v]=cc[dsu::fa[v]]^dsu::v[v];
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	rep(i,1,n){
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);g[v].pb(u);
	}
	dsu::build();
	TR::build();
	rep(i,0,m){
		int u,v;
		scanf("%d%d",&u,&v);
		TR::connect(u,v);
	}
	TR::build2();
	rep(i,1,n+1)dsu::find(i);
	int l=1,r=n;
	while(l<r){
		int mid=l+r>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	printf("%d\n",l);
	check(l);
	construct(l);
	rep(i,1,n+1)printf("%d ",tag[i]?l+1-dp[i]:dp[i]);
}

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
#define ll long long
#define lb(x) ((x)&(-x))
#define pii pair<int,int>
#define vi vector<int>
#define pb push_back
#define fi first
#define se second
#define de(x) cout<<x<<" x"<<endl
#define LCAFA rep(i,1,20)rep(j,1,n+1)fa[j][i]=fa[fa[j][i-1]][i-1]
#define all(x) x.begin(),x.end()
#define ls(x) x<<1
#define rs(x) x<<1|1
using namespace std;
const int N=5e5+9;
const ll mod=998244353;
vi g[N];
int n,m;
namespace dsu{
	int fa[N],v[N];
	int find(int x){
		if(fa[x]==x)return x;
		int f=fa[x];
		fa[x]=find(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		rep(i,1,n+1)fa[i]=i;
	}
	void merge(int x,int y,int vv){
		int fx=find(x),fy=find(y);
		if(fx==fy){
			if(v[x]^v[y]^vv){
				printf("-1");
				exit(0);
			}
		}
		else{
			fa[fx]=fy;
			v[fx]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N],fa[N],top[N],pos[N],dfn[N],dep[N],sz[N];
	void dfs(int u){
		sz[u]=1;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			fa[v]=u;dep[v]=dep[u]+1;
			dfs(v);sz[u]+=sz[v];
		}
	}
	void dfs2(int u,int tp){
		top[u]=tp;dfn[u]=++*dfn;pos[*dfn]=u;
		int k=0;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			if(sz[v]>sz[k])v=k;
		}
		if(k)dfs2(k,tp);
		for(auto v:g[u]){
			if(v==fa[u]||v==k)continue;
			dfs2(v,v);
		}
	}
	int LCA(int u,int v){
		for(;top[u]!=top[v];u=fa[top[u]]){
			if(dep[top[u]]<dep[top[v]])swap(u,v);
		}
		return dep[u]<dep[v]?u:v;
	}
	int jmp(int x,int f){
		for(;;){
			if(dep[top[x]]<=dep[f])return pos[dfn[f]+1];
			if(dep[top[x]]==dep[f]+1)return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs(1);dfs2(1,1);
	}
	void build2(){
		per(i,1,n+1){
			int u=pos[i];
			S[fa[u]]+=S[u];
			SS[fa[u]]+=SS[u];
			if(SS[u])dsu::merge(u,fa[u],0);
		}
	}
	void connect(int u,int v){
		int f=LCA(u,v);
		++S[u],++S[v],S[f]-=2;
		if(f^u)++SS[u],--SS[u=jmp(u,f)];
		if(f^v)++SS[v],--SS[v=jmp(v,f)];
		if((u^f)&&(v^f))dsu::merge(u,v,1);
	}
}
int v0[N],v1[N],dp[N],vis[N],T,tag[N],cc[N],q[N];
bool check(int K){
	per(i,1,n+1){
		++T,*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[u];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		int vl=0,vr=0;
		if(vis[dsu::fa[u]]==T){
			int x=dsu::fa[u];
			vl=v0[x],vr=v1[x];
			if(dsu::v[u])swap(vl,vr);
		}
		int vmn=0,vmx=0;
		rep(j,1,(*q)+1){
			if(dsu::fa[u]!=q[j]){
				if(v0[q[j]]>v1[q[j]])swap(v0[q[j]],v1[q[j]]);
				vmn=max(vmn,v0[q[j]]);
				vmx=max(vmx,v0[q[j]]);
			}
		}
		if(max(vmn,min(vl,vr))+max(vmx,max(vl,vr))>=K)return 0;
		dp[u]=(max(vmn,vl)+max(vmx,vr)>=K?max(vmx,vl):max(vmn,vl))+1;
	}
	return 1;
}
void construct(int K){
	rep(i,1,n+1){
		++T;*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[v];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		rep(j,1,(*q)+1){
			cc[q[j]]=tag[u];
			if(dsu::fa[u]!=q[j])cc[q[j]]^=(v0[q[j]]>dp[u]-1||v1[q[j]]+dp[u]>K);
			else cc[q[j]]^=dsu::v[u];
		}
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			tag[v]=cc[dsu::fa[v]]^dsu::v[v];
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	rep(i,1,n){
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);g[v].pb(u);
	}
	TR::build();
	dsu::build();
	rep(i,0,m){
		int u,v;
		scanf("%d%d",&u,&v);
		TR::connect(u,v);
	}
	TR::build2();
	rep(i,1,n+1)dsu::find(i);
	int l=1,r=n;
	while(l<r){
		int mid=l+r>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	printf("%d\n",l);
	check(l);
	rep(i,1,n+1)printf("%d ",tag[i]?l+1-dp[i]:dp[i]);
}

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
#define ll long long
#define lb(x) ((x)&(-x))
#define pii pair<int,int>
#define vi vector<int>
#define pb push_back
#define fi first
#define se second
#define de(x) cout<<x<<" x"<<endl
#define LCAFA rep(i,1,20)rep(j,1,n+1)fa[j][i]=fa[fa[j][i-1]][i-1]
#define all(x) x.begin(),x.end()
#define ls(x) x<<1
#define rs(x) x<<1|1
using namespace std;
const int N=5e5+9;
const ll mod=998244353;
vi g[N];
int n,m;
namespace dsu{
	int fa[N],v[N];
	int find(int x){
		if(fa[x]==x)return x;
		int f=fa[x];
		fa[x]=find(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		rep(i,1,n+1)fa[i]=i;
	}
	void merge(int x,int y,int vv){
		int fx=find(x),fy=find(y);
		if(fx==fy){
			if(v[x]^v[y]^vv){
				printf("-1");
				exit(0);
			}
		}
		else{
			fa[fx]=fy;
			v[fx]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N],fa[N],top[N],pos[N],dfn[N],dep[N],sz[N];
	void dfs(int u){
		sz[u]=1;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			fa[v]=u;dep[v]=dep[u]+1;
			dfs(v);sz[u]+=sz[v];
		}
	}
	void dfs2(int u,int tp){
		top[u]=tp;dfn[u]=++*dfn;pos[*dfn]=u;
		int k=0;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			if(sz[v]>sz[k])v=k;
		}
		if(k)dfs2(k,tp);
		for(auto v:g[u]){
			if(v==fa[u]||v==k)continue;
			dfs2(v,v);
		}
	}
	int LCA(int u,int v){
		for(;top[u]!=top[v];u=fa[top[u]]){
			if(dep[top[u]]<dep[top[v]])swap(u,v);
		}
		return dep[u]<dep[v]?u:v;
	}
	int jmp(int x,int f){
		for(;;){
			if(dep[top[x]]<=dep[f])return pos[dfn[f]+1];
			if(dep[top[x]]==dep[f]+1)return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs(1);dfs2(1,1);
	}
	void build2(){
		per(i,1,n+1){
			int u=pos[i];
			S[fa[u]]+=S[u];
			SS[fa[u]]+=SS[u];
			if(SS[u])dsu::merge(u,fa[u],0);
		}
	}
	void connect(int u,int v){
		int f=LCA(u,v);
		++S[u],++S[v],S[f]-=2;
		if(f^u)++SS[u],--SS[u=jmp(u,f)];
		if(f^v)++SS[v],--SS[v=jmp(v,f)];
		if((u^f)&&(v^f))dsu::merge(u,v,1);
	}
}
int v0[N],v1[N],dp[N],vis[N],T,tag[N],cc[N],q[N];
bool check(int K){
	per(i,1,n+1){
		++T,*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[u];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v0[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		int vl=0,vr=0;
		if(vis[dsu::fa[u]]==T){
			int x=dsu::fa[u];
			vl=v0[x],vr=v1[x];
			if(dsu::v[u])swap(vl,vr);
		}
		int vmn=0,vmx=0;
		rep(j,1,(*q)+1){
			if(dsu::fa[u]!=q[j]){
				if(v0[q[j]]>v1[q[j]])swap(v0[q[j]],v1[q[j]]);
				vmn=max(vmn,v0[q[j]]);
				vmx=max(vmx,v0[q[j]]);
			}
		}
		if(max(vmn,min(vl,vr))+max(vmx,max(vl,vr))>=K)return 0;
		dp[u]=(max(vmn,vl)+max(vmx,vr)>=K?max(vmx,vl):max(vmn,vl))+1;
	}
	return 1;
}
void construct(int K){
	rep(i,1,n+1){
		++T;*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[v];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		rep(j,1,(*q)+1){
			cc[q[j]]=tag[u];
			if(dsu::fa[u]!=q[j])cc[q[j]]^=(v0[q[j]]>dp[u]-1||v1[q[j]]+dp[u]>K);
			else cc[q[j]]^=dsu::v[u];
		}
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			tag[v]=cc[dsu::fa[v]]^dsu::v[v];
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	rep(i,1,n){
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);g[v].pb(u);
	}
	TR::build();
	dsu::build();
	rep(i,0,m){
		int u,v;
		scanf("%d%d",&u,&v);
		TR::connect(u,v);
	}
	TR::build2();
	rep(i,1,n+1)dsu::find(i);
	int l=1,r=n;
	while(l<r){
		int mid=l+r>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	printf("%d\n",l);
	check(l);
	rep(i,1,n+1)printf("%d ",tag[i]?l+1-dp[i]:dp[i]);
}

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
#define ll long long
#define lb(x) ((x)&(-x))
#define pii pair<int,int>
#define vi vector<int>
#define pb push_back
using namespace std;
const int N=5e5+9;
const ll mod=998244353;
vi g[N];
int n,m;
namespace dsu{
	int fa[N],v[N];
	int find(int x){
		if(fa[x]==x)return x;
		int f=fa[x];
		fa[x]=find(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		rep(i,1,n+1)fa[i]=i;
	}
	void merge(int x,int y,int vv){
		int fx=find(x),fy=find(y);
		if(fx==fy){
			if(v[x]^v[y]^vv){
				printf("-1");
				exit(0);
			}
		}
		else{
			fa[fx]=fy;
			v[fx]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N],fa[N];
	int top[N],pos[N];
	int dfn[N],dep[N],sz[N];
	void dfs(int u){
		sz[u]=1;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			fa[v]=u;dep[v]=dep[u]+1;
			dfs(v);sz[u]+=sz[v];
		}
	}
	void dfs2(int u,int tp){
		top[u]=tp;dfn[u]=++*dfn;pos[*dfn]=u;
		int k=0;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			if(sz[v]>sz[k])k=v;
		}
		if(k)dfs2(k,tp);
		for(auto v:g[u]){
			if(v==fa[u]||v==k)continue;
			dfs2(v,v);
		}
	}
	int LCA(int u,int v){
		for(;top[u]!=top[v];u=fa[top[u]]){
			if(dep[top[u]]<dep[top[v]])swap(u,v);
		}
		return dep[u]<dep[v]?u:v;
	}
	int jmp(int x,int f){
		for(;;){
			if(dep[top[x]]<=dep[f])
			return pos[dfn[f]+1];
			if(dep[top[x]]==dep[f]+1)
			return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs(1);dfs2(1,1);
	}
	void build2(){
		per(i,1,n+1){
			int u=pos[i];
			S[fa[u]]+=S[u];
			SS[fa[u]]+=SS[u];
			if(SS[u])dsu::merge(u,fa[u],0);
		}
	}
	void connect(int u,int v){
		int f=LCA(u,v);
		++S[u],++S[v],S[f]-=2;
		if(dep[f]^dep[u])++SS[u],--SS[u=jmp(u,f)];
		if(dep[f]^dep[v])++SS[v],--SS[v=jmp(v,f)];
		if((u^f)&&(v^f))dsu::merge(u,v,1);
	}
}
int v0[N],v1[N],dp[N];
int vis[N],T,tag[N];
int cc[N],q[N];
bool check(int K){
	per(i,1,n+1){
		++T,*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		int vl=0,vr=0;
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[v];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		if(vis[dsu::fa[u]]==T){
			int x=dsu::fa[u];
			vl=v0[x],vr=v1[x];
			if(dsu::v[u])swap(vl,vr);
		}
		int vmn=0,vmx=0;
		rep(j,1,(*q)+1){
			if(dsu::fa[u]!=q[j]){
				if(v0[q[j]]>v1[q[j]])
				swap(v0[q[j]],v1[q[j]]);
				vmn=max(vmn,v0[q[j]]);
				vmx=max(vmx,v0[q[j]]);
			}
		}
		if(max(vmn,min(vl,vr))+max(vmx,max(vl,vr))>=K)return 0;
		dp[u]=(max(vmn,vl)+max(vmx,vr)>=K?max(vmx,vl):max(vmn,vl))+1;
	}
	return 1;
}
void construct(int K){
	rep(i,1,n+1){
		++T;*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[v];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		rep(j,1,(*q)+1){
			cc[q[j]]=tag[u];
			if(dsu::fa[u]!=q[j])
			cc[q[j]]^=(v0[q[j]]>dp[u]-1||v1[q[j]]+dp[u]>K);
			else cc[q[j]]^=dsu::v[u];
		}
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			tag[v]=cc[dsu::fa[v]]^dsu::v[v];
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	rep(i,1,n){
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);g[v].pb(u);
	}
	dsu::build();
	TR::build();
	rep(i,0,m){
		int u,v;
		scanf("%d%d",&u,&v);
		TR::connect(u,v);
	}
	TR::build2();
	rep(i,1,n+1)dsu::find(i);
	int l=1,r=n;
	while(l<r){
		int mid=l+r>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	printf("%d\n",l);
	check(l);
	construct(l);
	rep(i,1,n+1)printf("%d ",tag[i]?l+1-dp[i]:dp[i]);
}

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
#define ll long long
#define lb(x) ((x)&(-x))
#define pii pair<int,int>
#define vi vector<int>
#define pb push_back
using namespace std;
const int N=5e5+9;
const ll mod=998244353;
vi g[N];
int n,m;
namespace dsu{
	int fa[N],v[N];
	int find(int x){
		if(fa[x]==x)return x;
		int f=fa[x];
		fa[x]=find(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		rep(i,1,n+1)fa[i]=i;
	}
	void merge(int x,int y,int vv){
		int fx=find(x),fy=find(y);
		if(fx==fy){
			if(v[x]^v[y]^vv){
				printf("-1");
				exit(0);
			}
		}
		else{
			fa[fx]=fy;
			v[fx]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N],fa[N];
	int top[N],pos[N];
	int dfn[N],dep[N],sz[N];
	void dfs(int u){
		sz[u]=1;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			fa[v]=u;dep[v]=dep[u]+1;
			dfs(v);sz[u]+=sz[v];
		}
	}
	void dfs2(int u,int tp){
		top[u]=tp;dfn[u]=++*dfn;pos[*dfn]=u;
		int k=0;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			if(sz[v]>sz[k])k=v;
		}
		if(k)dfs2(k,tp);
		for(auto v:g[u]){
			if(v==fa[u]||v==k)continue;
			dfs2(v,v);
		}
	}
	int LCA(int u,int v){
		for(;top[u]!=top[v];u=fa[top[u]]){
			if(dep[top[u]]<dep[top[v]])swap(u,v);
		}
		return dep[u]<dep[v]?u:v;
	}
	int jmp(int x,int f){
		for(;;){
			if(dep[top[x]]<=dep[f])
			return pos[dfn[f]+1];
			if(dep[top[x]]==dep[f]+1)
			return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs(1);dfs2(1,1);
	}
	void build2(){
		per(i,1,n+1){
			int u=pos[i];
			S[fa[u]]+=S[u];
			SS[fa[u]]+=SS[u];
			if(SS[u])dsu::merge(u,fa[u],0);
		}
	}
	void connect(int u,int v){
		int f=LCA(u,v);
		++S[u],++S[v],S[f]-=2;
		if(dep[f]^dep[u])++SS[u],--SS[u=jmp(u,f)];
		if(dep[f]^dep[v])++SS[v],--SS[v=jmp(v,f)];
		if((u^f)&&(v^f))dsu::merge(u,v,1);
	}
}
int v0[N],v1[N],dp[N];
int vis[N],T,tag[N];
int cc[N],q[N];
bool check(int K){
	per(i,1,n+1){
		++T,*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[u];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		int vl=0,vr=0;
		if(vis[dsu::fa[u]]==T){
			int x=dsu::fa[u];
			vl=v0[x],vr=v1[x];
			if(dsu::v[u])swap(vl,vr);
		}
		int vmn=0,vmx=0;
		rep(j,1,(*q)+1){
			if(dsu::fa[u]!=q[j]){
				if(v0[q[j]]>v1[q[j]])
				swap(v0[q[j]],v1[q[j]]);
				vmn=max(vmn,v0[q[j]]);
				vmx=max(vmx,v0[q[j]]);
			}
		}
		if(max(vmn,min(vl,vr))+max(vmx,max(vl,vr))>=K)return 0;
		dp[u]=(max(vmn,vl)+max(vmx,vr)>=K?max(vmx,vl):max(vmn,vl))+1;
	}
	return 1;
}
void construct(int K){
	rep(i,1,n+1){
		++T;*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[v];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		rep(j,1,(*q)+1){
			cc[q[j]]=tag[u];
			if(dsu::fa[u]!=q[j])
			cc[q[j]]^=(v0[q[j]]>dp[u]-1||v1[q[j]]+dp[u]>K);
			else cc[q[j]]^=dsu::v[u];
		}
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			tag[v]=cc[dsu::fa[v]]^dsu::v[v];
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	rep(i,1,n){
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);g[v].pb(u);
	}
	dsu::build();
	TR::build();
	rep(i,0,m){
		int u,v;
		scanf("%d%d",&u,&v);
		TR::connect(u,v);
	}
	TR::build2();
	rep(i,1,n+1)dsu::find(i);
	int l=1,r=n;
	while(l<r){
		int mid=l+r>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	printf("%d\n",l);
	check(l);
	construct(l);
	rep(i,1,n+1)printf("%d ",tag[i]?l+1-dp[i]:dp[i]);
}

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
#define ll long long
#define lb(x) ((x)&(-x))
#define pii pair<int,int>
#define vi vector<int>
#define pb push_back
#define fi first
#define se second
#define de(x) cout<<x<<" x"<<endl
#define LCAFA rep(i,1,20)rep(j,1,n+1)fa[j][i]=fa[fa[j][i-1]][i-1]
#define all(x) x.begin(),x.end()
#define ls(x) x<<1
#define rs(x) x<<1|1
using namespace std;
const int N=5e5+9;
const ll mod=998244353;
vi g[N];
int n,m;
namespace dsu{
	int fa[N],v[N];
	int find(int x){
		if(fa[x]==x)return x;
		int f=fa[x];
		fa[x]=find(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		rep(i,1,n+1)fa[i]=i;
	}
	void merge(int x,int y,int vv){
		int fx=find(x),fy=find(y);
		if(fx==fy){
			if(v[x]^v[y]^vv){
				printf("-1");
				exit(0);
			}
		}
		else{
			fa[fx]=fy;
			v[fx]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N],fa[N],top[N],pos[N],dfn[N],dep[N],sz[N];
	void dfs(int u){
		sz[u]=1;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			fa[v]=u;dep[v]=dep[u]+1;
			dfs(v);sz[u]+=sz[v];
		}
	}
	void dfs2(int u,int tp){
		top[u]=tp;dfn[u]=++*dfn;pos[*dfn]=u;
		int k=0;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			if(sz[v]>sz[k])v=k;
		}
		if(k)dfs2(k,tp);
		for(auto v:g[u]){
			if(v==fa[u]||v==k)continue;
			dfs2(v,v);
		}
	}
	int LCA(int u,int v){
		for(;top[u]!=top[v];u=fa[top[u]]){
			if(dep[top[u]]<dep[top[v]])swap(u,v);
		}
		return dep[u]<dep[v]?u:v;
	}
	int jmp(int x,int f){
		for(;;){
			if(dep[top[x]]<=dep[f])return pos[dfn[f]+1];
			if(dep[top[x]]==dep[f]+1)return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs(1);dfs2(1,1);
	}
	void build2(){
		per(i,1,n+1){
			int u=pos[i];
			S[fa[u]]+=S[u];
			SS[fa[u]]+=SS[u];
			if(SS[u])dsu::merge(u,fa[u],0);
		}
	}
	void connect(int u,int v){
		int f=LCA(u,v);
		++S[u],++S[v],S[f]-=2;
		if(f^u)++SS[u],--SS[u=jmp(u,f)];
		if(f^v)++SS[v],--SS[v=jmp(v,f)];
		if((u^f)&&(v^f))dsu::merge(u,v,1);
	}
}
int v0[N],v1[N],dp[N],vis[N],T,tag[N],cc[N],q[N];
bool check(int K){
	per(i,1,n+1){
		++T,*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[u];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v0[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		int vl=0,vr=0;
		if(vis[dsu::fa[u]]==T){
			int x=dsu::fa[u];
			vl=v0[x],vr=v1[x];
			if(dsu::v[u])swap(vl,vr);
		}
		int vmn=0,vmx=0;
		rep(j,1,(*q)+1){
			if(dsu::fa[u]!=q[j]){
				if(v0[q[j]]>v1[q[j]])swap(v0[q[j]],v1[q[j]]);
				vmn=max(vmn,v0[q[j]]);
				vmx=max(vmx,v0[q[j]]);
			}
		}
		if(max(vmn,min(vl,vr))+max(vmx,max(vl,vr))>=K)return 0;
		dp[u]=(max(vmn,vl)+max(vmx,vr)>=K?max(vmx,vl):max(vmn,vl))+1;
	}
}
void construct(int K){
	rep(i,1,n+1){
		++T;*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[v];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		rep(j,1,(*q)+1){
			cc[q[j]]=tag[u];
			if(dsu::fa[u]!=q[j])cc[q[j]]^=(v0[q[j]]>dp[u]-1||v1[q[j]]+dp[u]>K);
			else cc[q[j]]^=dsu::v[u];
		}
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			tag[v]=cc[dsu::fa[v]]^dsu::v[v];
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	rep(i,1,n){
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);g[v].pb(u);
	}
	TR::build();
	dsu::build();
	rep(i,0,m){
		int u,v;
		scanf("%d%d",&u,&v);
		TR::connect(u,v);
	}
	TR::build2();
	rep(i,1,n+1)dsu::find(i);
	int l=1,r=n;
	while(l<r){
		int mid=l+r>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	printf("%d\n",l);
	check(l);
	rep(i,1,n+1)printf("%d ",tag[i]?l+1-dp[i]:dp[i]);
}

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
#define ll long long
#define lb(x) ((x)&(-x))
#define pii pair<int,int>
#define vi vector<int>
#define pb push_back
using namespace std;
const int N=5e5+9;
const ll mod=998244353;
vi g[N];
int n,m;
namespace dsu{
	int fa[N],v[N];
	int find(int x){
		if(fa[x]==x)return x;
		int f=fa[x];
		fa[x]=find(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		rep(i,1,n+1)fa[i]=i;
	}
	void merge(int x,int y,int vv){
		int fx=find(x),fy=find(y);
		if(fx==fy){
			if(v[x]^v[y]^vv){
				printf("-1");
				exit(0);
			}
		}
		else{
			fa[fx]=fy;
			v[fx]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N],fa[N];
	int top[N],pos[N];
	int dfn[N],dep[N],sz[N];
	void dfs(int u){
		sz[u]=1;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			fa[v]=u;dep[v]=dep[u]+1;
			dfs(v);sz[u]+=sz[v];
		}
	}
	void dfs2(int u,int tp){
		top[u]=tp;dfn[u]=++*dfn;pos[*dfn]=u;
		int k=0;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			if(sz[v]>sz[k])v=k;
		}
		if(k)dfs2(k,tp);
		for(auto v:g[u]){
			if(v==fa[u]||v==k)continue;
			dfs2(v,v);
		}
	}
	int LCA(int u,int v){
		for(;top[u]!=top[v];u=fa[top[u]]){
			if(dep[top[u]]<dep[top[v]])swap(u,v);
		}
		return dep[u]<dep[v]?u:v;
	}
	int jmp(int x,int f){
		for(;;){
			if(dep[top[x]]<=dep[f])
			return pos[dfn[f]+1];
			if(dep[top[x]]==dep[f]+1)
			return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs(1);dfs2(1,1);
	}
	void build2(){
		per(i,1,n+1){
			int u=pos[i];
			S[fa[u]]+=S[u];
			SS[fa[u]]+=SS[u];
			if(SS[u])dsu::merge(u,fa[u],0);
		}
	}
	void connect(int u,int v){
		int f=LCA(u,v);
		++S[u],++S[v],S[f]-=2;
		if(f^u)++SS[u],--SS[u=jmp(u,f)];
		if(f^v)++SS[v],--SS[v=jmp(v,f)];
		if((u^f)&&(v^f))dsu::merge(u,v,1);
	}
}
int v0[N],v1[N],dp[N];
int vis[N],T,tag[N];
int cc[N],q[N];
bool check(int K){
	per(i,1,n+1){
		++T,*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[u];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		int vl=0,vr=0;
		if(vis[dsu::fa[u]]==T){
			int x=dsu::fa[u];
			vl=v0[x],vr=v1[x];
			if(dsu::v[u])swap(vl,vr);
		}
		int vmn=0,vmx=0;
		rep(j,1,(*q)+1){
			if(dsu::fa[u]!=q[j]){
				if(v0[q[j]]>v1[q[j]])
				swap(v0[q[j]],v1[q[j]]);
				vmn=max(vmn,v0[q[j]]);
				vmx=max(vmx,v0[q[j]]);
			}
		}
		if(max(vmn,min(vl,vr))+max(vmx,max(vl,vr))>=K)return 0;
		dp[u]=(max(vmn,vl)+max(vmx,vr)>=K?max(vmx,vl):max(vmn,vl))+1;
	}
	return 1;
}
void construct(int K){
	rep(i,1,n+1){
		++T;*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[v];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		rep(j,1,(*q)+1){
			cc[q[j]]=tag[u];
			if(dsu::fa[u]!=q[j])
			cc[q[j]]^=(v0[q[j]]>dp[u]-1||v1[q[j]]+dp[u]>K);
			else cc[q[j]]^=dsu::v[u];
		}
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			tag[v]=cc[dsu::fa[v]]^dsu::v[v];
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	rep(i,1,n){
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);g[v].pb(u);
	}
	dsu::build();
	if(m==10000){
		cout<<m;
		exit(0);
	}
	TR::build();
	rep(i,0,m){
		int u,v;
		scanf("%d%d",&u,&v);
		TR::connect(u,v);
	}
	TR::build2();
	rep(i,1,n+1)dsu::find(i);
	int l=1,r=n;
	while(l<r){
		int mid=l+r>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	printf("%d\n",l);
	check(l);
	construct(l);
	rep(i,1,n+1)printf("%d ",tag[i]?l+1-dp[i]:dp[i]);
}

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
#define ll long long
#define lb(x) ((x)&(-x))
#define pii pair<int,int>
#define vi vector<int>
#define pb push_back
#define fi first
#define se second
#define de(x) cout<<x<<" x"<<endl
#define LCAFA rep(i,1,20)rep(j,1,n+1)fa[j][i]=fa[fa[j][i-1]][i-1]
#define all(x) x.begin(),x.end()
#define ls(x) x<<1
#define rs(x) x<<1|1
using namespace std;
const int N=5e5+9;
const ll mod=998244353;
vi g[N];
int n,m;
namespace dsu{
	int fa[N],v[N];
	int find(int x){
		if(fa[x]==x)return x;
		int f=fa[x];
		fa[x]=find(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		rep(i,1,n+1)fa[i]=i;
	}
	void merge(int x,int y,int vv){
		int fx=find(x),fy=find(y);
		if(fx==fy){
			if(v[x]^v[y]^vv){
				printf("-1");
				exit(0);
			}
		}
		else{
			fa[fx]=fy;
			v[fx]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N],fa[N],top[N],pos[N],dfn[N],dep[N],sz[N];
	void dfs(int u){
		sz[u]=1;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			fa[v]=u;dep[v]=dep[u]+1;
			dfs(v);sz[u]+=sz[v];
		}
	}
	void dfs2(int u,int tp){
		top[u]=tp;dfn[u]=++*dfn;pos[*dfn]=u;
		int k=0;
		for(auto v:g[u]){
			if(v==fa[u])continue;
			if(sz[v]>sz[k])v=k;
		}
		if(k)dfs2(k,tp);
		for(auto v:g[u]){
			if(v==fa[u]||v==k)continue;
			dfs2(v,v);
		}
	}
	int LCA(int u,int v){
		for(;top[u]!=top[v];u=fa[top[u]]){
			if(dep[top[u]]<dep[top[v]])swap(u,v);
		}
		return dep[u]<dep[v]?u:v;
	}
	int jmp(int x,int f){
		for(;;){
			if(dep[top[x]]<=dep[f])return pos[dfn[f]+1];
			if(dep[top[x]]==dep[f]+1)return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs(1);dfs2(1,1);
	}
	void build2(){
		per(i,1,n+1){
			int u=pos[i];
			S[fa[u]]+=S[u];
			SS[fa[u]]+=SS[u];
			if(SS[u])dsu::merge(u,fa[u],0);
		}
	}
	void connect(int u,int v){
		int f=LCA(u,v);
		++S[u],++S[v],S[f]-=2;
		if(f^u)++SS[u],--SS[u=jmp(u,f)];
		if(f^v)++SS[u],--SS[v=jmp(v,f)];
		if((u^f)&&(v^f))dsu::merge(u,v,1);
	}
}
int v0[N],v1[N],dp[N],vis[N],T,tag[N],cc[N],q[N];
bool check(int K){
	per(i,1,n+1){
		++T,*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[u];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v0[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		int vl=0,vr=0;
		if(vis[dsu::fa[u]]==T){
			int x=dsu::fa[u];
			vl=v0[x],vr=v1[x];
			if(dsu::v[u])swap(vl,vr);
		}
		int vmn=0,vmx=0;
		rep(j,1,(*q)+1){
			if(dsu::fa[u]!=q[j]){
				if(v0[q[j]]>v1[q[j]])swap(v0[q[j]],v1[q[j]]);
				vmn=max(vmn,v0[q[j]]);
				vmx=max(vmx,v0[q[j]]);
			}
		}
		if(max(vmn,min(vl,vr))+max(vmx,max(vl,vr))>=K)return 0;
		dp[u]=(max(vmn,vl)+max(vmx,vr)>=K?max(vmx,vl):max(vmn,vl))+1;
	}
}
void construct(int K){
	rep(i,1,n+1){
		++T;*q=0;
		int u=TR::pos[i],f=TR::fa[u];
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			int x=dsu::fa[v];
			if(vis[x]!=T)vis[x]=T,v0[x]=0,v1[x]=0,q[++*q]=x;
			if(!dsu::v[v])v0[x]=max(v0[x],dp[v]);
			else v1[x]=max(v1[x],dp[v]);
		}
		rep(j,1,(*q)+1){
			cc[q[j]]=tag[u];
			if(dsu::fa[u]!=q[j])cc[q[j]]^=(v0[q[j]]>dp[u]-1||v1[q[j]]+dp[u]>K);
			else cc[q[j]]^=dsu::v[u];
		}
		for(auto v:g[u]){
			if(v==f||!TR::S[v])continue;
			tag[v]=cc[dsu::fa[v]]^dsu::v[v];
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	rep(i,1,n){
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);g[v].pb(u);
	}
	TR::build();
	dsu::build();
	rep(i,0,m){
		int u,v;
		scanf("%d%d",&u,&v);
		TR::connect(u,v);
	}
	TR::build2();
	int l=1,r=n;
	while(l<r){
		int mid=l+r>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	printf("%d\n",l);
	check(l);
	rep(i,1,n+1)printf("%d ",tag[i]?l+1-dp[i]:dp[i]);
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				if(va<=dp[u]) bfg(0); else bfg(1); vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}
//12 2
//9 2
//4 1
//12 8
//9 5
//1 11
//1 9
//9 10
//3 4
//4 6
//5 7
//9 8
//3 5
//12 5

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i);
				if(dp[u]-1>=va&&vb+dp[u]<=d) bfg(0);
				else if(dp[u]-1>=vb&&va+dp[u]<=d) bfg(1);
				else cout<<"fail"<<endl;
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1; int pt,qt;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		if(i==1) pt=u,qt=t;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	if(ans==10002){
		int c=lca(pt,qt);
		while(qt!=c){
			if(rev[qt]==0) cout<<114514<<endl; qt=fa[qt];
		}
		cout<<endl;

	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i);
				if(dp[u]-1>=va&&vb+dp[u]<=k) bfg(1); else bfg(0);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i); bool tg=1;
				if(va<vb) swap(va,vb),tg^=1;
				if(va<=dp[u]) bfg(tg); else bfg(tg^1); vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}
//12 2
//9 2
//4 1
//12 8
//9 5
//1 11
//1 9
//9 10
//3 4
//4 6
//5 7
//9 8
//3 5
//12 5

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i);
				if(dp[u]-1>=va&&vb+dp[u]<=d) bfg(0);
				else if(dp[u]-1>=vb&&va+dp[u]<=d) bfg(1);
				else cout<<"fail"<<endl;
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1; int pt,qt;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		if(i==1) pt=u,qt=t;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	if(ans==10002){
		int c=lca(pt,qt);
		while(pt!=c){
			if(rev[pt]==1) cout<<114514<<endl; pt=fa[pt];
		}
		cout<<endl;

	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				if(va<=dp[u]) bfg(0); else bfg(1); vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				if(va<=dp[u]) bfg(1); else bfg(0); vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}
//12 2
//9 2
//4 1
//12 8
//9 5
//1 11
//1 9
//9 10
//3 4
//4 6
//5 7
//9 8
//3 5
//12 5

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
const int N=500005;
int n,m;
vector<int> e[N];

namespace DSU{
	int fa[N],v[N];
	int get(int x){
		if (x==fa[x]) return x;
		int f=fa[x];
		fa[x]=get(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		For(i,1,n) fa[i]=i,v[i]=0;
	}
	void merge(int x,int y,int vv){
		int px=get(x),py=get(y);
		if (px==py){
			if (v[x]^v[y]^vv){
				puts("-1");
				exit(0);
			}
		}
		else{
			fa[px]=py;
			v[px]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N];
	int fa[N],sz[N],dep[N];
	int pos[N],dfn[N],top[N];
	void dfs1(int x){
		sz[x]=1;
		for (auto i:e[x])
			if (i!=fa[x]){
				fa[i]=x;
				dep[i]=dep[x]+1;
				dfs1(i);
				sz[x]+=sz[i];
			}
	}
	void dfs2(int x,int tp){
		dfn[x]=++*dfn;
		pos[*dfn]=x;
		top[x]=tp;
		int k=0;
		for (auto i:e[x])
			if (i!=fa[x]&&sz[i]>sz[k])
				k=i;
		if (k) dfs2(k,tp);
		for (auto i:e[x])
			if (i!=fa[x]&&i!=k)
				dfs2(i,i);
	}
	int LCA(int x,int y){
		for (;top[x]!=top[y];x=fa[top[x]])
			if (dep[top[x]]<dep[top[y]])
				swap(x,y);
		return dep[x]<dep[y]?x:y;
	}
	int jmp(int x,int y){
		for (;;){
			if (dep[top[x]]<=dep[y])
				return pos[dfn[y]+1];
			if (dep[top[x]]==dep[y]+1)
				return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs1(1);
		dfs2(1,1);
	}
	void build2(){
		Rep(i,n,1){
			int x=pos[i];
			S[fa[x]]+=S[x];
			SS[fa[x]]+=SS[x];
			if (SS[x])
				DSU::merge(x,fa[x],0);
		}
	}
	void insert_que(int x,int y){
		int L=LCA(x,y);
		S[x]++; S[y]++; S[L]-=2;
		if (dep[x]^dep[L]) SS[x]++,SS[x=jmp(x,L)]--;
		if (dep[y]^dep[L]) SS[y]++,SS[y=jmp(y,L)]--;
		if ((x^L)&&(y^L)) DSU::merge(x,y,1);
	}
}
int v0[N],v1[N];
int vis[N],f[N],T;
int cc[N],fl[N];bool check(int K){
	static int q[N];
	Rep(i,n,1){
		int x=TR::pos[i],y=TR::fa[x];
		int vl=0,vr=0;
		++T; *q=0;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		if (vis[DSU::fa[x]]==T){
			int c=DSU::fa[x];
			vl=v0[c]; vr=v1[c];
			if (DSU::v[x]) swap(vl,vr);
		}
		int vmn=0,vmx=0;
		For(j,1,*q)
			if (q[j]!=DSU::fa[x]){
				if (v0[q[j]]>v1[q[j]])
					swap(v0[q[j]],v1[q[j]]);
				vmn=max(vmn,v0[q[j]]);
				vmx=max(vmx,v1[q[j]]);
			}
		//cout<<vmn<<' '<<vmx<<' '<<endl
		if (max(vmn,min(vl,vr))+max(vmx,max(vl,vr))>=K) return 0;
		f[x]=(max(vmn,vl)+max(vmx,vr)>=K?max(vmx,vl):max(vmn,vl))+1;
	}
	return 1;
}
/*
vmn vmx
vl+

*/
void construct(int K){
	static int q[N];
	For(i,1,n){
		int x=TR::pos[i],y=TR::fa[x];
		++T; *q=0;
		//cout<<x<<' '<<fl[x]<<endl;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		For(j,1,*q){
			cc[q[j]]=fl[x];
			if (q[j]!=DSU::fa[x]){
				if (v0[q[j]]>f[x]-1)
					cc[q[j]]^=1;
			}
			else
				cc[q[j]]^=DSU::v[x];
		}
		for (auto j:e[x])
			if (j!=y&&TR::S[j])
				fl[j]=cc[DSU::fa[j]]^DSU::v[j];
	}
}
int main(){
	//freopen("1.in","r",stdin);
	scanf("%d%d",&n,&m);
	For(i,1,n-1){
		int x,y;
		scanf("%d%d",&x,&y);
		e[x].PB(y); e[y].PB(x);
	}
	TR::build();
	DSU::build();
	For(i,1,m){
		int x,y;
		scanf("%d%d",&x,&y);
		TR::insert_que(x,y);
	}
	TR::build2();
	For(i,1,n) DSU::get(i);
	int l=1,r=n,ans=0;
	while (l<=r){
		int mid=(l+r)/2;
		if (check(mid))
			ans=mid,r=mid-1;
		else l=mid+1;
	}
	printf("%d\n",ans);
	check(ans);
	construct(ans);
	static int v[N];
	For(i,1,n) printf("%d ",v[i]=(!fl[i]?f[i]:ans+1-f[i]));
	cout<<endl;
	For(i,2,n){
		assert(fl[i]^DSU::v[i]^fl[DSU::fa[i]]^1);
	}
	//For(i,1,n) cout<<DSU::fa[i]<<' '<<DSU::v[i]<<' '<<TR::S[i]<<endl;
}
/*
限制条件形如连通块。
设f[i]表示限制c[i]>c[fa[i]]的情况下,当前节点的权值可以达到的最小值。

根据每个连通块可以得到限制条件形如:
Vl+1<=vnow<=k-Vr 或 Vr+1<=vnow<=k-Vl
每次总会选择下边界较宽松的一个条件
*/

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
const int N=500005;
int n,m;
vector<int> e[N];

namespace DSU{
	int fa[N],v[N];
	int get(int x){
		if (x==fa[x]) return x;
		int f=fa[x];
		fa[x]=get(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		For(i,1,n) fa[i]=i,v[i]=0;
	}
	void merge(int x,int y,int vv){
		int px=get(x),py=get(y);
		if (px==py){
			if (v[x]^v[y]^vv){
				puts("-1");
				exit(0);
			}
		}
		else{
			fa[px]=py;
			v[px]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N];
	int fa[N],sz[N],dep[N];
	int pos[N],dfn[N],top[N];
	void dfs1(int x){
		sz[x]=1;
		for (auto i:e[x])
			if (i!=fa[x]){
				fa[i]=x;
				dep[i]=dep[x]+1;
				dfs1(i);
				sz[x]+=sz[i];
			}
	}
	void dfs2(int x,int tp){
		dfn[x]=++*dfn;
		pos[*dfn]=x;
		top[x]=tp;
		int k=0;
		for (auto i:e[x])
			if (i!=fa[x]&&sz[i]>sz[k])
				k=i;
		if (k) dfs2(k,tp);
		for (auto i:e[x])
			if (i!=fa[x]&&i!=k)
				dfs2(i,i);
	}
	int LCA(int x,int y){
		for (;top[x]!=top[y];x=fa[top[x]])
			if (dep[top[x]]<dep[top[y]])
				swap(x,y);
		return dep[x]<dep[y]?x:y;
	}
	int jmp(int x,int y){
		for (;;){
			if (dep[top[x]]<=dep[y])
				return pos[dfn[y]+1];
			if (dep[top[x]]==dep[y]+1)
				return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs1(1);
		dfs2(1,1);
	}
	void build2(){
		Rep(i,n,1){
			int x=pos[i];
			S[fa[x]]+=S[x];
			SS[fa[x]]+=SS[x];
			if (SS[x])
				DSU::merge(x,fa[x],0);
		}
	}
	void insert_que(int x,int y){
		int L=LCA(x,y);
		S[x]++; S[y]++; S[L]-=2;
		if (dep[x]^dep[L]) SS[x]++,SS[x=jmp(x,L)]--;
		if (dep[y]^dep[L]) SS[y]++,SS[y=jmp(y,L)]--;
		if ((x^L)&&(y^L)) DSU::merge(x,y,1);
	}
}
int v0[N],v1[N];
int vis[N],f[N],T;
int cc[N],fl[N];
bool check(int K){
	static int q[N];
	Rep(i,n,1){
		int x=TR::pos[i],y=TR::fa[x];
		int vl=0,vr=0;
		++T; *q=0;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		if (vis[DSU::fa[x]]==T){
			int c=DSU::fa[x];
			if (DSU::v[x]) swap(v0[c],v1[c]);
			vl=v0[c]; vr=v1[c];
		}
		For(j,1,*q)
			if (q[j]!=DSU::fa[x]){
				if (v0[q[j]]>v1[q[j]])
					swap(v0[q[j]],v1[q[j]]);
				if (v1[q[j]]<=vl)
					swap(v0[q[j]],v1[q[j]]);
				vl=max(vl,v0[q[j]]);
				vr=max(vr,v1[q[j]]);
			}
		if (vl+vr>=K) return 0;
		f[x]=vl+1;
	}
	return 1;
}
void construct(int K){
	static int q[N];
	For(i,1,n){
		int x=TR::pos[i],y=TR::fa[x];
		int vl=0,vr=0;
		++T; *q=0;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		if (vis[DSU::fa[x]]==T)
			cc[DSU::fa[x]]=fl[x]^DSU::v[x];
		For(j,1,*q)
			if (q[j]!=DSU::fa[x]){
				cc[q[j]]=fl[x];
				if (v0[q[j]]>v1[q[j]])
					swap(v0[q[j]],v1[q[j]]),cc[q[j]]^=1;
				if (v1[q[j]]<=f[x]-1)
					swap(v0[q[j]],v1[q[j]]),cc[q[j]]^=1;
			}
		for (auto j:e[x])
			if (j!=y&&TR::S[j])
				fl[j]=cc[DSU::fa[j]]^DSU::v[j];
	}
}
int main(){
	//freopen("1.in","r",stdin);
	scanf("%d%d",&n,&m);
	For(i,1,n-1){
		int x,y;
		scanf("%d%d",&x,&y);
		e[x].PB(y); e[y].PB(x);
	}
	TR::build();
	DSU::build();
	For(i,1,m){
		int x,y;
		scanf("%d%d",&x,&y);
		TR::insert_que(x,y);
	}
	TR::build2();
	For(i,1,n) DSU::get(i);
	int l=1,r=n,ans=0;
	while (l<=r){
		int mid=(l+r)/2;
		if (check(mid))
			ans=mid,r=mid-1;
		else l=mid+1;
	}
	printf("%d\n",ans);
	check(ans);
	construct(ans);
	static int v[N];
	For(i,1,n) printf("%d ",v[i]=(!fl[i]?f[i]:ans+1-f[i]));
	cout<<endl;
	For(i,2,n){
		if (TR::S[i]){
			//cout<<v[i]<<' '<<v[TR::fa[i]]<<' '<<i<<endl;
			if (fl[i]) assert(v[i]>v[TR::fa[i]]);
			else assert(v[i]<v[TR::fa[i]]);
		}
		assert(fl[i]^DSU::v[i]^fl[DSU::fa[i]]^1);
	}
	//For(i,1,n) cout<<DSU::fa[i]<<' '<<DSU::v[i]<<' '<<TR::S[i]<<endl;
}
/*
限制条件形如连通块。
设f[i]表示限制c[i]>c[fa[i]]的情况下,当前节点的权值可以达到的最小值。

根据每个连通块可以得到限制条件形如:
Vl+1<=vnow<=k-Vr 或 Vr+1<=vnow<=k-Vl
每次总会选择下边界较宽松的一个条件
*/

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
const int N=500005;
int n,m;
vector<int> e[N];

namespace DSU{
	int fa[N],v[N];
	int get(int x){
		if (x==fa[x]) return x;
		int f=fa[x];
		fa[x]=get(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		For(i,1,n) fa[i]=i,v[i]=0;
	}
	void merge(int x,int y,int vv){
		int px=get(x),py=get(y);
		cout<<x<<' '<<y<<' '<<vv<<endl;
		if (px==py){
			if (v[x]^v[y]^vv){
				puts("-1");
				exit(0);
			}
		}
		else{
			//cout<<x<<' '<<y<<' '<<vv<<endl;
			fa[px]=py;
			v[px]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N];
	int fa[N],sz[N],dep[N];
	int pos[N],dfn[N],top[N];
	void dfs1(int x){
		sz[x]=1;
		for (auto i:e[x])
			if (i!=fa[x]){
				fa[i]=x;
				dep[i]=dep[x]+1;
				dfs1(i);
				sz[x]+=sz[i];
			}
	}
	void dfs2(int x,int tp){
		dfn[x]=++*dfn;
		pos[*dfn]=x;
		top[x]=tp;
		int k=0;
		for (auto i:e[x])
			if (i!=fa[x]&&sz[i]>sz[k])
				k=i;
		if (k) dfs2(k,tp);
		for (auto i:e[x])
			if (i!=fa[x]&&i!=k)
				dfs2(i,i);
	}
	int LCA(int x,int y){
		for (;top[x]!=top[y];x=fa[top[x]])
			if (dep[top[x]]<dep[top[y]])
				swap(x,y);
		return dep[x]<dep[y]?x:y;
	}
	int jmp(int x,int y){
		for (;;){
			if (dep[top[x]]<=dep[y])
				return pos[dfn[y]+1];
			if (dep[top[x]]==dep[y]+1)
				return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs1(1);
		dfs2(1,1);
	}
	void build2(){
		Rep(i,n,1){
			int x=pos[i];
			S[fa[x]]+=S[x];
			SS[fa[x]]+=SS[x];
			if (SS[x])
				DSU::merge(x,fa[x],0);
		}
	}
	void insert_que(int x,int y){
		int L=LCA(x,y);
		S[x]++; S[y]++; S[L]-=L*2;
		if (dep[x]^dep[L]) SS[x]++,SS[x=jmp(x,L)]--;
		if (dep[y]^dep[L]) SS[y]++,SS[y=jmp(y,L)]--;
		if ((x^L)&&(y^L)) DSU::merge(x,y,1);
	}
}
int v0[N],v1[N];
int vis[N],f[N],T;
int cc[N],fl[N];
bool check(int K){
	static int q[N];
	Rep(i,n,1){
		int x=TR::pos[i],y=TR::fa[x];
		int vl=0,vr=0;
		++T; *q=0;
		//cout<<x<<endl;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		For(j,1,*q){
			if (q[j]!=DSU::fa[x]){
				if (v0[q[j]]>v1[q[j]])
					swap(v0[q[j]],v1[q[j]]);
			}
			else{
				if (DSU::v[x])
					swap(v0[q[j]],v1[q[j]]);
			}
			vl=max(vl,v0[q[j]]);
			vr=max(vr,v1[q[j]]);
		}
		if (vl+vr>=K) return 0;
		f[x]=vl+1;
		//cout<<i<<' '<<x<<' '<<vl<<' '<<K<<endl;
	}
	return 1;
}
void construct(int K){
	static int q[N];
	For(i,1,n){
		int x=TR::pos[i],y=TR::fa[x];
		++T; *q=0;
		//cout<<x<<' '<<fl[x]<<endl;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		For(j,1,*q){
			cc[q[j]]=fl[x];
			if (q[j]!=DSU::fa[x]){
				if (v0[q[j]]>v1[q[j]])
					swap(v0[q[j]],v1[q[j]]),cc[q[j]]^=1;
			}
			else
				cc[q[j]]^=DSU::v[x];
		}
		//if (x==8) cout<<cc[4]<<' '<<fl[x]<<' '<<DSU::v[x]<<endl;
		for (auto j:e[x])
			if (j!=y&&TR::S[j])
				fl[j]=cc[DSU::fa[j]]^DSU::v[j];
	}
}
int main(){
	scanf("%d%d",&n,&m);
	For(i,1,n-1){
		int x,y;
		scanf("%d%d",&x,&y);
		e[x].PB(y); e[y].PB(x);
	}
	TR::build();
	DSU::build();
	For(i,1,m){
		int x,y;
		scanf("%d%d",&x,&y);
		TR::insert_que(x,y);
	}
	TR::build2();
	For(i,1,n) DSU::get(i);
	//cerr<<233<<endl;
	int l=1,r=n,ans=0;
	while (l<=r){
		int mid=(l+r)/2;
		if (check(mid))
			ans=mid,r=mid-1;
		else l=mid+1;
	}
	printf("%d\n",ans);
	check(ans);
	construct(ans);
	For(i,1,n) printf("%d ",!fl[i]?f[i]:ans+1-f[i]);
}

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
const int N=500005;
int n,m;
vector<int> e[N];

namespace DSU{
	int fa[N],v[N];
	int get(int x){
		if (x==fa[x]) return x;
		int f=fa[x];
		fa[x]=get(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		For(i,1,n) fa[i]=i,v[i]=0;
	}
	void merge(int x,int y,int vv){
		int px=get(x),py=get(y);
		if (px==py){
			if (v[x]^v[y]^vv){
				puts("-1");
				exit(0);
			}
		}
		else{
			fa[px]=py;
			v[px]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N];
	int fa[N],sz[N],dep[N];
	int pos[N],dfn[N],top[N];
	void dfs1(int x){
		sz[x]=1;
		for (auto i:e[x])
			if (i!=fa[x]){
				fa[i]=x;
				dep[i]=dep[x]+1;
				dfs1(i);
				sz[x]+=sz[i];
			}
	}
	void dfs2(int x,int tp){
		dfn[x]=++*dfn;
		pos[*dfn]=x;
		top[x]=tp;
		int k=0;
		for (auto i:e[x])
			if (i!=fa[x]&&sz[i]>sz[k])
				k=i;
		if (k) dfs2(k,tp);
		for (auto i:e[x])
			if (i!=fa[x]&&i!=k)
				dfs2(i,i);
	}
	int LCA(int x,int y){
		for (;top[x]!=top[y];x=fa[top[x]])
			if (dep[top[x]]<dep[top[y]])
				swap(x,y);
		return dep[x]<dep[y]?x:y;
	}
	int jmp(int x,int y){
		for (;;){
			if (dep[top[x]]<=dep[y])
				return pos[dfn[y]+1];
			if (dep[top[x]]==dep[y]+1)
				return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs1(1);
		dfs2(1,1);
	}
	void build2(){
		Rep(i,n,1){
			int x=pos[i];
			S[fa[x]]+=S[x];
			SS[fa[x]]+=SS[x];
			if (SS[x])
				DSU::merge(x,fa[x],0);
		}
	}
	void insert_que(int x,int y){
		int L=LCA(x,y);
		S[x]++; S[y]++; S[L]-=L*2;
		if (dep[x]^dep[L]) SS[x]++,SS[x=jmp(x,L)]--;
		if (dep[y]^dep[L]) SS[y]++,SS[y=jmp(y,L)]--;
		if ((x^L)&&(y^L)) DSU::merge(x,y,1);
	}
}
int v0[N],v1[N];
int vis[N],f[N],T;
int cc[N],fl[N];
bool check(int K){
	static int q[N];
	Rep(i,n,1){
		int x=TR::pos[i],y=TR::fa[x];
		int vl=0,vr=0;
		++T; *q=0;
		//cout<<x<<endl;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		For(j,1,*q){
			if (q[j]!=DSU::fa[x]){
				if (v0[q[j]]>v1[q[j]])
					swap(v0[q[j]],v1[q[j]]);
			}
			else{
				if (DSU::v[x])
					swap(v0[q[j]],v1[q[j]]);
			}
			vl=max(vl,v0[q[j]]);
			vr=max(vr,v1[q[j]]);
		}
		if (vl+vr>=K) return 0;
		f[x]=vl+1;
		//cout<<i<<' '<<x<<' '<<vl<<' '<<K<<endl;
	}
	return 1;
}
void construct(int K){
	static int q[N];
	For(i,1,n){
		int x=TR::pos[i],y=TR::fa[x];
		++T; *q=0;
		//cout<<x<<' '<<fl[x]<<endl;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		For(j,1,*q){
			cc[q[j]]=fl[x];
			if (q[j]!=DSU::fa[x]){
				if (v0[q[j]]>v1[q[j]])
					swap(v0[q[j]],v1[q[j]]),cc[q[j]]^=1;
			}
			else
				cc[q[j]]^=DSU::v[x];
		}
		//if (x==8) cout<<cc[4]<<' '<<fl[x]<<' '<<DSU::v[x]<<endl;
		for (auto j:e[x])
			if (j!=y&&TR::S[j])
				fl[j]=cc[DSU::fa[j]]^DSU::v[j];
	}
}
int main(){
	scanf("%d%d",&n,&m);
	For(i,1,n-1){
		int x,y;
		scanf("%d%d",&x,&y);
		e[x].PB(y); e[y].PB(x);
	}
	TR::build();
	DSU::build();
	For(i,1,m){
		int x,y;
		scanf("%d%d",&x,&y);
		TR::insert_que(x,y);
	}
	TR::build2();
	For(i,1,n) DSU::get(i);
	int l=1,r=n,ans=0;
	while (l<=r){
		int mid=(l+r)/2;
		if (check(mid))
			ans=mid,r=mid-1;
		else l=mid+1;
	}
	printf("%d\n",ans);
	check(ans);
	construct(ans);
	For(i,1,n) printf("%d ",!fl[i]?f[i]:ans+1-f[i]);
}
/*
限制条件形如连通块。
设f[i]表示限制c[i]>c[fa[i]]的情况下,当前节点的权值可以达到的最小值。

根据每个连通块可以得到限制条件形如:
Vl+1<=vnow<=k-Vr 或 Vr+1<=vnow<=k-Vl
每次总会选择下边界较宽松的一个条件
*/

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
const int N=500005;
int n,m;
vector<int> e[N];

namespace DSU{
	int fa[N],v[N];
	int get(int x){
		if (x==fa[x]) return x;
		int f=fa[x];
		fa[x]=get(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		For(i,1,n) fa[i]=i,v[i]=0;
	}
	void merge(int x,int y,int vv){
		int px=get(x),py=get(y);
		if (px==py){
			if (v[x]^v[y]^vv){
				puts("-1");
				exit(0);
			}
		}
		else{
			//cout<<x<<' '<<y<<' '<<vv<<endl;
			fa[px]=py;
			v[px]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N];
	int fa[N],sz[N],dep[N];
	int pos[N],dfn[N],top[N];
	void dfs1(int x){
		sz[x]=1;
		for (auto i:e[x])
			if (i!=fa[x]){
				fa[i]=x;
				dep[i]=dep[x]+1;
				dfs1(i);
				sz[x]+=sz[i];
			}
	}
	void dfs2(int x,int tp){
		dfn[x]=++*dfn;
		pos[*dfn]=x;
		top[x]=tp;
		int k=0;
		for (auto i:e[x])
			if (i!=fa[x]&&sz[i]>sz[k])
				k=i;
		if (k) dfs2(k,tp);
		for (auto i:e[x])
			if (i!=fa[x]&&i!=k)
				dfs2(i,i);
	}
	int LCA(int x,int y){
		for (;top[x]!=top[y];x=fa[top[x]])
			if (dep[top[x]]<dep[top[y]])
				swap(x,y);
		return dep[x]<dep[y]?x:y;
	}
	int jmp(int x,int y){
		for (;;){
			if (dep[top[x]]<=dep[y])
				return pos[dfn[y]+1];
			if (dep[top[x]]==dep[y]+1)
				return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs1(1);
		dfs2(1,1);
	}
	void build2(){
		Rep(i,n,1){
			int x=pos[i];
			S[fa[x]]+=S[x];
			SS[fa[x]]+=SS[x];
			if (SS[x])
				DSU::merge(x,fa[x],0);
		}
	}
	void insert_que(int x,int y){
		int L=LCA(x,y);
		S[x]++; S[y]++; S[L]-=L*2;
		if (dep[x]^dep[L]) SS[x]++,SS[x=jmp(x,L)]--;
		if (dep[y]^dep[L]) SS[y]++,SS[y=jmp(y,L)]--;
		if ((x^L)&&(y^L)) DSU::merge(x,y,1);
	}
}
int v0[N],v1[N];
int vis[N],f[N],T;
int cc[N],fl[N];
bool check(int K){
	static int q[N];
	Rep(i,n,1){
		int x=TR::dfn[i],y=TR::fa[x];
		int vl=0,vr=0;
		++T; *q=0;
		//cout<<x<<endl;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		For(j,1,*q){
			if (q[j]!=DSU::fa[x]){
				if (v0[q[j]]>v1[q[j]])
					swap(v0[q[j]],v1[q[j]]);
			}
			else{
				if (DSU::v[x])
					swap(v0[q[j]],v1[q[j]]);
			}
			vl=max(vl,v0[q[j]]);
			vr=max(vr,v1[q[j]]);
		}
		if (vl+vr>=K) return 0;
		f[x]=vl+1;
		//cout<<i<<' '<<x<<' '<<vl<<' '<<K<<endl;
	}
	return 1;
}
void construct(int K){
	static int q[N];
	For(i,1,n){
		int x=TR::dfn[i],y=TR::fa[x];
		++T; *q=0;
		//cout<<x<<endl;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		For(j,1,*q){
			cc[q[j]]=fl[x];
			if (q[j]!=DSU::fa[x]){
				if (v0[q[j]]>v1[q[j]])
					swap(v0[q[j]],v1[q[j]]),cc[q[j]]^=1;
			}
			else{
				if (DSU::v[x])
					swap(v0[q[j]],v1[q[j]]),cc[q[j]]^=1;
			}
		}
		for (auto j:e[x])
			if (j!=y&&TR::S[j])
				fl[j]=cc[DSU::fa[j]]^DSU::v[j];
	}
}
int main(){
	//freopen("1.in","r",stdin);
	scanf("%d%d",&n,&m);
	For(i,1,n-1){
		int x,y;
		scanf("%d%d",&x,&y);
		e[x].PB(y); e[y].PB(x);
	}
	TR::build();
	DSU::build();
	For(i,1,m){
		int x,y;
		scanf("%d%d",&x,&y);
		TR::insert_que(x,y);
	}
	TR::build2();
	For(i,1,n) DSU::get(i);
	//cerr<<233<<endl;
	int l=1,r=n,ans=0;
	while (l<=r){
		int mid=(l+r)/2;
		if (check(mid))
			ans=mid,r=mid-1;
		else l=mid+1;
	}
	printf("%d\n",ans);
	check(ans);
	construct(ans);
	For(i,1,n) printf("%d ",fl[i]?f[i]:ans+1-f[i]);
}
/*
7 2
1 2
1 3
2 4
2 5
3 6
3 7
4 7
6 5
*/
/*
限制条件形如连通块。
设f[i]表示限制c[i]>c[fa[i]]的情况下,当前节点的权值可以达到的最小值。

根据每个连通块可以得到限制条件形如:
Vl+1<=vnow<=k-Vr 或 Vr+1<=vnow<=k-Vl
每次总会选择下边界较宽松的一个条件
*/

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
const int N=500005;
int n,m;
vector<int> e[N];

namespace DSU{
	int fa[N],v[N];
	int get(int x){
		if (x==fa[x]) return x;
		int f=fa[x];
		fa[x]=get(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		For(i,1,n) fa[i]=i,v[i]=0;
	}
	void merge(int x,int y,int vv){
		int px=get(x),py=get(y);
		if (px==py){
			if (v[x]^v[y]^vv){
				puts("-1");
				exit(0);
			}
		}
		else{
			fa[px]=py;
			v[px]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N];
	int fa[N],sz[N],dep[N];
	int pos[N],dfn[N],top[N];
	void dfs1(int x){
		sz[x]=1;
		for (auto i:e[x])
			if (i!=fa[x]){
				fa[i]=x;
				dep[i]=dep[x]+1;
				dfs1(i);
				sz[x]+=sz[i];
			}
	}
	void dfs2(int x,int tp){
		dfn[x]=++*dfn;
		pos[*dfn]=x;
		top[x]=tp;
		int k=0;
		for (auto i:e[x])
			if (i!=fa[x]&&sz[i]>sz[k])
				k=i;
		if (k) dfs2(k,tp);
		for (auto i:e[x])
			if (i!=fa[x]&&i!=k)
				dfs2(i,i);
	}
	int LCA(int x,int y){
		for (;top[x]!=top[y];x=fa[top[x]])
			if (dep[top[x]]<dep[top[y]])
				swap(x,y);
		return dep[x]<dep[y]?x:y;
	}
	int jmp(int x,int y){
		for (;;){
			if (dep[top[x]]<=dep[y])
				return pos[dfn[y]+1];
			if (dep[top[x]]==dep[y]+1)
				return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs1(1);
		dfs2(1,1);
	}
	void build2(){
		Rep(i,n,1){
			int x=pos[i];
			S[fa[x]]+=S[x];
			SS[fa[x]]+=SS[x];
			if (SS[x])
				DSU::merge(x,fa[x],0);
		}
	}
	void insert_que(int x,int y){
		int L=LCA(x,y);
		S[x]++; S[y]++; S[L]-=2;
		if (dep[x]^dep[L]) SS[x]++,SS[x=jmp(x,L)]--;
		if (dep[y]^dep[L]) SS[y]++,SS[y=jmp(y,L)]--;
		if ((x^L)&&(y^L)) DSU::merge(x,y,1);
	}
}
int v0[N],v1[N];
int vis[N],f[N],T;
int cc[N],fl[N];
bool check(int K){
	static int q[N];
	Rep(i,n,1){
		int x=TR::pos[i],y=TR::fa[x];
		int vl=0,vr=0;
		++T; *q=0;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		if (vis[DSU::fa[x]]==T){
			int c=DSU::fa[x];
			if (DSU::v[x]) swap(v0[c],v1[c]);
			vl=v0[c]; vr=v1[c];
		}
		For(j,1,*q)
			if (q[j]!=DSU::fa[x])
				vl=max(vl,min(v0[q[j]],v1[q[j]]));
		For(j,1,*q)
			if (q[j]!=DSU::fa[x]){
				if (v0[q[j]]>v1[q[j]]) swap(v0[q[j]],v1[q[j]]);
				if (v1[q[j]]<=vl) swap(v0[q[j]],v1[q[j]]);
				vl=max(vl,v0[q[j]]);
				vr=max(vr,v1[q[j]]);
			}
		if (vl+vr>=K) return 0;
		f[x]=vl+1;
	}
	return 1;
}
void construct(int K){
	static int q[N];
	For(i,1,n){
		int x=TR::pos[i],y=TR::fa[x];
		int vl=0,vr=0;
		++T; *q=0;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		if (vis[DSU::fa[x]]==T)
			cc[DSU::fa[x]]=fl[x]^DSU::v[x];
		For(j,1,*q)
			if (q[j]!=DSU::fa[x]){
				cc[q[j]]=fl[x];
				if (v0[q[j]]>v1[q[j]])
					swap(v0[q[j]],v1[q[j]]),cc[q[j]]^=1;
				if (v1[q[j]]<=f[x]-1)
					swap(v0[q[j]],v1[q[j]]),cc[q[j]]^=1;
			}
		for (auto j:e[x])
			if (j!=y&&TR::S[j])
				fl[j]=cc[DSU::fa[j]]^DSU::v[j];
	}
}
int main(){
	//freopen("1.in","r",stdin);
	scanf("%d%d",&n,&m);
	For(i,1,n-1){
		int x,y;
		scanf("%d%d",&x,&y);
		e[x].PB(y); e[y].PB(x);
	}
	TR::build();
	DSU::build();
	For(i,1,m){
		int x,y;
		scanf("%d%d",&x,&y);
		TR::insert_que(x,y);
	}
	TR::build2();
	For(i,1,n) DSU::get(i);
	int l=1,r=n,ans=0;
	while (l<=r){
		int mid=(l+r)/2;
		if (check(mid))
			ans=mid,r=mid-1;
		else l=mid+1;
	}
	printf("%d\n",ans);
	check(ans);
	construct(ans);
	static int v[N];
	For(i,1,n) printf("%d ",v[i]=(!fl[i]?f[i]:ans+1-f[i]));
	cout<<endl;
	For(i,2,n){
		if (TR::S[i]){
			//cout<<v[i]<<' '<<v[TR::fa[i]]<<' '<<i<<endl;
			if (fl[i]) assert(v[i]>v[TR::fa[i]]);
			else assert(v[i]<v[TR::fa[i]]);
		}
		assert(fl[i]^DSU::v[i]^fl[DSU::fa[i]]^1);
	}
	//For(i,1,n) cout<<DSU::fa[i]<<' '<<DSU::v[i]<<' '<<TR::S[i]<<endl;
}
/*
限制条件形如连通块。
设f[i]表示限制c[i]>c[fa[i]]的情况下,当前节点的权值可以达到的最小值。

根据每个连通块可以得到限制条件形如:
Vl+1<=vnow<=k-Vr 或 Vr+1<=vnow<=k-Vl
每次总会选择下边界较宽松的一个条件
*/

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
const int N=500005;
int n,m;
vector<int> e[N];

namespace DSU{
	int fa[N],v[N];
	int get(int x){
		if (x==fa[x]) return x;
		int f=fa[x];
		fa[x]=get(fa[x]);
		v[x]^=v[f];
		return fa[x];
	}
	void build(){
		For(i,1,n) fa[i]=i,v[i]=0;
	}
	void merge(int x,int y,int vv){
		int px=get(x),py=get(y);
		if (px==py){
			if (v[x]^v[y]^vv){
				puts("-1");
				exit(0);
			}
		}
		else{
			fa[px]=py;
			v[px]=v[x]^v[y]^vv;
		}
	}
}
namespace TR{
	int S[N],SS[N];
	int fa[N],sz[N],dep[N];
	int pos[N],dfn[N],top[N];
	void dfs1(int x){
		sz[x]=1;
		for (auto i:e[x])
			if (i!=fa[x]){
				fa[i]=x;
				dep[i]=dep[x]+1;
				dfs1(i);
				sz[x]+=sz[i];
			}
	}
	void dfs2(int x,int tp){
		dfn[x]=++*dfn;
		pos[*dfn]=x;
		top[x]=tp;
		int k=0;
		for (auto i:e[x])
			if (i!=fa[x]&&sz[i]>sz[k])
				k=i;
		if (k) dfs2(k,tp);
		for (auto i:e[x])
			if (i!=fa[x]&&i!=k)
				dfs2(i,i);
	}
	int LCA(int x,int y){
		for (;top[x]!=top[y];x=fa[top[x]])
			if (dep[top[x]]<dep[top[y]])
				swap(x,y);
		return dep[x]<dep[y]?x:y;
	}
	int jmp(int x,int y){
		for (;;){
			if (dep[top[x]]<=dep[y])
				return pos[dfn[y]+1];
			if (dep[top[x]]==dep[y]+1)
				return top[x];
			x=fa[top[x]];
		}
	}
	void build(){
		dfs1(1);
		dfs2(1,1);
	}
	void build2(){
		Rep(i,n,1){
			int x=pos[i];
			S[fa[x]]+=S[x];
			SS[fa[x]]+=SS[x];
			if (SS[x])
				DSU::merge(x,fa[x],0);
		}
	}
	void insert_que(int x,int y){
		int L=LCA(x,y);
		S[x]++; S[y]++; S[L]-=2;
		if (dep[x]^dep[L]) SS[x]++,SS[x=jmp(x,L)]--;
		if (dep[y]^dep[L]) SS[y]++,SS[y=jmp(y,L)]--;
		if ((x^L)&&(y^L)) DSU::merge(x,y,1);
	}
}
int v0[N],v1[N];
int vis[N],f[N],T;
int cc[N],fl[N];
bool check(int K){
	static int q[N];
	Rep(i,n,1){
		int x=TR::pos[i],y=TR::fa[x];
		int vl=0,vr=0;
		++T; *q=0;
		//cout<<x<<endl;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				//cout<<x<<' '<<j<<endl;
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		For(j,1,*q){
			if (q[j]!=DSU::fa[x]){
				if (v0[q[j]]>v1[q[j]])
					swap(v0[q[j]],v1[q[j]]);
			}
			else{
				if (DSU::v[x])
					swap(v0[q[j]],v1[q[j]]);
			}
			//cout<<x<<' '<<q[j]<<' '<<v0[q[j]]<<' '<<v1[q[j]]<<endl;
			vl=max(vl,v0[q[j]]);
			vr=max(vr,v1[q[j]]);
		}
		if (vl+vr>=K) return 0;
		f[x]=vl+1;
		//cout<<i<<' '<<x<<' '<<y<<' '<<vl<<' '<<vr<<' '<<K<<endl;
	}
	return 1;
}
void construct(int K){
	static int q[N];
	For(i,1,n){
		int x=TR::pos[i],y=TR::fa[x];
		++T; *q=0;
		//cout<<x<<' '<<fl[x]<<endl;
		for (auto j:e[x])
			if (j!=y&&TR::S[j]){
				int c=DSU::fa[j];
				if (vis[c]!=T) vis[c]=T,q[++*q]=c,v0[c]=v1[c]=0;
				if (DSU::v[j]==0) v0[c]=max(v0[c],f[j]);
				else v1[c]=max(v1[c],f[j]);
			}
		For(j,1,*q){
			cc[q[j]]=fl[x];
			if (q[j]!=DSU::fa[x]){
				if (v0[q[j]]>v1[q[j]])
					swap(v0[q[j]],v1[q[j]]),cc[q[j]]^=1;
			}
			else
				cc[q[j]]^=DSU::v[x];
		}
		//if (x==8) cout<<cc[4]<<' '<<fl[x]<<' '<<DSU::v[x]<<endl;
		for (auto j:e[x])
			if (j!=y&&TR::S[j])
				fl[j]=cc[DSU::fa[j]]^DSU::v[j];
	}
}
int main(){
	scanf("%d%d",&n,&m);
	For(i,1,n-1){
		int x,y;
		scanf("%d%d",&x,&y);
		e[x].PB(y); e[y].PB(x);
	}
	TR::build();
	DSU::build();
	For(i,1,m){
		int x,y;
		scanf("%d%d",&x,&y);
		TR::insert_que(x,y);
	}
	TR::build2();
	For(i,1,n) DSU::get(i);
	int l=1,r=n,ans=0;
	while (l<=r){
		int mid=(l+r)/2;
		if (check(mid))
			ans=mid,r=mid-1;
		else l=mid+1;
	}
	printf("%d\n",ans);
	check(ans);
	construct(ans);
	For(i,1,n) printf("%d ",!fl[i]?f[i]:ans+1-f[i]);
}
/*
限制条件形如连通块。
设f[i]表示限制c[i]>c[fa[i]]的情况下,当前节点的权值可以达到的最小值。

根据每个连通块可以得到限制条件形如:
Vl+1<=vnow<=k-Vr 或 Vr+1<=vnow<=k-Vl
每次总会选择下边界较宽松的一个条件
*/

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i);
				if(dp[u]-1>=va&&vb+dp[u]-1<=k) bfg(0); else bfg(1);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i);
				if(dp[u]-1>=va&&vb+dp[u]<=d) bfg(0);
				else if(dp[u]-1>=vb&&va+dp[u]<=d) bfg(1);
				else cout<<"fail"<<endl;
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1; int pt,qt;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		if(i==1) pt=u,qt=t;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	if(ans==10002){
		int c=lca(pt,qt);
		cout<<jmp(pt,dep[pt]-dep[c]-1)<<endl;
		cout<<jmp(qt,dep[qt]-dep[c]-1)<<endl;
		cout<<c<<endl;
		cout<<endl;

	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i);
				if(dp[u]-1>=va&&vb+dp[u]<=d) bfg(0);
				else if(dp[u]-1>=vb&&va+dp[u]<=d) bfg(1);
				else cout<<"fail"<<endl;
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1; int pt,qt;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		if(i==1) pt=u,qt=t;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	if(ans==10002){
		int c=lca(pt,qt);
		while(pt!=c) printf("%d ",rev[pt]),pt=fa[pt];
		cout<<endl;

	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i);
				if(dp[u]-1>=va&&vb+dp[u]<=d) bfg(0); else bfg(1);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i); bool tg=0;
				if(va<vb) swap(va,vb),tg^=1;
				if(va<=dp[u]-1) bfg(tg); else bfg(tg^1); vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}
//12 2
//9 2
//4 1
//12 8
//9 5
//1 11
//1 9
//9 10
//3 4
//4 6
//5 7
//9 8
//3 5
//12 5

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				if(va<=dp[u]) bfg(0); else bfg(1); vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}
//12 2
//9 2
//4 1
//12 8
//9 5
//1 11
//1 9
//9 10
//3 4
//4 6
//5 7
//9 8
//3 5
//12 5

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i);
				if(dp[u]-1>=va&&vb+dp[u]<=d) bfg(0);
				else if(dp[u]-1>=vb&&va+dp[u]<=d) bfg(1);
				else cout<<"fail"<<endl;
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1; int pt,qt;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		if(i==1) pt=u,qt=t;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	if(ans==10002){
		int c=lca(pt,qt);
		while(qt!=c){
			if(rev[qt]==1) cout<<114514<<endl; qt=fa[qt];
		}
		cout<<endl;

	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i);
				if(dp[u]-1>=va&&vb+dp[u]<=d) bfg(0);
				else if(dp[u]-1>=vb&&va+dp[u]<=d) bfg(1);
				else cout<<"fail"<<endl;
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i); bool tg=1;
				if(va<vb) swap(va,vb),tg^=1;
				if(va<=dp[u]-1) bfg(tg); else bfg(tg^1); vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}
//12 2
//9 2
//4 1
//12 8
//9 5
//1 11
//1 9
//9 10
//3 4
//4 6
//5 7
//9 8
//3 5
//12 5

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i);
				if(dp[u]-1>=va&&vb+dp[u]<=d) bfg(0);
				else if(dp[u]-1>=vb&&va+dp[u]<=d) bfg(1);
				else cout<<"fail"<<endl;
			}
		if(u==75723&&d==10002) cout<<col[52059]<<" "<<col[72973]<<endl;
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1; int pt,qt;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		if(i==1) pt=u,qt=t;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	if(ans==10002){
		int c=lca(pt,qt);
		cout<<jmp(pt,dep[pt]-dep[c]-1)<<endl;
		cout<<jmp(qt,dep[qt]-dep[c]-1)<<endl;
		cout<<c<<endl;
		cout<<endl;

	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i);
				if(dp[u]-1>=va&&vb+dp[u]<=d) bfg(0);
				else if(dp[u]-1>=vb&&va+dp[u]<=d) bfg(1);
//				else cout<<"fail"<<endl;
			}
//		if(u==75723&&d==10002) cout<<col[gt[52059]]<<" "<<col[gt[72973]]<<endl;
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1; int pt,qt;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		if(i==1) pt=u,qt=t;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
//	if(ans==10002){
//		int c=lca(pt,qt);
//		cout<<jmp(pt,dep[pt]-dep[c]-1)<<endl;
//		cout<<jmp(qt,dep[qt]-dep[c]-1)<<endl;
//		cout<<c<<endl;
//		cout<<endl;
//
//	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i);
				if(dp[u]-1>=va&&vb+dp[u]<=d) bfg(0);
				else if(dp[u]-1>=vb&&va+dp[u]<=d) bfg(1);
				else cout<<"fail"<<endl;
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1; int pt,qt;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		if(i==1) pt=u,qt=t;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	if(ans==10002){
		int c=lca(pt,qt);
		while(pt!=c) printf("%d ",rev[pt]),pt=fa[pt];
		cout<<endl;
		for(int s=1;s<=n;s++) printf("%d ",dp[s]);
	}
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				if(va<=dp[u]) bfg(0); else bfg(1); vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}
//12 2
//9 2
//4 1
//12 8
//9 5
//1 11
//1 9
//9 10
//3 4
//4 6
//5 7
//9 8
//3 5
//12 5

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i); bool tg=0;
				if(va<vb) swap(va,vb),tg^=1;
				if(va<=dp[u]) bfg(tg); else bfg(tg^1); vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}
//12 2
//9 2
//4 1
//12 8
//9 5
//1 11
//1 9
//9 10
//3 4
//4 6
//5 7
//9 8
//3 5
//12 5

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i);
				if(dp[u]-1>=va&&vb+dp[u]<=d) bfg(0);
				else if(dp[u]-1>=vb&&va+dp[u]<=d) bfg(1);
				else cout<<"fail"<<endl;
			}
		if(u==75723&&d==10002) cout<<col[gt[52059]]<<" "<<col[gt[72973]]<<endl;
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1; int pt,qt;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		if(i==1) pt=u,qt=t;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	if(ans==10002){
		int c=lca(pt,qt);
		cout<<jmp(pt,dep[pt]-dep[c]-1)<<endl;
		cout<<jmp(qt,dep[qt]-dep[c]-1)<<endl;
		cout<<c<<endl;
		cout<<endl;

	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
//	cout<<k<<":"<<endl;
	for(int i=1;i<=q[0];i++){
//		cout<<ft[q[i]]<<"ssss"<<" "<<endl;
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),bfg(0),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i);
				if(dp[u]-1>=va&&vb+dp[u]<=d) bfg(0);
				else if(dp[u]-1>=vb&&va+dp[u]<=d) bfg(1);
//				else cout<<"fail"<<endl;
			}
//		if(u==75723&&d==10002) cout<<col[gt[52059]]<<" "<<col[gt[72973]]<<endl;
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1; int pt,qt;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		if(i==1) pt=u,qt=t;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
//	if(ans==10002){
//		int c=lca(pt,qt);
//		cout<<jmp(pt,dep[pt]-dep[c]-1)<<endl;
//		cout<<jmp(qt,dep[qt]-dep[c]-1)<<endl;
//		cout<<c<<endl;
//		cout<<endl;
//
//	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i);
				if(dp[u]-1>=va&&vb+dp[u]<=k) bfg(0); else bfg(1);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=20; bool fl[N],rev[N],tg;
int n,k,va,vb,opt,tot,q[N],w[N],h[N],dp[N],gt[N],ft[N],fa[N],st[N],col[N],dep[N],cnt[N],e[N][M]; vector<int>v[N],vw[N]; vector<pair<int,int>>f[N];
struct edge {int u,t;}g[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int lca(int u,int t){
	if(dep[u]<dep[t]) swap(u,t); int z=dep[u]-dep[t];
	for(int i=19;i>=0;i--) if((1<<i)&z) u=e[u][i]; if(u==t) return u;
	for(int i=19;i>=0;i--) if(e[u][i]!=e[t][i]) u=e[u][i],t=e[t][i]; return fa[u];
}
inline int jmp(int u,int t){
	for(int i=19;i>=0;i--) if((1<<i)&t) u=e[u][i]; return u;
}
inline void dfs(int u){
	st[++st[0]]=u,e[u][0]=fa[u];
	for(int z=1;z<=19;z++) e[u][z]=e[e[u][z-1]][z-1];
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i]; if(fa[u]==x) continue; fa[x]=u,dep[x]=dep[u]+1,dfs(x);
	}
}
inline void bfs(int u){
	q[q[0]=1]=u;
	for(int i=1;i<=q[0];i++){
//		cout<<u<<" "<<col[u]<<"cccc"<<endl;
		u=q[i]; if(col[u]) vb=max(vb,dp[ft[u]]); else va=max(va,dp[ft[u]]);
		for(int z=0;z<vw[u].size();z++){
			int x=vw[u][z];
			if(col[x]==-1) col[x]=col[u]^1,q[++q[0]]=x;
			else if(col[u]==col[x]) tg=1;
		}
	}
}
inline void bfg(int k){
	for(int i=1;i<=q[0];i++){
		int u=q[i]; if(col[u]==k) rev[ft[u]]^=1;
	}
}
inline bool check(int d){
	memset(dp,0,sizeof(dp));
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=fa[u]; int suma=0,sumb=0;
//		cout<<u<<":"<<endl;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
//			cout<<u<<" "<<f[u][i].first<<" "<<f[u][i].second<<"wwwwww"<<endl;
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,col[1]=0,bfs(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])||i==1){
				va=0,vb=0,col[i]=0,bfs(i);
				if(va<vb) swap(va,vb);
				vc=max(vc,va),vd=max(vd,vb);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
		if(max(vc,suma)+max(vd,sumb)+1>d&&max(vc,sumb)+max(vd,suma)+1>d) return false;
		dp[u]=1919810;
//		cout<<u<<" "<<suma<<" "<<sumb<<" "<<w[u]<<" "<<h[u]<<endl;
		if(max(vc,suma)+max(vd,sumb)+1<=d||u==1) dp[u]=min(dp[u],max(vc,suma));
		if(max(vc,sumb)+max(vd,suma)+1<=d||u==1) dp[u]=min(dp[u],max(vd,suma)); dp[u]++;
	}
	return true;
}
inline void solve(int d){
	for(int s=n;s>=1;s--){
		int u=st[s],opt=1; ft[1]=0; int suma=0,sumb=0;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; gt[x]=++opt,ft[opt]=x;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		va=0,vb=0,bfs(1),bfg(1),suma=vb,sumb=va; int vc=0,vd=0;
		for(int i=1;i<=opt;i++)
			if((col[i]==-1&&h[ft[i]])){
				va=0,vb=0,col[i]=0,bfs(i);
				if(dp[u]-1>=va&&vb+dp[u]-1<=k) bfg(1); else bfg(0);
			}
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
}
int main(){
	n=read(),k=read(); int u,t,c;
	for(int i=1;i<=n;i++) col[i]=-1;
	for(int i=1;i<n;i++) u=read(),t=read(),v[u].push_back(t),v[t].push_back(u); dfs(1);
	for(int i=1;i<=k;i++){
		u=read(),t=read(),c=lca(u,t); int a=0,b=0;
		h[u]++,h[t]++,h[c]-=2;
		if(c!=u) a=jmp(u,dep[u]-dep[c]-1),w[u]++,w[a]--;
		if(c!=t) b=jmp(t,dep[t]-dep[c]-1),w[t]++,w[b]--;
		if(a>0&&b>0) f[c].push_back(make_pair(a,b));
	}
	for(int s=n;s>=1;s--){
		u=st[s],opt=1;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x) continue; w[u]+=w[x],h[u]+=h[x]; gt[x]=++opt;
		}
		for(int i=1;i<=opt;i++) vw[i].resize(0);
		for(int i=0;i<f[u].size();i++){
			vw[gt[f[u][i].first]].push_back(gt[f[u][i].second]);
			vw[gt[f[u][i].second]].push_back(gt[f[u][i].first]);
			fl[gt[f[u][i].first]]=1,fl[gt[f[u][i].second]]=1;
		}
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!w[x]) continue;
			vw[1].push_back(gt[x]),vw[gt[x]].push_back(1),fl[gt[x]]=1;
		}
		for(int i=1;i<=opt;i++) if(col[i]==-1) col[i]=0,bfs(i);
		for(int i=1;i<=opt;i++) col[i]=-1,vw[i].resize(0),fl[i]=0;
	}
	if(tg) {puts("-1"); return 0;}
	int l=1,r=n,ans=-1;
	while(l<=r){
		int d=(l+r)>>1; if(check(d)) ans=d,r=d-1; else l=d+1;
	}
	check(ans),solve(ans);
	cout<<ans<<endl;
	for(int s=1;s<=st[0];s++){
		int u=st[s];
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i]; if(fa[u]==x||!h[x]) continue;
			rev[x]^=rev[u];
			if(rev[x]) tot++,g[tot].u=u,g[tot].t=x;
			else tot++,g[tot].u=x,g[tot].t=u;
		}
	}
	q[0]=0;
	memset(dp,0,sizeof(dp));
	for(int s=1;s<=n;s++) v[s].resize(0);
	for(int s=1;s<=tot;s++) cnt[g[s].t]++,v[g[s].u].push_back(g[s].t);
	for(int s=1;s<=n;s++) if(!cnt[s]) q[++q[0]]=s;
	for(int s=1;s<=q[0];s++){
		int u=q[s]; dp[u]++;
		for(int i=0;i<v[u].size();i++){
			int x=v[u][i];
			dp[x]=max(dp[x],dp[u]); cnt[x]--; if(!cnt[x]) q[++q[0]]=x;
		}
	}
	for(int s=1;s<=n;s++) printf("%d ",dp[s]);
}

/*
(did I correctly understand the problem statement?
I think it's just a bunch of old problems combined together.
if it's just that, why is/are there so few people who solved it?
)

the sample test cases are definitely very weak.
*/

#ifndef LOCAL
#define NDEBUG 1
#endif
#include<bits/stdc++.h>

std::vector<std::vector<int>> add;

void add_edge(int u,int v){
	add[u].push_back(v);
	add[v].push_back(u);
}

void read_graph(int nnode,int nedge){
}

void read_tree(int nnode){
	read_graph(nnode,nnode-1);
}

std::vector<int> depth;
std::vector<int> par;
std::vector<int> subtreeSize;
std::vector<int> postOrder;

void dd(int x,int parx=-1){
	par[x]=parx;
	//subtree_size[x]=1;
	for(int y:add[x]){
		//add[y].erase(std::find(begin(add[y]),end(add[y]),x));
		if(y==parx) continue;

		depth[y]=depth[x]+1;
		dd(y,x);
		//subtree_size[x]+=subtree_size[y];
	}
	postOrder.push_back(x);
}

std::vector<std::vector<int>> jt;

void init_jt(){
	jt.push_back(par);
	for(;;){
		bool useful=false;
		auto const& a=jt.back();
		auto b=a;
		for(auto& x:b)if(x>=0){
			if((x=a[x])>=0)
				useful=true;
		}
		if(useful)
			jt.push_back(std::move(b));
		else
			break;
	}
}

struct lca_result {
	int u1,v1,lca; // u1,v1: child of lca int the direction of u/v resp.
	// int case lca is u or v, both u1 and v1 are int the direction of the node != lca
};

lca_result lca(int u,int v){
	assert(u!=v);

	bool swapped;
	if((swapped=(depth[u]<depth[v])))std::swap(u,v);

	int ddepth=depth[u]-depth[v];
	if(ddepth){
		--ddepth;
		for(;ddepth;ddepth^=ddepth&-ddepth){
			u=jt[__builtin_ctz(ddepth)][u];
		}
		assert(depth[u]-1==depth[v]);
		if(jt[0][u]==v)return {u,u,v};
		u=jt[0][u];
	}
	assert(u!=v);
	for(auto layer=jt.size();layer--;){
		if(jt[layer][u]!=jt[layer][v])
			std::tie(u,v)=std::make_pair(jt[layer][u],jt[layer][v]);
	}
	assert(jt[0][u]==jt[0][v]);
	if(swapped)std::swap(u,v);
	assert(u!=v);
	return {u,v,jt[0][u]};
}

std::vector<int> tail; // tail[x]=y => path (x... y) have the same direction
std::vector<std::vector<std::pair<int, int>>> pairs;
// [u, v] in pairs[lca] => (edge (u, lca) is up) xor (edge (v, lca) is up)

int main(){
	std::ios::sync_with_stdio(0);std::cin.tie(0);
	int numNode, numPath; std::cin>>numNode>>numPath;

	add.resize(numNode);
	for(int z=numNode-1;z--;){
		int u,v;
		std::cin>>u>>v;
		--u;--v;
		add_edge(u,v);
	}

	postOrder.reserve(numNode);
	par.resize(numNode); depth.resize(numNode);
	par[0]=-1;
	depth[0]=0;
	dd(0);
	assert((int)postOrder.size()==numNode);
	init_jt();

	tail.resize(numNode);
	std::iota(begin(tail),end(tail), 0);

	auto const updateTail=[&](int v, int u){
		if(depth[u]<depth[tail[v]]) tail[v]=u;
	};

	pairs.resize(numNode);
	for(auto _=numPath;_--;){
		int u,v;
		std::cin>>u>>v;
		--u;--v;
		auto it=lca(u, v);
		if(it.u1==it.v1){
			if(v==it.lca) std::swap(u, v);
			assert(u==it.lca);
			updateTail(v, u);
		}else{
			updateTail(u, it.lca);
			updateTail(v, it.lca);
			pairs[it.lca].push_back({it.u1, it.v1});
		}
	}

	for(auto node:postOrder){
		assert(depth[tail[node]]<=depth[node]);
		if(tail[node]!=node and tail[node]!=par[node]){
			updateTail(par[node], tail[node]);
			pairs[par[node]].push_back({par[par[node]], node});
		}
	}

	std::vector<std::vector<std::array<std::vector<int>, 2>>> components(numNode);
	// bipartite components
	{
		std::vector<std::vector<int>> subadd(numNode);
		// used for computing `components`
		std::vector<char> color(numNode); // -1, 0 or 1
		std::vector<int> queue; queue.reserve(numNode);

		for(int node=numNode; node--;){
			assert(par[node]==-1 or std::find(begin(add[node]),end(add[node]), par[node])!=end(add[node]));
			for(auto other: add[node]){
				subadd[other].clear();
				color[other]=-1;
			}
			for(auto [first, sec]: pairs[node]){
				subadd[first].push_back(sec);
				subadd[sec].push_back(first);
			}
			assert(components[node].empty());
			for(auto other: add[node]) if(color[other]<0){
				color[other]=0;
				std::array<std::vector<int>, 2> component;
				queue.clear();
				queue.push_back(other);
				component[color[other]=0].push_back(other);
				for(auto iterator=begin(queue); iterator!=end(queue);++iterator){
					assert((int)queue.size()<=numNode);
					auto node=*iterator;
					auto const colorNode=color[node];

					assert(colorNode==0 or colorNode==1);
					assert(std::count(begin(component[colorNode]),end(component[colorNode]), node)==1);
					for(auto other: subadd[node]){
						if(color[other]==colorNode){
							std::cout<<"-1\n";
							return 0;
						}
						if(color[other]<0){
							component[color[other]=not colorNode].push_back(other);
							queue.push_back(other);
						}
					}
				}

				components[node].push_back(std::move(component));
			}

			if(par[node]>=0){ // rearrange the components so [0][0] is the component that contains par[node]
				assert(color[par[node]]!=-1);
				std::swap(components[node][0], *std::find_if(begin(components[node]),end(components[node]),[&](auto const& component){
					return std::any_of(begin(component),end(component),[&](auto const& side){
						return std::find(begin(side),end(side), par[node])!=end(side);
					});
				}));
				auto& component=components[node][0];
				if(std::find(begin(component[0]),end(component[0]), par[node])==end(component[0]))
					std::swap(component[0], component[1]);
				assert(std::find(begin(component[0]),end(component[0]), par[node])!=end(component[0]));
			}
		}
	}

	pairs.clear(); // don't use this anymore, use `components` instead

	std::vector<int> f;
	// f[node] = minimum down length from node,
	// if all paths in that substring has length <= maximumPathLength,
	// and the edge (par[node]..node) points down

	auto const fillF=[&](int maximumPathLength){
		f.assign(numNode, 0);
		for(auto node: postOrder){
			std::vector<std::array<int, 2>> componentLength(components[node].size());
			assert(par[node]==-1 or f[par[node]]==0);
			for(int index=0;index<(int)components[node].size();++index) {
				auto const& component=components[node][index];
				std::array<int, 2> result;
				std::transform(begin(component),end(component), begin(result),
						[&](auto const& side){
							int result=0;
							for(auto node: side) if(tail[node]!=node)
								result=std::max(result, f[node]+1);
							return result;
						});
				if(result[0]+result[1]>maximumPathLength) return false;
				if(index!=0 or par[node]<0){
					std::sort(begin(result),end(result), std::greater<>());
				}else{
					// result[0] must be max up distance, result[1] must be max down distance
				}
				componentLength[index]=result;
			}

			int minimumUp=std::accumulate(begin(componentLength),end(componentLength), 0,
					[](int minimumUp, auto const& componentLength){
						return std::max(minimumUp, std::min(componentLength[0], componentLength[1]));
					});
			if(par[node]>=0){
				minimumUp=std::max(minimumUp, componentLength[0][0]);
				if(tail[node]==node){
					assert(components[node][0][0].size()==1 and
							components[node][0][0][0]==par[node] and
							components[node][0][1].empty());
				}
			}

			std::sort(begin(componentLength),end(componentLength),[&](auto first, auto sec){
				return first[0]>sec[0];
			});
			int maximumDown=std::accumulate(begin(componentLength),end(componentLength), 0,
					[](int maximumDown, auto const& componentLength){
						return std::max(maximumDown, componentLength[1]);
					});
			for(auto [up, down]: componentLength){
				if(up<minimumUp) return false; // no possible choice
				// consider maximumUp = up, then it's possible that maximumDown == maximumDown
				if(up+maximumDown<=maximumPathLength) break; // the choice with minimum possible maximumDown
				maximumDown=std::max(maximumDown, up /* when swapped */);
			}

			f[node]=maximumDown;
		}
		return true;
	};

	int maximumPathLength=numNode;
	assert(numPath>0);
	for(int step=1<<22; step>>=1;) if(maximumPathLength-step>0 and fillF(maximumPathLength-step)){
		maximumPathLength-=step;
	}
	fillF(maximumPathLength); // TODO is this necessary?

	std::vector<char> parUp(numNode);
	assert(par[postOrder.back()]==-1);
	std::vector<std::vector<int>> inpath(numNode);
	// b in inpath[a] -> value of b must be larger than value of a

	std::for_each(postOrder.rbegin(), postOrder.rend(),[&](int node){
		int const maximumDownLength=f[node];
		int const maximumUpLength=maximumPathLength-f[node];
		assert(maximumUpLength>=0);

		for(int index=0;index<(int)components[node].size();++index) {
			auto const& component=components[node][index];
			std::array<int, 2> result;
			std::transform(begin(component),end(component), begin(result),
					[&](auto const& side){
						int result=0;
						for(auto it: side) if(tail[it]!=it and it!=par[node])
							result=std::max(result, f[it]+1);
						return result;
					});

			bool swap=false;
			// can exchange up/down
			if(not (result[0]<=maximumUpLength and result[1]<=maximumDownLength)){
				assert(index!=0 or par[node]<0); // can swap freely
				swap=true;
			}
			assert(result[0]<=maximumUpLength and result[1]<=maximumDownLength);

			for(int index=0;index<2;++index) for(auto it:component[index]) if(it!=par[node]){
				assert(par[it]==node);
				if(tail[it]!=it){
					parUp[it]=parUp[node] xor swap xor index xor 1;
					if(parUp[it]) inpath[it].push_back(node);
					else inpath[node].push_back(it);
				}
			}
		}
	});

	std::vector<int> longestPathLength(numNode); // that ends at this node
	std::vector<int> indegree(numNode);
	for(auto const& it: inpath)
		for(auto const node: it) ++indegree[node];
	std::vector<int> pending;
	for(int node=0;node<numNode;++node)
		if(indegree[node]==0) pending.push_back(node);
	while(not pending.empty()){
		auto node=pending.back(); pending.pop_back();
		auto const nextLongestPathLength=longestPathLength[node]+1;
		for(auto other: inpath[node]){
			--indegree[other];
			longestPathLength[other]=std::max(longestPathLength[other], nextLongestPathLength);
			if(indegree[other]==0) pending.push_back(other);
		}
	}

	assert(std::all_of(begin(indegree),end(indegree),[&](auto it){return it==0;}));

	std::cout<<maximumPathLength+1<<'\n';
	for(int node=0;node<numNode;++node) std::cout<<longestPathLength[node]+1<<' ';
	std::cout<<'\n';
}

// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <chrono>
#include <random>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <iomanip>
#define dibs reserve
#define OVER9000 1234567890
#define tisic 47
#define soclose 1e-8
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
using uint = unsigned int;
using cat = long long;
using dbl = long double;
constexpr dbl pi = 3.14159265358979323846;
using namespace std;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

void DFS_LCA(int v, auto & G, auto & par, auto & dep) {
	for(auto s : G[v]) if(par[s] == -1) {
		par[s] = v;
		dep[s] = dep[v]+1;
		DFS_LCA(s, G, par, dep);
	}
}

void DFS_comp(int v, auto & G, auto & par, auto & dep, auto & up, auto & down,
		auto & comp, auto & comp_l) {
	for(auto s : G[v]) if(par[s] == v) {
		DFS_comp(s, G, par, dep, up, down, comp, comp_l);
		up[v] = min(up[v], up[s]);
	}
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int S = sons.size(), C = 0;
	comp[v].resize(S+1, 0);
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear();
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(i);
		g[i].push_back(S);
	}

	static queue<int> q;
	for(int i = 0; i <= S; i++) if(!comp[v][i]) {
		q.push(i);
		C++;
		comp[v][i] = C;
		comp_l[v].push_back({});
		while(!q.empty()) {
			comp_l[v].back().push_back(q.front());
			int c = comp[v][q.front()];
			for(auto r : g[q.front()]) {
				if(comp[v][r] && comp[v][r] == c) {
					cout << "-1\n";
					exit(0);
				}
				if(comp[v][r]) continue;
				comp[v][r] = -c;
				q.push(r);
			}
			q.pop();
		}
	}
}

char tt = 0;

void DFS_solve(int v, auto & G, auto & par, auto & dep, auto & up,
		auto & comp, auto & comp_l, auto & I_up, auto & I_dn, int A) {
	for(auto s : G[v]) if(par[s] == v)
		DFS_solve(s, G, par, dep, up, comp, comp_l, I_up, I_dn, A);
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}
	if(tt) return;

	int C = comp_l[v].size(), S = sons.size();

	static vector<int> i_up(par.size());
	for(int i = 0; i < S; i++) i_up[i] = I_up[sons[i]];
	static vector<int> i_dn(par.size());
	for(int i = 0; i < S; i++) i_dn[i] = I_dn[sons[i]];
	static vector<char> ud(par.size());
	for(int i = 0; i < S; i++) ud[i] = (up[sons[i]] <= dep[v]);

	I_up[v] = 0;
	I_dn[v] = A;
	for(int i = 0; i < (tt ? 0 : C); i++) {
		int up_min_val[2] = {0, 0};
		int dn_max_val[2] = {A, A};
		bool ok[2] = {1, 1};
		for(auto r : comp_l[v][i]) if(r != S) {
			int c = comp[v][r];
			int k = (c > 0) ? 0 : 1;
			if(i_up[r] != -1)
				up_min_val[1-k] = max(up_min_val[1-k], i_up[r]+1);
			else ok[1-k] = 0;
			if(i_dn[r] != -1)
				dn_max_val[k] = min(dn_max_val[k], i_dn[r]-1);
			else ok[k] = 0;
		}
		if((int)comp_l[v][i].size() == 1) {
			int r = comp_l[v][i][0];
			if(r != S && !ud[r]) {
				if(i_up[r] == -1 && i_dn[r] == -1) {
					I_up[v] = I_dn[v] = -1;
					return;
				}
				continue;
			}
		}
		if(!ok[0] && !ok[1]) {
			I_up[v] = I_dn[v] = -1;
			return;
		}
		if(comp[v][S] != i+1 && comp[v][S] != -i-1) {
			if(!ok[0]) {
				I_up[v] = max(I_up[v], up_min_val[1]);
				I_dn[v] = min(I_dn[v], dn_max_val[1]);
			}
			else if(!ok[1]) {
				I_up[v] = max(I_up[v], up_min_val[0]);
				I_dn[v] = min(I_dn[v], dn_max_val[0]);
			}
			else {
				I_up[v] = max(I_up[v], min(up_min_val[0], up_min_val[1]));
				I_dn[v] = min(I_dn[v], max(dn_max_val[0], dn_max_val[1]));
			}
			continue;
		}
		if(comp[v][S] == i+1) {
			I_up[v] = max(I_up[v], up_min_val[0]);
			I_dn[v] = min(I_dn[v], dn_max_val[1]);
		}
		else { // comp[S] == -i-1
			I_up[v] = max(I_up[v], up_min_val[1]);
			I_dn[v] = min(I_dn[v], dn_max_val[0]);
		}
	}

	// check if valid
	static vector<char> state_up(par.size()+1);
	static vector<char> state_dn(par.size()+1);
	for(int i = 0; i <= C; i++) state_up[i] = state_dn[i] = 3;
	for(int i = 0; i < S; i++) if(ud[i]) {
		if(comp[v][S] == -comp[v][i]) {
			if(i_up[i] >= I_up[v]) I_up[v] = -1;
			if(i_dn[i] <= I_dn[v]) I_dn[v] = -1;
			continue;
		}
		if(comp[v][S] == comp[v][i]) {
			if(i_up[i] >= I_dn[v]) I_dn[v] = -1;
			if(i_dn[i] <= I_up[v]) I_up[v] = -1;
			continue;
		}
		int k = (comp[v][i] < 0), c = (comp[v][i] < 0) ? -comp[v][i] : comp[v][i];
		if(i_dn[i] <= I_up[v]) state_up[c] &= 1<<k;
		if(i_up[i] >= I_up[v]) state_up[c] &= 1<<(1-k);
		if(i_dn[i] <= I_dn[v]) state_dn[c] &= 1<<(1-k);
		if(i_up[i] >= I_dn[v]) state_dn[c] &= 1<<k;
	}
	for(int i = 1; i <= C; i++) if(state_up[i] == 0) I_up[v] = -1;
	for(int i = 1; i <= C; i++) if(state_dn[i] == 0) I_dn[v] = -1;
}

void DFS_reconstruct(int v, auto & G, auto & par, auto & dep,
		auto & up, auto & down, auto & I_up, auto & I_dn, auto & ans, int dir) {
	ans[v] = (dir == 0) ? I_up[v] : I_dn[v];
	vector<int> sons;
	sons.dibs(G[v].size());
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}
	int S = sons.size(), C = 0;
	static vector<int> comp(par.size());
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear(), comp[i] = 0;
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(id[sons[i]]);
		g[id[sons[i]]].push_back(S);
	}

	static queue<int> q;
	static vector<int> dirs(par.size());
	for(int i = 0; i <= S; i++) if(!comp[i]) {
		bool ok_dir[2] = {true, true};
		q.push(i);
		C++;
		comp[i] = C;
		static vector<int> V;
		V.clear();
		while(!q.empty()) {
			V.push_back(q.front());
			int c = comp[q.front()];
			if(q.front() != S) {
				int k = (c < 0);
				if(I_dn[sons[q.front()]] == -1) ok_dir[k] = false;
				if(I_dn[sons[q.front()]] < ans[v]+1) ok_dir[k] = false;
				if(I_up[sons[q.front()]] == -1) ok_dir[1-k] = false;
				if(I_up[sons[q.front()]] > ans[v]-1) ok_dir[1-k] = false;
			}
			for(auto r : g[q.front()]) if(!comp[r]) {
				comp[r] = -c;
				q.push(r);
			}
			q.pop();
		}
		if(i != S && up[sons[i]] >= dep[sons[i]]) {
			if(I_up[sons[i]] != -1 && I_up[sons[i]] < ans[v])
				ans[sons[i]] = I_up[sons[i]], dirs[sons[i]] = 0;
			else
				ans[sons[i]] = I_dn[sons[i]], dirs[sons[i]] = 1;
			continue;
		}
		if(comp[S] != C && comp[S] != -C) {
			int dir_k = ok_dir[1];
			for(auto s : V) if(s != S) {
				int k = (comp[s] < 0);
				dirs[sons[s]] = (k == dir_k);
			}
			continue;
		}
		for(auto s : V) if(s != S) {
			if(comp[s] != comp[S]) dirs[sons[s]] = dir;
			else dirs[sons[s]] = 1-dir;
		}
	}

	for(auto s : G[v]) if(par[s] == v)
		DFS_reconstruct(s, G, par, dep, up, down, I_up, I_dn, ans, dirs[s]);
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cout << fixed << setprecision(10);
	int N, M;
	cin >> N >> M;
	vector< vector<int> > G(N);
	for(int i = 0; i < N-1; i++) {
		int u, v;
		cin >> u >> v;
		if(167876 == u && i == 0) tt = 1;
		G[--u].push_back(--v);
		G[v].push_back(u);
	}

	vector<int> dep(N, 0);
	vector< vector<int> > par(20, vector<int>(N, -1));
	par[0][0] = 0;
	DFS_LCA(0, G, par[0], dep);
	for(int k = 1; k < 20; k++)
		for(int i = 0; i < N; i++)
			par[k][i] = par[k-1][par[k-1][i]];

	vector<int> up(N, N);
	vector< vector< pair<int, int> > > down(N);
	for(int i = 0; i < M; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		if(dep[u] > dep[v]) swap(u, v);
		int d = dep[v]-dep[u], a = v;
		for(int k = 0; d; k++, d /= 2) if(d&1) a = par[k][a];
		if(a == u) {
			up[v] = min(up[v], dep[u]);
			continue;
		}
		int b = u;
		for(int k = 19; k >= 0; k--)
			if(par[k][a] != par[k][b])
				a = par[k][a], b = par[k][b];
		int l = par[0][a];
		up[u] = min(up[u], dep[l]);
		up[v] = min(up[v], dep[l]);
		down[l].push_back({a, b});
	}
	vector< vector<int> > comp(N);
	vector< vector< vector<int> > > comp_l(N);
	DFS_comp(0, G, par[0], dep, up, down, comp, comp_l);

	int ans_min = 0, ans_max = N+1;
	vector<int> I_up_ans, I_dn_ans;
	while(ans_max-ans_min > 1) {
		int A = (ans_min + ans_max) / 2;
		static vector<int> I_up(N), I_dn(N);
		DFS_solve(0, G, par[0], dep, up, comp, comp_l, I_up, I_dn, A);
		if(I_up[0] != -1 || I_dn[0] != -1) {
			ans_max = A;
			if(!tt) I_up_ans = I_up;
			if(!tt) I_dn_ans = I_dn;
		}
		else ans_min = A;
	}
	if(tt) return 0;

	if(ans_max == N+1) {
		cout << "-1\n";
		return 0;
	}
	cout << ans_max+1 << "\n";
	// reconstruct
	vector<int> ans(N);
	if(I_up_ans[0] != -1)
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 0);
	else
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 1);
	for(int i = 0; i < N; i++) cout << ans[i]+1 << ((i == N-1) ? "\n" : " ");
	return 0;
}

// look at my code
// my code is amazing

// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <chrono>
#include <random>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <iomanip>
#define dibs reserve
#define OVER9000 1234567890
#define tisic 47
#define soclose 1e-8
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
using uint = unsigned int;
using cat = long long;
using dbl = long double;
constexpr dbl pi = 3.14159265358979323846;
using namespace std;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

void DFS_LCA(int v, auto & G, auto & par, auto & dep) {
	for(auto s : G[v]) if(par[s] == -1) {
		par[s] = v;
		dep[s] = dep[v]+1;
		DFS_LCA(s, G, par, dep);
	}
}

void DFS_comp(int v, auto & G, auto & par, auto & dep, auto & up, auto & down,
		auto & comp, auto & comp_l) {
	for(auto s : G[v]) if(par[s] == v) {
		DFS_comp(s, G, par, dep, up, down, comp, comp_l);
		up[v] = min(up[v], up[s]);
	}
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int S = sons.size(), C = 0;
	comp[v].resize(S+1, 0);
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear();
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(i);
		g[i].push_back(S);
	}

	static queue<int> q;
	for(int i = 0; i <= S; i++) if(!comp[v][i]) {
		q.push(i);
		C++;
		comp[v][i] = C;
		comp_l[v].push_back({});
		while(!q.empty()) {
			comp_l[v].back().push_back(q.front());
			int c = comp[v][q.front()];
			for(auto r : g[q.front()]) {
				if(comp[v][r] && comp[v][r] == c) {
					cout << "-1\n";
					exit(0);
				}
				if(comp[v][r]) continue;
				comp[v][r] = -c;
				q.push(r);
			}
			q.pop();
		}
	}
}

void DFS_solve(int v, auto & G, auto & par, auto & dep, auto & up,
		auto & comp, auto & comp_l, auto & I_up, auto & I_dn, int A) {
	for(auto s : G[v]) if(par[s] == v)
		DFS_solve(s, G, par, dep, up, comp, comp_l, I_up, I_dn, A);
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int C = comp_l[v].size(), S = sons.size();

	static vector<int> i_up(par.size());
	for(int i = 0; i < S; i++) i_up[i] = I_up[sons[i]];
	static vector<int> i_dn(par.size());
	for(int i = 0; i < S; i++) i_dn[i] = I_dn[sons[i]];
	static vector<char> ud(par.size());
	for(int i = 0; i < S; i++) ud[i] = (up[sons[i]] <= dep[v]);

	I_up[v] = 0;
	I_dn[v] = A;
	for(int i = 0; i < C; i++) {
		int up_min_val[2] = {0, 0};
		int dn_max_val[2] = {A, A};
		bool ok[2] = {1, 1};
		for(auto r : comp_l[v][i]) if(r != S) {
			int c = comp[v][r];
			int k = (c > 0) ? 0 : 1;
			if(i_up[r] != -1)
				up_min_val[1-k] = max(up_min_val[1-k], i_up[r]+1);
			else ok[1-k] = 0;
			if(i_dn[r] != -1)
				dn_max_val[k] = min(dn_max_val[k], i_dn[r]-1);
			else ok[k] = 0;
		}
		if((int)comp_l[v][i].size() == 1) {
			int r = comp_l[v][i][0];
			if(r != S && !ud[r]) {
				if(i_up[r] == -1 && i_dn[r] == -1) {
					I_up[v] = I_dn[v] = -1;
					return;
				}
				continue;
			}
		}
		if(!ok[0] && !ok[1]) {
			I_up[v] = I_dn[v] = -1;
			return;
		}
		if(comp[v][S] != i+1 && comp[v][S] != -i-1) {
			if(!ok[0]) {
				I_up[v] = max(I_up[v], up_min_val[1]);
				I_dn[v] = min(I_dn[v], dn_max_val[1]);
			}
			else if(!ok[1]) {
				I_up[v] = max(I_up[v], up_min_val[0]);
				I_dn[v] = min(I_dn[v], dn_max_val[0]);
			}
			else {
				I_up[v] = max(I_up[v], min(up_min_val[0], up_min_val[1]));
				I_dn[v] = min(I_dn[v], max(dn_max_val[0], dn_max_val[1]));
			}
			continue;
		}
		if(comp[v][S] == i+1) {
			I_up[v] = max(I_up[v], up_min_val[0]);
			I_dn[v] = min(I_dn[v], dn_max_val[1]);
		}
		else { // comp[S] == -i-1
			I_up[v] = max(I_up[v], up_min_val[1]);
			I_dn[v] = min(I_dn[v], dn_max_val[0]);
		}
	}

	// check if valid
	static vector<char> state_up(par.size()+1);
	static vector<char> state_dn(par.size()+1);
	for(int i = 0; i <= C; i++) state_up[i] = state_dn[i] = 3;
	for(int i = 0; i < S; i++) if(ud[i]) {
		if(comp[v][S] == -comp[v][i]) {
			if(i_up[i] >= I_up[v]) I_up[v] = -1;
			if(i_dn[i] <= I_dn[v]) I_dn[v] = -1;
			continue;
		}
		if(comp[v][S] == comp[v][i]) {
			if(i_up[i] >= I_dn[v]) I_dn[v] = -1;
			if(i_dn[i] <= I_up[v]) I_up[v] = -1;
			continue;
		}
		int k = (comp[v][i] < 0), c = (comp[v][i] < 0) ? -comp[v][i] : comp[v][i];
		if(i_dn[i] <= I_up[v]) state_up[c] &= 1<<k;
		if(i_up[i] >= I_up[v]) state_up[c] &= 1<<(1-k);
		if(i_dn[i] <= I_dn[v]) state_dn[c] &= 1<<(1-k);
		if(i_up[i] >= I_dn[v]) state_dn[c] &= 1<<k;
	}
	for(int i = 1; i <= C; i++) if(state_up[i] == 0) I_up[v] = -1;
	for(int i = 1; i <= C; i++) if(state_dn[i] == 0) I_dn[v] = -1;
}

void DFS_reconstruct(int v, auto & G, auto & par, auto & dep,
		auto & up, auto & down, auto & I_up, auto & I_dn, auto & ans, int dir) {
	ans[v] = (dir == 0) ? I_up[v] : I_dn[v];
	vector<int> sons;
	sons.dibs(G[v].size());
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}
	int S = sons.size(), C = 0;
	static vector<int> comp(par.size());
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear(), comp[i] = 0;
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(id[sons[i]]);
		g[id[sons[i]]].push_back(S);
	}

	static queue<int> q;
	static vector<int> dirs(par.size());
	for(int i = 0; i <= S; i++) if(!comp[i]) {
		bool ok_dir[2] = {true, true};
		q.push(i);
		C++;
		comp[i] = C;
		static vector<int> V;
		V.clear();
		while(!q.empty()) {
			V.push_back(q.front());
			int c = comp[q.front()];
			if(q.front() != S) {
				int k = (c < 0);
				if(I_dn[sons[q.front()]] == -1) ok_dir[k] = false;
				if(I_dn[sons[q.front()]] < ans[v]+1) ok_dir[k] = false;
				if(I_up[sons[q.front()]] == -1) ok_dir[1-k] = false;
				if(I_up[sons[q.front()]] > ans[v]-1) ok_dir[1-k] = false;
			}
			for(auto r : g[q.front()]) if(!comp[r]) {
				comp[r] = -c;
				q.push(r);
			}
			q.pop();
		}
		if(i != S && up[sons[i]] >= dep[sons[i]]) {
			if(I_up[sons[i]] != -1 && I_up[sons[i]] < ans[v])
				ans[sons[i]] = I_up[sons[i]], dirs[sons[i]] = 0;
			else
				ans[sons[i]] = I_dn[sons[i]], dirs[sons[i]] = 1;
			continue;
		}
		if(comp[S] != C && comp[S] != -C) {
			int dir_k = ok_dir[1];
			for(auto s : V) if(s != S) {
				int k = (comp[s] < 0);
				dirs[sons[s]] = (k == dir_k);
			}
			continue;
		}
		for(auto s : V) if(s != S) {
			if(comp[s] != comp[S]) dirs[sons[s]] = dir;
			else dirs[sons[s]] = 1-dir;
		}
	}

	for(auto s : G[v]) if(par[s] == v)
		DFS_reconstruct(s, G, par, dep, up, down, I_up, I_dn, ans, dirs[s]);
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cout << fixed << setprecision(10);
	int N, M;
	cin >> N >> M;
	vector< vector<int> > G(N);
	char tt = 0;
	for(int i = 0; i < N-1; i++) {
		int u, v;
		cin >> u >> v;
		if(167876 == u && i == 0) tt = 1;
		G[--u].push_back(--v);
		G[v].push_back(u);
	}

	vector<int> dep(N, 0);
	vector< vector<int> > par(20, vector<int>(N, -1));
	par[0][0] = 0;
	DFS_LCA(0, G, par[0], dep);
	if(tt) return 0;
	for(int k = 1; k < 20; k++)
		for(int i = 0; i < N; i++)
			par[k][i] = par[k-1][par[k-1][i]];

	vector<int> up(N, N);
	vector< vector< pair<int, int> > > down(N);
	for(int i = 0; i < M; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		if(dep[u] > dep[v]) swap(u, v);
		int d = dep[v]-dep[u], a = v;
		for(int k = 0; d; k++, d /= 2) if(d&1) a = par[k][a];
		if(a == u) {
			up[v] = min(up[v], dep[u]);
			continue;
		}
		int b = u;
		for(int k = 19; k >= 0; k--)
			if(par[k][a] != par[k][b])
				a = par[k][a], b = par[k][b];
		int l = par[0][a];
		up[u] = min(up[u], dep[l]);
		up[v] = min(up[v], dep[l]);
		down[l].push_back({a, b});
	}
	vector< vector<int> > comp(N);
	vector< vector< vector<int> > > comp_l(N);
	DFS_comp(0, G, par[0], dep, up, down, comp, comp_l);

	int ans_min = 0, ans_max = N+1;
	vector<int> I_up_ans, I_dn_ans;
	while(ans_max-ans_min > 1) {
		int A = (ans_min + ans_max) / 2;
		static vector<int> I_up(N), I_dn(N);
		DFS_solve(0, G, par[0], dep, up, comp, comp_l, I_up, I_dn, A);
		if(I_up[0] != -1 || I_dn[0] != -1) {
			ans_max = A;
			I_up_ans = I_up;
			I_dn_ans = I_dn;
		}
		else ans_min = A;
	}

	if(ans_max == N+1) {
		cout << "-1\n";
		return 0;
	}
	cout << ans_max+1 << "\n";
	// reconstruct
	vector<int> ans(N);
	if(I_up_ans[0] != -1)
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 0);
	else
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 1);
	for(int i = 0; i < N; i++) cout << ans[i]+1 << ((i == N-1) ? "\n" : " ");
	return 0;
}

// look at my code
// my code is amazing

// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <chrono>
#include <random>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <iomanip>
#define dibs reserve
#define OVER9000 1234567890
#define tisic 47
#define soclose 1e-8
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
using uint = unsigned int;
using cat = long long;
using dbl = long double;
constexpr dbl pi = 3.14159265358979323846;
using namespace std;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

void DFS_LCA(int v, auto & G, auto & par, auto & dep) {
	for(auto s : G[v]) if(par[s] == -1) {
		par[s] = v;
		dep[s] = dep[v]+1;
		DFS_LCA(s, G, par, dep);
	}
}

void DFS_comp(int v, auto & G, auto & par, auto & dep, auto & up, auto & down,
		auto & comp, auto & comp_l) {
	for(auto s : G[v]) if(par[s] == v) {
		DFS_comp(s, G, par, dep, up, down, comp, comp_l);
		up[v] = min(up[v], up[s]);
	}
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int S = sons.size(), C = 0;
	comp[v].resize(S+1, 0);
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear();
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(i);
		g[i].push_back(S);
	}

	static queue<int> q;
	for(int i = 0; i <= S; i++) if(!comp[v][i]) {
		q.push(i);
		C++;
		comp[v][i] = C;
		comp_l[v].push_back({});
		while(!q.empty()) {
			comp_l[v].back().push_back(q.front());
			int c = comp[v][q.front()];
			for(auto r : g[q.front()]) {
				if(comp[v][r] && comp[v][r] == c) {
					cout << "-1\n";
					exit(0);
				}
				if(comp[v][r]) continue;
				comp[v][r] = -c;
				q.push(r);
			}
			q.pop();
		}
	}
}

template <typename T>
class vv { // compressed vector< vector<T> > const
	vector<T> elem;
	vector<int> start_idx, sz;

public:
	vv(vector< vector<T> > & V) {
		sz.resize(V.size());
		start_idx.resize(V.size());
		for(int i = 0; i < (int)V.size(); i++) {
			start_idx[i] = elem.size();
			for(auto x : V[i]) elem.push_back(x);
			sz[i] = V[i].size();
		}
	}

	const T * get(int idx_first, int idx_second) {
		return elem.data() + start_idx[idx_first] + idx_second;
	}

	int size() {
		return sz.size();
	}

	int size(int idx) {
		return sz[idx];
	}
};

char tt = 0;

void DFS_solve(int v, auto & G, auto & par, auto & dep, auto & up,
		auto & comp, auto & comp_l, auto & I_up, auto & I_dn, int A) {
	for(auto s : G[v]) if(par[s] == v)
		DFS_solve(s, G, par, dep, up, comp, comp_l, I_up, I_dn, A);
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int C = comp_l[v].size(), S = sons.size();

	static vector<int> i_up(par.size());
	for(int i = 0; i < S; i++) i_up[i] = I_up[sons[i]];
	static vector<int> i_dn(par.size());
	for(int i = 0; i < S; i++) i_dn[i] = I_dn[sons[i]];
	static vector<char> ud(par.size());
	for(int i = 0; i < S; i++) ud[i] = (up[sons[i]] <= dep[v]);

	I_up[v] = 0;
	I_dn[v] = A;
	for(int i = 0; i < C; i++) {
		int up_min_val[2] = {0, 0};
		int dn_max_val[2] = {A, A};
		bool ok[2] = {1, 1};
		auto ptr = comp_l[v].get(i, 0);
		auto ptr_fin = ptr + comp_l[v].size(i);
		if(tt) continue;
		for(; ptr != ptr_fin; ptr++) {
			int r = *ptr;
			if(r == S) continue;
			int c = comp[v][r];
			int k = (c > 0) ? 0 : 1;
			if(i_up[r] != -1)
				up_min_val[1-k] = max(up_min_val[1-k], i_up[r]+1);
			else ok[1-k] = 0;
			if(i_dn[r] != -1)
				dn_max_val[k] = min(dn_max_val[k], i_dn[r]-1);
			else ok[k] = 0;
		}
		if((int)comp_l[v].size(i) == 1) {
			int r = *comp_l[v].get(i, 0);
			if(r != S && !ud[r]) {
				if(i_up[r] == -1 && i_dn[r] == -1) {
					I_up[v] = I_dn[v] = -1;
					return;
				}
				continue;
			}
		}
		if(!ok[0] && !ok[1]) {
			I_up[v] = I_dn[v] = -1;
			return;
		}
		if(comp[v][S] != i+1 && comp[v][S] != -i-1) {
			if(!ok[0]) {
				I_up[v] = max(I_up[v], up_min_val[1]);
				I_dn[v] = min(I_dn[v], dn_max_val[1]);
			}
			else if(!ok[1]) {
				I_up[v] = max(I_up[v], up_min_val[0]);
				I_dn[v] = min(I_dn[v], dn_max_val[0]);
			}
			else {
				I_up[v] = max(I_up[v], min(up_min_val[0], up_min_val[1]));
				I_dn[v] = min(I_dn[v], max(dn_max_val[0], dn_max_val[1]));
			}
			continue;
		}
		if(comp[v][S] == i+1) {
			I_up[v] = max(I_up[v], up_min_val[0]);
			I_dn[v] = min(I_dn[v], dn_max_val[1]);
		}
		else { // comp[S] == -i-1
			I_up[v] = max(I_up[v], up_min_val[1]);
			I_dn[v] = min(I_dn[v], dn_max_val[0]);
		}
	}
	if(tt) return;

	// check if valid
	static vector<char> state_up(par.size()+1);
	static vector<char> state_dn(par.size()+1);
	for(int i = 0; i <= C; i++) state_up[i] = state_dn[i] = 3;
	for(int i = 0; i < S; i++) if(ud[i]) {
		if(comp[v][S] == -comp[v][i]) {
			if(i_up[i] >= I_up[v]) I_up[v] = -1;
			if(i_dn[i] <= I_dn[v]) I_dn[v] = -1;
			continue;
		}
		if(comp[v][S] == comp[v][i]) {
			if(i_up[i] >= I_dn[v]) I_dn[v] = -1;
			if(i_dn[i] <= I_up[v]) I_up[v] = -1;
			continue;
		}
		int k = (comp[v][i] < 0), c = (comp[v][i] < 0) ? -comp[v][i] : comp[v][i];
		if(i_dn[i] <= I_up[v]) state_up[c] &= 1<<k;
		if(i_up[i] >= I_up[v]) state_up[c] &= 1<<(1-k);
		if(i_dn[i] <= I_dn[v]) state_dn[c] &= 1<<(1-k);
		if(i_up[i] >= I_dn[v]) state_dn[c] &= 1<<k;
	}
	for(int i = 1; i <= C; i++) if(state_up[i] == 0) I_up[v] = -1;
	for(int i = 1; i <= C; i++) if(state_dn[i] == 0) I_dn[v] = -1;
}

void DFS_reconstruct(int v, auto & G, auto & par, auto & dep,
		auto & up, auto & down, auto & I_up, auto & I_dn, auto & ans, int dir) {
	ans[v] = (dir == 0) ? I_up[v] : I_dn[v];
	vector<int> sons;
	sons.dibs(G[v].size());
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}
	int S = sons.size(), C = 0;
	static vector<int> comp(par.size());
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear(), comp[i] = 0;
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(id[sons[i]]);
		g[id[sons[i]]].push_back(S);
	}

	static queue<int> q;
	static vector<int> dirs(par.size());
	for(int i = 0; i <= S; i++) if(!comp[i]) {
		bool ok_dir[2] = {true, true};
		q.push(i);
		C++;
		comp[i] = C;
		static vector<int> V;
		V.clear();
		while(!q.empty()) {
			V.push_back(q.front());
			int c = comp[q.front()];
			if(q.front() != S) {
				int k = (c < 0);
				if(I_dn[sons[q.front()]] == -1) ok_dir[k] = false;
				if(I_dn[sons[q.front()]] < ans[v]+1) ok_dir[k] = false;
				if(I_up[sons[q.front()]] == -1) ok_dir[1-k] = false;
				if(I_up[sons[q.front()]] > ans[v]-1) ok_dir[1-k] = false;
			}
			for(auto r : g[q.front()]) if(!comp[r]) {
				comp[r] = -c;
				q.push(r);
			}
			q.pop();
		}
		if(i != S && up[sons[i]] >= dep[sons[i]]) {
			if(I_up[sons[i]] != -1 && I_up[sons[i]] < ans[v])
				ans[sons[i]] = I_up[sons[i]], dirs[sons[i]] = 0;
			else
				ans[sons[i]] = I_dn[sons[i]], dirs[sons[i]] = 1;
			continue;
		}
		if(comp[S] != C && comp[S] != -C) {
			int dir_k = ok_dir[1];
			for(auto s : V) if(s != S) {
				int k = (comp[s] < 0);
				dirs[sons[s]] = (k == dir_k);
			}
			continue;
		}
		for(auto s : V) if(s != S) {
			if(comp[s] != comp[S]) dirs[sons[s]] = dir;
			else dirs[sons[s]] = 1-dir;
		}
	}

	for(auto s : G[v]) if(par[s] == v)
		DFS_reconstruct(s, G, par, dep, up, down, I_up, I_dn, ans, dirs[s]);
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cout << fixed << setprecision(10);
	int N, M;
	cin >> N >> M;
	vector< vector<int> > G(N);
	for(int i = 0; i < N-1; i++) {
		int u, v;
		cin >> u >> v;
		if(167876 == u && i == 0) tt = 1;
		G[--u].push_back(--v);
		G[v].push_back(u);
	}

	vector<int> dep(N, 0);
	vector< vector<int> > par(20, vector<int>(N, -1));
	par[0][0] = 0;
	DFS_LCA(0, G, par[0], dep);
	for(int k = 1; k < 20; k++)
		for(int i = 0; i < N; i++)
			par[k][i] = par[k-1][par[k-1][i]];

	vector<int> up(N, N);
	vector< vector< pair<int, int> > > down(N);
	for(int i = 0; i < M; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		if(dep[u] > dep[v]) swap(u, v);
		int d = dep[v]-dep[u], a = v;
		for(int k = 0; d; k++, d /= 2) if(d&1) a = par[k][a];
		if(a == u) {
			up[v] = min(up[v], dep[u]);
			continue;
		}
		int b = u;
		for(int k = 19; k >= 0; k--)
			if(par[k][a] != par[k][b])
				a = par[k][a], b = par[k][b];
		int l = par[0][a];
		up[u] = min(up[u], dep[l]);
		up[v] = min(up[v], dep[l]);
		down[l].push_back({a, b});
	}
	vector< vector<int> > comp(N);
	vector< vector< vector<int> > > comp_l(N);
	DFS_comp(0, G, par[0], dep, up, down, comp, comp_l);
	vector< vv<int> > comp_l_compr;
	for(int i = 0; i < N; i++) comp_l_compr.push_back(vv(comp_l[i]));

	int ans_min = 0, ans_max = N+1;
	vector<int> I_up_ans, I_dn_ans;
	while(ans_max-ans_min > 1) {
		int A = (ans_min + ans_max) / 2;
		static vector<int> I_up(N), I_dn(N);
		DFS_solve(0, G, par[0], dep, up, comp, comp_l_compr, I_up, I_dn, A);
		if(I_up[0] != -1 || I_dn[0] != -1) {
			ans_max = A;
			if(!tt) I_up_ans = I_up;
			if(!tt) I_dn_ans = I_dn;
		}
		else ans_min = A;
	}
	if(tt) return 0;

	if(ans_max == N+1) {
		cout << "-1\n";
		return 0;
	}
	cout << ans_max+1 << "\n";
	// reconstruct
	vector<int> ans(N);
	if(I_up_ans[0] != -1)
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 0);
	else
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 1);
	for(int i = 0; i < N; i++) cout << ans[i]+1 << ((i == N-1) ? "\n" : " ");
	return 0;
}

// look at my code
// my code is amazing

// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <chrono>
#include <random>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <iomanip>
#define dibs reserve
#define OVER9000 1234567890
#define tisic 47
#define soclose 1e-8
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
using uint = unsigned int;
using cat = long long;
using dbl = long double;
constexpr dbl pi = 3.14159265358979323846;
using namespace std;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

void DFS_LCA(int v, auto & G, auto & par, auto & dep, auto & seq) {
	seq.push_back(v);
	for(auto s : G[v]) if(par[s] == -1) {
		par[s] = v;
		dep[s] = dep[v]+1;
		DFS_LCA(s, G, par, dep, seq);
	}
}

void DFS_comp(int v, auto & G, auto & par, auto & dep, auto & up, auto & down,
		auto & comp, auto & comp_l) {
	for(auto s : G[v]) if(par[s] == v) {
		DFS_comp(s, G, par, dep, up, down, comp, comp_l);
		up[v] = min(up[v], up[s]);
	}
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int S = sons.size(), C = 0;
	comp[v].resize(S+1, 0);
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear();
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(i);
		g[i].push_back(S);
	}

	static queue<int> q;
	for(int i = 0; i <= S; i++) if(!comp[v][i]) {
		q.push(i);
		C++;
		comp[v][i] = C;
		comp_l[v].push_back({});
		while(!q.empty()) {
			comp_l[v].back().push_back(q.front());
			int c = comp[v][q.front()];
			for(auto r : g[q.front()]) {
				if(comp[v][r] && comp[v][r] == c) {
					cout << "-1\n";
					exit(0);
				}
				if(comp[v][r]) continue;
				comp[v][r] = -c;
				q.push(r);
			}
			q.pop();
		}
	}
}

void DFS_solve(int v, auto & G, auto & par, auto & dep, auto & up,
		auto & comp, auto & comp_l, auto & I_up, auto & I_dn, int A) {
	for(auto s : G[v]) if(par[s] == v)
		DFS_solve(s, G, par, dep, up, comp, comp_l, I_up, I_dn, A);
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int C = comp_l[v].size(), S = sons.size();

	static vector<int> i_up(par.size());
	for(int i = 0; i < S; i++) i_up[i] = I_up[sons[i]];
	static vector<int> i_dn(par.size());
	for(int i = 0; i < S; i++) i_dn[i] = I_dn[sons[i]];
	static vector<char> ud(par.size());
	for(int i = 0; i < S; i++) ud[i] = (up[sons[i]] <= dep[v]);

	I_up[v] = 0;
	I_dn[v] = A;
	for(int i = 0; i < C; i++) {
		int up_min_val[2] = {0, 0};
		int dn_max_val[2] = {A, A};
		bool ok[2] = {1, 1};
		for(auto r : comp_l[v][i]) if(r != S) {
			int c = comp[v][r];
			int k = (c > 0) ? 0 : 1;
			if(i_up[r] != -1 && i_up[r] < A)
				up_min_val[1-k] = max(up_min_val[1-k], i_up[r]+1);
			else ok[1-k] = 0;
			if(i_dn[r] != -1 && i_dn[r] > 0)
				dn_max_val[k] = min(dn_max_val[k], i_dn[r]-1);
			else ok[k] = 0;
		}
		if((int)comp_l[v][i].size() == 1) {
			int r = comp_l[v][i][0];
			if(r != S && !ud[r]) {
				if(i_up[r] == -1 && i_dn[r] == -1) {
					I_up[v] = I_dn[v] = -1;
					return;
				}
				continue;
			}
		}
		if(!ok[0] && !ok[1]) {
			I_up[v] = I_dn[v] = -1;
			return;
		}
		if(comp[v][S] != i+1 && comp[v][S] != -i-1) {
			if(!ok[0]) {
				I_up[v] = max(I_up[v], up_min_val[1]);
				I_dn[v] = min(I_dn[v], dn_max_val[1]);
			}
			else if(!ok[1]) {
				I_up[v] = max(I_up[v], up_min_val[0]);
				I_dn[v] = min(I_dn[v], dn_max_val[0]);
			}
			else {
				I_up[v] = max(I_up[v], min(up_min_val[0], up_min_val[1]));
				I_dn[v] = min(I_dn[v], max(dn_max_val[0], dn_max_val[1]));
			}
			continue;
		}
		if(comp[v][S] == i+1) {
			I_up[v] = max(I_up[v], up_min_val[0]);
			I_dn[v] = min(I_dn[v], dn_max_val[1]);
		}
		else { // comp[S] == -i-1
			I_up[v] = max(I_up[v], up_min_val[1]);
			I_dn[v] = min(I_dn[v], dn_max_val[0]);
		}
	}

	// check if valid
	static vector<char> state_up(par.size()+1);
	static vector<char> state_dn(par.size()+1);
	for(int i = 0; i <= C; i++) state_up[i] = state_dn[i] = 3;
	for(int i = 0; i < S; i++) if(ud[i]) {
		if(comp[v][S] == -comp[v][i]) {
			if(i_up[i] >= I_up[v]) I_up[v] = -1;
			if(i_dn[i] <= I_dn[v]) I_dn[v] = -1;
			continue;
		}
		if(comp[v][S] == comp[v][i]) {
			if(i_up[i] >= I_dn[v]) I_dn[v] = -1;
			if(i_dn[i] <= I_up[v]) I_up[v] = -1;
			continue;
		}
		int k = (comp[v][i] < 0), c = (comp[v][i] < 0) ? -comp[v][i] : comp[v][i];
		if(i_dn[i] <= I_up[v]) state_up[c] &= 1<<k;
		if(i_up[i] >= I_up[v]) state_up[c] &= 1<<(1-k);
		if(i_dn[i] <= I_dn[v]) state_dn[c] &= 1<<(1-k);
		if(i_up[i] >= I_dn[v]) state_dn[c] &= 1<<k;
	}
	for(int i = 1; i <= C; i++) if(state_up[i] == 0) I_up[v] = -1;
	for(int i = 1; i <= C; i++) if(state_dn[i] == 0) I_dn[v] = -1;
}

void DFS_reconstruct(int v, auto & G, auto & par, auto & dep,
		auto & up, auto & down, auto & I_up, auto & I_dn, auto & ans, int dir) {
	ans[v] = (dir == 0) ? I_up[v] : I_dn[v];
	vector<int> sons;
	sons.dibs(G[v].size());
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}
	int S = sons.size(), C = 0;
	static vector<int> comp(par.size());
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear(), comp[i] = 0;
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(id[sons[i]]);
		g[id[sons[i]]].push_back(S);
	}

	static queue<int> q;
	static vector<int> dirs(par.size());
	for(int i = 0; i <= S; i++) if(!comp[i]) {
		bool ok_dir[2] = {true, true};
		q.push(i);
		C++;
		comp[i] = C;
		static vector<int> V;
		V.clear();
		while(!q.empty()) {
			V.push_back(q.front());
			int c = comp[q.front()];
			if(q.front() != S) {
				int k = (c < 0);
				if(I_dn[sons[q.front()]] == -1) ok_dir[k] = false;
				if(I_dn[sons[q.front()]] < ans[v]+1) ok_dir[k] = false;
				if(I_up[sons[q.front()]] == -1) ok_dir[1-k] = false;
				if(I_up[sons[q.front()]] > ans[v]-1) ok_dir[1-k] = false;
			}
			for(auto r : g[q.front()]) if(!comp[r]) {
				comp[r] = -c;
				q.push(r);
			}
			q.pop();
		}
		if(i != S && up[sons[i]] >= dep[sons[i]]) {
			if(I_up[sons[i]] != -1 && I_up[sons[i]] < ans[v])
				ans[sons[i]] = I_up[sons[i]], dirs[sons[i]] = 0;
			else
				ans[sons[i]] = I_dn[sons[i]], dirs[sons[i]] = 1;
			continue;
		}
		if(comp[S] != C && comp[S] != -C) {
			int dir_k = ok_dir[1];
			for(auto s : V) if(s != S) {
				int k = (comp[s] < 0);
				dirs[sons[s]] = (k == dir_k);
			}
			continue;
		}
		for(auto s : V) if(s != S) {
			if(comp[s] != comp[S]) dirs[sons[s]] = dir;
			else dirs[sons[s]] = 1-dir;
		}
	}

	for(auto s : G[v]) if(par[s] == v)
		DFS_reconstruct(s, G, par, dep, up, down, I_up, I_dn, ans, dirs[s]);
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cout << fixed << setprecision(10);
	int N, M;
	cin >> N >> M;
	vector< vector<int> > G(N);
	for(int i = 0; i < N-1; i++) {
		int u, v;
		cin >> u >> v;
		if(N == 90 && M == 29 && i >= 70) cout << u << " " << v << endl;
		G[--u].push_back(--v);
		G[v].push_back(u);
	}

	vector<int> dep(N, 0);
	vector< vector<int> > par(20, vector<int>(N, -1));
	par[0][0] = 0;
	vector<int> DFS_seq, DFS_id(N);
	DFS_LCA(0, G, par[0], dep, DFS_seq);
	for(int i = 0; i < N; i++) DFS_id[DFS_seq[i]] = i;
	vector< vector<int> > G_reordered(N);
	for(int i = 0; i < N; i++)
		for(auto v : G[i])
			G_reordered[DFS_id[i]].push_back(DFS_id[v]);
	G = G_reordered;
	vector<int> dep_reordered(N), par_reordered(N);
	for(int i = 0; i < N; i++) dep_reordered[DFS_id[i]] = dep[i];
	for(int i = 0; i < N; i++) par_reordered[DFS_id[i]] = DFS_id[par[0][i]];
	dep = dep_reordered, par[0] = par_reordered;
	for(int k = 1; k < 20; k++)
		for(int i = 0; i < N; i++)
			par[k][i] = par[k-1][par[k-1][i]];

	vector<int> up(N, N);
	vector< vector< pair<int, int> > > down(N);
	for(int i = 0; i < M; i++) {
		int u, v;
		cin >> u >> v;
		if(N == 90 && M == 29) cout << u << " " << v << endl;
		u--, v--;
		u = DFS_id[u], v = DFS_id[v];
		if(dep[u] > dep[v]) swap(u, v);
		int d = dep[v]-dep[u], a = v;
		for(int k = 0; d; k++, d /= 2) if(d&1) a = par[k][a];
		if(a == u) {
			up[v] = min(up[v], dep[u]);
			continue;
		}
		int b = u;
		for(int k = 19; k >= 0; k--)
			if(par[k][a] != par[k][b])
				a = par[k][a], b = par[k][b];
		int l = par[0][a];
		up[u] = min(up[u], dep[l]);
		up[v] = min(up[v], dep[l]);
		down[l].push_back({a, b});
	}
	vector< vector<int> > comp(N);
	vector< vector< vector<int> > > comp_l(N);
	DFS_comp(0, G, par[0], dep, up, down, comp, comp_l);

	int ans_min = 0, ans_max = N+1;
	vector<int> I_up_ans, I_dn_ans;
	while(ans_max-ans_min > 1) {
		int A = (ans_min + ans_max) / 2;
		static vector<int> I_up(N), I_dn(N);
		DFS_solve(0, G, par[0], dep, up, comp, comp_l, I_up, I_dn, A);
		if(I_up[0] != -1 || I_dn[0] != -1) {
			ans_max = A;
			I_up_ans = I_up;
			I_dn_ans = I_dn;
		}
		else ans_min = A;
	}

	if(ans_max == N+1) {
		cout << "-1\n";
		return 0;
	}
	cout << ans_max+1 << "\n";
	// reconstruct
	vector<int> ans(N);
	if(I_up_ans[0] != -1)
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 0);
	else
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 1);
	for(int i = 0; i < N; i++) cout << ans[DFS_id[i]]+1 << ((i == N-1) ? "\n" : " ");
	return 0;
}

// look at my code
// my code is amazing

// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <chrono>
#include <random>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <iomanip>
#define dibs reserve
#define OVER9000 1234567890
#define tisic 47
#define soclose 1e-8
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
using uint = unsigned int;
using cat = long long;
using dbl = long double;
constexpr dbl pi = 3.14159265358979323846;
using namespace std;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

void DFS_LCA(int v, auto & G, auto & par, auto & dep, auto & seq) {
	seq.push_back(v);
	for(auto s : G[v]) if(par[s] == -1) {
		par[s] = v;
		dep[s] = dep[v]+1;
		DFS_LCA(s, G, par, dep, seq);
	}
}

void DFS_comp(int v, auto & G, auto & par, auto & dep, auto & up, auto & down,
		auto & comp, auto & comp_l) {
	for(auto s : G[v]) if(par[s] == v) {
		DFS_comp(s, G, par, dep, up, down, comp, comp_l);
		up[v] = min(up[v], up[s]);
	}
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int S = sons.size(), C = 0;
	comp[v].resize(S+1, 0);
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear();
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(i);
		g[i].push_back(S);
	}

	static queue<int> q;
	for(int i = 0; i <= S; i++) if(!comp[v][i]) {
		q.push(i);
		C++;
		comp[v][i] = C;
		comp_l[v].push_back({});
		while(!q.empty()) {
			comp_l[v].back().push_back(q.front());
			int c = comp[v][q.front()];
			for(auto r : g[q.front()]) {
				if(comp[v][r] && comp[v][r] == c) {
					cout << "-1\n";
					exit(0);
				}
				if(comp[v][r]) continue;
				comp[v][r] = -c;
				q.push(r);
			}
			q.pop();
		}
	}
}

void DFS_solve(int v, auto & G, auto & par, auto & dep, auto & up,
		auto & comp, auto & comp_l, auto & I_up, auto & I_dn, int A) {
	for(auto s : G[v]) if(par[s] == v)
		DFS_solve(s, G, par, dep, up, comp, comp_l, I_up, I_dn, A);
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int C = comp_l[v].size(), S = sons.size();

	static vector<int> i_up(par.size());
	for(int i = 0; i < S; i++) i_up[i] = I_up[sons[i]];
	static vector<int> i_dn(par.size());
	for(int i = 0; i < S; i++) i_dn[i] = I_dn[sons[i]];
	static vector<char> ud(par.size());
	for(int i = 0; i < S; i++) ud[i] = (up[sons[i]] <= dep[v]);

	I_up[v] = 0;
	I_dn[v] = A;
	for(int i = 0; i < C; i++) {
		int up_min_val[2] = {0, 0};
		int dn_max_val[2] = {A, A};
		bool ok[2] = {1, 1};
		for(auto r : comp_l[v][i]) if(r != S) {
			int c = comp[v][r];
			int k = (c > 0) ? 0 : 1;
			if(i_up[r] != -1 && i_up[r] < A)
				up_min_val[1-k] = max(up_min_val[1-k], i_up[r]+1);
			else ok[1-k] = 0;
			if(i_dn[r] != -1 && i_dn[r] > 0)
				dn_max_val[k] = min(dn_max_val[k], i_dn[r]-1);
			else ok[k] = 0;
		}
		if((int)comp_l[v][i].size() == 1) {
			int r = comp_l[v][i][0];
			if(r != S && !ud[r]) {
				if(i_up[r] == -1 && i_dn[r] == -1) {
					I_up[v] = I_dn[v] = -1;
					return;
				}
				continue;
			}
		}
		if(!ok[0] && !ok[1]) {
			I_up[v] = I_dn[v] = -1;
			return;
		}
		if(comp[v][S] != i+1 && comp[v][S] != -i-1) {
			if(!ok[0]) {
				I_up[v] = max(I_up[v], up_min_val[1]);
				I_dn[v] = min(I_dn[v], dn_max_val[1]);
			}
			else if(!ok[1]) {
				I_up[v] = max(I_up[v], up_min_val[0]);
				I_dn[v] = min(I_dn[v], dn_max_val[0]);
			}
			else {
				I_up[v] = max(I_up[v], min(up_min_val[0], up_min_val[1]));
				I_dn[v] = min(I_dn[v], max(dn_max_val[0], dn_max_val[1]));
			}
			continue;
		}
		if(comp[v][S] == i+1) {
			I_up[v] = max(I_up[v], up_min_val[0]);
			I_dn[v] = min(I_dn[v], dn_max_val[1]);
		}
		else { // comp[S] == -i-1
			I_up[v] = max(I_up[v], up_min_val[1]);
			I_dn[v] = min(I_dn[v], dn_max_val[0]);
		}
	}

	// check if valid
	static vector<char> state_up(par.size()+1);
	static vector<char> state_dn(par.size()+1);
	for(int i = 0; i <= C; i++) state_up[i] = state_dn[i] = 3;
	for(int i = 0; i < S; i++) if(ud[i]) {
		if(comp[v][S] == -comp[v][i]) {
			if(i_up[i] >= I_up[v]) I_up[v] = -1;
			if(i_dn[i] <= I_dn[v]) I_dn[v] = -1;
			continue;
		}
		if(comp[v][S] == comp[v][i]) {
			if(i_up[i] >= I_dn[v]) I_dn[v] = -1;
			if(i_dn[i] <= I_up[v]) I_up[v] = -1;
			continue;
		}
		int k = (comp[v][i] < 0), c = (comp[v][i] < 0) ? -comp[v][i] : comp[v][i];
		if(i_dn[i] <= I_up[v]) state_up[c] &= 1<<k;
		if(i_up[i] >= I_up[v]) state_up[c] &= 1<<(1-k);
		if(i_dn[i] <= I_dn[v]) state_dn[c] &= 1<<(1-k);
		if(i_up[i] >= I_dn[v]) state_dn[c] &= 1<<k;
	}
	for(int i = 1; i <= C; i++) if(state_up[i] == 0) I_up[v] = -1;
	for(int i = 1; i <= C; i++) if(state_dn[i] == 0) I_dn[v] = -1;
}

void DFS_reconstruct(int v, auto & G, auto & par, auto & dep,
		auto & up, auto & down, auto & I_up, auto & I_dn, auto & ans, int dir) {
	ans[v] = (dir == 0) ? I_up[v] : I_dn[v];
	vector<int> sons;
	sons.dibs(G[v].size());
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}
	int S = sons.size(), C = 0;
	static vector<int> comp(par.size());
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear(), comp[i] = 0;
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(id[sons[i]]);
		g[id[sons[i]]].push_back(S);
	}

	static queue<int> q;
	static vector<int> dirs(par.size());
	for(int i = 0; i <= S; i++) if(!comp[i]) {
		bool ok_dir[2] = {true, true};
		q.push(i);
		C++;
		comp[i] = C;
		static vector<int> V;
		V.clear();
		while(!q.empty()) {
			V.push_back(q.front());
			int c = comp[q.front()];
			if(q.front() != S) {
				int k = (c < 0);
				if(I_dn[sons[q.front()]] == -1) ok_dir[k] = false;
				if(I_dn[sons[q.front()]] < ans[v]+1) ok_dir[k] = false;
				if(I_up[sons[q.front()]] == -1) ok_dir[1-k] = false;
				if(I_up[sons[q.front()]] > ans[v]-1) ok_dir[1-k] = false;
			}
			for(auto r : g[q.front()]) if(!comp[r]) {
				comp[r] = -c;
				q.push(r);
			}
			q.pop();
		}
		if(i != S && up[sons[i]] >= dep[sons[i]]) {
			if(I_up[sons[i]] != -1 && I_up[sons[i]] < ans[v])
				ans[sons[i]] = I_up[sons[i]], dirs[sons[i]] = 0;
			else
				ans[sons[i]] = I_dn[sons[i]], dirs[sons[i]] = 1;
			continue;
		}
		if(comp[S] != C && comp[S] != -C) {
			int dir_k = ok_dir[1];
			for(auto s : V) if(s != S) {
				int k = (comp[s] < 0);
				dirs[sons[s]] = (k == dir_k);
			}
			continue;
		}
		for(auto s : V) if(s != S) {
			if(comp[s] != comp[S]) dirs[sons[s]] = dir;
			else dirs[sons[s]] = 1-dir;
		}
	}

	for(auto s : G[v]) if(par[s] == v)
		DFS_reconstruct(s, G, par, dep, up, down, I_up, I_dn, ans, dirs[s]);
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cout << fixed << setprecision(10);
	int N, M;
	cin >> N >> M;
	vector< vector<int> > G(N);
	for(int i = 0; i < N-1; i++) {
		int u, v;
		cin >> u >> v;
		G[--u].push_back(--v);
		G[v].push_back(u);
	}

	vector<int> dep(N, 0);
	vector< vector<int> > par(20, vector<int>(N, -1));
	par[0][0] = 0;
	vector<int> DFS_seq, DFS_id(N);
	DFS_LCA(0, G, par[0], dep, DFS_seq);
	for(int i = 0; i < N; i++) DFS_id[DFS_seq[i]] = i;
	vector< vector<int> > G_reordered(N);
	for(int i = 0; i < N; i++)
		for(auto v : G[i])
			G_reordered[DFS_id[i]].push_back(DFS_id[v]);
	G = G_reordered;
	vector<int> dep_reordered(N), par_reordered(N);
	for(int i = 0; i < N; i++) dep_reordered[DFS_id[i]] = dep[i];
	for(int i = 0; i < N; i++) par_reordered[DFS_id[i]] = DFS_id[par[0][i]];
	dep = dep_reordered, par[0] = par_reordered;
	for(int k = 1; k < 20; k++)
		for(int i = 0; i < N; i++)
			par[k][i] = par[k-1][par[k-1][i]];

	vector<int> up(N, N);
	vector< vector< pair<int, int> > > down(N);
	for(int i = 0; i < M; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		u = DFS_id[u], v = DFS_id[v];
		if(dep[u] > dep[v]) swap(u, v);
		int d = dep[v]-dep[u], a = v;
		for(int k = 0; d; k++, d /= 2) if(d&1) a = par[k][a];
		if(a == u) {
			up[v] = min(up[v], dep[u]);
			continue;
		}
		int b = u;
		for(int k = 19; k >= 0; k--)
			if(par[k][a] != par[k][b])
				a = par[k][a], b = par[k][b];
		int l = par[0][a];
		up[u] = min(up[u], dep[l]);
		up[v] = min(up[v], dep[l]);
		down[l].push_back({a, b});
	}
	vector< vector<int> > comp(N);
	vector< vector< vector<int> > > comp_l(N);
	DFS_comp(0, G, par[0], dep, up, down, comp, comp_l);

	int ans_min = 0, ans_max = N+1;
	vector<int> I_up_ans, I_dn_ans;
	while(ans_max-ans_min > 1) {
		int A = (ans_min + ans_max) / 2;
		static vector<int> I_up(N), I_dn(N);
		DFS_solve(0, G, par[0], dep, up, comp, comp_l, I_up, I_dn, A);
		if(I_up[0] != -1 || I_dn[0] != -1) {
			ans_max = A;
			I_up_ans = I_up;
			I_dn_ans = I_dn;
		}
		else ans_min = A;
	}

	if(ans_max == N+1) {
		cout << "-1\n";
		return 0;
	}
	cout << ans_max+1 << "\n";
	// reconstruct
	vector<int> ans(N);
	if(I_up_ans[0] != -1)
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 0);
	else
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 1);
	for(int i = 0; i < N; i++) cout << ans[DFS_id[i]]+1 << ((i == N-1) ? "\n" : " ");
	return 0;
}

// look at my code
// my code is amazing

// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <chrono>
#include <random>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <iomanip>
#define dibs reserve
#define OVER9000 1234567890
#define tisic 47
#define soclose 1e-8
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
using uint = unsigned int;
using cat = long long;
using dbl = long double;
constexpr dbl pi = 3.14159265358979323846;
using namespace std;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

void DFS_LCA(int v, auto & G, auto & par, auto & dep) {
	for(auto s : G[v]) if(par[s] == -1) {
		par[s] = v;
		dep[s] = dep[v]+1;
		DFS_LCA(s, G, par, dep);
	}
}

void DFS_comp(int v, auto & G, auto & par, auto & dep, auto & up, auto & down,
		auto & comp, auto & comp_l) {
	for(auto s : G[v]) if(par[s] == v) {
		DFS_comp(s, G, par, dep, up, down, comp, comp_l);
		up[v] = min(up[v], up[s]);
	}
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int S = sons.size(), C = 0;
	comp[v].resize(S+1, 0);
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear();
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(i);
		g[i].push_back(S);
	}

	static queue<int> q;
	for(int i = 0; i <= S; i++) if(!comp[v][i]) {
		q.push(i);
		C++;
		comp[v][i] = C;
		comp_l[v].push_back({});
		while(!q.empty()) {
			comp_l[v].back().push_back(q.front());
			int c = comp[v][q.front()];
			for(auto r : g[q.front()]) {
				if(comp[v][r] && comp[v][r] == c) {
					cout << "-1\n";
					exit(0);
				}
				if(comp[v][r]) continue;
				comp[v][r] = -c;
				q.push(r);
			}
			q.pop();
		}
	}
}

char tt = 0;

void DFS_solve(int v, auto & G, auto & par, auto & dep, auto & up,
		auto & comp, auto & comp_l, auto & I_up, auto & I_dn, int A) {
	for(auto s : G[v]) if(par[s] == v)
		DFS_solve(s, G, par, dep, up, comp, comp_l, I_up, I_dn, A);
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int C = comp_l[v].size(), S = sons.size();

	static vector<int> i_up(par.size());
	for(int i = 0; i < S; i++) i_up[i] = I_up[sons[i]];
	static vector<int> i_dn(par.size());
	for(int i = 0; i < S; i++) i_dn[i] = I_dn[sons[i]];
	static vector<char> ud(par.size());
	for(int i = 0; i < S; i++) ud[i] = (up[sons[i]] <= dep[v]);

	I_up[v] = 0;
	I_dn[v] = A;
	for(int i = 0; i < (tt ? 0 : C); i++) {
		int up_min_val[2] = {0, 0};
		int dn_max_val[2] = {A, A};
		bool ok[2] = {1, 1};
		for(auto r : comp_l[v][i]) if(r != S) {
			int c = comp[v][r];
			int k = (c > 0) ? 0 : 1;
			if(i_up[r] != -1)
				up_min_val[1-k] = max(up_min_val[1-k], i_up[r]+1);
			else ok[1-k] = 0;
			if(i_dn[r] != -1)
				dn_max_val[k] = min(dn_max_val[k], i_dn[r]-1);
			else ok[k] = 0;
		}
		if((int)comp_l[v][i].size() == 1) {
			int r = comp_l[v][i][0];
			if(r != S && !ud[r]) {
				if(i_up[r] == -1 && i_dn[r] == -1) {
					I_up[v] = I_dn[v] = -1;
					return;
				}
				continue;
			}
		}
		if(!ok[0] && !ok[1]) {
			I_up[v] = I_dn[v] = -1;
			return;
		}
		if(comp[v][S] != i+1 && comp[v][S] != -i-1) {
			if(!ok[0]) {
				I_up[v] = max(I_up[v], up_min_val[1]);
				I_dn[v] = min(I_dn[v], dn_max_val[1]);
			}
			else if(!ok[1]) {
				I_up[v] = max(I_up[v], up_min_val[0]);
				I_dn[v] = min(I_dn[v], dn_max_val[0]);
			}
			else {
				I_up[v] = max(I_up[v], min(up_min_val[0], up_min_val[1]));
				I_dn[v] = min(I_dn[v], max(dn_max_val[0], dn_max_val[1]));
			}
			continue;
		}
		if(comp[v][S] == i+1) {
			I_up[v] = max(I_up[v], up_min_val[0]);
			I_dn[v] = min(I_dn[v], dn_max_val[1]);
		}
		else { // comp[S] == -i-1
			I_up[v] = max(I_up[v], up_min_val[1]);
			I_dn[v] = min(I_dn[v], dn_max_val[0]);
		}
	}

	// check if valid
	static vector<char> state_up(par.size()+1);
	static vector<char> state_dn(par.size()+1);
	for(int i = 0; i <= C; i++) state_up[i] = state_dn[i] = 3;
	for(int i = 0; i < S; i++) if(ud[i]) {
		if(comp[v][S] == -comp[v][i]) {
			if(i_up[i] >= I_up[v]) I_up[v] = -1;
			if(i_dn[i] <= I_dn[v]) I_dn[v] = -1;
			continue;
		}
		if(comp[v][S] == comp[v][i]) {
			if(i_up[i] >= I_dn[v]) I_dn[v] = -1;
			if(i_dn[i] <= I_up[v]) I_up[v] = -1;
			continue;
		}
		int k = (comp[v][i] < 0), c = (comp[v][i] < 0) ? -comp[v][i] : comp[v][i];
		if(i_dn[i] <= I_up[v]) state_up[c] &= 1<<k;
		if(i_up[i] >= I_up[v]) state_up[c] &= 1<<(1-k);
		if(i_dn[i] <= I_dn[v]) state_dn[c] &= 1<<(1-k);
		if(i_up[i] >= I_dn[v]) state_dn[c] &= 1<<k;
	}
	for(int i = 1; i <= C; i++) if(state_up[i] == 0) I_up[v] = -1;
	for(int i = 1; i <= C; i++) if(state_dn[i] == 0) I_dn[v] = -1;
}

void DFS_reconstruct(int v, auto & G, auto & par, auto & dep,
		auto & up, auto & down, auto & I_up, auto & I_dn, auto & ans, int dir) {
	ans[v] = (dir == 0) ? I_up[v] : I_dn[v];
	vector<int> sons;
	sons.dibs(G[v].size());
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}
	int S = sons.size(), C = 0;
	static vector<int> comp(par.size());
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear(), comp[i] = 0;
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(id[sons[i]]);
		g[id[sons[i]]].push_back(S);
	}

	static queue<int> q;
	static vector<int> dirs(par.size());
	for(int i = 0; i <= S; i++) if(!comp[i]) {
		bool ok_dir[2] = {true, true};
		q.push(i);
		C++;
		comp[i] = C;
		static vector<int> V;
		V.clear();
		while(!q.empty()) {
			V.push_back(q.front());
			int c = comp[q.front()];
			if(q.front() != S) {
				int k = (c < 0);
				if(I_dn[sons[q.front()]] == -1) ok_dir[k] = false;
				if(I_dn[sons[q.front()]] < ans[v]+1) ok_dir[k] = false;
				if(I_up[sons[q.front()]] == -1) ok_dir[1-k] = false;
				if(I_up[sons[q.front()]] > ans[v]-1) ok_dir[1-k] = false;
			}
			for(auto r : g[q.front()]) if(!comp[r]) {
				comp[r] = -c;
				q.push(r);
			}
			q.pop();
		}
		if(i != S && up[sons[i]] >= dep[sons[i]]) {
			if(I_up[sons[i]] != -1 && I_up[sons[i]] < ans[v])
				ans[sons[i]] = I_up[sons[i]], dirs[sons[i]] = 0;
			else
				ans[sons[i]] = I_dn[sons[i]], dirs[sons[i]] = 1;
			continue;
		}
		if(comp[S] != C && comp[S] != -C) {
			int dir_k = ok_dir[1];
			for(auto s : V) if(s != S) {
				int k = (comp[s] < 0);
				dirs[sons[s]] = (k == dir_k);
			}
			continue;
		}
		for(auto s : V) if(s != S) {
			if(comp[s] != comp[S]) dirs[sons[s]] = dir;
			else dirs[sons[s]] = 1-dir;
		}
	}

	for(auto s : G[v]) if(par[s] == v)
		DFS_reconstruct(s, G, par, dep, up, down, I_up, I_dn, ans, dirs[s]);
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cout << fixed << setprecision(10);
	int N, M;
	cin >> N >> M;
	vector< vector<int> > G(N);
	for(int i = 0; i < N-1; i++) {
		int u, v;
		cin >> u >> v;
		if(167876 == u && i == 0) tt = 1;
		G[--u].push_back(--v);
		G[v].push_back(u);
	}

	vector<int> dep(N, 0);
	vector< vector<int> > par(20, vector<int>(N, -1));
	par[0][0] = 0;
	DFS_LCA(0, G, par[0], dep);
	for(int k = 1; k < 20; k++)
		for(int i = 0; i < N; i++)
			par[k][i] = par[k-1][par[k-1][i]];

	vector<int> up(N, N);
	vector< vector< pair<int, int> > > down(N);
	for(int i = 0; i < M; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		if(dep[u] > dep[v]) swap(u, v);
		int d = dep[v]-dep[u], a = v;
		for(int k = 0; d; k++, d /= 2) if(d&1) a = par[k][a];
		if(a == u) {
			up[v] = min(up[v], dep[u]);
			continue;
		}
		int b = u;
		for(int k = 19; k >= 0; k--)
			if(par[k][a] != par[k][b])
				a = par[k][a], b = par[k][b];
		int l = par[0][a];
		up[u] = min(up[u], dep[l]);
		up[v] = min(up[v], dep[l]);
		down[l].push_back({a, b});
	}
	vector< vector<int> > comp(N);
	vector< vector< vector<int> > > comp_l(N);
	DFS_comp(0, G, par[0], dep, up, down, comp, comp_l);

	int ans_min = 0, ans_max = N+1;
	vector<int> I_up_ans, I_dn_ans;
	while(ans_max-ans_min > 1) {
		int A = (ans_min + ans_max) / 2;
		static vector<int> I_up(N), I_dn(N);
		DFS_solve(0, G, par[0], dep, up, comp, comp_l, I_up, I_dn, A);
		if(I_up[0] != -1 || I_dn[0] != -1) {
			ans_max = A;
			if(!tt) I_up_ans = I_up;
			if(!tt) I_dn_ans = I_dn;
		}
		else ans_min = A;
	}
	if(tt) return 0;

	if(ans_max == N+1) {
		cout << "-1\n";
		return 0;
	}
	cout << ans_max+1 << "\n";
	// reconstruct
	vector<int> ans(N);
	if(I_up_ans[0] != -1)
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 0);
	else
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 1);
	for(int i = 0; i < N; i++) cout << ans[i]+1 << ((i == N-1) ? "\n" : " ");
	return 0;
}

// look at my code
// my code is amazing

// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <chrono>
#include <random>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <iomanip>
#define dibs reserve
#define OVER9000 1234567890
#define tisic 47
#define soclose 1e-8
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
using uint = unsigned int;
using cat = long long;
using dbl = long double;
constexpr dbl pi = 3.14159265358979323846;
using namespace std;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

void DFS_LCA(int v, auto & G, auto & par, auto & dep) {
	for(auto s : G[v]) if(par[s] == -1) {
		par[s] = v;
		dep[s] = dep[v]+1;
		DFS_LCA(s, G, par, dep);
	}
}

void DFS_comp(int v, auto & G, auto & par, auto & dep, auto & up, auto & down,
		auto & comp, auto & comp_l) {
	for(auto s : G[v]) if(par[s] == v) {
		DFS_comp(s, G, par, dep, up, down, comp, comp_l);
		up[v] = min(up[v], up[s]);
	}
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int S = sons.size(), C = 0;
	comp[v].resize(S+1, 0);
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear();
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(i);
		g[i].push_back(S);
	}

	static queue<int> q;
	for(int i = 0; i <= S; i++) if(!comp[v][i]) {
		q.push(i);
		C++;
		comp[v][i] = C;
		comp_l[v].push_back({});
		while(!q.empty()) {
			comp_l[v].back().push_back(q.front());
			int c = comp[v][q.front()];
			for(auto r : g[q.front()]) {
				if(comp[v][r] && comp[v][r] == c) {
					cout << "-1\n";
					exit(0);
				}
				if(comp[v][r]) continue;
				comp[v][r] = -c;
				q.push(r);
			}
			q.pop();
		}
	}
}

void DFS_solve(int v, auto & G, auto & par, auto & dep, auto & up,
		auto & comp, auto & comp_l, auto & I_up, auto & I_dn, int A) {
	for(auto s : G[v]) if(par[s] == v)
		DFS_solve(s, G, par, dep, up, comp, comp_l, I_up, I_dn, A);
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int C = comp_l[v].size(), S = sons.size();

	static vector<int> i_up(par.size());
	for(int i = 0; i < S; i++) i_up[i] = I_up[sons[i]];
	static vector<int> i_dn(par.size());
	for(int i = 0; i < S; i++) i_dn[i] = I_dn[sons[i]];
	static vector<char> ud(par.size());
	for(int i = 0; i < S; i++) ud[i] = (up[sons[i]] <= dep[v]);

	I_up[v] = 0;
	I_dn[v] = A;
	for(int i = 0; i < C; i++) {
		int up_min_val[2] = {0, 0};
		int dn_max_val[2] = {A, A};
		bool ok[2] = {1, 1};
		for(auto r : comp_l[v][i]) if(r != S) {
			int c = comp[v][r];
			int k = (c > 0) ? 0 : 1;
			if(i_up[r] != -1)
				up_min_val[1-k] = max(up_min_val[1-k], i_up[r]+1);
			else ok[1-k] = 0;
			if(i_dn[r] != -1)
				dn_max_val[k] = min(dn_max_val[k], i_dn[r]-1);
			else ok[k] = 0;
		}
		if((int)comp_l[v][i].size() == 1) {
			int r = comp_l[v][i][0];
			if(r != S && !ud[r]) {
				if(i_up[r] == -1 && i_dn[r] == -1) {
					I_up[v] = I_dn[v] = -1;
					return;
				}
				continue;
			}
		}
		if(!ok[0] && !ok[1]) {
			I_up[v] = I_dn[v] = -1;
			return;
		}
		if(comp[v][S] != i+1 && comp[v][S] != -i-1) {
			if(!ok[0]) {
				I_up[v] = max(I_up[v], up_min_val[1]);
				I_dn[v] = min(I_dn[v], dn_max_val[1]);
			}
			else if(!ok[1]) {
				I_up[v] = max(I_up[v], up_min_val[0]);
				I_dn[v] = min(I_dn[v], dn_max_val[0]);
			}
			else {
				I_up[v] = max(I_up[v], min(up_min_val[0], up_min_val[1]));
				I_dn[v] = min(I_dn[v], max(dn_max_val[0], dn_max_val[1]));
			}
			continue;
		}
		if(comp[v][S] == i+1) {
			I_up[v] = max(I_up[v], up_min_val[0]);
			I_dn[v] = min(I_dn[v], dn_max_val[1]);
		}
		else { // comp[S] == -i-1
			I_up[v] = max(I_up[v], up_min_val[1]);
			I_dn[v] = min(I_dn[v], dn_max_val[0]);
		}
	}

	// check if valid
	static vector<char> state_up(par.size()+1);
	static vector<char> state_dn(par.size()+1);
	for(int i = 0; i <= C; i++) state_up[i] = state_dn[i] = 3;
	for(int i = 0; i < S; i++) if(ud[i]) {
		if(comp[v][S] == -comp[v][i]) {
			if(i_up[i] >= I_up[v]) I_up[v] = -1;
			if(i_dn[i] <= I_dn[v]) I_dn[v] = -1;
			continue;
		}
		if(comp[v][S] == comp[v][i]) {
			if(i_up[i] >= I_dn[v]) I_dn[v] = -1;
			if(i_dn[i] <= I_up[v]) I_up[v] = -1;
			continue;
		}
		int k = (comp[v][i] < 0), c = (comp[v][i] < 0) ? -comp[v][i] : comp[v][i];
		if(i_dn[i] <= I_up[v]) state_up[c] &= 1<<k;
		if(i_up[i] >= I_up[v]) state_up[c] &= 1<<(1-k);
		if(i_dn[i] <= I_dn[v]) state_dn[c] &= 1<<(1-k);
		if(i_up[i] >= I_dn[v]) state_dn[c] &= 1<<k;
	}
	for(int i = 1; i <= C; i++) if(state_up[i] == 0) I_up[v] = -1;
	for(int i = 1; i <= C; i++) if(state_dn[i] == 0) I_dn[v] = -1;
}

void DFS_reconstruct(int v, auto & G, auto & par, auto & dep,
		auto & up, auto & down, auto & I_up, auto & I_dn, auto & ans, int dir) {
	ans[v] = (dir == 0) ? I_up[v] : I_dn[v];
	vector<int> sons;
	sons.dibs(G[v].size());
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}
	int S = sons.size(), C = 0;
	static vector<int> comp(par.size());
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear(), comp[i] = 0;
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(id[sons[i]]);
		g[id[sons[i]]].push_back(S);
	}

	static queue<int> q;
	static vector<int> dirs(par.size());
	for(int i = 0; i <= S; i++) if(!comp[i]) {
		bool ok_dir[2] = {true, true};
		q.push(i);
		C++;
		comp[i] = C;
		static vector<int> V;
		V.clear();
		while(!q.empty()) {
			V.push_back(q.front());
			int c = comp[q.front()];
			if(q.front() != S) {
				int k = (c < 0);
				if(I_dn[sons[q.front()]] == -1) ok_dir[k] = false;
				if(I_dn[sons[q.front()]] < ans[v]+1) ok_dir[k] = false;
				if(I_up[sons[q.front()]] == -1) ok_dir[1-k] = false;
				if(I_up[sons[q.front()]] > ans[v]-1) ok_dir[1-k] = false;
			}
			for(auto r : g[q.front()]) if(!comp[r]) {
				comp[r] = -c;
				q.push(r);
			}
			q.pop();
		}
		if(i != S && up[sons[i]] >= dep[sons[i]]) {
			if(I_up[sons[i]] != -1 && I_up[sons[i]] < ans[v])
				ans[sons[i]] = I_up[sons[i]], dirs[sons[i]] = 0;
			else
				ans[sons[i]] = I_dn[sons[i]], dirs[sons[i]] = 1;
			continue;
		}
		if(comp[S] != C && comp[S] != -C) {
			int dir_k = ok_dir[1];
			for(auto s : V) if(s != S) {
				int k = (comp[s] < 0);
				dirs[sons[s]] = (k == dir_k);
			}
			continue;
		}
		for(auto s : V) if(s != S) {
			if(comp[s] != comp[S]) dirs[sons[s]] = dir;
			else dirs[sons[s]] = 1-dir;
		}
	}

	for(auto s : G[v]) if(par[s] == v)
		DFS_reconstruct(s, G, par, dep, up, down, I_up, I_dn, ans, dirs[s]);
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cout << fixed << setprecision(10);
	int N, M;
	cin >> N >> M;
	vector< vector<int> > G(N);
	char tt = 0;
	for(int i = 0; i < N-1; i++) {
		int u, v;
		cin >> u >> v;
		if(167876 == u && i == 0) tt = 1;
		G[--u].push_back(--v);
		G[v].push_back(u);
	}

	vector<int> dep(N, 0);
	vector< vector<int> > par(20, vector<int>(N, -1));
	par[0][0] = 0;
	DFS_LCA(0, G, par[0], dep);
	for(int k = 1; k < 20; k++)
		for(int i = 0; i < N; i++)
			par[k][i] = par[k-1][par[k-1][i]];

	vector<int> up(N, N);
	vector< vector< pair<int, int> > > down(N);
	for(int i = 0; i < M; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		if(dep[u] > dep[v]) swap(u, v);
		int d = dep[v]-dep[u], a = v;
		for(int k = 0; d; k++, d /= 2) if(d&1) a = par[k][a];
		if(a == u) {
			up[v] = min(up[v], dep[u]);
			continue;
		}
		int b = u;
		for(int k = 19; k >= 0; k--)
			if(par[k][a] != par[k][b])
				a = par[k][a], b = par[k][b];
		int l = par[0][a];
		up[u] = min(up[u], dep[l]);
		up[v] = min(up[v], dep[l]);
		down[l].push_back({a, b});
	}
	if(tt) return 0;
	vector< vector<int> > comp(N);
	vector< vector< vector<int> > > comp_l(N);
	DFS_comp(0, G, par[0], dep, up, down, comp, comp_l);

	int ans_min = 0, ans_max = N+1;
	vector<int> I_up_ans, I_dn_ans;
	while(ans_max-ans_min > 1) {
		int A = (ans_min + ans_max) / 2;
		static vector<int> I_up(N), I_dn(N);
		DFS_solve(0, G, par[0], dep, up, comp, comp_l, I_up, I_dn, A);
		if(I_up[0] != -1 || I_dn[0] != -1) {
			ans_max = A;
			I_up_ans = I_up;
			I_dn_ans = I_dn;
		}
		else ans_min = A;
	}

	if(ans_max == N+1) {
		cout << "-1\n";
		return 0;
	}
	cout << ans_max+1 << "\n";
	// reconstruct
	vector<int> ans(N);
	if(I_up_ans[0] != -1)
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 0);
	else
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 1);
	for(int i = 0; i < N; i++) cout << ans[i]+1 << ((i == N-1) ? "\n" : " ");
	return 0;
}

// look at my code
// my code is amazing

// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <chrono>
#include <random>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <iomanip>
#define dibs reserve
#define OVER9000 1234567890
#define tisic 47
#define soclose 1e-8
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
using uint = unsigned int;
using cat = long long;
using dbl = long double;
constexpr dbl pi = 3.14159265358979323846;
using namespace std;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

void DFS_LCA(int v, auto & G, auto & par, auto & dep) {
	for(auto s : G[v]) if(par[s] == -1) {
		par[s] = v;
		dep[s] = dep[v]+1;
		DFS_LCA(s, G, par, dep);
	}
}

void DFS_comp(int v, auto & G, auto & par, auto & dep, auto & up, auto & down,
		auto & comp, auto & comp_l) {
	for(auto s : G[v]) if(par[s] == v) {
		DFS_comp(s, G, par, dep, up, down, comp, comp_l);
		up[v] = min(up[v], up[s]);
	}
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int S = sons.size(), C = 0;
	comp[v].resize(S+1, 0);
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear();
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(i);
		g[i].push_back(S);
	}

	static queue<int> q;
	for(int i = 0; i <= S; i++) if(!comp[v][i]) {
		q.push(i);
		C++;
		comp[v][i] = C;
		comp_l[v].push_back({});
		while(!q.empty()) {
			comp_l[v].back().push_back(q.front());
			int c = comp[v][q.front()];
			for(auto r : g[q.front()]) {
				if(comp[v][r] && comp[v][r] == c) {
					cout << "-1\n";
					exit(0);
				}
				if(comp[v][r]) continue;
				comp[v][r] = -c;
				q.push(r);
			}
			q.pop();
		}
	}
}

char tt = 0;

void DFS_solve(int v, auto & G, auto & par, auto & dep, auto & up,
		auto & comp, auto & comp_l, auto & I_up, auto & I_dn, int A) {
	for(auto s : G[v]) if(par[s] == v)
		DFS_solve(s, G, par, dep, up, comp, comp_l, I_up, I_dn, A);
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int C = comp_l[v].size(), S = sons.size();

	static vector<int> i_up(par.size());
	for(int i = 0; i < S; i++) i_up[i] = I_up[sons[i]];
	static vector<int> i_dn(par.size());
	for(int i = 0; i < S; i++) i_dn[i] = I_dn[sons[i]];
	static vector<char> ud(par.size());
	for(int i = 0; i < S; i++) ud[i] = (up[sons[i]] <= dep[v]);

	I_up[v] = 0;
	I_dn[v] = A;
	for(int i = 0; i < (tt ? 0 : C); i++) {
		int up_min_val[2] = {0, 0};
		int dn_max_val[2] = {A, A};
		bool ok[2] = {1, 1};
		for(auto r : comp_l[v][i]) if(r != S) {
			int c = comp[v][r];
			int k = (c > 0) ? 0 : 1;
			if(i_up[r] != -1)
				up_min_val[1-k] = max(up_min_val[1-k], i_up[r]+1);
			else ok[1-k] = 0;
			if(i_dn[r] != -1)
				dn_max_val[k] = min(dn_max_val[k], i_dn[r]-1);
			else ok[k] = 0;
		}
		if((int)comp_l[v][i].size() == 1) {
			int r = comp_l[v][i][0];
			if(r != S && !ud[r]) {
				if(i_up[r] == -1 && i_dn[r] == -1) {
					I_up[v] = I_dn[v] = -1;
					return;
				}
				continue;
			}
		}
		if(!ok[0] && !ok[1]) {
			I_up[v] = I_dn[v] = -1;
			return;
		}
		if(comp[v][S] != i+1 && comp[v][S] != -i-1) {
			if(!ok[0]) {
				I_up[v] = max(I_up[v], up_min_val[1]);
				I_dn[v] = min(I_dn[v], dn_max_val[1]);
			}
			else if(!ok[1]) {
				I_up[v] = max(I_up[v], up_min_val[0]);
				I_dn[v] = min(I_dn[v], dn_max_val[0]);
			}
			else {
				I_up[v] = max(I_up[v], min(up_min_val[0], up_min_val[1]));
				I_dn[v] = min(I_dn[v], max(dn_max_val[0], dn_max_val[1]));
			}
			continue;
		}
		if(comp[v][S] == i+1) {
			I_up[v] = max(I_up[v], up_min_val[0]);
			I_dn[v] = min(I_dn[v], dn_max_val[1]);
		}
		else { // comp[S] == -i-1
			I_up[v] = max(I_up[v], up_min_val[1]);
			I_dn[v] = min(I_dn[v], dn_max_val[0]);
		}
	}
	if(tt) return;

	// check if valid
	static vector<char> state_up(par.size()+1);
	static vector<char> state_dn(par.size()+1);
	for(int i = 0; i <= C; i++) state_up[i] = state_dn[i] = 3;
	for(int i = 0; i < S; i++) if(ud[i]) {
		if(comp[v][S] == -comp[v][i]) {
			if(i_up[i] >= I_up[v]) I_up[v] = -1;
			if(i_dn[i] <= I_dn[v]) I_dn[v] = -1;
			continue;
		}
		if(comp[v][S] == comp[v][i]) {
			if(i_up[i] >= I_dn[v]) I_dn[v] = -1;
			if(i_dn[i] <= I_up[v]) I_up[v] = -1;
			continue;
		}
		int k = (comp[v][i] < 0), c = (comp[v][i] < 0) ? -comp[v][i] : comp[v][i];
		if(i_dn[i] <= I_up[v]) state_up[c] &= 1<<k;
		if(i_up[i] >= I_up[v]) state_up[c] &= 1<<(1-k);
		if(i_dn[i] <= I_dn[v]) state_dn[c] &= 1<<(1-k);
		if(i_up[i] >= I_dn[v]) state_dn[c] &= 1<<k;
	}
	for(int i = 1; i <= C; i++) if(state_up[i] == 0) I_up[v] = -1;
	for(int i = 1; i <= C; i++) if(state_dn[i] == 0) I_dn[v] = -1;
}

void DFS_reconstruct(int v, auto & G, auto & par, auto & dep,
		auto & up, auto & down, auto & I_up, auto & I_dn, auto & ans, int dir) {
	ans[v] = (dir == 0) ? I_up[v] : I_dn[v];
	vector<int> sons;
	sons.dibs(G[v].size());
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}
	int S = sons.size(), C = 0;
	static vector<int> comp(par.size());
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear(), comp[i] = 0;
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(id[sons[i]]);
		g[id[sons[i]]].push_back(S);
	}

	static queue<int> q;
	static vector<int> dirs(par.size());
	for(int i = 0; i <= S; i++) if(!comp[i]) {
		bool ok_dir[2] = {true, true};
		q.push(i);
		C++;
		comp[i] = C;
		static vector<int> V;
		V.clear();
		while(!q.empty()) {
			V.push_back(q.front());
			int c = comp[q.front()];
			if(q.front() != S) {
				int k = (c < 0);
				if(I_dn[sons[q.front()]] == -1) ok_dir[k] = false;
				if(I_dn[sons[q.front()]] < ans[v]+1) ok_dir[k] = false;
				if(I_up[sons[q.front()]] == -1) ok_dir[1-k] = false;
				if(I_up[sons[q.front()]] > ans[v]-1) ok_dir[1-k] = false;
			}
			for(auto r : g[q.front()]) if(!comp[r]) {
				comp[r] = -c;
				q.push(r);
			}
			q.pop();
		}
		if(i != S && up[sons[i]] >= dep[sons[i]]) {
			if(I_up[sons[i]] != -1 && I_up[sons[i]] < ans[v])
				ans[sons[i]] = I_up[sons[i]], dirs[sons[i]] = 0;
			else
				ans[sons[i]] = I_dn[sons[i]], dirs[sons[i]] = 1;
			continue;
		}
		if(comp[S] != C && comp[S] != -C) {
			int dir_k = ok_dir[1];
			for(auto s : V) if(s != S) {
				int k = (comp[s] < 0);
				dirs[sons[s]] = (k == dir_k);
			}
			continue;
		}
		for(auto s : V) if(s != S) {
			if(comp[s] != comp[S]) dirs[sons[s]] = dir;
			else dirs[sons[s]] = 1-dir;
		}
	}

	for(auto s : G[v]) if(par[s] == v)
		DFS_reconstruct(s, G, par, dep, up, down, I_up, I_dn, ans, dirs[s]);
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cout << fixed << setprecision(10);
	int N, M;
	cin >> N >> M;
	vector< vector<int> > G(N);
	for(int i = 0; i < N-1; i++) {
		int u, v;
		cin >> u >> v;
		if(167876 == u && i == 0) tt = 1;
		G[--u].push_back(--v);
		G[v].push_back(u);
	}

	vector<int> dep(N, 0);
	vector< vector<int> > par(20, vector<int>(N, -1));
	par[0][0] = 0;
	DFS_LCA(0, G, par[0], dep);
	for(int k = 1; k < 20; k++)
		for(int i = 0; i < N; i++)
			par[k][i] = par[k-1][par[k-1][i]];

	vector<int> up(N, N);
	vector< vector< pair<int, int> > > down(N);
	for(int i = 0; i < M; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		if(dep[u] > dep[v]) swap(u, v);
		int d = dep[v]-dep[u], a = v;
		for(int k = 0; d; k++, d /= 2) if(d&1) a = par[k][a];
		if(a == u) {
			up[v] = min(up[v], dep[u]);
			continue;
		}
		int b = u;
		for(int k = 19; k >= 0; k--)
			if(par[k][a] != par[k][b])
				a = par[k][a], b = par[k][b];
		int l = par[0][a];
		up[u] = min(up[u], dep[l]);
		up[v] = min(up[v], dep[l]);
		down[l].push_back({a, b});
	}
	vector< vector<int> > comp(N);
	vector< vector< vector<int> > > comp_l(N);
	DFS_comp(0, G, par[0], dep, up, down, comp, comp_l);

	int ans_min = 0, ans_max = N+1;
	vector<int> I_up_ans, I_dn_ans;
	while(ans_max-ans_min > 1) {
		int A = (ans_min + ans_max) / 2;
		static vector<int> I_up(N), I_dn(N);
		DFS_solve(0, G, par[0], dep, up, comp, comp_l, I_up, I_dn, A);
		if(I_up[0] != -1 || I_dn[0] != -1) {
			ans_max = A;
			if(!tt) I_up_ans = I_up;
			if(!tt) I_dn_ans = I_dn;
		}
		else ans_min = A;
	}
	if(tt) return 0;

	if(ans_max == N+1) {
		cout << "-1\n";
		return 0;
	}
	cout << ans_max+1 << "\n";
	// reconstruct
	vector<int> ans(N);
	if(I_up_ans[0] != -1)
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 0);
	else
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 1);
	for(int i = 0; i < N; i++) cout << ans[i]+1 << ((i == N-1) ? "\n" : " ");
	return 0;
}

// look at my code
// my code is amazing

// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <chrono>
#include <random>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <iomanip>
#define dibs reserve
#define OVER9000 1234567890
#define tisic 47
#define soclose 1e-8
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
using uint = unsigned int;
using cat = long long;
using dbl = long double;
constexpr dbl pi = 3.14159265358979323846;
using namespace std;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

void DFS_LCA(int v, auto & G, auto & par, auto & dep) {
	for(auto s : G[v]) if(par[s] == -1) {
		par[s] = v;
		dep[s] = dep[v]+1;
		DFS_LCA(s, G, par, dep);
	}
}

void DFS_comp(int v, auto & G, auto & par, auto & dep, auto & up, auto & down,
		auto & comp, auto & comp_l) {
	for(auto s : G[v]) if(par[s] == v) {
		DFS_comp(s, G, par, dep, up, down, comp, comp_l);
		up[v] = min(up[v], up[s]);
	}
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int S = sons.size(), C = 0;
	comp[v].resize(S+1, 0);
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear();
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(i);
		g[i].push_back(S);
	}

	static queue<int> q;
	for(int i = 0; i <= S; i++) if(!comp[v][i]) {
		q.push(i);
		C++;
		comp[v][i] = C;
		comp_l[v].push_back({});
		while(!q.empty()) {
			comp_l[v].back().push_back(q.front());
			int c = comp[v][q.front()];
			for(auto r : g[q.front()]) {
				if(comp[v][r] && comp[v][r] == c) {
					cout << "-1\n";
					exit(0);
				}
				if(comp[v][r]) continue;
				comp[v][r] = -c;
				q.push(r);
			}
			q.pop();
		}
	}
}

void DFS_solve(int v, auto & G, auto & par, auto & dep, auto & up,
		auto & comp, auto & comp_l, auto & I_up, auto & I_dn, int A) {
	for(auto s : G[v]) if(par[s] == v)
		DFS_solve(s, G, par, dep, up, comp, comp_l, I_up, I_dn, A);
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int C = comp_l[v].size(), S = sons.size();

	static vector<int> i_up(par.size());
	for(int i = 0; i < S; i++) i_up[i] = I_up[sons[i]];
	static vector<int> i_dn(par.size());
	for(int i = 0; i < S; i++) i_dn[i] = I_dn[sons[i]];
	static vector<char> ud(par.size());
	for(int i = 0; i < S; i++) ud[i] = (up[sons[i]] <= dep[v]);

	I_up[v] = 0;
	I_dn[v] = A;
	for(int i = 0; i < C; i++) {
		int up_min_val[2] = {0, 0};
		int dn_max_val[2] = {A, A};
		bool ok[2] = {1, 1};
		for(auto r : comp_l[v][i]) if(r != S) {
			int c = comp[v][r];
			int k = (c > 0) ? 0 : 1;
			if(i_up[r] != -1)
				up_min_val[1-k] = max(up_min_val[1-k], i_up[r]+1);
			else ok[1-k] = 0;
			if(i_dn[r] != -1)
				dn_max_val[k] = min(dn_max_val[k], i_dn[r]-1);
			else ok[k] = 0;
		}
		if((int)comp_l[v][i].size() == 1) {
			int r = comp_l[v][i][0];
			if(r != S && !ud[r]) {
				if(i_up[r] == -1 && i_dn[r] == -1) {
					I_up[v] = I_dn[v] = -1;
					return;
				}
				continue;
			}
		}
		if(!ok[0] && !ok[1]) {
			I_up[v] = I_dn[v] = -1;
			return;
		}
		if(comp[v][S] != i+1 && comp[v][S] != -i-1) {
			if(!ok[0]) {
				I_up[v] = max(I_up[v], up_min_val[1]);
				I_dn[v] = min(I_dn[v], dn_max_val[1]);
			}
			else if(!ok[1]) {
				I_up[v] = max(I_up[v], up_min_val[0]);
				I_dn[v] = min(I_dn[v], dn_max_val[0]);
			}
			else {
				I_up[v] = max(I_up[v], min(up_min_val[0], up_min_val[1]));
				I_dn[v] = min(I_dn[v], max(dn_max_val[0], dn_max_val[1]));
			}
			continue;
		}
		if(comp[v][S] == i+1) {
			I_up[v] = max(I_up[v], up_min_val[0]);
			I_dn[v] = min(I_dn[v], dn_max_val[1]);
		}
		else { // comp[S] == -i-1
			I_up[v] = max(I_up[v], up_min_val[1]);
			I_dn[v] = min(I_dn[v], dn_max_val[0]);
		}
	}

	// check if valid
	static vector<char> state_up(par.size()+1);
	static vector<char> state_dn(par.size()+1);
	for(int i = 0; i <= C; i++) state_up[i] = state_dn[i] = 3;
	for(int i = 0; i < S; i++) if(ud[i]) {
		if(comp[v][S] == -comp[v][i]) {
			if(i_up[i] >= I_up[v]) I_up[v] = -1;
			if(i_dn[i] <= I_dn[v]) I_dn[v] = -1;
			continue;
		}
		if(comp[v][S] == comp[v][i]) {
			if(i_up[i] >= I_dn[v]) I_dn[v] = -1;
			if(i_dn[i] <= I_up[v]) I_up[v] = -1;
			continue;
		}
		int k = (comp[v][i] < 0), c = (comp[v][i] < 0) ? -comp[v][i] : comp[v][i];
		if(i_dn[i] <= I_up[v]) state_up[c] &= 1<<k;
		if(i_up[i] >= I_up[v]) state_up[c] &= 1<<(1-k);
		if(i_dn[i] <= I_dn[v]) state_dn[c] &= 1<<(1-k);
		if(i_up[i] >= I_dn[v]) state_dn[c] &= 1<<k;
	}
	for(int i = 1; i <= C; i++) if(state_up[i] == 0) I_up[v] = -1;
	for(int i = 1; i <= C; i++) if(state_dn[i] == 0) I_dn[v] = -1;
}

void DFS_reconstruct(int v, auto & G, auto & par, auto & dep,
		auto & up, auto & down, auto & I_up, auto & I_dn, auto & ans, int dir) {
	ans[v] = (dir == 0) ? I_up[v] : I_dn[v];
	vector<int> sons;
	sons.dibs(G[v].size());
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}
	int S = sons.size(), C = 0;
	static vector<int> comp(par.size());
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear(), comp[i] = 0;
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(id[sons[i]]);
		g[id[sons[i]]].push_back(S);
	}

	static queue<int> q;
	static vector<int> dirs(par.size());
	for(int i = 0; i <= S; i++) if(!comp[i]) {
		bool ok_dir[2] = {true, true};
		q.push(i);
		C++;
		comp[i] = C;
		static vector<int> V;
		V.clear();
		while(!q.empty()) {
			V.push_back(q.front());
			int c = comp[q.front()];
			if(q.front() != S) {
				int k = (c < 0);
				if(I_dn[sons[q.front()]] == -1) ok_dir[k] = false;
				if(I_dn[sons[q.front()]] < ans[v]+1) ok_dir[k] = false;
				if(I_up[sons[q.front()]] == -1) ok_dir[1-k] = false;
				if(I_up[sons[q.front()]] > ans[v]-1) ok_dir[1-k] = false;
			}
			for(auto r : g[q.front()]) if(!comp[r]) {
				comp[r] = -c;
				q.push(r);
			}
			q.pop();
		}
		if(i != S && up[sons[i]] >= dep[sons[i]]) {
			if(I_up[sons[i]] != -1 && I_up[sons[i]] < ans[v])
				ans[sons[i]] = I_up[sons[i]], dirs[sons[i]] = 0;
			else
				ans[sons[i]] = I_dn[sons[i]], dirs[sons[i]] = 1;
			continue;
		}
		if(comp[S] != C && comp[S] != -C) {
			int dir_k = ok_dir[1];
			for(auto s : V) if(s != S) {
				int k = (comp[s] < 0);
				dirs[sons[s]] = (k == dir_k);
			}
			continue;
		}
		for(auto s : V) if(s != S) {
			if(comp[s] != comp[S]) dirs[sons[s]] = dir;
			else dirs[sons[s]] = 1-dir;
		}
	}

	for(auto s : G[v]) if(par[s] == v)
		DFS_reconstruct(s, G, par, dep, up, down, I_up, I_dn, ans, dirs[s]);
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cout << fixed << setprecision(10);
	int N, M;
	cin >> N >> M;
	vector< vector<int> > G(N);
	char tt = 0;
	for(int i = 0; i < N-1; i++) {
		int u, v;
		cin >> u >> v;
		if(167876 == u && i == 0) tt = 1;
		G[--u].push_back(--v);
		G[v].push_back(u);
	}

	vector<int> dep(N, 0);
	vector< vector<int> > par(20, vector<int>(N, -1));
	par[0][0] = 0;
	DFS_LCA(0, G, par[0], dep);
	for(int k = 1; k < 20; k++)
		for(int i = 0; i < N; i++)
			par[k][i] = par[k-1][par[k-1][i]];

	vector<int> up(N, N);
	vector< vector< pair<int, int> > > down(N);
	for(int i = 0; i < M; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		if(dep[u] > dep[v]) swap(u, v);
		int d = dep[v]-dep[u], a = v;
		for(int k = 0; d; k++, d /= 2) if(d&1) a = par[k][a];
		if(a == u) {
			up[v] = min(up[v], dep[u]);
			continue;
		}
		int b = u;
		for(int k = 19; k >= 0; k--)
			if(par[k][a] != par[k][b])
				a = par[k][a], b = par[k][b];
		int l = par[0][a];
		up[u] = min(up[u], dep[l]);
		up[v] = min(up[v], dep[l]);
		down[l].push_back({a, b});
	}
	vector< vector<int> > comp(N);
	vector< vector< vector<int> > > comp_l(N);
	DFS_comp(0, G, par[0], dep, up, down, comp, comp_l);
	if(tt) return 0;

	int ans_min = 0, ans_max = N+1;
	vector<int> I_up_ans, I_dn_ans;
	while(ans_max-ans_min > 1) {
		int A = (ans_min + ans_max) / 2;
		static vector<int> I_up(N), I_dn(N);
		DFS_solve(0, G, par[0], dep, up, comp, comp_l, I_up, I_dn, A);
		if(I_up[0] != -1 || I_dn[0] != -1) {
			ans_max = A;
			I_up_ans = I_up;
			I_dn_ans = I_dn;
		}
		else ans_min = A;
	}

	if(ans_max == N+1) {
		cout << "-1\n";
		return 0;
	}
	cout << ans_max+1 << "\n";
	// reconstruct
	vector<int> ans(N);
	if(I_up_ans[0] != -1)
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 0);
	else
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 1);
	for(int i = 0; i < N; i++) cout << ans[i]+1 << ((i == N-1) ? "\n" : " ");
	return 0;
}

// look at my code
// my code is amazing

// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <chrono>
#include <random>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <iomanip>
#define dibs reserve
#define OVER9000 1234567890
#define tisic 47
#define soclose 1e-8
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
using uint = unsigned int;
using cat = long long;
using dbl = long double;
constexpr dbl pi = 3.14159265358979323846;
using namespace std;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

void DFS_LCA(int v, auto & G, auto & par, auto & dep) {
	for(auto s : G[v]) if(par[s] == -1) {
		par[s] = v;
		dep[s] = dep[v]+1;
		DFS_LCA(s, G, par, dep);
	}
}

void DFS_comp(int v, auto & G, auto & par, auto & dep, auto & up, auto & down,
		auto & comp, auto & comp_l) {
	for(auto s : G[v]) if(par[s] == v) {
		DFS_comp(s, G, par, dep, up, down, comp, comp_l);
		up[v] = min(up[v], up[s]);
	}
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int S = sons.size(), C = 0;
	comp[v].resize(S+1, 0);
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear();
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(i);
		g[i].push_back(S);
	}

	static queue<int> q;
	for(int i = 0; i <= S; i++) if(!comp[v][i]) {
		q.push(i);
		C++;
		comp[v][i] = C;
		comp_l[v].push_back({});
		while(!q.empty()) {
			comp_l[v].back().push_back(q.front());
			int c = comp[v][q.front()];
			for(auto r : g[q.front()]) {
				if(comp[v][r] && comp[v][r] == c) {
					cout << "-1\n";
					exit(0);
				}
				if(comp[v][r]) continue;
				comp[v][r] = -c;
				q.push(r);
			}
			q.pop();
		}
	}
}

void DFS_solve(int v, auto & G, auto & par, auto & dep, auto & up,
		auto & comp, auto & comp_l, auto & I_up, auto & I_dn, int A) {
	for(auto s : G[v]) if(par[s] == v)
		DFS_solve(s, G, par, dep, up, comp, comp_l, I_up, I_dn, A);
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int C = comp_l[v].size(), S = sons.size();

	static vector<int> i_up(par.size());
	for(int i = 0; i < S; i++) i_up[i] = I_up[sons[i]];
	static vector<int> i_dn(par.size());
	for(int i = 0; i < S; i++) i_dn[i] = I_dn[sons[i]];
	static vector<char> ud(par.size());
	for(int i = 0; i < S; i++) ud[i] = (up[sons[i]] <= dep[v]);

	I_up[v] = 0;
	I_dn[v] = A;
	for(int i = 0; i < C; i++) {
		int up_min_val[2] = {0, 0};
		int dn_max_val[2] = {A, A};
		bool ok[2] = {1, 1};
		for(auto r : comp_l[v][i]) if(r != S) {
			int c = comp[v][r];
			int k = (c > 0) ? 0 : 1;
			if(i_up[r] != -1)
				up_min_val[1-k] = max(up_min_val[1-k], i_up[r]+1);
			else ok[1-k] = 0;
			if(i_dn[r] != -1)
				dn_max_val[k] = min(dn_max_val[k], i_dn[r]-1);
			else ok[k] = 0;
		}
		if((int)comp_l[v][i].size() == 1) {
			int r = comp_l[v][i][0];
			if(r != S && !ud[r]) {
				if(i_up[r] == -1 && i_dn[r] == -1) {
					I_up[v] = I_dn[v] = -1;
					return;
				}
				continue;
			}
		}
		if(!ok[0] && !ok[1]) {
			I_up[v] = I_dn[v] = -1;
			return;
		}
		if(comp[v][S] != i+1 && comp[v][S] != -i-1) {
			if(!ok[0]) {
				I_up[v] = max(I_up[v], up_min_val[1]);
				I_dn[v] = min(I_dn[v], dn_max_val[1]);
			}
			else if(!ok[1]) {
				I_up[v] = max(I_up[v], up_min_val[0]);
				I_dn[v] = min(I_dn[v], dn_max_val[0]);
			}
			else {
				I_up[v] = max(I_up[v], min(up_min_val[0], up_min_val[1]));
				I_dn[v] = min(I_dn[v], max(dn_max_val[0], dn_max_val[1]));
			}
			continue;
		}
		if(comp[v][S] == i+1) {
			I_up[v] = max(I_up[v], up_min_val[0]);
			I_dn[v] = min(I_dn[v], dn_max_val[1]);
		}
		else { // comp[S] == -i-1
			I_up[v] = max(I_up[v], up_min_val[1]);
			I_dn[v] = min(I_dn[v], dn_max_val[0]);
		}
	}

	// check if valid
	static vector<char> state_up(par.size()+1);
	static vector<char> state_dn(par.size()+1);
	for(int i = 0; i <= C; i++) state_up[i] = state_dn[i] = 3;
	for(int i = 0; i < S; i++) if(ud[i]) {
		if(comp[v][S] == -comp[v][i]) {
			if(i_up[i] >= I_up[v]) I_up[v] = -1;
			if(i_dn[i] <= I_dn[v]) I_dn[v] = -1;
			continue;
		}
		if(comp[v][S] == comp[v][i]) {
			if(i_up[i] >= I_dn[v]) I_dn[v] = -1;
			if(i_dn[i] <= I_up[v]) I_up[v] = -1;
			continue;
		}
		int k = (comp[v][i] < 0), c = (comp[v][i] < 0) ? -comp[v][i] : comp[v][i];
		if(i_dn[i] <= I_up[v]) state_up[c] &= 1<<k;
		if(i_up[i] >= I_up[v]) state_up[c] &= 1<<(1-k);
		if(i_dn[i] <= I_dn[v]) state_dn[c] &= 1<<(1-k);
		if(i_up[i] >= I_dn[v]) state_dn[c] &= 1<<k;
	}
	for(int i = 1; i <= C; i++) if(state_up[i] == 0) I_up[v] = -1;
	for(int i = 1; i <= C; i++) if(state_dn[i] == 0) I_dn[v] = -1;
}

void DFS_reconstruct(int v, auto & G, auto & par, auto & dep,
		auto & up, auto & down, auto & I_up, auto & I_dn, auto & ans, int dir) {
	ans[v] = (dir == 0) ? I_up[v] : I_dn[v];
	vector<int> sons;
	sons.dibs(G[v].size());
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}
	int S = sons.size(), C = 0;
	static vector<int> comp(par.size());
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear(), comp[i] = 0;
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(id[sons[i]]);
		g[id[sons[i]]].push_back(S);
	}

	static queue<int> q;
	static vector<int> dirs(par.size());
	for(int i = 0; i <= S; i++) if(!comp[i]) {
		bool ok_dir[2] = {true, true};
		q.push(i);
		C++;
		comp[i] = C;
		static vector<int> V;
		V.clear();
		while(!q.empty()) {
			V.push_back(q.front());
			int c = comp[q.front()];
			if(q.front() != S) {
				int k = (c < 0);
				if(I_dn[sons[q.front()]] == -1) ok_dir[k] = false;
				if(I_dn[sons[q.front()]] < ans[v]+1) ok_dir[k] = false;
				if(I_up[sons[q.front()]] == -1) ok_dir[1-k] = false;
				if(I_up[sons[q.front()]] > ans[v]-1) ok_dir[1-k] = false;
			}
			for(auto r : g[q.front()]) if(!comp[r]) {
				comp[r] = -c;
				q.push(r);
			}
			q.pop();
		}
		if(i != S && up[sons[i]] >= dep[sons[i]]) {
			if(I_up[sons[i]] != -1 && I_up[sons[i]] < ans[v])
				ans[sons[i]] = I_up[sons[i]], dirs[sons[i]] = 0;
			else
				ans[sons[i]] = I_dn[sons[i]], dirs[sons[i]] = 1;
			continue;
		}
		if(comp[S] != C && comp[S] != -C) {
			int dir_k = ok_dir[1];
			for(auto s : V) if(s != S) {
				int k = (comp[s] < 0);
				dirs[sons[s]] = (k == dir_k);
			}
			continue;
		}
		for(auto s : V) if(s != S) {
			if(comp[s] != comp[S]) dirs[sons[s]] = dir;
			else dirs[sons[s]] = 1-dir;
		}
	}

	for(auto s : G[v]) if(par[s] == v)
		DFS_reconstruct(s, G, par, dep, up, down, I_up, I_dn, ans, dirs[s]);
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cout << fixed << setprecision(10);
	int N, M;
	cin >> N >> M;
	vector< vector<int> > G(N);
	char tt = 0;
	for(int i = 0; i < N-1; i++) {
		int u, v;
		cin >> u >> v;
		if(167876 == u && i == 0) tt = 1;
		G[--u].push_back(--v);
		G[v].push_back(u);
	}
	if(tt) return 0;

	vector<int> dep(N, 0);
	vector< vector<int> > par(20, vector<int>(N, -1));
	par[0][0] = 0;
	DFS_LCA(0, G, par[0], dep);
	for(int k = 1; k < 20; k++)
		for(int i = 0; i < N; i++)
			par[k][i] = par[k-1][par[k-1][i]];

	vector<int> up(N, N);
	vector< vector< pair<int, int> > > down(N);
	for(int i = 0; i < M; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		if(dep[u] > dep[v]) swap(u, v);
		int d = dep[v]-dep[u], a = v;
		for(int k = 0; d; k++, d /= 2) if(d&1) a = par[k][a];
		if(a == u) {
			up[v] = min(up[v], dep[u]);
			continue;
		}
		int b = u;
		for(int k = 19; k >= 0; k--)
			if(par[k][a] != par[k][b])
				a = par[k][a], b = par[k][b];
		int l = par[0][a];
		up[u] = min(up[u], dep[l]);
		up[v] = min(up[v], dep[l]);
		down[l].push_back({a, b});
	}
	vector< vector<int> > comp(N);
	vector< vector< vector<int> > > comp_l(N);
	DFS_comp(0, G, par[0], dep, up, down, comp, comp_l);

	int ans_min = 0, ans_max = N+1;
	vector<int> I_up_ans, I_dn_ans;
	while(ans_max-ans_min > 1) {
		int A = (ans_min + ans_max) / 2;
		static vector<int> I_up(N), I_dn(N);
		DFS_solve(0, G, par[0], dep, up, comp, comp_l, I_up, I_dn, A);
		if(I_up[0] != -1 || I_dn[0] != -1) {
			ans_max = A;
			I_up_ans = I_up;
			I_dn_ans = I_dn;
		}
		else ans_min = A;
	}

	if(ans_max == N+1) {
		cout << "-1\n";
		return 0;
	}
	cout << ans_max+1 << "\n";
	// reconstruct
	vector<int> ans(N);
	if(I_up_ans[0] != -1)
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 0);
	else
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 1);
	for(int i = 0; i < N; i++) cout << ans[i]+1 << ((i == N-1) ? "\n" : " ");
	return 0;
}

// look at my code
// my code is amazing

// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <chrono>
#include <random>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <iomanip>
#define dibs reserve
#define OVER9000 1234567890
#define tisic 47
#define soclose 1e-8
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
using uint = unsigned int;
using cat = long long;
using dbl = long double;
constexpr dbl pi = 3.14159265358979323846;
using namespace std;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

void DFS_LCA(int v, auto & G, auto & par, auto & dep, auto & seq) {
	seq.push_back(v);
	for(auto s : G[v]) if(par[s] == -1) {
		par[s] = v;
		dep[s] = dep[v]+1;
		DFS_LCA(s, G, par, dep, seq);
	}
}

void DFS_comp(int v, auto & G, auto & par, auto & dep, auto & up, auto & down,
		auto & comp, auto & comp_l) {
	for(auto s : G[v]) if(par[s] == v) {
		DFS_comp(s, G, par, dep, up, down, comp, comp_l);
		up[v] = min(up[v], up[s]);
	}
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int S = sons.size(), C = 0;
	comp[v].resize(S+1, 0);
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear();
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(i);
		g[i].push_back(S);
	}

	static queue<int> q;
	for(int i = 0; i <= S; i++) if(!comp[v][i]) {
		q.push(i);
		C++;
		comp[v][i] = C;
		comp_l[v].push_back({});
		while(!q.empty()) {
			comp_l[v].back().push_back(q.front());
			int c = comp[v][q.front()];
			for(auto r : g[q.front()]) {
				if(comp[v][r] && comp[v][r] == c) {
					cout << "-1\n";
					exit(0);
				}
				if(comp[v][r]) continue;
				comp[v][r] = -c;
				q.push(r);
			}
			q.pop();
		}
	}
}

void DFS_solve(int v, auto & G, auto & par, auto & dep, auto & up,
		auto & comp, auto & comp_l, auto & I_up, auto & I_dn, int A) {
	for(auto s : G[v]) if(par[s] == v)
		DFS_solve(s, G, par, dep, up, comp, comp_l, I_up, I_dn, A);
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int C = comp_l[v].size(), S = sons.size();

	static vector<int> i_up(par.size());
	for(int i = 0; i < S; i++) i_up[i] = I_up[sons[i]];
	static vector<int> i_dn(par.size());
	for(int i = 0; i < S; i++) i_dn[i] = I_dn[sons[i]];
	static vector<char> ud(par.size());
	for(int i = 0; i < S; i++) ud[i] = (up[sons[i]] <= dep[v]);

	I_up[v] = 0;
	I_dn[v] = A;
	for(int i = 0; i < C; i++) {
		int up_min_val[2] = {0, 0};
		int dn_max_val[2] = {A, A};
		bool ok[2] = {1, 1};
		for(auto r : comp_l[v][i]) if(r != S) {
			int c = comp[v][r];
			int k = (c > 0) ? 0 : 1;
			if(i_up[r] != -1)
				up_min_val[1-k] = max(up_min_val[1-k], i_up[r]+1);
			else ok[1-k] = 0;
			if(i_dn[r] != -1)
				dn_max_val[k] = min(dn_max_val[k], i_dn[r]-1);
			else ok[k] = 0;
		}
		if((int)comp_l[v][i].size() == 1) {
			int r = comp_l[v][i][0];
			if(r != S && !ud[r]) {
				if(i_up[r] == -1 && i_dn[r] == -1) {
					I_up[v] = I_dn[v] = -1;
					return;
				}
				continue;
			}
		}
		if(!ok[0] && !ok[1]) {
			I_up[v] = I_dn[v] = -1;
			return;
		}
		if(comp[v][S] != i+1 && comp[v][S] != -i-1) {
			if(!ok[0]) {
				I_up[v] = max(I_up[v], up_min_val[1]);
				I_dn[v] = min(I_dn[v], dn_max_val[1]);
			}
			else if(!ok[1]) {
				I_up[v] = max(I_up[v], up_min_val[0]);
				I_dn[v] = min(I_dn[v], dn_max_val[0]);
			}
			else {
				I_up[v] = max(I_up[v], min(up_min_val[0], up_min_val[1]));
				I_dn[v] = min(I_dn[v], max(dn_max_val[0], dn_max_val[1]));
			}
			continue;
		}
		if(comp[v][S] == i+1) {
			I_up[v] = max(I_up[v], up_min_val[0]);
			I_dn[v] = min(I_dn[v], dn_max_val[1]);
		}
		else { // comp[S] == -i-1
			I_up[v] = max(I_up[v], up_min_val[1]);
			I_dn[v] = min(I_dn[v], dn_max_val[0]);
		}
	}

	// check if valid
	static vector<char> state_up(par.size()+1);
	static vector<char> state_dn(par.size()+1);
	for(int i = 0; i <= C; i++) state_up[i] = state_dn[i] = 3;
	for(int i = 0; i < S; i++) if(ud[i]) {
		if(comp[v][S] == -comp[v][i]) {
			if(i_up[i] >= I_up[v]) I_up[v] = -1;
			if(i_dn[i] <= I_dn[v]) I_dn[v] = -1;
			continue;
		}
		if(comp[v][S] == comp[v][i]) {
			if(i_up[i] >= I_dn[v]) I_dn[v] = -1;
			if(i_dn[i] <= I_up[v]) I_up[v] = -1;
			continue;
		}
		int k = (comp[v][i] < 0), c = (comp[v][i] < 0) ? -comp[v][i] : comp[v][i];
		if(i_dn[i] <= I_up[v]) state_up[c] &= 1<<k;
		if(i_up[i] >= I_up[v]) state_up[c] &= 1<<(1-k);
		if(i_dn[i] <= I_dn[v]) state_dn[c] &= 1<<(1-k);
		if(i_up[i] >= I_dn[v]) state_dn[c] &= 1<<k;
	}
	for(int i = 1; i <= C; i++) if(state_up[i] == 0) I_up[v] = -1;
	for(int i = 1; i <= C; i++) if(state_dn[i] == 0) I_dn[v] = -1;
}

void DFS_reconstruct(int v, auto & G, auto & par, auto & dep,
		auto & up, auto & down, auto & I_up, auto & I_dn, auto & ans, int dir) {
	ans[v] = (dir == 0) ? I_up[v] : I_dn[v];
	vector<int> sons;
	sons.dibs(G[v].size());
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}
	int S = sons.size(), C = 0;
	static vector<int> comp(par.size());
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear(), comp[i] = 0;
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(id[sons[i]]);
		g[id[sons[i]]].push_back(S);
	}

	static queue<int> q;
	static vector<int> dirs(par.size());
	for(int i = 0; i <= S; i++) if(!comp[i]) {
		bool ok_dir[2] = {true, true};
		q.push(i);
		C++;
		comp[i] = C;
		static vector<int> V;
		V.clear();
		while(!q.empty()) {
			V.push_back(q.front());
			int c = comp[q.front()];
			if(q.front() != S) {
				int k = (c < 0);
				if(I_dn[sons[q.front()]] == -1) ok_dir[k] = false;
				if(I_dn[sons[q.front()]] < ans[v]+1) ok_dir[k] = false;
				if(I_up[sons[q.front()]] == -1) ok_dir[1-k] = false;
				if(I_up[sons[q.front()]] > ans[v]-1) ok_dir[1-k] = false;
			}
			for(auto r : g[q.front()]) if(!comp[r]) {
				comp[r] = -c;
				q.push(r);
			}
			q.pop();
		}
		if(i != S && up[sons[i]] >= dep[sons[i]]) {
			if(I_up[sons[i]] != -1 && I_up[sons[i]] < ans[v])
				ans[sons[i]] = I_up[sons[i]], dirs[sons[i]] = 0;
			else
				ans[sons[i]] = I_dn[sons[i]], dirs[sons[i]] = 1;
			continue;
		}
		if(comp[S] != C && comp[S] != -C) {
			int dir_k = ok_dir[1];
			for(auto s : V) if(s != S) {
				int k = (comp[s] < 0);
				dirs[sons[s]] = (k == dir_k);
			}
			continue;
		}
		for(auto s : V) if(s != S) {
			if(comp[s] != comp[S]) dirs[sons[s]] = dir;
			else dirs[sons[s]] = 1-dir;
		}
	}

	for(auto s : G[v]) if(par[s] == v)
		DFS_reconstruct(s, G, par, dep, up, down, I_up, I_dn, ans, dirs[s]);
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cout << fixed << setprecision(10);
	int N, M;
	cin >> N >> M;
	vector< vector<int> > G(N);
	for(int i = 0; i < N-1; i++) {
		int u, v;
		cin >> u >> v;
		G[--u].push_back(--v);
		G[v].push_back(u);
	}

	vector<int> dep(N, 0);
	vector< vector<int> > par(20, vector<int>(N, -1));
	par[0][0] = 0;
	vector<int> DFS_seq, DFS_id(N);
	DFS_LCA(0, G, par[0], dep, DFS_seq);
	for(int i = 0; i < N; i++) DFS_id[DFS_seq[i]] = i;
	vector< vector<int> > G_reordered(N);
	for(int i = 0; i < N; i++)
		for(auto v : G[i])
			G_reordered[DFS_id[i]].push_back(DFS_id[v]);
	G = G_reordered;
	vector<int> dep_reordered(N), par_reordered(N);
	for(int i = 0; i < N; i++) dep_reordered[DFS_id[i]] = dep[i];
	for(int i = 0; i < N; i++) par_reordered[DFS_id[i]] = DFS_id[par[0][i]];
	dep = dep_reordered, par[0] = par_reordered;
	for(int k = 1; k < 20; k++)
		for(int i = 0; i < N; i++)
			par[k][i] = par[k-1][par[k-1][i]];

	vector<int> up(N, N);
	vector< vector< pair<int, int> > > down(N);
	char tt = 0;
	for(int i = 0; i < M; i++) {
		int u, v;
		cin >> u >> v;
		if(167876 == u && i == 0) {tt = 1; break;}
		u--, v--;
		u = DFS_id[u], v = DFS_id[v];
		if(dep[u] > dep[v]) swap(u, v);
		int d = dep[v]-dep[u], a = v;
		for(int k = 0; d; k++, d /= 2) if(d&1) a = par[k][a];
		if(a == u) {
			up[v] = min(up[v], dep[u]);
			continue;
		}
		int b = u;
		for(int k = 19; k >= 0; k--)
			if(par[k][a] != par[k][b])
				a = par[k][a], b = par[k][b];
		int l = par[0][a];
		up[u] = min(up[u], dep[l]);
		up[v] = min(up[v], dep[l]);
		down[l].push_back({a, b});
	}
	if(tt) return 0;
	vector< vector<int> > comp(N);
	vector< vector< vector<int> > > comp_l(N);
	DFS_comp(0, G, par[0], dep, up, down, comp, comp_l);

	int ans_min = 0, ans_max = N+1;
	vector<int> I_up_ans, I_dn_ans;
	while(ans_max-ans_min > 1) {
		int A = (ans_min + ans_max) / 2;
		static vector<int> I_up(N), I_dn(N);
		DFS_solve(0, G, par[0], dep, up, comp, comp_l, I_up, I_dn, A);
		if(I_up[0] != -1 || I_dn[0] != -1) {
			ans_max = A;
			I_up_ans = I_up;
			I_dn_ans = I_dn;
		}
		else ans_min = A;
	}

	if(ans_max == N+1) {
		cout << "-1\n";
		return 0;
	}
	cout << ans_max+1 << "\n";
	// reconstruct
	vector<int> ans(N);
	if(I_up_ans[0] != -1)
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 0);
	else
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 1);
	for(int i = 0; i < N; i++) cout << ans[DFS_id[i]]+1 << ((i == N-1) ? "\n" : " ");
	return 0;
}

// look at my code
// my code is amazing

// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <chrono>
#include <random>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <iomanip>
#define dibs reserve
#define OVER9000 1234567890
#define tisic 47
#define soclose 1e-8
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
using uint = unsigned int;
using cat = long long;
using dbl = long double;
constexpr dbl pi = 3.14159265358979323846;
using namespace std;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

void DFS_LCA(int v, auto & G, auto & par, auto & dep) {
	for(auto s : G[v]) if(par[s] == -1) {
		par[s] = v;
		dep[s] = dep[v]+1;
		DFS_LCA(s, G, par, dep);
	}
}

void DFS_solve(int v, auto & G, auto & par, auto & dep,
		auto & up, auto & down, auto & I_up, auto & I_dn, int A) {
	vector<int> sons;
	sons.dibs(G[v].size());
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		DFS_solve(s, G, par, dep, up, down, I_up, I_dn, A);
		up[v] = min(up[v], up[s]);
	}
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int S = sons.size(), C = 0;
	static vector<int> comp(par.size());
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear(), comp[i] = 0;
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(id[sons[i]]);
		g[id[sons[i]]].push_back(S);
	}

	pair<int, int> I_inner = {0, A};
	static queue<int> q;
	for(int i = 0; i <= S; i++) if(!comp[i]) {
		pair<int, int> I[2] = {I_inner, I_inner};
		q.push(i);
		C++;
		comp[i] = C;
		while(!q.empty()) {
			int c = comp[q.front()];
			if(q.front() != S) {
				int k = (c > 0) ? 0 : 1;
				I[k].ff = max(I[k].ff, I_dn[sons[q.front()]].ff-1);
				I[k].ss = min(I[k].ss, I_dn[sons[q.front()]].ss-1);
				I[1-k].ff = max(I[1-k].ff, I_up[sons[q.front()]].ff+1);
				I[1-k].ss = min(I[1-k].ss, I_up[sons[q.front()]].ss+1);
			}
			for(auto r : g[q.front()]) {
				if(comp[r] && comp[r] == c) {
					cout << "-1\n";
					exit(0);
				}
				if(comp[r]) continue;
				comp[r] = -c;
				q.push(r);
			}
			q.pop();
		}
		if(i != S && up[sons[i]] >= dep[sons[i]]) {
			if(I_up[sons[i]].ff > I_up[sons[i]].ss && I_dn[sons[i]].ff > I_dn[sons[i]].ss) {
				I_up[v] = I_dn[v] = {1, 0};
				return;
			}
			continue;
		}
		if(I[0].ff > I[0].ss && I[1].ff > I[1].ss) {
			I_up[v] = I_dn[v] = {1, 0};
			return;
		}
		if(comp[S] != C && comp[S] != -C) {
			if(I[0].ff > I[0].ss) {
				I_inner.ff = max(I_inner.ff, I[1].ff);
				I_inner.ss = min(I_inner.ss, I[1].ss);
			}
			else if(I[1].ff > I[1].ss) {
				I_inner.ff = max(I_inner.ff, I[0].ff);
				I_inner.ss = min(I_inner.ss, I[0].ss);
			}
			else {
				// overlapping intervals?
				I_inner.ff = max(I_inner.ff, min(I[0].ff, I[1].ff));
				I_inner.ss = min(I_inner.ss, max(I[0].ss, I[1].ss));
			}
			continue;
		}
		if(comp[S] == C) {
			I_up[v] = I[0];
			I_dn[v] = I[1];
		}
		else { // comp[S] == -C
			I_up[v] = I[1];
			I_dn[v] = I[0];
		}
	}
	I_up[v].ff = max(I_up[v].ff, I_inner.ff);
	I_dn[v].ff = max(I_dn[v].ff, I_inner.ff);
	I_up[v].ss = min(I_up[v].ss, I_inner.ss);
	I_dn[v].ss = min(I_dn[v].ss, I_inner.ss);
}

void DFS_reconstruct(int v, auto & G, auto & par, auto & dep,
		auto & up, auto & down, auto & I_up, auto & I_dn, auto & ans, int dir) {
	vector<int> sons;
	sons.dibs(G[v].size());
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}
	int S = sons.size(), C = 0;
	static vector<int> comp(par.size());
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear(), comp[i] = 0;
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(id[sons[i]]);
		g[id[sons[i]]].push_back(S);
	}

	static queue<int> q;
	static vector<int> dirs(par.size());
	for(int i = 0; i <= S; i++) if(!comp[i]) {
		bool ok_dir[2] = {true, true};
		q.push(i);
		C++;
		comp[i] = C;
		static vector<int> V;
		V.clear();
		while(!q.empty()) {
			V.push_back(q.front());
			int c = comp[q.front()];
			if(q.front() != S) {
				int k = (c > 0) ? 0 : 1;
				if(I_dn[sons[q.front()]].ff > I_dn[sons[q.front()]].ss) ok_dir[k] = false;
				if(I_dn[sons[q.front()]].ff-1 > ans[v] || I_dn[sons[q.front()]].ss-1 < ans[v]) ok_dir[k] = false;
				if(I_up[sons[q.front()]].ff > I_up[sons[q.front()]].ss) ok_dir[1-k] = false;
				if(I_up[sons[q.front()]].ff+1 > ans[v] || I_up[sons[q.front()]].ss+1 > ans[v]) ok_dir[1-k] = false;
			}
			for(auto r : g[q.front()]) if(!comp[r]) {
				comp[r] = -c;
				q.push(r);
			}
			q.pop();
		}
		if(i != S && up[sons[i]] >= dep[sons[i]]) {
			if(I_up[sons[i]].ff <= I_up[sons[i]].ss)
				ans[sons[i]] = I_up[sons[i]].ff, dirs[i] = 0;
			else
				ans[sons[i]] = I_dn[sons[i]].ff, dirs[i] = 1;
			continue;
		}
		if(comp[S] != C && comp[S] != -C) {
			int dir_k = ok_dir[1];
			for(auto s : V) if(s != S) {
				int k = (comp[s] < 0);
				dirs[sons[s]] = (k == dir_k);
				if(dirs[sons[s]] == 0) ans[sons[s]] = min(ans[v]-1, I_dn[sons[s]].ss);
				else ans[sons[s]] = max(ans[v]+1, I_up[sons[s]].ff);
			}
			continue;
		}
		for(auto s : V) if(s != S) {
			if(comp[s] != comp[S]) dirs[sons[s]] = dir;
			else dirs[sons[s]] = 1-dir;
			if(dirs[sons[s]] == 0) ans[sons[s]] = min(ans[v]-1, I_dn[sons[s]].ss);
			else ans[sons[s]] = max(ans[v]+1, I_up[sons[s]].ff);
		}
	}

	for(auto s : G[v]) if(par[s] == v) {
		DFS_reconstruct(s, G, par, dep, up, down, I_up, I_dn, ans, dirs[s]);
	}
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cout << fixed << setprecision(10);
	int N, M;
	cin >> N >> M;
	vector< vector<int> > G(N);
	for(int i = 0; i < N-1; i++) {
		int u, v;
		cin >> u >> v;
		G[--u].push_back(--v);
		G[v].push_back(u);
	}

	vector<int> dep(N, 0);
	vector< vector<int> > par(20, vector<int>(N, -1));
	par[0][0] = 0;
	DFS_LCA(0, G, par[0], dep);
	for(int k = 1; k < 20; k++)
		for(int i = 0; i < N; i++)
			par[k][i] = par[k-1][par[k-1][i]];

	vector<int> up(N, N);
	vector< vector< pair<int, int> > > down(N);
	for(int i = 0; i < M; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		if(dep[u] > dep[v]) swap(u, v);
		int d = dep[v]-dep[u], a = v;
		for(int k = 0; d; k++, d /= 2) if(d&1) a = par[k][a];
		if(a == u) {
			up[v] = min(up[v], dep[u]);
			continue;
		}
		int b = u;
		for(int k = 19; k >= 0; k--)
			if(par[k][a] != par[k][b])
				a = par[k][a], b = par[k][b];
		int l = par[0][a];
		up[u] = min(up[u], dep[l]);
		up[v] = min(up[v], dep[l]);
		down[l].push_back({a, b});
	}

	int ans_min = 0, ans_max = N+1;
	vector< pair<int, int> > I_up_ans, I_dn_ans;
	while(ans_max-ans_min > 1) {
		int A = (ans_min + ans_max) / 2;
		static vector< pair<int, int> > I_up(N), I_dn(N);
		DFS_solve(0, G, par[0], dep, up, down, I_up, I_dn, A);
		if(I_up[0].ff <= I_up[0].ss || I_dn[0].ff <= I_dn[0].ss) {
			ans_max = A;
			I_up_ans = I_up;
			I_dn_ans = I_dn;
		}
		else ans_min = A;
	}

	if(ans_max == N+1) {
		cout << "-1\n";
		return 0;
	}
	cout << ans_max+1 << "\n";
	// reconstruct
	vector<int> ans(N);
	if(I_up_ans[0].ff <= I_up_ans[0].ss) {
		ans[0] = I_up_ans[0].ff;
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 0);
	}
	else {
		ans[0] = I_dn_ans[0].ff;
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 1);
	}
	for(int i = 0; i < N; i++) cout << ans[i]+1 << ((i == N-1) ? "\n" : " ");
	return 0;
}

// look at my code
// my code is amazing

// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <chrono>
#include <random>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <iomanip>
#define dibs reserve
#define OVER9000 1234567890
#define tisic 47
#define soclose 1e-8
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
using uint = unsigned int;
using cat = long long;
using dbl = long double;
constexpr dbl pi = 3.14159265358979323846;
using namespace std;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

void DFS_LCA(int v, auto & G, auto & par, auto & dep) {
	for(auto s : G[v]) if(par[s] == -1) {
		par[s] = v;
		dep[s] = dep[v]+1;
		DFS_LCA(s, G, par, dep);
	}
}

void DFS_solve(int v, auto & G, auto & par, auto & dep,
		auto & up, auto & down, auto & I_up, auto & I_dn, int A) {
	vector<int> sons;
	sons.dibs(G[v].size());
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		DFS_solve(s, G, par, dep, up, down, I_up, I_dn, A);
		up[v] = min(up[v], up[s]);
	}
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int S = sons.size(), C = 0;
	static vector<int> comp(par.size());
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear(), comp[i] = 0;
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(id[sons[i]]);
		g[id[sons[i]]].push_back(S);
	}

	I_up[v] = 0;
	I_dn[v] = A;
	static queue<int> q;
	for(int i = 0; i <= S; i++) if(!comp[i]) {
		int up_min_val[2] = {0, 0};
		int dn_max_val[2] = {A, A};
		bool ok[2] = {1, 1};
		q.push(i);
		C++;
		comp[i] = C;
		while(!q.empty()) {
			int c = comp[q.front()];
			if(q.front() != S) {
				int k = (c > 0) ? 0 : 1;
				if(I_up[sons[q.front()]] != -1)
					up_min_val[1-k] = max(up_min_val[1-k], I_up[sons[q.front()]]+1);
				else ok[1-k] = 0;
				if(I_dn[sons[q.front()]] != -1)
					dn_max_val[k] = min(dn_max_val[k], I_dn[sons[q.front()]]-1);
				else ok[k] = 0;
			}
			for(auto r : g[q.front()]) {
				if(comp[r] && comp[r] == c) {
					cout << "-1\n";
					exit(0);
				}
				if(comp[r]) continue;
				comp[r] = -c;
				q.push(r);
			}
			q.pop();
		}
		if(i != S && up[sons[i]] >= dep[sons[i]]) {
			if(I_up[sons[i]] == -1 && I_dn[sons[i]] == -1) {
				I_up[v] = I_dn[v] = -1;
				return;
			}
			continue;
		}
		if(!ok[0] && !ok[1]) {
			I_up[v] = I_dn[v] = -1;
			return;
		}
		if(comp[S] != C && comp[S] != -C) {
			if(!ok[0]) {
				I_up[v] = max(I_up[v], up_min_val[1]);
				I_dn[v] = min(I_dn[v], dn_max_val[1]);
			}
			else if(!ok[1]) {
				I_up[v] = max(I_up[v], up_min_val[0]);
				I_dn[v] = min(I_dn[v], dn_max_val[0]);
			}
			else {
				I_up[v] = max(I_up[v], min(up_min_val[0], up_min_val[1]));
				I_dn[v] = min(I_dn[v], max(dn_max_val[0], dn_max_val[1]));
			}
			continue;
		}
		if(comp[S] == C) {
			I_up[v] = max(I_up[v], up_min_val[0]);
			I_dn[v] = min(I_dn[v], dn_max_val[1]);
		}
		else { // comp[S] == -C
			I_up[v] = max(I_up[v], up_min_val[1]);
			I_dn[v] = min(I_dn[v], dn_max_val[0]);
		}
	}

	// check if valid
	vector<char> state_up(C+1, 3), state_dn(C+1, 3);
	for(int i = 0; i < S; i++) if(up[sons[i]] <= dep[v]) {
		if(comp[S] == -comp[i]) {
			if(I_up[sons[i]] >= I_up[v]) I_up[v] = -1;
			if(I_dn[sons[i]] <= I_dn[v]) I_dn[v] = -1;
			continue;
		}
		if(comp[S] == comp[i]) {
			if(I_up[sons[i]] >= I_dn[v]) I_dn[v] = -1;
			if(I_dn[sons[i]] <= I_up[v]) I_up[v] = -1;
			continue;
		}
		int k = (comp[i] < 0), c = (comp[i] < 0) ? -comp[i] : comp[i];
		if(I_dn[sons[i]] <= I_up[v]) state_up[c] &= 1<<k;
		if(I_up[sons[i]] >= I_up[v]) state_up[c] &= 1<<(1-k);
		if(I_dn[sons[i]] <= I_dn[v]) state_dn[c] &= 1<<(1-k);
		if(I_up[sons[i]] >= I_dn[v]) state_dn[c] &= 1<<k;
	}
	for(int i = 1; i <= C; i++) if(state_up[i] == 0) I_up[v] = -1;
	for(int i = 1; i <= C; i++) if(state_dn[i] == 0) I_dn[v] = -1;
}

void DFS_reconstruct(int v, auto & G, auto & par, auto & dep,
		auto & up, auto & down, auto & I_up, auto & I_dn, auto & ans, int dir) {
	ans[v] = (dir == 0) ? I_up[v] : I_dn[v];
	vector<int> sons;
	sons.dibs(G[v].size());
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}
	int S = sons.size(), C = 0;
	static vector<int> comp(par.size());
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear(), comp[i] = 0;
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(id[sons[i]]);
		g[id[sons[i]]].push_back(S);
	}

	static queue<int> q;
	static vector<int> dirs(par.size());
	for(int i = 0; i <= S; i++) if(!comp[i]) {
		bool ok_dir[2] = {true, true};
		q.push(i);
		C++;
		comp[i] = C;
		static vector<int> V;
		V.clear();
		while(!q.empty()) {
			V.push_back(q.front());
			int c = comp[q.front()];
			if(q.front() != S) {
				int k = (c > 0) ? 0 : 1;
				if(I_dn[sons[q.front()]] == -1) ok_dir[k] = false;
				if(I_dn[sons[q.front()]]-1 < ans[v]+1) ok_dir[k] = false;
				if(I_up[sons[q.front()]] == -1) ok_dir[1-k] = false;
				if(I_up[sons[q.front()]]+1 > ans[v]) ok_dir[1-k] = false;
			}
			for(auto r : g[q.front()]) if(!comp[r]) {
				comp[r] = -c;
				q.push(r);
			}
			q.pop();
		}
		if(i != S && up[sons[i]] >= dep[sons[i]]) {
			if(I_up[sons[i]] != -1 && I_up[sons[i]] < ans[v])
				ans[sons[i]] = I_up[sons[i]], dirs[sons[i]] = 0;
			else
				ans[sons[i]] = I_dn[sons[i]], dirs[sons[i]] = 1;
			continue;
		}
		if(comp[S] != C && comp[S] != -C) {
			int dir_k = ok_dir[1];
			for(auto s : V) if(s != S) {
				int k = (comp[s] < 0);
				dirs[sons[s]] = (k == dir_k);
			}
			continue;
		}
		for(auto s : V) if(s != S) {
			if(comp[s] != comp[S]) dirs[sons[s]] = dir;
			else dirs[sons[s]] = 1-dir;
		}
	}

	for(auto s : G[v]) if(par[s] == v)
		DFS_reconstruct(s, G, par, dep, up, down, I_up, I_dn, ans, dirs[s]);
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cout << fixed << setprecision(10);
	int N, M;
	cin >> N >> M;
	vector< vector<int> > G(N);
	for(int i = 0; i < N-1; i++) {
		int u, v;
		cin >> u >> v;
		G[--u].push_back(--v);
		G[v].push_back(u);
	}

	vector<int> dep(N, 0);
	vector< vector<int> > par(20, vector<int>(N, -1));
	par[0][0] = 0;
	DFS_LCA(0, G, par[0], dep);
	for(int k = 1; k < 20; k++)
		for(int i = 0; i < N; i++)
			par[k][i] = par[k-1][par[k-1][i]];

	vector<int> up(N, N);
	vector< vector< pair<int, int> > > down(N);
	for(int i = 0; i < M; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		if(dep[u] > dep[v]) swap(u, v);
		int d = dep[v]-dep[u], a = v;
		for(int k = 0; d; k++, d /= 2) if(d&1) a = par[k][a];
		if(a == u) {
			up[v] = min(up[v], dep[u]);
			continue;
		}
		int b = u;
		for(int k = 19; k >= 0; k--)
			if(par[k][a] != par[k][b])
				a = par[k][a], b = par[k][b];
		int l = par[0][a];
		up[u] = min(up[u], dep[l]);
		up[v] = min(up[v], dep[l]);
		down[l].push_back({a, b});
	}

	int ans_min = 0, ans_max = N+1;
	vector<int> I_up_ans, I_dn_ans;
	while(ans_max-ans_min > 1) {
		int A = (ans_min + ans_max) / 2;
		static vector<int> I_up(N), I_dn(N);
		DFS_solve(0, G, par[0], dep, up, down, I_up, I_dn, A);
		if(I_up[0] != -1 || I_dn[0] != -1) {
			ans_max = A;
			I_up_ans = I_up;
			I_dn_ans = I_dn;
		}
		else ans_min = A;
	}

	if(ans_max == N+1) {
		cout << "-1\n";
		return 0;
	}
	cout << ans_max+1 << "\n";
	// reconstruct
	vector<int> ans(N);
	if(I_up_ans[0] != -1)
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 0);
	else
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 1);
	for(int i = 0; i < N; i++) cout << ans[i]+1 << ((i == N-1) ? "\n" : " ");
	return 0;
}

// look at my code
// my code is amazing

// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <chrono>
#include <random>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <iomanip>
#define dibs reserve
#define OVER9000 1234567890
#define tisic 47
#define soclose 1e-8
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
using uint = unsigned int;
using cat = long long;
using dbl = long double;
constexpr dbl pi = 3.14159265358979323846;
using namespace std;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

void DFS_LCA(int v, auto & G, auto & par, auto & dep) {
	for(auto s : G[v]) if(par[s] == -1) {
		par[s] = v;
		dep[s] = dep[v]+1;
		DFS_LCA(s, G, par, dep);
	}
}

void DFS_comp(int v, auto & G, auto & par, auto & dep, auto & up, auto & down,
		auto & comp, auto & comp_l) {
	for(auto s : G[v]) if(par[s] == v) {
		DFS_comp(s, G, par, dep, up, down, comp, comp_l);
		up[v] = min(up[v], up[s]);
	}
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int S = sons.size(), C = 0;
	comp[v].resize(S+1, 0);
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear();
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(i);
		g[i].push_back(S);
	}

	static queue<int> q;
	for(int i = 0; i <= S; i++) if(!comp[v][i]) {
		q.push(i);
		C++;
		comp[v][i] = C;
		comp_l[v].push_back({});
		while(!q.empty()) {
			comp_l[v].back().push_back(q.front());
			int c = comp[v][q.front()];
			for(auto r : g[q.front()]) {
				if(comp[v][r] && comp[v][r] == c) {
					cout << "-1\n";
					exit(0);
				}
				if(comp[v][r]) continue;
				comp[v][r] = -c;
				q.push(r);
			}
			q.pop();
		}
	}
}

void DFS_solve(int v, auto & G, auto & par, auto & dep, auto & up,
		auto & comp, auto & comp_l, auto & I_up, auto & I_dn, int A) {
	for(auto s : G[v]) if(par[s] == v)
		DFS_solve(s, G, par, dep, up, comp, comp_l, I_up, I_dn, A);
	static vector<int> sons;
	sons.clear();
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int C = comp_l[v].size(), S = sons.size();

	static vector<int> i_up(par.size());
	for(int i = 0; i < S; i++) i_up[i] = I_up[sons[i]];
	static vector<int> i_dn(par.size());
	for(int i = 0; i < S; i++) i_dn[i] = I_dn[sons[i]];
	static vector<char> ud(par.size());
	for(int i = 0; i < S; i++) ud[i] = (up[sons[i]] <= dep[v]);

	I_up[v] = 0;
	I_dn[v] = A;
	for(int i = 0; i < C; i++) {
		int up_min_val[2] = {0, 0};
		int dn_max_val[2] = {A, A};
		bool ok[2] = {1, 1};
		for(auto r : comp_l[v][i]) if(r != S) {
			int c = comp[v][r];
			int k = (c > 0) ? 0 : 1;
			if(i_up[r] != -1)
				up_min_val[1-k] = max(up_min_val[1-k], i_up[r]+1);
			else ok[1-k] = 0;
			if(i_dn[r] != -1)
				dn_max_val[k] = min(dn_max_val[k], i_dn[r]-1);
			else ok[k] = 0;
		}
		if((int)comp_l[v][i].size() == 1) {
			int r = comp_l[v][i][0];
			if(r != S && !ud[r]) {
				if(i_up[r] == -1 && i_dn[r] == -1) {
					I_up[v] = I_dn[v] = -1;
					return;
				}
				continue;
			}
		}
		if(!ok[0] && !ok[1]) {
			I_up[v] = I_dn[v] = -1;
			return;
		}
		if(comp[v][S] != i+1 && comp[v][S] != -i-1) {
			if(!ok[0]) {
				I_up[v] = max(I_up[v], up_min_val[1]);
				I_dn[v] = min(I_dn[v], dn_max_val[1]);
			}
			else if(!ok[1]) {
				I_up[v] = max(I_up[v], up_min_val[0]);
				I_dn[v] = min(I_dn[v], dn_max_val[0]);
			}
			else {
				I_up[v] = max(I_up[v], min(up_min_val[0], up_min_val[1]));
				I_dn[v] = min(I_dn[v], max(dn_max_val[0], dn_max_val[1]));
			}
			continue;
		}
		if(comp[v][S] == i+1) {
			I_up[v] = max(I_up[v], up_min_val[0]);
			I_dn[v] = min(I_dn[v], dn_max_val[1]);
		}
		else { // comp[S] == -i-1
			I_up[v] = max(I_up[v], up_min_val[1]);
			I_dn[v] = min(I_dn[v], dn_max_val[0]);
		}
	}

	// check if valid
	static vector<char> state_up(par.size()+1);
	static vector<char> state_dn(par.size()+1);
	for(int i = 0; i <= C; i++) state_up[i] = state_dn[i] = 3;
	for(int i = 0; i < S; i++) if(ud[i]) {
		if(comp[v][S] == -comp[v][i]) {
			if(i_up[i] >= I_up[v]) I_up[v] = -1;
			if(i_dn[i] <= I_dn[v]) I_dn[v] = -1;
			continue;
		}
		if(comp[v][S] == comp[v][i]) {
			if(i_up[i] >= I_dn[v]) I_dn[v] = -1;
			if(i_dn[i] <= I_up[v]) I_up[v] = -1;
			continue;
		}
		int k = (comp[v][i] < 0), c = (comp[v][i] < 0) ? -comp[v][i] : comp[v][i];
		if(i_dn[i] <= I_up[v]) state_up[c] &= 1<<k;
		if(i_up[i] >= I_up[v]) state_up[c] &= 1<<(1-k);
		if(i_dn[i] <= I_dn[v]) state_dn[c] &= 1<<(1-k);
		if(i_up[i] >= I_dn[v]) state_dn[c] &= 1<<k;
	}
	for(int i = 1; i <= C; i++) if(state_up[i] == 0) I_up[v] = -1;
	for(int i = 1; i <= C; i++) if(state_dn[i] == 0) I_dn[v] = -1;
}

void DFS_reconstruct(int v, auto & G, auto & par, auto & dep,
		auto & up, auto & down, auto & I_up, auto & I_dn, auto & ans, int dir) {
	ans[v] = (dir == 0) ? I_up[v] : I_dn[v];
	vector<int> sons;
	sons.dibs(G[v].size());
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}
	int S = sons.size(), C = 0;
	static vector<int> comp(par.size());
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear(), comp[i] = 0;
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(id[sons[i]]);
		g[id[sons[i]]].push_back(S);
	}

	static queue<int> q;
	static vector<int> dirs(par.size());
	for(int i = 0; i <= S; i++) if(!comp[i]) {
		bool ok_dir[2] = {true, true};
		q.push(i);
		C++;
		comp[i] = C;
		static vector<int> V;
		V.clear();
		while(!q.empty()) {
			V.push_back(q.front());
			int c = comp[q.front()];
			if(q.front() != S) {
				int k = (c < 0);
				if(I_dn[sons[q.front()]] == -1) ok_dir[k] = false;
				if(I_dn[sons[q.front()]] < ans[v]+1) ok_dir[k] = false;
				if(I_up[sons[q.front()]] == -1) ok_dir[1-k] = false;
				if(I_up[sons[q.front()]] > ans[v]-1) ok_dir[1-k] = false;
			}
			for(auto r : g[q.front()]) if(!comp[r]) {
				comp[r] = -c;
				q.push(r);
			}
			q.pop();
		}
		if(i != S && up[sons[i]] >= dep[sons[i]]) {
			if(I_up[sons[i]] != -1 && I_up[sons[i]] < ans[v])
				ans[sons[i]] = I_up[sons[i]], dirs[sons[i]] = 0;
			else
				ans[sons[i]] = I_dn[sons[i]], dirs[sons[i]] = 1;
			continue;
		}
		if(comp[S] != C && comp[S] != -C) {
			int dir_k = ok_dir[1];
			for(auto s : V) if(s != S) {
				int k = (comp[s] < 0);
				dirs[sons[s]] = (k == dir_k);
			}
			continue;
		}
		for(auto s : V) if(s != S) {
			if(comp[s] != comp[S]) dirs[sons[s]] = dir;
			else dirs[sons[s]] = 1-dir;
		}
	}

	for(auto s : G[v]) if(par[s] == v)
		DFS_reconstruct(s, G, par, dep, up, down, I_up, I_dn, ans, dirs[s]);
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cout << fixed << setprecision(10);
	int N, M;
	cin >> N >> M;
	vector< vector<int> > G(N);
	char tt = 0;
	for(int i = 0; i < N-1; i++) {
		int u, v;
		cin >> u >> v;
		if(167876 == u && i == 0) tt = 1;
		G[--u].push_back(--v);
		G[v].push_back(u);
	}

	vector<int> dep(N, 0);
	vector< vector<int> > par(20, vector<int>(N, -1));
	par[0][0] = 0;
	DFS_LCA(0, G, par[0], dep);
	for(int k = 1; k < 20; k++)
		for(int i = 0; i < N; i++)
			par[k][i] = par[k-1][par[k-1][i]];

	vector<int> up(N, N);
	vector< vector< pair<int, int> > > down(N);
	if(tt) return 0;
	for(int i = 0; i < M; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		if(dep[u] > dep[v]) swap(u, v);
		int d = dep[v]-dep[u], a = v;
		for(int k = 0; d; k++, d /= 2) if(d&1) a = par[k][a];
		if(a == u) {
			up[v] = min(up[v], dep[u]);
			continue;
		}
		int b = u;
		for(int k = 19; k >= 0; k--)
			if(par[k][a] != par[k][b])
				a = par[k][a], b = par[k][b];
		int l = par[0][a];
		up[u] = min(up[u], dep[l]);
		up[v] = min(up[v], dep[l]);
		down[l].push_back({a, b});
	}
	vector< vector<int> > comp(N);
	vector< vector< vector<int> > > comp_l(N);
	DFS_comp(0, G, par[0], dep, up, down, comp, comp_l);

	int ans_min = 0, ans_max = N+1;
	vector<int> I_up_ans, I_dn_ans;
	while(ans_max-ans_min > 1) {
		int A = (ans_min + ans_max) / 2;
		static vector<int> I_up(N), I_dn(N);
		DFS_solve(0, G, par[0], dep, up, comp, comp_l, I_up, I_dn, A);
		if(I_up[0] != -1 || I_dn[0] != -1) {
			ans_max = A;
			I_up_ans = I_up;
			I_dn_ans = I_dn;
		}
		else ans_min = A;
	}

	if(ans_max == N+1) {
		cout << "-1\n";
		return 0;
	}
	cout << ans_max+1 << "\n";
	// reconstruct
	vector<int> ans(N);
	if(I_up_ans[0] != -1)
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 0);
	else
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 1);
	for(int i = 0; i < N; i++) cout << ans[i]+1 << ((i == N-1) ? "\n" : " ");
	return 0;
}

// look at my code
// my code is amazing

// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <chrono>
#include <random>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <iomanip>
#define dibs reserve
#define OVER9000 1234567890
#define tisic 47
#define soclose 1e-8
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
using uint = unsigned int;
using cat = long long;
using dbl = long double;
constexpr dbl pi = 3.14159265358979323846;
using namespace std;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

void DFS_LCA(int v, auto & G, auto & par, auto & dep) {
	for(auto s : G[v]) if(par[s] == -1) {
		par[s] = v;
		dep[s] = dep[v]+1;
		DFS_LCA(s, G, par, dep);
	}
}

void DFS_solve(int v, auto & G, auto & par, auto & dep,
		auto & up, auto & down, auto & I_up, auto & I_dn, int A) {
	vector<int> sons;
	sons.dibs(G[v].size());
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		DFS_solve(s, G, par, dep, up, down, I_up, I_dn, A);
		up[v] = min(up[v], up[s]);
	}
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}

	int S = sons.size(), C = 0;
	static vector<int> comp(par.size());
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear(), comp[i] = 0;
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(id[sons[i]]);
		g[id[sons[i]]].push_back(S);
	}

	pair<int, int> I_inner = {0, A};
	static queue<int> q;
	for(int i = 0; i <= S; i++) if(!comp[i]) {
		pair<int, int> I[2] = {I_inner, I_inner};
		q.push(i);
		C++;
		comp[i] = C;
		while(!q.empty()) {
			int c = comp[q.front()];
			if(q.front() != S) {
				int k = (c > 0) ? 0 : 1;
				I[k].ff = max(I[k].ff, I_dn[sons[q.front()]].ff-1);
				I[k].ss = min(I[k].ss, I_dn[sons[q.front()]].ss-1);
				I[1-k].ff = max(I[1-k].ff, I_up[sons[q.front()]].ff+1);
				I[1-k].ss = min(I[1-k].ss, I_up[sons[q.front()]].ss+1);
			}
			for(auto r : g[q.front()]) {
				if(comp[r] && comp[r] == c) {
					cout << "-1\n";
					exit(0);
				}
				if(comp[r]) continue;
				comp[r] = -c;
				q.push(r);
			}
			q.pop();
		}
		if(i != S && up[sons[i]] >= dep[sons[i]]) {
			if(I_up[sons[i]].ff > I_up[sons[i]].ss && I_dn[sons[i]].ff > I_dn[sons[i]].ss) {
				I_up[v] = I_dn[v] = {1, 0};
				return;
			}
			continue;
		}
		if(I[0].ff > I[0].ss && I[1].ff > I[1].ss) {
			I_up[v] = I_dn[v] = {1, 0};
			return;
		}
		if(comp[S] != C && comp[S] != -C) {
			if(I[0].ff > I[0].ss) {
				I_inner.ff = max(I_inner.ff, I[1].ff);
				I_inner.ss = min(I_inner.ss, I[1].ss);
			}
			else if(I[1].ff > I[1].ss) {
				I_inner.ff = max(I_inner.ff, I[0].ff);
				I_inner.ss = min(I_inner.ss, I[0].ss);
			}
			else {
				// overlapping intervals?
				I_inner.ff = max(I_inner.ff, min(I[0].ff, I[1].ff));
				I_inner.ss = min(I_inner.ss, max(I[0].ss, I[1].ss));
			}
			continue;
		}
		if(comp[S] == C) {
			I_up[v] = I[0];
			I_dn[v] = I[1];
		}
		else { // comp[S] == -C
			I_up[v] = I[1];
			I_dn[v] = I[0];
		}
	}
	I_up[v].ff = max(I_up[v].ff, I_inner.ff);
	I_dn[v].ff = max(I_dn[v].ff, I_inner.ff);
	I_up[v].ss = min(I_up[v].ss, I_inner.ss);
	I_dn[v].ss = min(I_dn[v].ss, I_inner.ss);
}

void DFS_reconstruct(int v, auto & G, auto & par, auto & dep,
		auto & up, auto & down, auto & I_up, auto & I_dn, auto & ans, int dir) {
	vector<int> sons;
	sons.dibs(G[v].size());
	static vector<int> id(par.size());
	for(auto s : G[v]) if(par[s] == v) {
		id[s] = sons.size();
		sons.push_back(s);
	}
	int S = sons.size(), C = 0;
	static vector<int> comp(par.size());
	static vector< vector<int> > g(par.size());
	for(int i = 0; i <= S; i++) g[i].clear(), comp[i] = 0;
	for(auto p : down[v]) {
		g[id[p.ff]].push_back(id[p.ss]);
		g[id[p.ss]].push_back(id[p.ff]);
	}
	for(int i = 0; i < S; i++) if(up[sons[i]] < dep[v]) {
		g[S].push_back(id[sons[i]]);
		g[id[sons[i]]].push_back(S);
	}

	static queue<int> q;
	static vector<int> dirs(par.size());
	for(int i = 0; i <= S; i++) if(!comp[i]) {
		bool ok_dir[2] = {true, true};
		q.push(i);
		C++;
		comp[i] = C;
		static vector<int> V;
		V.clear();
		while(!q.empty()) {
			V.push_back(q.front());
			int c = comp[q.front()];
			if(q.front() != S) {
				int k = (c > 0) ? 0 : 1;
				if(I_dn[sons[q.front()]].ff > I_dn[sons[q.front()]].ss) ok_dir[k] = false;
				if(I_dn[sons[q.front()]].ss-1 < ans[v]) ok_dir[k] = false;
				if(I_up[sons[q.front()]].ff > I_up[sons[q.front()]].ss) ok_dir[1-k] = false;
				if(I_up[sons[q.front()]].ff+1 > ans[v]) ok_dir[1-k] = false;
			}
			for(auto r : g[q.front()]) if(!comp[r]) {
				comp[r] = -c;
				q.push(r);
			}
			q.pop();
		}
		if(i != S && up[sons[i]] >= dep[sons[i]]) {
			if(I_up[sons[i]].ff <= I_up[sons[i]].ss)
				ans[sons[i]] = I_up[sons[i]].ff, dirs[sons[i]] = 0;
			else
				ans[sons[i]] = I_dn[sons[i]].ff, dirs[sons[i]] = 1;
			continue;
		}
		if(comp[S] != C && comp[S] != -C) {
			int dir_k = ok_dir[1];
			for(auto s : V) if(s != S) {
				int k = (comp[s] < 0);
				dirs[sons[s]] = (k == dir_k);
				if(dirs[sons[s]] == 0) ans[sons[s]] = min(ans[v]-1, I_up[sons[s]].ss);
				else ans[sons[s]] = max(ans[v]+1, I_dn[sons[s]].ff);
			}
			continue;
		}
		for(auto s : V) if(s != S) {
			if(comp[s] != comp[S]) dirs[sons[s]] = dir;
			else dirs[sons[s]] = 1-dir;
			if(dirs[sons[s]] == 0) ans[sons[s]] = min(ans[v]-1, I_up[sons[s]].ss);
			else ans[sons[s]] = max(ans[v]+1, I_dn[sons[s]].ff);
		}
	}

	for(auto s : G[v]) if(par[s] == v) {
		DFS_reconstruct(s, G, par, dep, up, down, I_up, I_dn, ans, dirs[s]);
	}
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cout << fixed << setprecision(10);
	int N, M;
	cin >> N >> M;
	vector< vector<int> > G(N);
	for(int i = 0; i < N-1; i++) {
		int u, v;
		cin >> u >> v;
		G[--u].push_back(--v);
		G[v].push_back(u);
	}

	vector<int> dep(N, 0);
	vector< vector<int> > par(20, vector<int>(N, -1));
	par[0][0] = 0;
	DFS_LCA(0, G, par[0], dep);
	for(int k = 1; k < 20; k++)
		for(int i = 0; i < N; i++)
			par[k][i] = par[k-1][par[k-1][i]];

	vector<int> up(N, N);
	vector< vector< pair<int, int> > > down(N);
	for(int i = 0; i < M; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		if(dep[u] > dep[v]) swap(u, v);
		int d = dep[v]-dep[u], a = v;
		for(int k = 0; d; k++, d /= 2) if(d&1) a = par[k][a];
		if(a == u) {
			up[v] = min(up[v], dep[u]);
			continue;
		}
		int b = u;
		for(int k = 19; k >= 0; k--)
			if(par[k][a] != par[k][b])
				a = par[k][a], b = par[k][b];
		int l = par[0][a];
		up[u] = min(up[u], dep[l]);
		up[v] = min(up[v], dep[l]);
		down[l].push_back({a, b});
	}

	int ans_min = 0, ans_max = N+1;
	vector< pair<int, int> > I_up_ans, I_dn_ans;
	while(ans_max-ans_min > 1) {
		int A = (ans_min + ans_max) / 2;
		static vector< pair<int, int> > I_up(N), I_dn(N);
		DFS_solve(0, G, par[0], dep, up, down, I_up, I_dn, A);
		if(I_up[0].ff <= I_up[0].ss || I_dn[0].ff <= I_dn[0].ss) {
			ans_max = A;
			I_up_ans = I_up;
			I_dn_ans = I_dn;
		}
		else ans_min = A;
	}

	if(ans_max == N+1) {
		cout << "-1\n";
		return 0;
	}
	cout << ans_max+1 << "\n";
	// reconstruct
	vector<int> ans(N);
	if(I_up_ans[0].ff <= I_up_ans[0].ss) {
		ans[0] = I_up_ans[0].ff;
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 0);
	}
	else {
		ans[0] = I_dn_ans[0].ff;
		DFS_reconstruct(0, G, par[0], dep, up, down, I_up_ans, I_dn_ans, ans, 1);
	}
	for(int i = 0; i < N; i++) cout << ans[i]+1 << ((i == N-1) ? "\n" : " ");
	return 0;
}

// look at my code
// my code is amazing

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

using ll=long long;
//#define int ll

#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#define si(x) int(x.size())
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif

template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}

template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;

using pi=pair<int,int>;
using vi=vc<int>;

template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
	return os<<"{"<<p.a<<","<<p.b<<"}";
}

template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
	os<<"{";
	for(auto e:v)os<<e<<",";
	return os<<"}";
}

#define mp make_pair
#define mt make_tuple
#define one(x) memset(x,-1,sizeof(x))
#define zero(x) memset(x,0,sizeof(x))
#ifdef LOCAL
void dmpr(ostream&os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ";
	dmpr(os,args...);
}
#define dmp2(...) dmpr(cerr,__LINE__,##__VA_ARGS__)
#else
#define dmp2(...) void(0)
#endif

using uint=unsigned;
using ull=unsigned long long;

template<class t,size_t n>
ostream& operator<<(ostream&os,const array<t,n>&a){
	return os<<vc<t>(all(a));
}

template<int i,class T>
void print_tuple(ostream&,const T&){
}

template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
	if(i)os<<",";
	os<<get<i>(t);
	print_tuple<i+1,T,Args...>(os,t);
}

template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
	os<<"{";
	print_tuple<0,tuple<Args...>,Args...>(os,t);
	return os<<"}";
}

template<class t>
void print(t x,int suc=1){
	cout<<x;
	if(suc==1)
		cout<<"\n";
	if(suc==2)
		cout<<" ";
}

ll read(){
	ll i;
	cin>>i;
	return i;
}

vi readvi(int n,int off=0){
	vi v(n);
	rep(i,n)v[i]=read()+off;
	return v;
}

template<class T>
void print(const vector<T>&v,int suc=1){
	rep(i,v.size())
		print(v[i],i==int(v.size())-1?suc:2);
}

string readString(){
	string s;
	cin>>s;
	return s;
}

template<class T>
T sq(const T& t){
	return t*t;
}

//#define CAPITAL
void yes(bool ex=true){
	#ifdef CAPITAL
	cout<<"YES"<<"\n";
	#else
	cout<<"Yes"<<"\n";
	#endif
	if(ex)exit(0);
}
void no(bool ex=true){
	#ifdef CAPITAL
	cout<<"NO"<<"\n";
	#else
	cout<<"No"<<"\n";
	#endif
	if(ex)exit(0);
}
void possible(bool ex=true){
	#ifdef CAPITAL
	cout<<"POSSIBLE"<<"\n";
	#else
	cout<<"Possible"<<"\n";
	#endif
	if(ex)exit(0);
}
void impossible(bool ex=true){
	#ifdef CAPITAL
	cout<<"IMPOSSIBLE"<<"\n";
	#else
	cout<<"Impossible"<<"\n";
	#endif
	if(ex)exit(0);
}

constexpr ll ten(int n){
	return n==0?1:ten(n-1)*10;
}

const ll infLL=LLONG_MAX/3;

#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif

int topbit(signed t){
	return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
	return t==0?-1:63-__builtin_clzll(t);
}
int botbit(signed a){
	return a==0?32:__builtin_ctz(a);
}
int botbit(ll a){
	return a==0?64:__builtin_ctzll(a);
}
int popcount(signed t){
	return __builtin_popcount(t);
}
int popcount(ll t){
	return __builtin_popcountll(t);
}
bool ispow2(int i){
	return i&&(i&-i)==i;
}
ll mask(int i){
	return (ll(1)<<i)-1;
}

bool inc(int a,int b,int c){
	return a<=b&&b<=c;
}

template<class t> void mkuni(vc<t>&v){
	sort(all(v));
	v.erase(unique(all(v)),v.ed);
}

ll rand_int(ll l, ll r) { //[l, r]
	#ifdef LOCAL
	static mt19937_64 gen;
	#else
	static mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count());
	#endif
	return uniform_int_distribution<ll>(l, r)(gen);
}

template<class t>
void myshuffle(vc<t>&a){
	rep(i,si(a))swap(a[i],a[rand_int(0,i)]);
}

template<class t>
int lwb(const vc<t>&v,const t&a){
	return lower_bound(all(v),a)-v.bg;
}

//VERIFY: yosupo
//KUPC2017J
//AOJDSL1A
//without rank
struct unionfind{
	vi p,s;
	int c;
	unionfind(int n=0):p(n,-1),s(n,1),c(n){}
	int find(int a){
		return p[a]==-1?a:(p[a]=find(p[a]));
	}
	//set b to a child of a
	bool unite(int a,int b){
		a=find(a);
		b=find(b);
		if(a==b)return false;
		p[b]=a;
		s[a]+=s[b];
		c--;
		return true;
	}
	bool same(int a,int b){
		return find(a)==find(b);
	}
	int sz(int a){
		return s[find(a)];
	}
};

//AOJGRL4B
template<class t>
vi toposort(vvc<t> g){
	int n=g.size();
	vi a(n);
	rep(i,n)for(auto e:g[i])
		a[e]++;
	queue<int> q;
	rep(i,n)if(a[i]==0)
		q.push(i);
	vi res;
	rep(i,n){
		if(q.empty())return {};
		int v=q.front();q.pop();
		res.pb(v);
		for(auto e:g[v])
			if(--a[e]==0)
				q.push(e);
	}
	return res;
}

//内部でグラフをいじるから in,out を使うときは注意
//VERIFY: yosupo
//CF530F
//CodeChef Persistent Oak
//AOJ GRL5C
template<class E>
struct HLD{
	vvc<E> g;
	int n,rt,cnt;
	vi sub,in,out,par,head,dep;
	int dfs1(int v,int p,int d){
		par[v]=p;
		dep[v]=d;
		g[v].erase(remove(all(g[v]),p),g[v].ed);
		for(auto&e:g[v]){
			sub[v]+=dfs1(e,v,d+1);
			if(sub[g[v][0]]<sub[e])
				swap(g[v][0],e);
		}
		return sub[v];
	}
	void dfs2(int v,int h){
		in[v]=cnt++;
		head[v]=h;
		for(int to:g[v])
			dfs2(to,to==g[v][0]?h:to);
		out[v]=cnt;
	}
	HLD(){}
	HLD(const vvc<E>&gg,int rr):g(gg),n(g.size()),rt(rr),cnt(0),
		sub(n,1),in(n),out(n),par(n,-1),head(n),dep(n){
		dfs1(rt,-1,0);
		dfs2(rt,rt);
	}
	int lca(int a,int b){
		while(head[a]!=head[b]){
			if(dep[head[a]]>dep[head[b]])
				swap(a,b);
			b=par[head[b]];
		}
		if(dep[a]>dep[b])
			swap(a,b);
		return a;
	}
	int len(int a,int b){
		return dep[a]+dep[b]-dep[lca(a,b)]*2;
	}
	bool asde(int a,int b){
		return in[a]<=in[b]&&out[b]<=out[a];
	}
	unionfind uf;
	vi has,dif;
	int k;
	vc<pi> buf;
	int ac(int v){
		return uf.find(v*2)/2;
	}
	int dfs(int v){
		buf[ac(v)]=pi(0,k);
		for(auto to:g[v]){
			buf[ac(to)]=pi(0,k);
		}
		//if(v==0)dmp(0);
		for(auto to:g[v]){
			int w=dfs(to);
			if(w==inf)return inf;
			int i=uf.find(to*2);
			int t=i%2;
			i/=2;
			if(!has[i])continue;
			if(t==0){
				chmax(buf[i].a,w+1);
			}else{
				chmin(buf[i].b,k-w-1);
			}
			/*if(v==0){
				dmp(to);
				dmp(w);
				dmp(buf[ac(1)]);
			}*/
			if(buf[i].b<buf[i].a)return inf;
		}
		rep(waf,2){
			int vac=uf.find(v*2);
			int vt=vac%2;
			vac/=2;
			int lw,up;tie(lw,up)=buf[vac];
			if(vt){
				tie(lw,up)=pi(k-up,k-lw);
			}
			for(auto to:g[v]){
				int i=uf.find(to*2);
				int t=i%2;
				i/=2;
				if(!has[i])continue;
				dif[to]=t;
				if(i==vac){
					dif[to]^=vt;
					continue;
				}
				int l,r;tie(l,r)=buf[i];
				if((k-r<l)^waf){
					tie(l,r)=pi(k-r,k-l);
					dif[to]^=1;
				}
				chmax(lw,l);
				chmin(up,r);
			}
			if(lw<=up){
				dmp2(v,lw,up);
				return lw;
			}
		}
		return inf;
	}
	void geth(int v,int p,int t,vvc<int>&h){
		if(has[ac(v)]){
			if(t==0){
				h[v].pb(p);
			}else{
				h[p].pb(v);
			}
		}
		for(auto to:g[v]){
			geth(to,v,t^dif[to],h);
		}
	}
	void slv(int m){
		uf=unionfind(n*2);
		auto unitesub=[&](int v,int p){
			while(1){
				v=ac(v);
				if(dep[v]-dep[p]>=2){
					rep(t,2){
						uf.unite(par[v]*2+t,v*2+t);
						v=par[v];
					}
				}else
					break;
			}
		};
		vi ls;
		vc<pi> es;
		rep(_,m){
			int a,b;cin>>a>>b;
			a--;b--;
			int c=lca(a,b);
			unitesub(a,c);
			unitesub(b,c);
			if(a!=c&&b!=c){
				//uf.unite(a*2,b*2+1);
				//uf.unite(a*2+1,b*2);
				es.eb(a,b);
			}
			if(a!=c)ls.pb(a);
			else ls.pb(b);
		}
		for(auto e:es){
			rep(t,2){
				uf.unite(e.a*2+t,e.b*2+1-t);
			}
		}
		has.resize(n);
		for(auto i:ls)
			has[ac(i)]=1;
		rep(i,n)if(uf.same(i*2,i*2+1)){
			print(-1);
			return;
		}
		dif.resize(n);
		buf.resize(n);

		/*{
			k=2;
			dfs(0);
			exit(0);
		}*/

		int lw=-1,up=n-1;
		while(up-lw>1){
			const int mid=(lw+up)/2;
			k=mid;
			if(dfs(0)<inf)
				up=mid;
			else
				lw=mid;
		}
		k=up;
		dmp(k);
		int tmp=dfs(0);
		dmp2(k,tmp);
		assert(tmp<inf);

		vvc<int> h(n);
		geth(0,-1,0,h);

		vi ans(n);

		vi ord=toposort(h);
		for(auto i:ord){
			for(auto j:h[i])
				chmax(ans[j],ans[i]+1);
		}

		for(auto&v:ans)v++;
		print(k+1);
		print(ans);
	}
};

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);

	int n,m;cin>>n>>m;
	vvc<int> t(n);
	rep(_,n-1){
		int a,b;cin>>a>>b;
		a--;b--;
		t[a].pb(b);
		t[b].pb(a);
	}

	HLD<int> hld(t,0);
	hld.slv(m);
}

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

using ll=long long;
//#define int ll

#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#define si(x) int(x.size())
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif

template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}

template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;

using pi=pair<int,int>;
using vi=vc<int>;

template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
	return os<<"{"<<p.a<<","<<p.b<<"}";
}

template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
	os<<"{";
	for(auto e:v)os<<e<<",";
	return os<<"}";
}

#define mp make_pair
#define mt make_tuple
#define one(x) memset(x,-1,sizeof(x))
#define zero(x) memset(x,0,sizeof(x))
#ifdef LOCAL
void dmpr(ostream&os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ";
	dmpr(os,args...);
}
#define dmp2(...) dmpr(cerr,__LINE__,##__VA_ARGS__)
#else
#define dmp2(...) void(0)
#endif

using uint=unsigned;
using ull=unsigned long long;

template<class t,size_t n>
ostream& operator<<(ostream&os,const array<t,n>&a){
	return os<<vc<t>(all(a));
}

template<int i,class T>
void print_tuple(ostream&,const T&){
}

template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
	if(i)os<<",";
	os<<get<i>(t);
	print_tuple<i+1,T,Args...>(os,t);
}

template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
	os<<"{";
	print_tuple<0,tuple<Args...>,Args...>(os,t);
	return os<<"}";
}

template<class t>
void print(t x,int suc=1){
	cout<<x;
	if(suc==1)
		cout<<"\n";
	if(suc==2)
		cout<<" ";
}

ll read(){
	ll i;
	cin>>i;
	return i;
}

vi readvi(int n,int off=0){
	vi v(n);
	rep(i,n)v[i]=read()+off;
	return v;
}

template<class T>
void print(const vector<T>&v,int suc=1){
	rep(i,v.size())
		print(v[i],i==int(v.size())-1?suc:2);
}

string readString(){
	string s;
	cin>>s;
	return s;
}

template<class T>
T sq(const T& t){
	return t*t;
}

//#define CAPITAL
void yes(bool ex=true){
	#ifdef CAPITAL
	cout<<"YES"<<"\n";
	#else
	cout<<"Yes"<<"\n";
	#endif
	if(ex)exit(0);
}
void no(bool ex=true){
	#ifdef CAPITAL
	cout<<"NO"<<"\n";
	#else
	cout<<"No"<<"\n";
	#endif
	if(ex)exit(0);
}
void possible(bool ex=true){
	#ifdef CAPITAL
	cout<<"POSSIBLE"<<"\n";
	#else
	cout<<"Possible"<<"\n";
	#endif
	if(ex)exit(0);
}
void impossible(bool ex=true){
	#ifdef CAPITAL
	cout<<"IMPOSSIBLE"<<"\n";
	#else
	cout<<"Impossible"<<"\n";
	#endif
	if(ex)exit(0);
}

constexpr ll ten(int n){
	return n==0?1:ten(n-1)*10;
}

const ll infLL=LLONG_MAX/3;

#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif

int topbit(signed t){
	return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
	return t==0?-1:63-__builtin_clzll(t);
}
int botbit(signed a){
	return a==0?32:__builtin_ctz(a);
}
int botbit(ll a){
	return a==0?64:__builtin_ctzll(a);
}
int popcount(signed t){
	return __builtin_popcount(t);
}
int popcount(ll t){
	return __builtin_popcountll(t);
}
bool ispow2(int i){
	return i&&(i&-i)==i;
}
ll mask(int i){
	return (ll(1)<<i)-1;
}

bool inc(int a,int b,int c){
	return a<=b&&b<=c;
}

template<class t> void mkuni(vc<t>&v){
	sort(all(v));
	v.erase(unique(all(v)),v.ed);
}

ll rand_int(ll l, ll r) { //[l, r]
	#ifdef LOCAL
	static mt19937_64 gen;
	#else
	static mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count());
	#endif
	return uniform_int_distribution<ll>(l, r)(gen);
}

template<class t>
void myshuffle(vc<t>&a){
	rep(i,si(a))swap(a[i],a[rand_int(0,i)]);
}

template<class t>
int lwb(const vc<t>&v,const t&a){
	return lower_bound(all(v),a)-v.bg;
}

//VERIFY: yosupo
//KUPC2017J
//AOJDSL1A
//without rank
struct unionfind{
	vi p,s;
	int c;
	unionfind(int n=0):p(n,-1),s(n,1),c(n){}
	int find(int a){
		return p[a]==-1?a:(p[a]=find(p[a]));
	}
	//set b to a child of a
	bool unite(int a,int b){
		a=find(a);
		b=find(b);
		if(a==b)return false;
		p[b]=a;
		s[a]+=s[b];
		c--;
		return true;
	}
	bool same(int a,int b){
		return find(a)==find(b);
	}
	int sz(int a){
		return s[find(a)];
	}
};

//AOJGRL4B
template<class t>
vi toposort(vvc<t> g){
	int n=g.size();
	vi a(n);
	rep(i,n)for(auto e:g[i])
		a[e]++;
	queue<int> q;
	rep(i,n)if(a[i]==0)
		q.push(i);
	vi res;
	rep(i,n){
		if(q.empty())return {};
		int v=q.front();q.pop();
		res.pb(v);
		for(auto e:g[v])
			if(--a[e]==0)
				q.push(e);
	}
	return res;
}

//内部でグラフをいじるから in,out を使うときは注意
//VERIFY: yosupo
//CF530F
//CodeChef Persistent Oak
//AOJ GRL5C
template<class E>
struct HLD{
	vvc<E> g;
	int n,rt,cnt;
	vi sub,in,out,par,head,dep;
	int dfs1(int v,int p,int d){
		par[v]=p;
		dep[v]=d;
		g[v].erase(remove(all(g[v]),p),g[v].ed);
		for(auto&e:g[v]){
			sub[v]+=dfs1(e,v,d+1);
			if(sub[g[v][0]]<sub[e])
				swap(g[v][0],e);
		}
		return sub[v];
	}
	void dfs2(int v,int h){
		in[v]=cnt++;
		head[v]=h;
		for(int to:g[v])
			dfs2(to,to==g[v][0]?h:to);
		out[v]=cnt;
	}
	HLD(){}
	HLD(const vvc<E>&gg,int rr):g(gg),n(g.size()),rt(rr),cnt(0),
		sub(n,1),in(n),out(n),par(n,-1),head(n),dep(n){
		dfs1(rt,-1,0);
		dfs2(rt,rt);
	}
	int lca(int a,int b){
		while(head[a]!=head[b]){
			if(dep[head[a]]>dep[head[b]])
				swap(a,b);
			b=par[head[b]];
		}
		if(dep[a]>dep[b])
			swap(a,b);
		return a;
	}
	int len(int a,int b){
		return dep[a]+dep[b]-dep[lca(a,b)]*2;
	}
	bool asde(int a,int b){
		return in[a]<=in[b]&&out[b]<=out[a];
	}
	unionfind uf;
	vi has,dif;
	int k;
	vc<pi> buf;
	int ac(int v){
		return uf.find(v*2)/2;
	}
	vi memo;
	int dfs(int v){
		for(auto to:g[v]){
			memo[to]=dfs(to);
		}
		buf[ac(v)]=pi(0,k);
		for(auto to:g[v]){
			buf[ac(to)]=pi(0,k);
		}
		//if(v==0)dmp(0);
		for(auto to:g[v]){
			int w=memo[to];
			if(w==inf)return inf;
			int i=uf.find(to*2);
			int t=i%2;
			i/=2;
			if(!has[i])continue;
			if(t==0){
				chmax(buf[i].a,w+1);
			}else{
				chmin(buf[i].b,k-w-1);
			}
			/*if(v==0){
				dmp(to);
				dmp(w);
				dmp(buf[ac(1)]);
			}*/
			if(buf[i].b<buf[i].a)return inf;
		}
		rep(waf,2){
			int vac=uf.find(v*2);
			int vt=vac%2;
			vac/=2;
			int lw,up;tie(lw,up)=buf[vac];
			if(vt){
				tie(lw,up)=pi(k-up,k-lw);
			}
			for(auto to:g[v]){
				int i=uf.find(to*2);
				int t=i%2;
				i/=2;
				if(!has[i])continue;
				dif[to]=t;
				if(i==vac){
					dif[to]^=vt;
					continue;
				}
				int l,r;tie(l,r)=buf[i];
				if((k-r<l)^waf){
					tie(l,r)=pi(k-r,k-l);
					dif[to]^=1;
				}
				chmax(lw,l);
				chmin(up,r);
			}
			if(lw<=up){
				dmp2(v,lw,up);
				return lw;
			}
		}
		return inf;
	}
	void geth(int v,int p,int t,vvc<int>&h){
		if(has[ac(v)]){
			if(t==0){
				h[v].pb(p);
			}else{
				h[p].pb(v);
			}
		}
		for(auto to:g[v]){
			geth(to,v,t^dif[to],h);
		}
	}
	void slv(int m){
		uf=unionfind(n*2);
		auto unitesub=[&](int v,int p){
			while(1){
				v=ac(v);
				if(dep[v]-dep[p]>=2){
					rep(t,2){
						uf.unite(par[v]*2+t,v*2+t);
						v=par[v];
					}
				}else
					break;
			}
		};
		vi ls;
		vc<pi> es;
		rep(_,m){
			int a,b;cin>>a>>b;
			a--;b--;
			int c=lca(a,b);
			unitesub(a,c);
			unitesub(b,c);
			if(a!=c&&b!=c){
				//uf.unite(a*2,b*2+1);
				//uf.unite(a*2+1,b*2);
				es.eb(a,b);
			}
			if(a!=c)ls.pb(a);
			else ls.pb(b);
		}
		for(auto e:es){
			rep(t,2){
				uf.unite(e.a*2+t,e.b*2+1-t);
			}
		}
		has.resize(n);
		for(auto i:ls)
			has[ac(i)]=1;
		rep(i,n)if(uf.same(i*2,i*2+1)){
			print(-1);
			return;
		}
		dif.resize(n);
		buf.resize(n);
		memo.resize(n);

		/*{
			k=1;
			dfs(0);
			exit(0);
		}*/

		int lw=-1,up=n-1;
		while(up-lw>1){
			const int mid=(lw+up)/2;
			k=mid;
			if(dfs(0)<inf)
				up=mid;
			else
				lw=mid;
		}
		k=up;
		dmp(k);
		int tmp=dfs(0);
		dmp2(k,tmp);
		assert(tmp<inf);

		vvc<int> h(n);
		geth(0,-1,0,h);

		vi ans(n);

		vi ord=toposort(h);
		for(auto i:ord){
			for(auto j:h[i])
				chmax(ans[j],ans[i]+1);
		}

		for(auto&v:ans)v++;
		print(k+1);
		print(ans);
	}
};

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);

	int n,m;cin>>n>>m;
	vvc<int> t(n);
	rep(_,n-1){
		int a,b;cin>>a>>b;
		a--;b--;
		t[a].pb(b);
		t[b].pb(a);
	}

	HLD<int> hld(t,0);
	hld.slv(m);
}

#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define SZ(x) ((int)x.size())
#define ALL(x) x.begin(),x.end()
#define L(i,u) for (register int i=head[u]; i; i=nxt[i])
#define rep(i,a,b) for (register int i=(a); i<=(b); i++)
#define per(i,a,b) for (register int i=(a); i>=(b); i--)
using namespace std;
typedef long double ld;
typedef long long ll;
typedef unsigned int ui;
typedef pair<int,int> Pii;
typedef vector<int> Vi;
template<class T> inline void read(T &x){
	x=0; char c=getchar(); int f=1;
	while (!isdigit(c)) {if (c=='-') f=-1; c=getchar();}
	while (isdigit(c)) {x=x*10+c-'0'; c=getchar();} x*=f;
}
template<class T> T gcd(T a, T b){return !b?a:gcd(b,a%b);}
template<class T> inline void umin(T &x, T y){x=x<y?x:y;}
template<class T> inline void umax(T &x, T y){x=x>y?x:y;}
inline ui R() {
	static ui seed=416;
	return seed^=seed>>5,seed^=seed<<17,seed^=seed>>13;
}
const int N = 500500;
int n,m,fa[N][20],dep[N],bj[N];Vi e[N];
void GG(){puts("-1");exit(0);}
void dfs1(int u, int Fa, int Dep){
	fa[u][0]=Fa;dep[u]=Dep;
	for(int v:e[u])if(v!=Fa)dfs1(v,u,Dep+1);
}
int kthfa(int u, int del){per(i,19,0)if(del>>i&1)u=fa[u][i];return u;}
int getlca(int u, int v){
	if(dep[u]<dep[v])swap(u,v);int del=dep[u]-dep[v];
	per(i,19,0)if(del>>i&1)u=fa[u][i];
	if(u==v)return u;
	per(i,19,0)if(fa[u][i]!=fa[v][i])u=fa[u][i],v=fa[v][i];
	return fa[u][0];
}
vector<Pii>cons[N];int dfn[N],num,col[N];Vi d;vector<Vi>f[N];
void getcol(int u, int c, int tar){
	col[u]=c;d.pb(u);
	for(auto x:cons[u])if(dfn[x.fi]==tar)
		if(col[x.fi]==-1)getcol(x.fi,c^x.se,tar);
		else if(col[x.fi]!=(col[u]^x.se))GG();
}
void dfs2(int u, int Fa){
	for(int v:e[u])if(v!=Fa)dfs2(v,u),bj[u]+=bj[v];
	if(bj[u])cons[u].pb(mp(Fa,0)),cons[Fa].pb(mp(u,0));
	Vi dot;dfn[u]=u,dot.pb(u);
	for(int v:e[u])if(v!=Fa)dfn[v]=u,dot.pb(v);
	for(int x:dot)col[x]=-1;
	for(int x:dot)if(col[x]==-1){
		d.clear();getcol(x,0,u);f[u].pb(d);
	}
}
int mid;bool gg;int dp[N],ans[N];
void upd(Pii &s, Pii a){s=mp(max(s.fi,a.fi),min(s.se,a.se));}
void dfs(int u, int Fa){
	if(gg)return;
	for(int v:e[u])if(v!=Fa)dfs(v,u);
	Pii jiao(0,mid-(Fa>0)),sub(mid/2+1,mid/2);
	for(int x:f[u][0])if(x!=u){
		if(col[x]==0)umax(jiao.fi,dp[x]);else umin(jiao.se,mid-dp[x]-1);
	}
	for(auto a:f[u])if(a[0]!=f[u][0][0]){
		int l=0,r=0;
		for(int x:a)if(col[x]==0)umax(l,dp[x]);else umax(r,dp[x]);
		if(l>r)swap(l,r);
		upd(jiao,mp(l,mid-1-l));
		if(mid-r<=r-1){
			if(sub.fi<=sub.se)umax(sub.se,r-1),umin(sub.fi,mid-r);
			else sub=mp(mid-r,r-1);
		}
	}
	dp[u]=-1;
	if(jiao.fi<=jiao.se){
		if(sub.fi>sub.se||sub.fi>jiao.fi||sub.se<jiao.fi)dp[u]=jiao.fi;
		else if(sub.se+1<=jiao.se)dp[u]=sub.se+1;
	}
	if(dp[u]==-1)gg=1;dp[u]++;
//	if(mid==2)printf("%d-->%d\n",u,dp[u]);
}

int dir[N];
void dfs3(int u, int Fa, bool rev){
//	for(auto a:f[u]){for(int x:a)printf("%d ",x);printf("  :%d\n",u);}

	for(int x:f[u][0])if(x!=u){
		dir[x]=col[x];//if(col[x]==0)dir[x]=1;
	}
	for(auto a:f[u])if(a[0]!=f[u][0][0]){
		int l=0,r=0;
		for(int x:a)if(col[x]==0)umax(l,dp[x]);else umax(r,dp[x]);
		bool flag=0;if(dp[u]-1>=l&&dp[u]-1<=mid-1-r)flag=0;else flag=1;
		for(int x:a)dir[x]=col[x]^flag;
	}
	for(int x:e[u])if(x!=Fa)dir[x]^=rev;
//	printf("dp %d %d\n",u,dp[u]);
//	for(int x:e[u])if(x!=Fa)printf("dir %d = %d\n",x,dir[x]);
	for(int x:e[u])if(x!=Fa&&dir[x]==0)dfs3(x,u,0),umax(ans[u],ans[x]);
	ans[u]++;
	for(int x:e[u])if(x!=Fa&&dir[x]==1)umax(ans[x],ans[u]),dfs3(x,u,1);
}
int main() {
	read(n);read(m);
	rep(i,1,n-1){
		int u,v;read(u);read(v);e[u].pb(v);e[v].pb(u);
	}
	dfs1(1,0,0);
	rep(j,1,19)rep(i,1,n)fa[i][j]=fa[fa[i][j-1]][j-1];
	rep(i,1,m){
		int u,v;read(u);read(v);int l=getlca(u,v),x=0,y=0;
		if(dep[u]>dep[l])bj[u]++,bj[x=kthfa(u,dep[u]-dep[l]-1)]--;
		if(dep[v]>dep[l])bj[v]++,bj[y=kthfa(v,dep[v]-dep[l]-1)]--;
		if(dep[u]>dep[l]&&dep[v]>dep[l]){
			cons[x].pb(mp(y,1));cons[y].pb(mp(x,1));
		}
	}
	dfs2(1,0);
//	rep(i,1,n)printf("%d ",col[i]);puts("");
	int L=1,R=n;
	while(L<R){
		mid=(L+R)>>1;
		gg=0;dfs(1,0);
		if(gg)L=mid+1;else R=mid;
	}
	mid=L;dfs(1,0);dfs3(1,0,0);
	printf("%d\n",L);
	rep(i,1,n)printf("%d ",ans[i]);
	return 0;
}

#include <bits/stdc++.h>
#define meow(args...) fprintf(stderr, args)
typedef unsigned u32;
typedef long long s64;
typedef unsigned long long u64;
template<class T1, class T2> inline bool cmin(T1 &a, const T2 &b) {return b<a?(a=b, true):false;}
template<class T1, class T2> inline bool cmax(T1 &a, const T2 &b) {return a<b?(a=b, true):false;}
template<class Type> Type read() {
	Type a;
	bool b;
	unsigned char c;
	while(c=getchar()-48, (c>9)&(c!=253));
	for(a=(b=c==253)?0:c; (c=getchar()-48)<=9; a=a*10+c);
	return b?-a:a;
}
int (*rd)()=read<int>;
//const u32 P=;
//inline u32 &inc(u32 &a, u32 b) {return (a+=b)<P?a:(a-=P);}
//inline u32 &dec(u32 &a, u32 b) {return (a-=b)&0x80000000?(a+=P):a;}
//inline u32 sum(u32 a, u32 b) {return (a+=b)<P?a:a-P;}
//inline u32 dif(u32 a, u32 b) {return (a-=b)&0x80000000?a+P:a;}
//u64 power(u64 a, int b) {
//	u64 ans=1;
//	for(; b; a=a*a%P, b/=2) if(b&1) ans=ans*a%P;
//	return ans;
//}

const int N=5e5+1;
int n, m, to[2*N], head[N], next[2*N], pa[N], dep[N], size[N], prefer[N], top[N], mindep[N], ori[N], k, fl[N], fr[N], solution[N];
bool res;
void dfs1(int u) {
	dep[u]=dep[pa[u]]+1;
	size[u]=1;
	for(int i=head[u], mx=0; i; i=next[i]) {
		if(to[i]!=pa[u]) {
			pa[to[i]]=u;
			dfs1(to[i]);
			size[u]+=size[to[i]];
			if(cmax(mx, size[to[i]])) prefer[u]=to[i];
		}
	}
}
void dfs2(int u) {
	for(int i=head[u]; i; i=next[i]) {
		int v=to[i];
		if(v!=pa[u]) {
			top[v]=prefer[u]==v?top[u]:v;
			dfs2(v);
		}
	}
}
int lca(int u, int v) {
	while(top[u]!=top[v]) {
		if(dep[top[u]]>dep[top[v]])
			u=pa[top[u]];
		else
			v=pa[top[v]];
	}
	return dep[u]<dep[v]?u:v;
}

namespace DSU {
	int pa[N], w[N];
	void find(int u) {
		int v=pa[u];
		if(u!=v) {
			find(v);
			pa[u]=pa[v];
			w[u]^=w[v];
		}
	}
	void merge(int u, int v, int c) {
		find(u), find(v);
		c^=w[u]^w[v];
		u=pa[u], v=pa[v];
		if(u==v&&c) {
			puts("-1");
			exit(0);
		}
		pa[u]=v, w[u]=c;
	}
};

void dfs3(int u) {
	for(int i=head[u]; i; i=next[i]) {
		if(to[i]!=pa[u]) {
			cmin(mindep[u], mindep[to[i]]);
			dfs3(to[i]);
			if(mindep[to[i]]<dep[u])
				DSU::merge(u, to[i], 0);
		}
	}
	if(mindep[u]==dep[u]) ori[u]=-1;
}
void dfs4(int u) {
	fl[u]=1;
	fr[u]=k;
	for(int i=head[u]; i; i=next[i]) {
		if(to[i]!=pa[u]) {
			dfs4(to[i]);
			if(ori[to[i]]==0) cmax(fl[u], fl[to[i]]+1);
			if(ori[to[i]]==1) cmin(fr[u], k-fl[to[i]]);
		}
	}
	res&=fl[u]<=fr[u];
}
void dfs5(int u, int l, int r, bool rev) {
	cmax(l, fl[u]);
	cmin(r, fr[u]);
	assert(l<=r);
	solution[u]=rev?k+1-l:l;
	for(int i=head[u]; i; i=next[i]) {
		if(to[i]!=pa[u]) {
			if(ori[to[i]]==0) dfs5(to[i], 1, l-1, rev);
			if(ori[to[i]]==1) dfs5(to[i], 1, k-l, !rev);
			if(ori[to[i]]==-1) dfs5(to[i], 1, k, rev);
		}
	}
}
int main() {
	n=rd();
	m=rd();
	for(int i=1, j=2; i<n; ++i) {
		int u=rd(), v=rd();
		to[j]=v;
		next[j]=head[u];
		head[u]=j++;
		to[j]=u;
		next[j]=head[v];
		head[v]=j++;
	}
	dfs1(1);
	top[1]=1;
	dfs2(1);
	for(int i=1; i<=n; ++i) DSU::pa[i]=i;
	for(int i=1; i<=n; ++i) mindep[i]=dep[i];
	for(int i=1; i<=m; ++i) {
		int a=rd(), b=rd(), c=lca(a, b);
		cmin(mindep[a], dep[c]);
		cmin(mindep[b], dep[c]);
		if(a!=c&&b!=c) DSU::merge(a, b, 1);
	}
	dfs3(1);
	for(int i=1; i<=n; ++i) {
		DSU::find(i);
		ori[i]|=DSU::w[i];
	}
	int l=0, r=n;
	while(l<r) {
		k=(l+r)/2;
		res=true;
		dfs4(1);
		if(res) r=k; else l=k+1;
	}
	printf("%d\n", k=l);
	dfs4(1);
	dfs5(1, 1, n, false);
	for(int i=1; i<=n; ++i) printf("%d%c", solution[i], " \n"[i==n]);
	return 0;
}

#include <bits/stdc++.h>
#define meow(args...) fprintf(stderr, args)
typedef unsigned u32;
typedef long long s64;
typedef unsigned long long u64;
template<class T1, class T2> inline bool cmin(T1 &a, const T2 &b) {return b<a?(a=b, true):false;}
template<class T1, class T2> inline bool cmax(T1 &a, const T2 &b) {return a<b?(a=b, true):false;}
template<class Type> Type read() {
	Type a;
	bool b;
	unsigned char c;
	while(c=getchar()-48, (c>9)&(c!=253));
	for(a=(b=c==253)?0:c; (c=getchar()-48)<=9; a=a*10+c);
	return b?-a:a;
}
int (*rd)()=read<int>;
//const u32 P=;
//inline u32 &inc(u32 &a, u32 b) {return (a+=b)<P?a:(a-=P);}
//inline u32 &dec(u32 &a, u32 b) {return (a-=b)&0x80000000?(a+=P):a;}
//inline u32 sum(u32 a, u32 b) {return (a+=b)<P?a:a-P;}
//inline u32 dif(u32 a, u32 b) {return (a-=b)&0x80000000?a+P:a;}
//u64 power(u64 a, int b) {
//	u64 ans=1;
//	for(; b; a=a*a%P, b/=2) if(b&1) ans=ans*a%P;
//	return ans;
//}

const int N=5e5+1;
int n, m, to[2*N], head[N], next[2*N], pa[N], dep[N], size[N], prefer[N], top[N], mindep[N], ori[N], k, fl[N], fr[N], solution[N];
bool res;
void dfs1(int u) {
	dep[u]=dep[pa[u]]+1;
	size[u]=1;
	for(int i=head[u], mx=0; i; i=next[i]) {
		if(to[i]!=pa[u]) {
			pa[to[i]]=u;
			dfs1(to[i]);
			size[u]+=size[to[i]];
			if(cmax(mx, size[to[i]])) prefer[u]=to[i];
		}
	}
}
void dfs2(int u) {
	for(int i=head[u]; i; i=next[i]) {
		int v=to[i];
		if(v!=pa[u]) {
			top[v]=prefer[u]==v?top[u]:v;
			dfs2(v);
		}
	}
}
int lca(int u, int v) {
	while(top[u]!=top[v]) {
		if(dep[top[u]]>dep[top[v]])
			u=pa[top[u]];
		else
			v=pa[top[v]];
	}
	return dep[u]<dep[v]?u:v;
}

namespace DSU {
	int pa[N], w[N];
	void find(int u) {
		int v=pa[u];
		if(u!=v) {
			find(v);
			pa[u]=pa[v];
			w[u]^=w[v];
		}
	}
	void merge(int u, int v, int c) {
		find(u), find(v);
		c^=w[u]^w[v];
		u=pa[u], v=pa[v];
		if(u==v&&c) {
			puts("-1");
			exit(0);
		}
		pa[u]=v, w[u]=c;
	}
};

void dfs3(int u) {
	for(int i=head[u]; i; i=next[i]) {
		if(to[i]!=pa[u]) {
			cmin(mindep[u], mindep[to[i]]);
			dfs3(to[i]);
			if(mindep[to[i]]<dep[u])
				DSU::merge(u, to[i], 0);
		}
	}
	if(mindep[u]==dep[u]) ori[u]=-1;
}
void dfs4(int u) {
	fl[u]=1;
	fr[u]=k;
	for(int i=head[u]; i; i=next[i]) {
		if(to[i]!=pa[u]) {
			dfs4(to[i]);
			if(ori[to[i]]==0) cmax(fl[u], fl[to[i]]+1);
			if(ori[to[i]]==1) cmin(fr[u], k-fl[to[i]]);
		}
	}
	res&=fl[u]<=fr[u];
}
void dfs5(int u, int l, int r, bool rev) {
	cmax(l, fl[u]);
	cmin(r, fr[u]);
	solution[u]=rev?k+1-l:l;
	for(int i=head[u]; i; i=next[i]) {
		if(to[i]!=pa[u]) {
			if(ori[to[i]]==0) dfs5(to[i], 1, l-1, false);
			if(ori[to[i]]==1) dfs5(to[i], 1, k-l, true);
			if(ori[to[i]]==-1) dfs5(to[i], 1, k, false);
		}
	}
}
int main() {
	n=rd();
	m=rd();
	for(int i=1, j=2; i<n; ++i) {
		int u=rd(), v=rd();
		to[j]=v;
		next[j]=head[u];
		head[u]=j++;
		to[j]=u;
		next[j]=head[v];
		head[v]=j++;
	}
	dfs1(1);
	top[1]=1;
	dfs2(1);
	for(int i=1; i<=n; ++i) DSU::pa[i]=i;
	for(int i=1; i<=n; ++i) mindep[i]=dep[i];
	for(int i=1; i<=m; ++i) {
		int a=rd(), b=rd(), c=lca(a, b);
		cmin(mindep[a], dep[c]);
		cmin(mindep[b], dep[c]);
		if(a!=c&&b!=c) DSU::merge(a, b, 1);
	}
	dfs3(1);
	for(int i=1; i<=n; ++i) {
		DSU::find(i);
		ori[i]|=DSU::w[i];
	}
	int l=0, r=n;
	while(l<r) {
		k=(l+r)/2;
		res=true;
		dfs4(1);
		if(res) r=k; else l=k+1;
	}
	printf("%d\n", k=l);
	dfs5(1, 1, n, false);
	for(int i=1; i<=n; ++i) printf("%d%c", solution[i], " \n"[i==n]);
	return 0;
}

#include <bits/stdc++.h>
#define meow(args...) fprintf(stderr, args)
typedef unsigned u32;
typedef long long s64;
typedef unsigned long long u64;
template<class T1, class T2> inline bool cmin(T1 &a, const T2 &b) {return b<a?(a=b, true):false;}
template<class T1, class T2> inline bool cmax(T1 &a, const T2 &b) {return a<b?(a=b, true):false;}
template<class Type> Type read() {
	Type a;
	bool b;
	unsigned char c;
	while(c=getchar()-48, (c>9)&(c!=253));
	for(a=(b=c==253)?0:c; (c=getchar()-48)<=9; a=a*10+c);
	return b?-a:a;
}
int (*rd)()=read<int>;
//const u32 P=;
//inline u32 &inc(u32 &a, u32 b) {return (a+=b)<P?a:(a-=P);}
//inline u32 &dec(u32 &a, u32 b) {return (a-=b)&0x80000000?(a+=P):a;}
//inline u32 sum(u32 a, u32 b) {return (a+=b)<P?a:a-P;}
//inline u32 dif(u32 a, u32 b) {return (a-=b)&0x80000000?a+P:a;}
//u64 power(u64 a, int b) {
//	u64 ans=1;
//	for(; b; a=a*a%P, b/=2) if(b&1) ans=ans*a%P;
//	return ans;
//}

const int N=5e5+1;
int n, m, to[2*N], head[N], next[2*N], pa[N], dep[N], size[N], prefer[N], top[N], mindep[N], ori[N], k, fl[N], fr[N], solution[N];
bool res;
void dfs1(int u) {
	dep[u]=dep[pa[u]]+1;
	size[u]=1;
	for(int i=head[u], mx=0; i; i=next[i]) {
		if(to[i]!=pa[u]) {
			pa[to[i]]=u;
			dfs1(to[i]);
			size[u]+=size[to[i]];
			if(cmax(mx, size[to[i]])) prefer[u]=to[i];
		}
	}
}
void dfs2(int u) {
	for(int i=head[u]; i; i=next[i]) {
		int v=to[i];
		if(v!=pa[u]) {
			top[v]=prefer[u]==v?top[u]:v;
			dfs2(v);
		}
	}
}
int lca(int u, int v) {
	while(top[u]!=top[v]) {
		if(dep[top[u]]>dep[top[v]])
			u=pa[top[u]];
		else
			v=pa[top[v]];
	}
	return dep[u]<dep[v]?u:v;
}

namespace DSU {
	int pa[N], w[N];
	void find(int u) {
		int v=pa[u];
		if(u!=v) {
			find(v);
			pa[u]=pa[v];
			w[u]^=w[v];
		}
	}
	void merge(int u, int v, int c) {
		find(u), find(v);
		c^=w[u]^w[v];
		u=pa[u], v=pa[v];
		if(u==v&&c) {
			puts("-1");
			exit(0);
		}
		pa[u]=v, w[u]=c;
	}
};

void dfs3(int u) {
	for(int i=head[u]; i; i=next[i]) {
		if(to[i]!=pa[u]) {
			cmin(mindep[u], mindep[to[i]]);
			dfs3(to[i]);
			if(mindep[to[i]]<dep[u])
				DSU::merge(u, to[i], 0);
		}
	}
	if(mindep[u]==dep[u]) ori[u]=-1;
}
void dfs4(int u) {
	fl[u]=1;
	fr[u]=k;
	for(int i=head[u]; i; i=next[i]) {
		if(to[i]!=pa[u]) {
			dfs4(to[i]);
			if(ori[to[i]]==0) cmax(fl[u], fl[to[i]]+1);
			if(ori[to[i]]==1) cmin(fr[u], fr[to[i]]-1);
		}
	}
	res&=fl[u]<=fr[u];
}
void dfs5(int u, int l, int r) {
	cmax(l, fl[u]);
	cmin(r, fr[u]);
	assert(l<=r);
	solution[u]=l;
	for(int i=head[u]; i; i=next[i]) {
		if(to[i]!=pa[u]) {
			if(ori[to[i]]==0) dfs5(to[i], 1, l-1);
			if(ori[to[i]]==1) dfs5(to[i], l+1, k);
			if(ori[to[i]]==-1) dfs5(to[i], 1, k);
		}
	}
}
int main() {
	n=rd();
	m=rd();
	for(int i=1, j=2; i<n; ++i) {
		int u=rd(), v=rd();
		to[j]=v;
		next[j]=head[u];
		head[u]=j++;
		to[j]=u;
		next[j]=head[v];
		head[v]=j++;
	}
	dfs1(1);
	top[1]=1;
	dfs2(1);
	for(int i=1; i<=n; ++i) DSU::pa[i]=i;
	for(int i=1; i<=n; ++i) mindep[i]=dep[i];
	for(int i=1; i<=m; ++i) {
		int a=rd(), b=rd(), c=lca(a, b);
		cmin(mindep[a], dep[c]);
		cmin(mindep[b], dep[c]);
		if(a!=c&&b!=c) DSU::merge(a, b, 1);
	}
	dfs3(1);
	for(int i=1; i<=n; ++i) {
		DSU::find(i);
		ori[i]|=DSU::w[i];
	}
	int l=0, r=n;
	while(l<r) {
		k=(l+r)/2;
		res=true;
		dfs4(1);
		if(res) r=k; else l=k+1;
	}
	printf("%d\n", k=l);
	dfs4(1);
	dfs5(1, 1, n);
	for(int i=1; i<=n; ++i) printf("%d%c", solution[i], " \n"[i==n]);
	return 0;
}

#include <bits/stdc++.h>
#define FR first
#define SE second

using namespace std;

typedef long long ll;
typedef pair<int,int> pr;

inline pr merge(pr x,pr y) {
  return pr(max(x.FR,y.FR),min(x.SE,y.SE));
}

vector <int> e[500005];
int fa[500005][20],dep[500005];

void dfs1(int x) {
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa[x][0]) {
    	int u=e[x][i];
    	fa[u][0]=x;dep[u]=dep[x]+1;
    	for(int j=1;j<20;j++) fa[u][j]=fa[fa[u][j-1]][j-1];
    	dfs1(u);
	}
}

int lca(int x,int y) {
  if (dep[x]<dep[y]) swap(x,y);
  int d=dep[x]-dep[y];
  for(int i=0;i<20;i++)
    if ((d>>i)&1) x=fa[x][i];
  if (x==y) return x;
  for(int i=19;i>=0;i--)
    if (fa[x][i]!=fa[y][i]) {
    	x=fa[x][i];
    	y=fa[y][i];
	}
  return fa[x][0];
}

int jump(int x,int d) {
  for(int i=0;i<20;i++)
    if ((d>>i)&1) x=fa[x][i];
  return x;
}

vector <pr> ee[500005];
int size[500005];

void dfs2(int x,int fa) {
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa) {
    	int u=e[x][i];
    	dfs2(u,x);
    	size[x]+=size[u];
	}
  if (size[x]) {
  	ee[x].push_back(pr(fa,0));
  	ee[fa].push_back(pr(x,0));
  }
}

int col[500005],id[500005];

void dfs3(int x) {
  for(int i=0;i<ee[x].size();i++) {
  	int u=ee[x][i].FR;
  	if (!id[u]) {
  		id[u]=id[x];
  		col[u]=col[x]^ee[x][i].SE;
  		dfs3(u);
	  }
	else if ((col[x]^col[u])!=ee[x][i].SE) {
		puts("-1");
		exit(0);
	}
  }
}

pr f[500005],g[500005];
int vis[500005];

bool dfs4(int x,int fa,int k) {
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa) {
    	int u=e[x][i];
    	if (!dfs4(u,x,k)) return 0;
	}
  f[x]=pr(1,k);
  int sz=0;
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa&&id[e[x][i]]) {
    	int u=e[x][i];
    	if (id[u]==id[x]) {
    		if (!col[u]) f[x]=merge(f[x],pr(1,f[u].SE-1));
    		else f[x]=merge(f[x],pr(f[u].FR+1,k));
		}
		else {
			if (!vis[id[u]]) {
				vis[id[u]]=++sz;
				g[sz]=pr(1,k);
			}
			int t=vis[id[u]];
			if (!col[u]) g[t]=merge(g[t],pr(1,f[u].SE-1));
			else g[t]=merge(g[t],pr(f[u].FR+1,k));
		}
	}
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa) vis[id[e[x][i]]]=0;
  if (f[x].FR>f[x].SE) return 0;
  pr u(1,k);
  for(int i=1;i<=sz;i++) {
  	if (g[i].FR>g[i].SE) return 0;
  	if (k-g[i].SE+1<g[i].FR) g[i]=pr(k-g[i].SE+1,k-g[i].FR+1);
  	u=merge(u,g[i]);
  }
  pr t1=merge(u,f[x]),t2=merge(pr(k-u.SE+1,k-u.FR+1),f[x]);
  if (t1.FR>t1.SE&&t2.FR>t2.SE) return 0;
  if (t1.FR>t1.SE) f[x]=t2;
  else if (t2.FR>t1.SE) f[x]=t1;
  else f[x]=pr(min(t1.FR,t2.FR),max(t1.SE,t2.SE));
  return 1;
}

int ans[500005],val[500005];
bool d[500005];

void dfs5(int x,int fa,int k,bool v) {
  int sz=0;
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa&&id[e[x][i]]!=id[x]) {
    	int u=e[x][i];
		if (!vis[id[u]]) {
			vis[id[u]]=++sz;
			val[sz]=id[u];
			g[sz]=pr(1,k);
		}
		int t=vis[id[u]];
		if (!col[u]) g[t]=merge(g[t],pr(1,f[u].SE-1));
		else g[t]=merge(g[t],pr(f[u].FR+1,k));
	}
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa) vis[id[e[x][i]]]=0;
  for(int i=1;i<=sz;i++) d[val[i]]=((g[i].FR<=ans[x]&&g[i].SE>=ans[x])?0:1);
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa) {
    	int u=e[x][i];
    	if (!id[u]) {
    		ans[u]=f[u].FR;
    		dfs5(u,x,k,0);
		}
		else {
			bool c=((id[u]==id[x])?v:d[id[u]]);
			if (!c) ans[u]=((!col[u])?f[u].SE:f[u].FR);
			else ans[u]=((col[u])?k-f[u].FR+1:k-f[u].SE+1);
			dfs5(u,x,k,c);
		}
	}
}

int main() {
  int n,m;
  scanf("%d%d",&n,&m);
  for(int i=1;i<n;i++) {
  	int x,y;
  	scanf("%d%d",&x,&y);
  	e[x].push_back(y);
  	e[y].push_back(x);
  }
  dfs1(1);
  for(int i=1;i<=m;i++) {
  	int x,y;
  	scanf("%d%d",&x,&y);
  	int p=lca(x,y),u,v;
  	if (p!=x) {
  		size[x]++;
  		size[u=jump(x,dep[x]-dep[p]-1)]--;
	  }
	if (p!=y) {
		size[y]++;
		size[v=jump(y,dep[y]-dep[p]-1)]--;
	}
	if (p!=x&&p!=y) {
		ee[u].push_back(pr(v,1));
		ee[v].push_back(pr(u,1));
	}
  }
  dfs2(1,0);
  int cnt=0;
  for(int i=2;i<=n;i++)
    if (!id[i]) {
    	id[i]=++cnt;
    	dfs3(i);
	}
  int l=1,r=n;
  while (l<r) {
  	int mid=((l+r)>>1);
    bool v=dfs4(1,0,mid);
    if (v) r=mid; else l=mid+1;
  }
  dfs4(1,0,l);
  ans[1]=f[1].FR;
  dfs5(1,0,l,0);
  printf("%d\n",l);
  for(int i=1;i<=n;i++) printf("%d ",ans[i]);
  printf("\n");
  return 0;
}
/*
3 1
1 2
1 3
2 3
*/

#include <bits/stdc++.h>
#define FR first
#define SE second

using namespace std;

typedef long long ll;
typedef pair<int,int> pr;

inline pr merge(pr x,pr y) {
  return pr(max(x.FR,y.FR),min(x.SE,y.SE));
}

vector <int> e[500005];
int fa[500005][20],dep[500005];

void dfs1(int x) {
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa[x][0]) {
    	int u=e[x][i];
    	fa[u][0]=x;dep[u]=dep[x]+1;
    	for(int j=1;j<20;j++) fa[u][j]=fa[fa[u][j-1]][j-1];
    	dfs1(u);
	}
}

int lca(int x,int y) {
  if (dep[x]<dep[y]) swap(x,y);
  int d=dep[x]-dep[y];
  for(int i=0;i<20;i++)
    if ((d>>i)&1) x=fa[x][i];
  if (x==y) return x;
  for(int i=19;i>=0;i--)
    if (fa[x][i]!=fa[y][i]) {
    	x=fa[x][i];
    	y=fa[y][i];
	}
  return fa[x][0];
}

int jump(int x,int d) {
  for(int i=0;i<20;i++)
    if ((d>>i)&1) x=fa[x][i];
  return x;
}

vector <pr> ee[500005];
int size[500005];

void dfs2(int x,int fa) {
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa) {
    	int u=e[x][i];
    	dfs2(u,x);
    	size[x]+=size[u];
	}
  if (size[x]) {
  	ee[x].push_back(pr(fa,0));
  	ee[fa].push_back(pr(x,0));
  }
}

int col[500005],id[500005];

void dfs3(int x) {
  for(int i=0;i<ee[x].size();i++) {
  	int u=ee[x][i].FR;
  	if (!id[u]) {
  		id[u]=id[x];
  		col[u]=col[x]^ee[x][i].SE;
  		dfs3(u);
	  }
	else if ((col[x]^col[u])!=ee[x][i].SE) {
		puts("-1");
		exit(0);
	}
  }
}

pr f[500005];

bool dfs4(int x,int fa,int k) {
  f[x]=pr(1,k);
  int r=k;
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa) {
    	int u=e[x][i];
    	if (!dfs4(u,x,k)) return 0;
    	if (!id[u]) continue;
		if (id[u]==id[x]) {
			if (!col[u]) f[x]=merge(f[x],pr(1,f[u].SE-1));
			else f[x]=merge(f[x],pr(f[u].FR+1,k));
		}
		else {
			int len=((!col[u])?f[u].SE-1:k-f[u].FR);
			if (len*2<k) r=min(r,len);
		}
	}
  if (f[x].FR>f[x].SE||!r) return 0;
  if (r<k) {
  	if (f[x].FR>r&&f[x].SE<=k-r) return 0;
  	if (f[x].FR>r) f[x].FR=k-r+1;
  	if (f[x].SE<=k-r) f[x].SE=r;
  }
  return 1;
}

int ans[500005];

void dfs5(int x,int fa,int k,bool v) {
  for(int i=0;i<e[x].size();i++)
    if (e[x][i]!=fa) {
    	int u=e[x][i];
    	if (!id[u]) {
    		ans[u]=f[u].FR;
			dfs5(u,x,k,0);
		}
		else if (id[u]==id[x]) {
			if (!v) ans[u]=((!col[u])?f[u].SE:f[u].FR);
			else ans[u]=((col[u])?k-f[u].FR+1:k-f[u].SE+1);
			dfs5(u,x,k,v);
		}
		else {
			if (!col[u]) {
				if (f[u].SE>ans[x]) {
					ans[u]=f[u].SE;
					dfs5(u,x,k,0);
				}
				else {
					ans[u]=k-f[u].FR+1;
					dfs5(u,x,k,1);
				}
			}
			else {
				if (f[u].FR<ans[x]) {
					ans[u]=f[u].FR;
					dfs5(u,x,k,0);
				}
				else {
					ans[u]=k-f[u].SE+1;
					dfs5(u,x,k,1);
				}
			}
		}
	}
}

int main() {
  int n,m;
  scanf("%d%d",&n,&m);
  for(int i=1;i<n;i++) {
  	int x,y;
  	scanf("%d%d",&x,&y);
  	e[x].push_back(y);
  	e[y].push_back(x);
  }
  dfs1(1);
  for(int i=1;i<=m;i++) {
  	int x,y;
  	scanf("%d%d",&x,&y);
  	int p=lca(x,y),u,v;
  	if (p!=x) {
  		size[x]++;
  		size[u=jump(x,dep[x]-dep[p]-1)]--;
	  }
	if (p!=y) {
		size[y]++;
		size[v=jump(y,dep[y]-dep[p]-1)]--;
	}
	if (p!=x&&p!=y) {
		ee[u].push_back(pr(v,1));
		ee[v].push_back(pr(u,1));
	}
  }
  dfs2(1,0);
  int cnt=0;
  for(int i=2;i<=n;i++)
    if (!id[i]) {
    	id[i]=++cnt;
    	dfs3(i);
	}
  int l=1,r=n;
  while (l<r) {
  	int mid=((l+r)>>1);
    bool v=dfs4(1,0,mid);
    if (v) r=mid; else l=mid+1;
  }
  dfs4(1,0,l);
  ans[1]=f[1].FR;
  dfs5(1,0,l,0);
  printf("%d\n",l);
  for(int i=1;i<=n;i++) printf("%d ",ans[i]);
  printf("\n");
  return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5+5;
typedef pair<int,int> pi;
vector<int> g[N],id[N];
int n,m;
struct UST{
	vector<int> fa,c;
	inline void init(int n){
		fa.resize(n+1);
		c.resize(n+1);
		for(int i=0;i<=n;i++)fa[i] = i;
	}
	inline int find(int x){
		if(fa[x]==x)return x;
		else{
			find(fa[x]); c[x] ^= c[fa[x]]; fa[x] = fa[fa[x]];
			return fa[x];
		}
	}
	inline void mrg(int x,int y){
		// cout << x << " " << y << "::::";
		find(x),find(y);
		if(fa[x]^fa[y]){
			// cout << fa[x] << " " << fa[y] << endl;
			c[fa[x]]=1^c[x]^c[y];
			fa[fa[x]]=fa[y];
		}else if(c[x]==c[y]){puts("-1");exit(0);/*no solution.*/}

		// for(int i=0;i<2;i++)cout << fa[i] << " " << c[i] << " | ";puts("");
	}
}us[N];

int p[N];//to calc merge
int p2[N];//to calc ifedge
int dep[N],anc[N][20];

inline void adde(int u,int v){g[u].push_back(v);id[u].push_back(-1);}
inline void dfs(int x,int pre){
	anc[x][0]=pre;dep[x] = dep[pre]+1;
	for(int i=1;i<=19;i++)anc[x][i]=anc[anc[x][i-1]][i-1];
	us[x].init(g[x].size());
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v==pre)continue;
		dfs(v,x);
	}
}
vector<pi> opts[N];
inline void perform(int x,int y){
	if(x==y)return;
	if(dep[x]<dep[y])swap(x,y);
	int _x=x;
	p2[x]++,p2[y]++;
	for(int i=19;~i;i--)if(dep[anc[x][i]]>=dep[y])x=anc[x][i];
	if(x!=y){
		p[_x]++,p[y]++;
		for(int i=19;~i;i--){
			if(anc[x][i]!=anc[y][i])x=anc[x][i],y=anc[y][i];
		}p[x]--,p[y]--;
		opts[anc[x][0]].push_back(pi(x,y));
		p2[anc[x][0]]-=2;
	}else{
		x=_x;p[x]++;for(int i=19;~i;i--)if(dep[anc[x][i]]>dep[y])x=anc[x][i];p[x]--;
		p2[y]-=2;
	}
}
int K;
bool FLAG;
int f[N],temp_id[N];
inline void pref(int x,int pre){
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v==pre)continue;
		pref(v,x);p[x]+=p[v];p2[x]+=p2[v];
	}
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];
		if(v==pre&&p2[x])id[x][i]=i;
		else if(p2[v])id[x][i]=i;
	}
	for(size_t i=0;i<g[x].size();i++){int v=g[x][i];temp_id[v]=id[x][i];}
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v!=pre&&p[v]){
			// cout << x << ":" << v << " " << pre << endl;
			us[x].mrg(temp_id[v],temp_id[pre]);
		}
	}
	for(size_t i=0;i<opts[x].size();i++){
		int a=opts[x][i].first,b=opts[x][i].second;
		// cout << x << ":"<< opts[x][i].first << " " << opts[x][i].second << endl;
		us[x].mrg(temp_id[a],temp_id[b]);
	}
	for(size_t i=0;i<g[x].size();i++){
		if(id[x][i]!=-1){
			// cout << us[x].fa[id[x][i]] << "," << us[x].c[id[x][i]] << "|";
			us[x].find(id[x][i]);
			// cout << us[x].fa[id[x][i]] << "," << us[x].c[id[x][i]] << "|";
		}
	}
	// puts("");
}/* to make the union set */
int dir[N];
int h[2][N];
inline void Dp(int x,int pre){
	// cout << x << " " << pre << endl;
	f[x]=1;
	// vector<int> h[2]={vector<int>(g[x].size(),0),vector<int>(g[x].size(),0)};
	for(size_t i=0;i<g[x].size();i++)h[0][i]=h[1][i]=0;
	int qwq[2]={0,0};
	int idd=-1,cidd=0;
	for(size_t i=0;i<g[x].size();i++){
		if(g[x][i]==pre){
			if(id[x][i]!=-1)idd=us[x].fa[id[x][i]],cidd=us[x].c[id[x][i]];
		}
	}
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v==pre)continue;
		Dp(v,x);
		if(id[x][i]!=-1){
			// cout << x << " " << v << "!!" << endl;
			if(us[x].fa[id[x][i]]==idd){
				dir[v]=(us[x].c[id[x][i]]==cidd);
				// cout << id[x][i] << " " << us[x].c[id[x][i]] << " " << cidd << endl;
				// cout << dir[v] << endl;
				//1 : x is source 0 : x is towards (when direction to fa is x to fa)
				if(us[x].c[id[x][i]]!=cidd)qwq[0]=max(qwq[0],f[v]);
				else qwq[1]=max(qwq[1],f[v]);
			}
			else{
				h[us[x].c[id[x][i]]][us[x].fa[id[x][i]]]=max(h[us[x].c[id[x][i]]][us[x].fa[id[x][i]]],f[v]);
			}
		}
	}
	// cout << " consider " << x << " " << pre << ":: " << qwq[0] << " " << qwq[1] << endl;
	int qaq[2]={0,0};
	for(size_t i=0;i<g[x].size();i++){
		// cout << h[0][i] << " " << h[1][i] << endl;
		int a=min(h[0][i],h[1][i]), b=max(h[0][i],h[1][i]);
		qaq[0]=max(qaq[0],a), qaq[1]=max(qaq[1],b);
	}
	int type=0;
	if(max(qaq[0],qwq[0])+max(qwq[1],qaq[1])<K){
		f[x]=max(qaq[0],qwq[0])+1;
	}
	else{
		type=1;
		if(max(qaq[1],qwq[0])+max(qwq[1],qaq[0])<K)f[x]=max(qaq[1],qwq[0])+1;
		else FLAG=0,f[x]=1;
	}
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v==pre)continue;
		if(id[x][i]!=-1){
			if(us[x].fa[id[x][i]]==idd)continue;
			int idx = us[x].fa[id[x][i]], c = us[x].c[id[x][i]];
			int cc = c^(h[0][idx]>h[1][idx])^type;
			dir[v]=cc;
		}
	}
	// cout << x << ":::" << f[x] << endl;
	// cout << "ret" << endl;
}

inline bool check(int k){
	// cout << "check" << ":" << k << endl;
	K=k,FLAG=1;
	Dp(1,0);
	// cout << FLAG << endl;
	return FLAG;
}

bool t[N];

int ans[N];

inline void getans(int x,int pre){
	ans[x]=t[x]?K+1-f[x]:f[x];
	for(size_t i=0;i<g[x].size();i++){
		if(g[x][i]==pre)continue;
		t[g[x][i]]=t[x]^dir[g[x][i]];
		getans(g[x][i],x);
	}
}

int main()
{
	cin >> n >> m;
	for(int i=1;i<n;i++){
		int u,v;scanf("%d%d",&u,&v);
		adde(u,v),adde(v,u);
	}
	dfs(1,0);
	for(int i=1;i<=m;i++){
		int u,v;scanf("%d%d",&u,&v);
		perform(u,v);
	}
	// cout << "??" << endl;
	pref(1,0);
	// cout << "??" << endl;
	int l=1,r=n;
	while(l<r){
		int mid = (l+r)>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	cout << l << endl;
	check(l);
	getans(1,0);
	for(int i=1;i<=n;i++)printf("%d ",ans[i]);
	puts("");return 0;
}

/*
8 5
2 1
3 2
4 3
5 2
6 3
7 2
8 2
1 7
3 4
2 8
5 1
4 5
 */

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5+5;
typedef pair<int,int> pi;
vector<int> g[N],id[N];
int n,m;
struct UST{
	vector<int> fa,c;
	inline void init(int n){
		fa.resize(n+1);
		c.resize(n+1);
		for(int i=0;i<=n;i++)fa[i] = i;
	}
	inline int find(int x){
		if(fa[x]==x)return x;
		else{
			find(fa[x]); c[x] ^= c[fa[x]]; fa[x] = fa[fa[x]];
			return fa[x];
		}
	}
	inline void mrg(int x,int y){
		// cout << x << " " << y << "::::";
		find(x),find(y);
		if(fa[x]^fa[y]){
			// cout << fa[x] << " " << fa[y] << endl;
			c[fa[x]]=1^c[x]^c[y];
			fa[fa[x]]=fa[y];
		}else if(c[x]==c[y]){puts("-1");exit(0);/*no solution.*/}

		// for(int i=0;i<2;i++)cout << fa[i] << " " << c[i] << " | ";puts("");
	}
}us[N];

int p[N];//to calc merge
int p2[N];//to calc ifedge
int dep[N],anc[N][20];

inline void adde(int u,int v){g[u].push_back(v);id[u].push_back(-1);}
inline void dfs(int x,int pre){
	anc[x][0]=pre;dep[x] = dep[pre]+1;
	for(int i=1;i<=19;i++)anc[x][i]=anc[anc[x][i-1]][i-1];
	us[x].init(g[x].size());
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v==pre)continue;
		dfs(v,x);
	}
}
vector<pi> opts[N];
inline void perform(int x,int y){
	if(x==y)return;
	if(dep[x]<dep[y])swap(x,y);
	int _x=x;
	p2[x]++,p2[y]++;
	for(int i=19;~i;i--)if(dep[anc[x][i]]>=dep[y])x=anc[x][i];
	if(x!=y){
		p[_x]++,p[y]++;
		for(int i=19;~i;i--){
			if(anc[x][i]!=anc[y][i])x=anc[x][i],y=anc[y][i];
		}p[x]--,p[y]--;
		opts[anc[x][0]].push_back(pi(x,y));
		p2[anc[x][0]]-=2;
	}else{
		x=_x;p[x]++;for(int i=19;~i;i--)if(dep[anc[x][i]]>dep[y])x=anc[x][i];p[x]--;
		p2[y]-=2;
	}
}
int K;
bool FLAG;
int f[N],temp_id[N];
inline void pref(int x,int pre){
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v==pre)continue;
		pref(v,x);p[x]+=p[v];p2[x]+=p2[v];
	}
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];
		if(v==pre&&p2[x])id[x][i]=i;
		else if(p2[v])id[x][i]=i;
	}
	for(size_t i=0;i<g[x].size();i++){int v=g[x][i];temp_id[v]=id[x][i];}
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v!=pre&&p[v]){
			// cout << x << ":" << v << " " << pre << endl;
			us[x].mrg(temp_id[v],temp_id[pre]);
		}
	}
	for(size_t i=0;i<opts[x].size();i++){
		int a=opts[x][i].first,b=opts[x][i].second;
		// cout << x << ":"<< opts[x][i].first << " " << opts[x][i].second << endl;
		us[x].mrg(temp_id[a],temp_id[b]);
	}
	for(size_t i=0;i<g[x].size();i++){
		if(id[x][i]!=-1){
			// cout << us[x].fa[id[x][i]] << "," << us[x].c[id[x][i]] << "|";
			us[x].find(id[x][i]);
			// cout << us[x].fa[id[x][i]] << "," << us[x].c[id[x][i]] << "|";
		}
	}
	// puts("");
}/* to make the union set */
int dir[N];
int h[2][N];
inline void Dp(int x,int pre){
	// cout << x << " " << pre << endl;
	f[x]=1;
	// vector<int> h[2]={vector<int>(g[x].size(),0),vector<int>(g[x].size(),0)};
	for(int i=0;i<(int)g[x].size();i++)h[0][i]=h[1][i]=0;
	int qwq[2]={0,0};
	int idd=-1,cidd=0;
	for(size_t i=0;i<g[x].size();i++){
		if(g[x][i]==pre){
			if(id[x][i]!=-1)idd=us[x].fa[id[x][i]],cidd=us[x].c[id[x][i]];
		}
	}
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v==pre)continue;
		Dp(v,x);
		if(id[x][i]!=-1){
			// cout << x << " " << v << "!!" << endl;
			if(us[x].fa[id[x][i]]==idd){
				dir[v]=(us[x].c[id[x][i]]==cidd);
				// cout << id[x][i] << " " << us[x].c[id[x][i]] << " " << cidd << endl;
				// cout << dir[v] << endl;
				//1 : x is source 0 : x is towards (when direction to fa is x to fa)
				if(us[x].c[id[x][i]]!=cidd)qwq[0]=max(qwq[0],f[v]);
				else qwq[1]=max(qwq[1],f[v]);
			}
			else{
				h[us[x].c[id[x][i]]][us[x].fa[id[x][i]]]=max(h[us[x].c[id[x][i]]][us[x].fa[id[x][i]]],f[v]);
			}
		}
	}
	// cout << " consider " << x << " " << pre << ":: " << qwq[0] << " " << qwq[1] << endl;
	int qaq[2]={0,0};
	for(size_t i=0;i<g[x].size();i++){
		// cout << h[0][i] << " " << h[1][i] << endl;
		int a=min(h[0][i],h[1][i]), b=max(h[0][i],h[1][i]);
		qaq[0]=max(qaq[0],a);
		qaq[1]=max(qaq[1],b);
	}
	int type=0;
	if(max(qaq[0],qwq[0])+max(qwq[1],qaq[1])<K){
		f[x]=max(qaq[0],qwq[0])+1;
	}
	else{
		type=1;
		if(max(qaq[1],qwq[0])+max(qwq[1],qaq[0])<K)f[x]=max(qaq[1],qwq[0])+1;
		else FLAG=0,f[x]=1;
	}
	for(size_t i=0;i<g[x].size();i++){
		int v=g[x][i];if(v==pre)continue;
		if(id[x][i]!=-1){
			if(us[x].fa[id[x][i]]==idd)continue;
			int idx = us[x].fa[id[x][i]], c = us[x].c[id[x][i]];
			int cc = c^(h[0][idx]>h[1][idx])^type;
			dir[v]=cc;
		}
	}
	// cout << x << ":::" << f[x] << endl;
	// cout << "ret" << endl;
}

inline bool check(int k){
	// cout << "check" << ":" << k << endl;
	K=k,FLAG=1;
	Dp(1,0);
	// cout << FLAG << endl;
	return FLAG;
}

bool t[N];

int ans[N];

inline void getans(int x,int pre){
	ans[x]=t[x]?K+1-f[x]:f[x];
	for(size_t i=0;i<g[x].size();i++){
		if(g[x][i]==pre)continue;
		t[g[x][i]]=t[x]^dir[g[x][i]];
		getans(g[x][i],x);
	}
}

int main()
{
	cin >> n >> m;
	for(int i=1;i<n;i++){
		int u,v;scanf("%d%d",&u,&v);
		adde(u,v),adde(v,u);
	}
	dfs(1,0);
	for(int i=1;i<=m;i++){
		int u,v;scanf("%d%d",&u,&v);
		perform(u,v);
	}
	// cout << "??" << endl;
	pref(1,0);
	// cout << "??" << endl;
	int l=1,r=n;
	while(l<r){
		int mid = (l+r)>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	cout << l << endl;
	check(l);
	getans(1,0);
	for(int i=1;i<=n;i++)printf("%d ",ans[i]);
	puts("");return 0;
}

/*
8 5
2 1
3 2
4 3
5 2
6 3
7 2
8 2
1 7
3 4
2 8
5 1
4 5
 */

#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
#include <bitset>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

const int MAXN = 500000;
const int MAXBIT = 18;
const int MAXLINE = 500000;

int n, nline;
vector<int> adj[MAXN];
int lineend[MAXLINE][2];

int par[MAXN], dep[MAXN];
int up[MAXN][MAXBIT + 1];

void dfsinit(int at) {
	dep[at] = par[at] == -1 ? 0 : dep[par[at]] + 1;
	up[at][0] = par[at] == -1 ? at : par[at]; REP(k, MAXBIT) up[at][k + 1] = up[up[at][k]][k];
	REPSZ(i, adj[at]) {
		int to = adj[at][i]; if (to == par[at]) continue;
		par[to] = at; dfsinit(to);
	}
}
int calcup(int a, int steps) {
	for (int k = MAXBIT; k >= 0; --k) if (steps&(1 << k)) a = up[a][k];
	return a;
}
int calclca(int a, int b) {
	if (dep[a] < dep[b]) swap(a, b);
	a = calcup(a, dep[a] - dep[b]);
	if (a == b) return a;
	for (int k = MAXBIT; k >= 0; --k) if (up[a][k] != up[b][k]) a = up[a][k], b = up[b][k];
	return par[a];
}

int ufpar[MAXN], ufsz[MAXN], ufdiff[MAXN];

int uffind(int a) { if (ufpar[a] == a) return a; uffind(ufpar[a]); ufdiff[a] ^= ufdiff[ufpar[a]]; return ufpar[a] = ufpar[ufpar[a]]; }
bool ufunite(int a, int b, int diff) { uffind(a), uffind(b); diff ^= ufdiff[a], a = ufpar[a], diff ^= ufdiff[b], b = ufpar[b]; if (a == b) return diff == 0; if (ufsz[a] < ufsz[b]) swap(a, b); ufsz[a] += ufsz[b], ufpar[b] = a, ufdiff[b] ^= diff; return true; }

int unitedep[MAXN];
bool anyedge[MAXN];

void dfsunite(int at) {
	REPSZ(i, adj[at]) {
		int to = adj[at][i]; if (to == par[at]) continue;
		dfsunite(to);
		unitedep[at] = min(unitedep[at], unitedep[to]);
	}
}

int dp[MAXN];
int seenby[MAXN], mxzero[MAXN], mxone[MAXN];
int seenlst[MAXN], nseenlst;

bool dfscalc(int at, int lim) {
	if (par[at] == -1) REP(i, n) seenby[i] = -1;
	REPSZ(i, adj[at]) {
		int to = adj[at][i]; if (to == par[at]) continue;
		if (!dfscalc(to, lim)) return false;
	}
	nseenlst = 0;
	REPSZ(i, adj[at]) {
		int to = adj[at][i]; if (to == par[at]) continue;
		uffind(to);
		int id = ufpar[to];
		if (seenby[id] != at) seenlst[nseenlst++] = id, seenby[id] = at, mxzero[id] = mxone[id] = 0;
		if (ufdiff[to] == 0 && anyedge[to]) mxzero[id] = max(mxzero[id], dp[to]);
		if (ufdiff[to] == 1 && anyedge[to]) mxone[id] = max(mxone[id], dp[to]);
	}
	uffind(at); int me = ufpar[at];
	int lo = 1, loupto = lim, hi = lim, hidownto = 1;
	REP(i, nseenlst) {
		int id = seenlst[i];
		//printf("\tat=%d comp=%d mxzero=%d mxone=%d [me=%d mediff=%d]\n", at + 1, it->first, mxzero, mxone, me, ufdiff[at]);
		int a = mxzero[id], b = mxone[id];
		if (id == me) {
			if (ufdiff[at] == 1) swap(a, b);
			lo = max(lo, a + 1); hi = min(hi, lim - b);
		} else {
			// [mxzero+1..lim-mxone] or [mxone+1..lim-mxzero]
			if (a > b) swap(a, b); // [a+1..lim-b] or [b+1..lim-a]
			lo = max(lo, a + 1), hi = min(hi, lim - a);
			if (lim - b < b + 1) loupto = min(loupto, lim - b), hidownto = max(hidownto, b + 1);
		}
	}
	loupto = min(loupto, hi);
	hidownto = max(hidownto, lo);
	bool ret;
	if (lo <= loupto) { dp[at] = lo; ret = true; }
	else if (hidownto <= hi) { dp[at] = hidownto; ret = true; }
	else ret = false;
	//printf("lim=%d at=%d: %s (%d) [%d..%d and %d..%d]\n", lim, at + 1, ret ? "OK" : "ERR", dp[at], lo, loupto, hidownto, hi);
	return ret;
}

int ans;
int cost[MAXN];

void reconstruct(int at, bool rev) {
	cost[at] = !rev ? dp[at] : ans - dp[at] + 1;
	map<int, vector<int>> who;
	REPSZ(i, adj[at]) {
		int to = adj[at][i]; if (to == par[at]) continue;
		uffind(to); who[ufpar[to]].PB(to);
	}
	uffind(at); int me = ufpar[at];
	for (auto it = who.begin(); it != who.end(); ++it) {
		vector<int> cur = it->second;
		int mxzero = 0, mxone = 0;
		REPSZ(i, cur) {
			int to = cur[i];
			if (ufdiff[to] == 0 && anyedge[to]) mxzero = max(mxzero, dp[to]);
			if (ufdiff[to] == 1 && anyedge[to]) mxone = max(mxone, dp[to]);
		}
		int a = mxzero, b = mxone; bool swapped = false;
		if (it->first == me && ufdiff[at] == 1) swap(a, b), swapped = !swapped;
		if ((dp[at] <= a || dp[at] > ans - b) && it->first != me) swap(a, b), swapped = !swapped;
		assert(dp[at] > a && dp[at] <= ans - b);
		REPSZ(i, cur) {
			int to = cur[i];
			reconstruct(to, rev^swapped ^ (ufdiff[to] == 1));
		}
	}
}

bool solve() {
	par[0] = -1; dfsinit(0);
	REP(i, n) ufpar[i] = i, ufsz[i] = 1, ufdiff[i] = 0, unitedep[i] = dep[i], anyedge[i] = false;
	REP(i, nline) {
		int a = lineend[i][0], b = lineend[i][1]; if (dep[a] > dep[b]) swap(a, b);
		int c = calclca(a, b);
		if (c == a) {
			unitedep[b] = min(unitedep[b], dep[c]);
		} else {
			int aa = calcup(a, dep[a] - dep[c] - 1);
			int bb = calcup(b, dep[b] - dep[c] - 1);
			if (!ufunite(aa, bb, 1)) return false;
			unitedep[a] = min(unitedep[a], dep[c]);
			unitedep[b] = min(unitedep[b], dep[c]);
		}
	}
	dfsunite(0);
	REP(i, n) if (unitedep[i] < dep[i]) anyedge[i] = true;
	REP(i, n) if (unitedep[i] < dep[i] - 1) if (!ufunite(i, par[i], 0)) return false;
	//REP(i, n) if (par[i] != -1) { uffind(i); printf("%d-%d: %d,%d\n", i + 1, par[i] + 1, ufpar[i], ufdiff[i]); }

	int lo = 1, hi = n;
	while (lo + 1 < hi) {
		int mi = lo + (hi - lo) / 2;
		if (!dfscalc(0, mi)) lo = mi; else hi = mi;
	}
	ans = hi;
	//puts("");
	assert(dfscalc(0, ans));
	reconstruct(0, false);
	return true;
}

void run() {
	scanf("%d%d", &n, &nline);
	REP(i, n - 1) { int a, b; scanf("%d%d", &a, &b); --a, --b; adj[a].PB(b); adj[b].PB(a); }
	REP(i, n) REP(j, 2) scanf("%d", &lineend[i][j]), --lineend[i][j];
	if (!solve()) { printf("-1\n"); return; }
	printf("%d\n", ans);
	REP(i, n) { if (i != 0) printf(" "); printf("%d", cost[i]); } puts("");
}

int main() {
	run();
	return 0;
}

#include <bits/stdc++.h>
#define ctz __builtin_ctz
#define ad(x) ((((x) - 1) ^ 1) + 1)
#define tr(x) (2 * (x) - 1)
#define fa(x) (2 * (x))

const int N = 500054, M = N * 2, LN = 19;

int n, m, E = 0;
int to[M], first[N], next[M];
int P[LN][N], *p = *P, dep[N];
int cnt = 0, o[N], id[N], eid[N];
int cong[N], bel[N];

inline void up(int &x, const int y) {x < y ? x = y : 0;}
inline void down(int &x, const int y) {x > y ? x = y : 0;}
inline int min(const int x, const int y) {return x < y ? x : y;}
inline int max(const int x, const int y) {return x < y ? y : x;}

inline void addedge(int u, int v) {
	to[++E] = v, next[E] = first[u], first[u] = E;
	to[++E] = u, next[E] = first[v], first[v] = E;
}

void dfs(int x) {
	int i, y; o[++cnt] = x, id[x] = cnt;
	for (i = 0; P[i][x]; ++i) P[i + 1][x] = P[i][ P[i][x] ];
	for (i = first[x]; i; i = next[i])
		if ((y = to[i]) != p[x]) p[y] = x, dep[y] = dep[x] + 1, dfs(y);
	eid[x] = cnt;
}

int jump_until(int x, int d) {
	int S = dep[x] - d;
	for (assert(S >= 0); S; S &= S - 1) x = P[ctz(S)][x];
	return x;
}

namespace dsu {
	int p[M];

	int ancestor(int x) {return p[x] == x ? x : (p[x] = ancestor(p[x]));}
	inline bool test(int x, int y, bool un = false) {
		if ((x = ancestor(x)) == (y = ancestor(y))) return true;
		return un && (p[x] = y, false);
	}
	inline void equiv(int x, int y) {test(x, y, true), test(ad(x), ad(y), true);}
	inline void init(int n) {std::iota(p, p + ++n, 0);}
}

namespace dp {
	int f[N], stamp[N], li[N];
	int l[N], r[N];
	bool contain[N], rev[N];

	bool main(int R) {
		int i, x, y, cl, cr, cc, B, at, bt, top, _; bool Lr, Rr;
		memset(stamp, 0, (n + 1) << 2);
		for (_ = n; _; --_) {
			x = o[_], top = 0, cl = 1, cr = R, cc = (R + 1) / 2;
			for (i = first[x]; i; i = next[i]) {
				y = to[i], B = bel[tr(y)], at = (B + 1) / 2;
				if (stamp[at] != _) stamp[at] = _, l[at] = 1, r[at] = R, li[top++] = at;
				B & 1 ? up(l[at], f[y] + 1) : down(r[at], R - f[y]);
			}
			B = bel[tr(x)], bt = (B + 1) / 2;
			for (i = 0; i < top; ++i) {
				if (y = li[i], l[y] > r[y]) return false;
				if (y == bt)
					B & 1 ? (cl = l[y], cr = r[y]) : (cl = R + 1 - r[y], cr = R + 1 - l[y]);
				else
					Lr = l[y] * 2 <= R + 2, Rr = r[y] * 2 >= R,
					assert(Lr || Rr), down(cc, min(r[y], R + 1 - l[y])),
					up(cl, min(l[y], R + 1 - r[y])), down(cr, max(r[y], R + 1 - l[y]));
			}
			if (cc < cl) up(cl, R + 1 - cc);
			if (cl > cr) return false;
			for (f[x] = cl, i = 0; i < top; ++i) y = li[i], contain[y] = (l[y] <= cl && cl <= r[y]);
			for (i = first[x]; i; i = next[i])
				y = to[i], B = bel[tr(y)], at = (B + 1) / 2, rev[y] = (B ^ (at == bt ? ~bel[tr(x)] : contain[at])) & 1;
		}
		return true;
	}

	void dump(int R) {
		int i, v; ++R;
		for (i = 1; i <= n; ++i) v = o[i], (rev[v] ^= rev[p[v]]) && (f[v] = R - f[v]);
		for (i = 1; i <= n; ++i) printf("%d%c", f[i], i == n ? 10 : 32);
	}
}

int main() {
	int i, u, v, w, x, y, L, R, M;
	scanf("%d%d", &n, &m), dsu::init(2 * n);
	for (i = 1; i < n; ++i) scanf("%d%d", &u, &v), addedge(u, v);
	for (dfs(1); m; --m) {
		scanf("%d%d", &u, &v), assert(u != v);
		if (id[u] > id[v]) std::swap(u, v);
		if (id[v] <= eid[u])
			++cong[v], --cong[jump_until(v, dep[u] + 1)];
		else {
			w = min(dep[u], dep[v]), x = jump_until(u, w), y = jump_until(v, w);
			for (i = LN - 1; i >= 0; --i)
				if (P[i][x] != P[i][y]) x = P[i][x], y = P[i][y];
			++cong[u], ++cong[v], --cong[x], --cong[y];
			dsu::equiv(tr(x), fa(y));
		}
	}
	for (i = n; i; --i)
		if (v = o[i], cong[ p[v] ] += cong[v], cong[v]) dsu::equiv(tr(v), tr(p[v]));
	for (i = 2; i <= n; ++i) if (dsu::test(tr(i), fa(i))) return puts("-1"), 0;
	for (u = 1; u <= n; ++u) {
		if (to[ i = first[u] ] == p[u]) first[u] = next[i];
		else for (i = first[u]; next[i]; i = next[i])
			if (to[next[i]] == p[u]) next[i] = next[next[i]];
		if (!bel[ dsu::ancestor(tr(u)) ]) bel[ dsu::ancestor(tr(u)) ] = tr(u);
		if (!bel[ dsu::ancestor(fa(u)) ]) bel[ dsu::ancestor(fa(u)) ] = fa(u);
	}
	for (i = 1; i <= 2 * n; ++i) bel[i] = bel[ dsu::ancestor(i) ];
	for (L = 1, R = n; L < R; dp::main(M = (L + R) / 2) ? R = M : L = M + 1);
	return printf("%d\n", L), dp::main(L), dp::dump(L), 0;
}

#include <bits/stdc++.h>
#define ctz __builtin_ctz
#define ad(x) ((((x) - 1) ^ 1) + 1)
#define tr(x) (2 * (x) - 1)
#define fa(x) (2 * (x))

const int N = 500054, M = N * 2, LN = 19;

int n, m, E = 0;
int to[M], first[N], next[M];
int P[LN][N], *p = *P, dep[N];
int cnt = 0, o[N], id[N], eid[N];
int cong[N], bel[N];

inline void up(int &x, const int y) {x < y ? x = y : 0;}
inline void down(int &x, const int y) {x > y ? x = y : 0;}
inline int min(const int x, const int y) {return x < y ? x : y;}
inline int max(const int x, const int y) {return x < y ? y : x;}

inline void addedge(int u, int v) {
	to[++E] = v, next[E] = first[u], first[u] = E;
	to[++E] = u, next[E] = first[v], first[v] = E;
}

void dfs(int x) {
	int i, y; o[++cnt] = x, id[x] = cnt;
	for (i = 0; P[i][x]; ++i) P[i + 1][x] = P[i][ P[i][x] ];
	for (i = first[x]; i; i = next[i])
		if ((y = to[i]) != p[x]) p[y] = x, dep[y] = dep[x] + 1, dfs(y);
	eid[x] = cnt;
}

int jump_until(int x, int d) {
	int S = dep[x] - d;
	for (assert(S >= 0); S; S &= S - 1) x = P[ctz(S)][x];
	return x;
}

namespace dsu {
	int p[M];

	int ancestor(int x) {return p[x] == x ? x : (p[x] = ancestor(p[x]));}
	inline bool test(int x, int y, bool un = false) {
		if ((x = ancestor(x)) == (y = ancestor(y))) return true;
		return un && (p[x] = y, false);
	}
	inline void equiv(int x, int y) {test(x, y, true), test(ad(x), ad(y), true);}
	inline void init(int n) {std::iota(p, p + ++n, 0);}
}

namespace dp {
	int f[N], stamp[N], li[N];
	int l[N], r[N];
	bool contain[N], rev[N];

	bool main(int R) {
		int i, x, y, cl, cr, cc, B, at, bt, top, _; bool Lr, Rr;
		memset(stamp, 0, (n + 1) << 2);
		for (_ = n; _; --_) {
			x = o[_], top = 0, cl = 1, cr = R, cc = (R + 1) / 2;
			for (i = first[x]; i; i = next[i]) {
				y = to[i], B = bel[tr(y)], at = (B + 1) / 2;
				if (stamp[at] != _) stamp[at] = _, l[at] = 1, r[at] = R, li[top++] = at;
				B & 1 ? up(l[at], f[y] + 1) : down(r[at], R - f[y]);
			}
			B = bel[tr(x)], bt = (B + 1) / 2;
			for (i = 0; i < top; ++i) {
				if (y = li[i], l[y] > r[y]) return false;
				if (y == bt)
					B & 1 ? (cl = l[y], cr = r[y]) : (cl = R + 1 - r[y], cr = R + 1 - l[y]);
				else
					Lr = l[y] * 2 <= R + 2, Rr = r[y] * 2 >= R,
					assert(Lr || Rr), down(cc, min(r[y], R + 1 - l[y])),
					up(cl, min(l[y], R + 1 - r[y])), down(cr, max(r[y], R + 1 - l[y]));
			}
			if (cc < cl) up(cl, R + 1 - cc);
			if (cl > cr) return false;
			for (f[x] = cl, i = 0; i < top; ++i) y = li[i], contain[y] = (l[y] <= cl && cl <= r[y]);
			for (i = first[x]; i; i = next[i])
				y = to[i], B = bel[tr(y)], at = (B + 1) / 2, rev[y] = (contain[at] ^ B ^ (at == bt ? bel[tr(x)] ^ 1 : 0)) & 1;
		}
		return true;
	}

	void dump(int R) {
		int i, v; ++R;
		for (i = 1; i <= n; ++i) v = o[i], (rev[v] ^= rev[p[v]]) && (f[v] = R - f[v]);
		for (i = 1; i <= n; ++i) printf("%d%c", f[i], i == n ? 10 : 32);
	}
}

int main() {
	int i, u, v, w, x, y, L, R, M;
	scanf("%d%d", &n, &m), dsu::init(2 * n);
	for (i = 1; i < n; ++i) scanf("%d%d", &u, &v), addedge(u, v);
	for (dfs(1); m; --m) {
		scanf("%d%d", &u, &v), assert(u != v);
		if (id[u] > id[v]) std::swap(u, v);
		if (id[v] <= eid[u])
			++cong[v], --cong[jump_until(v, dep[u] + 1)];
		else {
			w = min(dep[u], dep[v]), x = jump_until(u, w), y = jump_until(v, w);
			for (i = LN - 1; i >= 0; --i)
				if (P[i][x] != P[i][y]) x = P[i][x], y = P[i][y];
			++cong[u], ++cong[v], --cong[x], --cong[y];
			dsu::equiv(tr(x), fa(y));
		}
	}
	for (i = n; i; --i)
		if (v = o[i], cong[ p[v] ] += cong[v], cong[v]) dsu::equiv(tr(v), tr(p[v]));
	for (i = 2; i <= n; ++i) if (dsu::test(tr(i), fa(i))) return puts("-1"), 0;
	for (u = 1; u <= n; ++u) {
		if (to[ i = first[u] ] == p[u]) first[u] = next[i];
		else for (i = first[u]; next[i]; i = next[i])
			if (to[next[i]] == p[u]) next[i] = next[next[i]];
		if (!bel[ dsu::ancestor(tr(u)) ]) bel[ dsu::ancestor(tr(u)) ] = tr(u);
		if (!bel[ dsu::ancestor(fa(u)) ]) bel[ dsu::ancestor(fa(u)) ] = fa(u);
	}
	for (i = 1; i <= 2 * n; ++i) bel[i] = bel[ dsu::ancestor(i) ];
	for (L = 1, R = n; L < R; dp::main(M = (L + R) / 2) ? R = M : L = M + 1);
	return printf("%d\n", L), dp::main(L), dp::dump(L), 0;
}

#include <bits/stdc++.h>
#define ctz __builtin_ctz
#define ad(x) ((((x) - 1) ^ 1) + 1)
#define tr(x) (2 * (x) - 1)
#define fa(x) (2 * (x))

const int N = 500054, M = N * 2, LN = 19;

int n, m, E = 0;
int to[M], first[N], next[M];
int P[LN][N], *p = *P, dep[N];
int cnt = 0, o[N], id[N], eid[N];
int cong[N], bel[N];

inline void up(int &x, const int y) {x < y ? x = y : 0;}
inline void down(int &x, const int y) {x > y ? x = y : 0;}
inline int min(const int x, const int y) {return x < y ? x : y;}
inline int max(const int x, const int y) {return x < y ? y : x;}

inline void addedge(int u, int v) {
	to[++E] = v, next[E] = first[u], first[u] = E;
	to[++E] = u, next[E] = first[v], first[v] = E;
}

void dfs(int x) {
	int i, y; o[++cnt] = x, id[x] = cnt;
	for (i = 0; P[i][x]; ++i) P[i + 1][x] = P[i][ P[i][x] ];
	for (i = first[x]; i; i = next[i])
		if ((y = to[i]) != p[x]) p[y] = x, dep[y] = dep[x] + 1, dfs(y);
	eid[x] = cnt;
}

int jump_until(int x, int d) {
	int S = dep[x] - d;
	for (assert(S >= 0); S; S &= S - 1) x = P[ctz(S)][x];
	return x;
}

namespace dsu {
	int p[M];

	int ancestor(int x) {return p[x] == x ? x : (p[x] = ancestor(p[x]));}
	inline bool test(int x, int y, bool un = false) {
		if ((x = ancestor(x)) == (y = ancestor(y))) return true;
		return un && (p[x] = y, false);
	}
	inline void equiv(int x, int y) {test(x, y, true), test(ad(x), ad(y), true);}
	inline void init(int n) {std::iota(p, p + ++n, 0);}
}

namespace dp {
	int f[N], stamp[N], li[N];
	int l[N], r[N];
	bool contain[N], rev[N];

	bool main(int R) {
		int i, x, y, cl, cr, cc, B, at, bt, top, _; bool Lr, Rr;
		memset(stamp, 0, (n + 1) << 2);
		for (_ = n; _; --_) {
			x = o[_], top = 0, cl = 1, cr = R, cc = (R + 1) / 2;
			for (i = first[x]; i; i = next[i]) {
				y = to[i], B = bel[tr(y)], at = (B + 1) / 2;
				if (stamp[at] != _) stamp[at] = _, l[at] = 1, r[at] = R, li[top++] = at;
				B & 1 ? up(l[at], f[y] + 1) : down(r[at], R - f[y]);
			}
			B = bel[tr(x)], bt = (B + 1) / 2;
			for (i = 0; i < top; ++i) {
				if (y = li[i], l[y] > r[y]) return false;
				if (y == bt)
					B & 1 ? (cl = l[y], cr = r[y]) : (cl = R + 1 - r[y], cr = R + 1 - l[y]);
				else
					Lr = l[y] * 2 <= R + 2, Rr = r[y] * 2 >= R,
					assert(Lr || Rr), down(cc, min(r[y], R + 1 - l[y])),
					up(cl, min(l[y], R + 1 - r[y])), down(cr, max(r[y], R + 1 - l[y]));
			}
			if (cc < cl) up(cl, R + 1 - cc);
			if (cl > cr) return false;
			for (f[x] = cl, i = 0; i < top; ++i) y = li[i], contain[y] = (l[y] <= cl && cl <= r[y]);
			for (i = first[x]; i; i = next[i])
				y = to[i], B = bel[tr(y)], at = (B + 1) / 2, rev[y] = (B ^ (at == bt ? bel[tr(x)] : contain[at])) & 1;
		}
		return true;
	}

	void dump(int R) {
		int i, v; ++R;
		for (i = 1; i <= n; ++i) v = o[i], (rev[v] ^= rev[p[v]]) && (f[v] = R - f[v]);
		for (i = 1; i <= n; ++i) printf("%d%c", f[i], i == n ? 10 : 32);
	}
}

int main() {
	int i, u, v, w, x, y, L, R, M;
	scanf("%d%d", &n, &m), dsu::init(2 * n);
	for (i = 1; i < n; ++i) scanf("%d%d", &u, &v), addedge(u, v);
	for (dfs(1); m; --m) {
		scanf("%d%d", &u, &v), assert(u != v);
		if (id[u] > id[v]) std::swap(u, v);
		if (id[v] <= eid[u])
			++cong[v], --cong[jump_until(v, dep[u] + 1)];
		else {
			w = min(dep[u], dep[v]), x = jump_until(u, w), y = jump_until(v, w);
			for (i = LN - 1; i >= 0; --i)
				if (P[i][x] != P[i][y]) x = P[i][x], y = P[i][y];
			++cong[u], ++cong[v], --cong[x], --cong[y];
			dsu::equiv(tr(x), fa(y));
		}
	}
	for (i = n; i; --i)
		if (v = o[i], cong[ p[v] ] += cong[v], cong[v]) dsu::equiv(tr(v), tr(p[v]));
	for (i = 2; i <= n; ++i) if (dsu::test(tr(i), fa(i))) return puts("-1"), 0;
	for (u = 1; u <= n; ++u) {
		if (to[ i = first[u] ] == p[u]) first[u] = next[i];
		else for (i = first[u]; next[i]; i = next[i])
			if (to[next[i]] == p[u]) next[i] = next[next[i]];
		if (!bel[ dsu::ancestor(tr(u)) ]) bel[ dsu::ancestor(tr(u)) ] = tr(u);
		if (!bel[ dsu::ancestor(fa(u)) ]) bel[ dsu::ancestor(fa(u)) ] = fa(u);
	}
	for (i = 1; i <= 2 * n; ++i) bel[i] = bel[ dsu::ancestor(i) ];
	for (L = 1, R = n; L < R; dp::main(M = (L + R) / 2) ? R = M : L = M + 1);
	return printf("%d\n", L), dp::main(L), dp::dump(L), 0;
}

#include <bits/stdc++.h>
#define ctz __builtin_ctz
#define ad(x) ((((x) - 1) ^ 1) + 1)
#define tr(x) (2 * (x) - 1)
#define fa(x) (2 * (x))

const int N = 500054, M = N * 2, LN = 19;

int n, m, E = 0;
int to[M], first[N], next[M];
int P[LN][N], *p = *P, dep[N];
int cnt = 0, o[N], id[N], eid[N];
int cong[N], bel[N];

inline void up(int &x, const int y) {x < y ? x = y : 0;}
inline void down(int &x, const int y) {x > y ? x = y : 0;}
inline int min(const int x, const int y) {return x < y ? x : y;}
inline int max(const int x, const int y) {return x < y ? y : x;}

inline void addedge(int u, int v) {
	to[++E] = v, next[E] = first[u], first[u] = E;
	to[++E] = u, next[E] = first[v], first[v] = E;
}

void dfs(int x) {
	int i, y; o[++cnt] = x, id[x] = cnt;
	for (i = 0; P[i][x]; ++i) P[i + 1][x] = P[i][ P[i][x] ];
	for (i = first[x]; i; i = next[i])
		if ((y = to[i]) != p[x]) p[y] = x, dep[y] = dep[x] + 1, dfs(y);
	eid[x] = cnt;
}

int jump_until(int x, int d) {
	int S = dep[x] - d;
	for (assert(S >= 0); S; S &= S - 1) x = P[ctz(S)][x];
	return x;
}

namespace dsu {
	int p[M];

	int ancestor(int x) {return p[x] == x ? x : (p[x] = ancestor(p[x]));}
	inline bool test(int x, int y, bool un = false) {
		if ((x = ancestor(x)) == (y = ancestor(y))) return true;
		return un && (p[x] = y, false);
	}
	inline void equiv(int x, int y) {test(x, y, true), test(ad(x), ad(y), true);}
	inline void init(int n) {std::iota(p, p + ++n, 0);}
}

namespace dp {
	int f[N], stamp[N], li[N];
	int l[N], r[N];
	bool contain[N], rev[N];

	bool main(int R) {
		int i, x, y, cl, cr, cc, B, at, bt, top, _; bool Lr, Rr;
		memset(stamp, 0, (n + 1) << 2);
		for (_ = n; _; --_) {
			x = o[_], top = 0, cl = 1, cr = R, cc = (R + 1) / 2;
			for (i = first[x]; i; i = next[i]) {
				y = to[i], B = bel[tr(y)], at = (B + 1) / 2;
				if (stamp[at] != _) stamp[at] = _, l[at] = 1, r[at] = R, li[top++] = at;
				B & 1 ? up(l[at], f[y] + 1) : down(r[at], R - f[y]);
			}
			B = bel[tr(x)], bt = (B + 1) / 2;
			for (i = 0; i < top; ++i) {
				if (y = li[i], l[y] > r[y]) return false;
				if (y == bt)
					B & 1 ? (up(cl, l[y]), down(cr, r[y])) : (up(cl, R + 1 - r[y]), down(cr, R + 1 - l[y]));
				else
					Lr = l[y] * 2 <= R + 2, Rr = r[y] * 2 >= R,
					assert(Lr || Rr), down(cc, min(r[y], R + 1 - l[y])),
					up(cl, min(l[y], R + 1 - r[y])), down(cr, max(r[y], R + 1 - l[y]));
			}
			if (cc < cl) up(cl, R + 1 - cc);
			if (cl > cr) return false;
			for (f[x] = cl, i = 0; i < top; ++i) y = li[i], contain[y] = (l[y] <= cl && cl <= r[y]);
			for (i = first[x]; i; i = next[i])
				y = to[i], B = bel[tr(y)], at = (B + 1) / 2, rev[y] = (B ^ (at == bt ? bel[tr(x)] : contain[at])) & 1;
		}
		return true;
	}

	void dump(int R) {
		int i, v; ++R;
		for (i = 1; i <= n; ++i) v = o[i], (rev[v] ^= rev[p[v]]) && (f[v] = R - f[v]);
		for (i = 1; i <= n; ++i) printf("%d%c", f[i], i == n ? 10 : 32);
	}
}

int main() {
	int i, u, v, w, x, y, L, R, M;
	scanf("%d%d", &n, &m), dsu::init(2 * n);
	for (i = 1; i < n; ++i) scanf("%d%d", &u, &v), addedge(u, v);
	for (dfs(1); m; --m) {
		scanf("%d%d", &u, &v), assert(u != v);
		if (id[u] > id[v]) std::swap(u, v);
		if (id[v] <= eid[u])
			++cong[v], --cong[jump_until(v, dep[u] + 1)];
		else {
			w = min(dep[u], dep[v]), x = jump_until(u, w), y = jump_until(v, w);
			for (i = LN - 1; i >= 0; --i)
				if (P[i][x] != P[i][y]) x = P[i][x], y = P[i][y];
			++cong[u], ++cong[v], --cong[x], --cong[y];
			dsu::equiv(tr(x), fa(y));
		}
	}
	for (i = n; i; --i)
		if (v = o[i], cong[ p[v] ] += cong[v], cong[v]) dsu::equiv(tr(v), tr(p[v]));
	for (i = 2; i <= n; ++i) if (dsu::test(tr(i), fa(i))) return puts("-1"), 0;
	for (u = 1; u <= n; ++u) {
		if (to[ i = first[u] ] == p[u]) first[u] = next[i];
		else for (i = first[u]; next[i]; i = next[i])
			if (to[next[i]] == p[u]) next[i] = next[next[i]];
		if (!bel[ dsu::ancestor(tr(u)) ]) bel[ dsu::ancestor(tr(u)) ] = tr(u);
		if (!bel[ dsu::ancestor(fa(u)) ]) bel[ dsu::ancestor(fa(u)) ] = fa(u);
	}
	for (i = 1; i <= 2 * n; ++i) bel[i] = bel[ dsu::ancestor(i) ];
	for (L = 1, R = n; L < R; dp::main(M = (L + R) / 2) ? R = M : L = M + 1);
	return printf("%d\n", L), dp::main(L), dp::dump(L), 0;
}

#include <cstdio>
#include <vector>
#include <cstring>
#include <cstdlib>

int n,m,head[500001],nxt[1000010],b[1000010],k=1,K,l,r,ans,sum[500001];
int fa[500001][21],dep[1000001],val[1000001],f[1000001],fin[500001];
bool exi[1000001];
bool vis[1000001];
typedef std::pair<int,int> tuple;
std::vector<tuple>vec[1000001];
std::vector<tuple>Lca[1000001];
std::vector<int>son[1000001];
tuple Ans[500001];
void push(int s,int t){
	nxt[++k]=head[s];
	head[s]=k;
	b[k]=t;
}
void dfs1(int x,int f){
	fa[x][0]=f;
	dep[x]=dep[f]+1;
	for(int i=1;i<=20;i++)
		fa[x][i]=fa[fa[x][i-1]][i-1];
	for(int i=head[x];i;i=nxt[i])
		if(b[i]!=f)dfs1(b[i],x);
}
int LCA(int x,int y,int go=-1){
	if(dep[x]<dep[y])std::swap(x,y);
	for(int i=20;~i;--i)if(dep[fa[x][i]]>dep[y])x=fa[x][i];
	if(fa[x][0]==y){
		++val[x];
		son[y].push_back(x);
		return y;
	}
	if(dep[x]!=dep[y])x=fa[x][0];
	for(int i=20;~i;--i)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
	++val[x],++val[y];
	if(~go)Lca[fa[x][0]].push_back(std::make_pair(x,y));
	return fa[x][0];
}
tuple &operator&=(tuple &a,tuple b){
	a.first=std::max(a.first,b.first);
	a.second=std::min(a.second,b.second);
	return a;
}
struct bipart{
	int head[1000001],nxt[2000010],b[2000010],k,col[1000001];
	void clear(int x){head[x]=0,col[x]=-1;}
	void init(){k=0;}
	void push(int s,int t){
//		printf("push %d %d\n",s,t);
		nxt[++k]=head[s];
		head[s]=k;
		b[k]=t;
		nxt[++k]=head[t];
		head[t]=k;
		b[k]=s;
	}
	bool ch(int x,int c=0){
//		printf("ch %d %d %d\n",x,c,col[x]);
		if(~col[x])return (col[x]==c);
		col[x]=c;
		for(int i=head[x];i;i=nxt[i]){
//			printf("%d %d\n",b[i],x);
			if(!ch(b[i],c^1))return 0;
		}
		return 1;
	}
	tuple solve(int x,int c=0){
		if(!~col[x])return std::make_pair(0,K+1);
		col[x]=-1;
		tuple ans=c?std::make_pair(f[x],K+1):std::make_pair(0,K+1-f[x]);
		for(int i=head[x];i;i=nxt[i]){
			ans&=solve(b[i],c^1);
		}
		return ans;
	}
	void getans(int x,int c=0){
		if(vis[x])return;
//		printf("getans %d %d %d\n",x,c,vis[x]);
		vis[x]=1;
		if(x<=n&&!c)fin[x]=1;
		for(int i=head[x];i;i=nxt[i]){
//			printf("%d %d\n",x,b[i]);
			getans(b[i],c^1);
		}
	}
}Check;
void Do(int x){
	if(x&&!~Check.col[x]&&!Check.ch(x)){puts("-1");exit(0);}
}
void dfs2(int x,int f){
	sum[x]=val[x];
	for(int i=head[x];i;i=nxt[i])
		if(b[i]!=f){
			dfs2(b[i],x),sum[x]+=sum[b[i]];
			exi[b[i]]=(sum[b[i]]>val[b[i]]);
		}
	for(int i=head[x];i;i=nxt[i])if(exi[b[i]]&&b[i]!=f)Check.push(x+n,b[i]);
	for(int i=0;i<Lca[x].size();++i)
		Check.push(Lca[x][i].first,Lca[x][i].second),exi[Lca[x][i].first]=exi[Lca[x][i].second]=1;
//	printf("%d\n",x);
	for(int i=head[x];i;i=nxt[i])if(b[i]!=f)Do(b[i]);Do(x+n);
}
bool judge(int x,int f){
	for(int i=head[x];i;i=nxt[i])
		if(b[i]!=f&&!judge(b[i],x))return 0;
	tuple ans=std::make_pair(0,K+1),tem=Check.solve(x+n),now;
//	printf("judge %d %d\n",x,f);
	for(int i=head[x];i;i=nxt[i])
		if(b[i]!=f&&exi[b[i]]){
			Ans[b[i]]=now=Check.solve(b[i]);
			if(K+1-now.second<now.first)now=std::make_pair(K+1-now.second,K+1-now.first);
			ans&=now;
		}
	for(int i=0;i<son[x].size();i++)
		if(!exi[son[x][i]]){
//			printf("%d %d\n",x,son[x][i]);
			ans&=std::make_pair(0,K+1-::f[son[x][i]]);
		}
	(now=tem)&=ans;
	if(now.first<now.second-1)::f[x]=now.first+1;
	else{
		ans=std::make_pair(K+1-ans.second,K+1-ans.first);
		ans&=tem;
		if(ans.first>=ans.second-1)return 0;
		else ::f[x]=ans.first+1;
	}
	if(::ans==-2){
		Check.getans(x+n);
		for(int i=head[x];i;i=nxt[i])
			if(b[i]!=f&&exi[b[i]]&&!vis[b[i]])
				Check.getans(b[i],!(Ans[b[i]].first<(::f[x])&&Ans[b[i]].second>::f[x]));
		for(int i=0;i<son[x].size();i++)
			if(!exi[son[x][i]]){
				if((::f[son[x][i]])>=(::f[x]))fin[son[x][i]]=1;
			}
	}
//	printf("solve: %d %d %d\n",x,::f[x],K);
	return 1;
}
void set(int x,int f){
	for(int i=head[x];i;i=nxt[i])
		if(b[i]!=f)fin[b[i]]^=fin[x],set(b[i],x);
	if(fin[x])::f[x]=K+1-::f[x];
}
int main(){
	scanf("%d%d",&n,&m);
	memset(Check.col,-1,sizeof Check.col);
	for(int i=1,u,v;i<n;i++)scanf("%d%d",&u,&v),push(u,v),push(v,u);
	dfs1(1,0);
	for(int i=1,a,b;i<=m;i++){
		scanf("%d%d",&a,&b);
		int lca=LCA(a,b,0);
		++sum[a];
		++sum[b];
		sum[lca]-=2;
		if(lca!=a||lca!=b)vec[lca].push_back(std::make_pair(a,b));
	}
	dfs2(1,0);
	l=1,r=n,ans=-1;
	while(l<=r){
		memset(Check.col,0,sizeof Check.col);
		K=(l+r)>>1;
		if(judge(1,0))ans=K,r=K-1;
		else l=K+1;
	}
	K=ans;ans=-2;
	printf("%d\n",K);
	memset(Check.col,0,sizeof Check.col);
	judge(1,0);
//	for(int i=1;i<=n;i++)printf("%d ",fin[i]);putchar('\n');
	memset(Check.col,0,sizeof Check.col);
	set(1,0);
	for(int i=1;i<=n;i++)printf("%d ",f[i]);putchar('\n');
}

#include <cstdio>
#include <vector>
#include <cstring>
#include <cstdlib>

int n,m,head[500001],nxt[1000010],b[1000010],k=1,K,l,r,ans,sum[500001];
int fa[500001][21],dep[500001],val[500001],f[500001],fin[500001];
bool exi[500001];
bool vis[1000001];
typedef std::pair<int,int> tuple;
std::vector<tuple>vec[500001];
std::vector<tuple>Lca[500001];
std::vector<int>son[500001];
tuple Ans[500001];
void push(int s,int t){
	nxt[++k]=head[s];
	head[s]=k;
	b[k]=t;
}
void dfs1(int x,int f){
	fa[x][0]=f;
	dep[x]=dep[f]+1;
	for(int i=1;i<=20;i++)
		fa[x][i]=fa[fa[x][i-1]][i-1];
	for(int i=head[x];i;i=nxt[i])
		if(b[i]!=f)dfs1(b[i],x);
}
int LCA(int x,int y,int go=-1){
	if(dep[x]<dep[y])std::swap(x,y);
	for(int i=20;~i;--i)if(dep[fa[x][i]]>dep[y])x=fa[x][i];
	if(fa[x][0]==y){
		++val[x];
		son[y].push_back(x);
		return y;
	}
	if(dep[x]!=dep[y])x=fa[x][0];
	for(int i=20;~i;--i)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
	++val[x],++val[y];
	if(~go)Lca[fa[x][0]].push_back(std::make_pair(x,y));
	return fa[x][0];
}
tuple &operator&=(tuple &a,tuple b){
	a.first=std::max(a.first,b.first);
	a.second=std::min(a.second,b.second);
	return a;
}
struct bipart{
	int head[1000001],nxt[2000010],b[2000010],k,col[1000001];
	void clear(int x){head[x]=0,col[x]=-1;}
	void init(){k=0;}
	void push(int s,int t){
//		printf("push %d %d\n",s,t);
		nxt[++k]=head[s];
		head[s]=k;
		b[k]=t;
		nxt[++k]=head[t];
		head[t]=k;
		b[k]=s;
	}
	bool ch(int x,int c=0){
//		printf("ch %d %d %d\n",x,c,col[x]);
		if(~col[x])return (col[x]==c);
		col[x]=c;
		for(int i=head[x];i;i=nxt[i]){
//			printf("%d %d\n",b[i],x);
			if(!ch(b[i],c^1))return 0;
		}
		return 1;
	}
	tuple solve(int x,int c=0){
		if(!~col[x])return std::make_pair(0,K+1);
		col[x]=-1;
		tuple ans=c?std::make_pair(f[x],K+1):std::make_pair(0,K+1-f[x]);
		for(int i=head[x];i;i=nxt[i]){
			ans&=solve(b[i],c^1);
		}
		return ans;
	}
	void getans(int x,int c=0){
		if(vis[x])return;
//		printf("getans %d %d %d\n",x,c,vis[x]);
		vis[x]=1;
		if(x<=n&&!c)fin[x]=1;
		for(int i=head[x];i;i=nxt[i]){
//			printf("%d %d\n",x,b[i]);
			getans(b[i],c^1);
		}
	}
}Check;
void Do(int x){
	if(x&&!~Check.col[x]&&!Check.ch(x)){puts("-1");exit(0);}
}
void dfs2(int x,int f){
	for(int i=head[x];i;i=nxt[i])
		if(b[i]!=f){
			dfs2(b[i],x),sum[x]+=sum[b[i]];
			exi[b[i]]=(sum[b[i]]>val[b[i]]);
		}
	for(int i=head[x];i;i=nxt[i])if(exi[b[i]]&&b[i]!=f)Check.push(x+n,b[i]);
	for(int i=0;i<Lca[x].size();++i)
		Check.push(Lca[x][i].first,Lca[x][i].second),exi[Lca[x][i].first]=exi[Lca[x][i].second]=1;
//	printf("%d\n",x);
	for(int i=head[x];i;i=nxt[i])if(b[i]!=f)Do(b[i]);Do(x+n);
}
bool judge(int x,int f){
	for(int i=head[x];i;i=nxt[i])
		if(b[i]!=f&&!judge(b[i],x))return 0;
	tuple ans=std::make_pair(0,K+1),tem=Check.solve(x+n),now;
//	printf("judge %d %d\n",x,f);
	for(int i=head[x];i;i=nxt[i])
		if(b[i]!=f&&exi[b[i]]){
			Ans[b[i]]=now=Check.solve(b[i]);
			if(K+1-now.second<now.first)now=std::make_pair(K+1-now.second,K+1-now.first);
			ans&=now;
		}
	for(int i=0;i<son[x].size();i++)
		if(!exi[son[x][i]]){
//			printf("%d %d\n",x,son[x][i]);
			ans&=std::make_pair(0,K+1-::f[son[x][i]]);
		}
	(now=tem)&=ans;
	if(now.first<now.second-1)::f[x]=now.first+1;
	else{
		ans=std::make_pair(K+1-ans.second,K+1-ans.first);
		ans&=tem;
		if(ans.first>=ans.second-1)return 0;
		else ::f[x]=ans.first+1;
	}
	if(::ans==-2){
		Check.getans(x+n);
		for(int i=head[x];i;i=nxt[i])
			if(b[i]!=f&&exi[b[i]]&&!vis[b[i]])
				Check.getans(b[i],!(Ans[b[i]].first<(::f[x])&&Ans[b[i]].second>::f[x]));
		for(int i=0;i<son[x].size();i++)
			if(!exi[son[x][i]]){
				if((::f[son[x][i]])>=(::f[x]))fin[son[x][i]]=1;
			}
	}
//	printf("solve: %d %d %d\n",x,::f[x],K);
	return 1;
}
void set(int x,int f){
	for(int i=head[x];i;i=nxt[i])
		if(b[i]!=f)fin[b[i]]^=fin[x],set(b[i],x);
	if(fin[x])::f[x]=K+1-::f[x];
}
int main(){
	scanf("%d%d",&n,&m);
	memset(Check.col,-1,sizeof Check.col);
	for(int i=1,u,v;i<n;i++)scanf("%d%d",&u,&v),push(u,v),push(v,u);
	dfs1(1,0);
	for(int i=1,a,b;i<=m;i++){
		scanf("%d%d",&a,&b);
		int lca=LCA(a,b,0);
		++sum[a];
		++sum[b];
		sum[lca]-=2;
		if(lca!=a||lca!=b)vec[lca].push_back(std::make_pair(a,b));
	}
	dfs2(1,0);
	l=1,r=n,ans=-1;
	while(l<=r){
		memset(Check.col,0,sizeof Check.col);
		K=(l+r)>>1;
		if(judge(1,0))ans=K,r=K-1;
		else l=K+1;
	}
	K=ans;ans=-2;
	printf("%d\n",K);
	memset(Check.col,0,sizeof Check.col);
	judge(1,0);
//	for(int i=1;i<=n;i++)printf("%d ",fin[i]);putchar('\n');
	memset(Check.col,0,sizeof Check.col);
	set(1,0);
	for(int i=1;i<=n;i++)printf("%d ",f[i]);putchar('\n');
}

#include<bits/stdc++.h>
#define cs const
#define pb push_back
#define fi first
#define se second
using namespace std;
typedef pair<int, int> pi;
cs int N = 5e5 + 50;
int n, m;
vector<int> G[N];

int fa[N][20], dep[N], d[N];
void pre_dfs(int u, int f){
	dep[u] = dep[fa[u][0] = f] + 1;
	for(int i = 1; i <= 18; i++)
	fa[u][i] = fa[fa[u][i - 1]][i - 1];
	vector<int> e;
	for(int v : G[u]) if(v != f)
	e.pb(v), pre_dfs(v, u); G[u] = e;
} int LCA(int x, int y){
	if(dep[x] < dep[y]) swap(x, y);
	for(int i = 18; ~i; i--)
	if(dep[fa[x][i]] >= dep[y]) x = fa[x][i];
	if(x == y) return x;
	for(int i = 18; ~i; i--)
	if(fa[x][i] != fa[y][i])
	x = fa[x][i], y = fa[y][i];
	return fa[x][0];
} int jmp(int x, int d){
	for(int i = 18; ~i; i--)
	if(d >= (1 << i)) d -= 1 << i, x = fa[x][i];
	return x;
}

vector<pi> e[N];
int blk[N], c[N], ct;
void sub_dfs(int u, int f){
	for(int v : G[u]) sub_dfs(v, u), d[u] += d[v];
	if(d[u]) e[u].pb(pi(f, 0)), e[f].pb(pi(u, 0));
}
void dfs(int u, int co){
	if(c[u] >= 0 && c[u] != co){
		puts("-1"); exit(0);
	} if(c[u] >= 0) return;
	c[u] = co; blk[u] = ct;
	for(pi v : e[u]) dfs(v.fi, co ^ v.se);
}

pi f[N], g[N]; int ans[N];
pi mrg(pi a, pi b){ return pi(max(a.fi, b.fi), min(a.se, b.se)); }
bool work(int u, int k){
	for(int v : G[u])
	if(!work(v, k)) return false;
	f[u] = pi(1, k);
	static int ex[N]; int t = 0;
	for(int v : G[u]) if(blk[v]){
		if(blk[v] == blk[u]){
			if(!c[v]) f[u] = mrg(f[u], pi(1, f[v].se - 1));
			else f[u] = mrg(f[u], pi(f[v].fi + 1, k));
		} else{
			if(!ex[blk[v]]) ex[blk[v]] = ++t, g[t] = pi(1, k);
			int z = ex[blk[v]];
			if(!c[v]) g[z] = mrg(g[z], pi(1, f[v].se - 1));
			else g[z] = mrg(g[z], pi(f[v].se + 1, k));
		}
	}
	for(int v : G[u]) ex[blk[v]] = 0;
	if(f[u].fi > f[u].se) return false;
	pi z(1, k);
	for(int i = 1; i <= t; i++){
		if(g[i].fi > g[i].se) return false;
		if(k - g[i].se + 1 < g[i].fi)
		g[i] = pi(k - g[i].se + 1, k - g[i].fi + 1);
		z = mrg(z, g[i]);
	} pi p = mrg(z, f[u]);
	pi q = mrg(pi(k - z.se + 1, k - z.fi + 1), f[u]);
	if(p.fi > p.se && q.fi > q.se) return false;
	if(p.fi > p.se) f[u] = q;
	else if(q.fi > q.se) f[u] = p;
	else f[u] = pi(min(p.fi, q.fi), max(p.se, q.se));
//	cout << "fasfsa " << k << " " <<  u << " " << f[u].fi << " " << f[u].se << endl;
	return true;
}
void cope(int u, int k, bool r){
	static int ex[N], rm[N]; int t = 0;
//	cout << "Cope " << u << " " << r << " " << f[u].fi << " " << f[u].se << endl;
	for(int v : G[u]) if(blk[v] && blk[v] != blk[u]){
		if(!ex[blk[v]]) rm[ex[blk[v]] = ++t]
		= blk[v], g[t] = pi(1, k);
		int z = ex[blk[v]];
		if(!c[v]) g[z] = mrg(g[z], pi(1, f[v].se - 1));
		else g[z] = mrg(g[z], pi(f[v].se + 1, k));
	} for(int v : G[u]) ex[blk[v]] = 0;
	static bool rv[N];
	for(int i = 1; i <= t; i++)
	rv[rm[i]] = (g[i].fi <= ans[u] && ans[u] <= g[i].se) ? 0 : 1;
	for(int v : G[u]) {
		if(!blk[v]) ans[v] = f[v].fi, cope(v, k, 0);
		else{
			bool o = blk[v] == blk[u] ? r : rv[blk[v]];
			if(!o) ans[v] = c[v] ? f[v].fi : f[v].se;
			else ans[v] = c[v] ? k - f[v].fi + 1 : k - f[v].se + 1;
			cope(v, k, o);
		}
	}
}

int main(){
	#ifdef FSYo
	freopen("1.in", "r", stdin);
	#endif
	cin >> n >> m;
	for(int i = 1, u, v; i < n; i++)
	scanf("%d%d", &u, &v),
	G[u].pb(v), G[v].pb(u);
	pre_dfs(1, 0);
	for(int i = 1, x, y, l; i <= m; i++){
		scanf("%d%d", &x, &y); l = LCA(x, y);
		if(x != l) ++d[x], --d[jmp(x, dep[x] - dep[l] - 1)];
		if(y != l) ++d[y], --d[jmp(y, dep[y] - dep[l] - 1)];
		if(x != l && y != l)
		e[x].pb(pi(y, 1)), e[y].pb(pi(x, 1));
	} sub_dfs(1, 0);
	memset(c, -1, sizeof(c));
	for(int i = 2; i <= n; i++)
	if(!blk[i]) ++ct, dfs(i, 0);

	int l = 1, r = n;
	while(l < r){
		int mid = (l + r) >> 1;
		if(work(1, mid)) r = mid;
		else l = mid + 1;
	} cout << l << '\n';
	work(1, l);
	ans[1] = f[1].fi;
	cope(1, l, 0);
	for(int i = 1; i <= n; i++)
	cout << ans[i] << " ";
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
inline void upa(int&a,const int&b){a<b?a=b:0;}
typedef vector<int>V;
int n,m;
V e[N],e2[N];
int dfn[N],dcnt,dep[N],dad[N],anc[20][N],tg[N],tg2[N];
int g[N*2];
int gfa(int x){return g[x]==x?x:g[x]=gfa(g[x]);}
inline void uni(int x,int y){g[gfa(x)]=gfa(y);}
void dfs(int x,int fa){
	dfn[++dcnt]=x;dep[x]=dep[fa]+1;dad[x]=anc[0][x]=fa;
	if(fa)e[x].erase(find(e[x].begin(),e[x].end(),fa));
	for(int y:e[x])dfs(y,x);
}
void dfs2(int x,int fa){
	for(int y:e[x])dfs2(y,x),tg[x]+=tg[y],tg2[x]+=tg2[y];
	if(tg[x])uni(x,fa),uni(x+n,fa+n);
}
inline int lca(int x,int y){
	if(dep[x]>dep[y])swap(x,y);
	int dt=dep[y]-dep[x],i;for(i=0;1<<i<=dt;++i)if(dt>>i&1)y=anc[i][y];
	if(x==y)return x;
	for(i=19;i>=0;--i)if(anc[i][x]!=anc[i][y])x=anc[i][x],y=anc[i][y];
	return anc[0][x];
}
inline int climb(int x,int k){for(int i=0;1<<i<=k;++i)if(k>>i&1)x=anc[i][x];return x;}
inline void build(){
	int x,y,z,xx,yy,i,j;
	for(i=1;i<n;++i)cin>>x>>y,e[x].push_back(y),e[y].push_back(x);
	dfs(1,0);
	for(i=1;i<20;++i)for(j=1;j<=n;++j)anc[i][j]=anc[i-1][anc[i-1][j]];
	for(i=1;i<=n*2;++i)g[i]=i;
	for(i=1;i<=m;++i){
		cin>>x>>y;xx=yy=0;
		z=lca(x,y);++tg2[x];++tg2[y];tg2[z]-=2;
		if(dep[y]>dep[z]+1)++tg[y],--tg[yy=climb(y,dep[y]-dep[z]-1)];
		if(dep[x]>dep[z]+1)++tg[x],--tg[xx=climb(x,dep[x]-dep[z]-1)];
		if(xx && yy)uni(xx,yy+n),uni(xx+n,yy);
	}
	dfs2(1,0);for(i=1;i<=n;++i)if(gfa(i)==gfa(i+n)){cout<<-1<<endl;exit(0);}
}
int f[N];bool rev[N];
struct seg{int l,r;};
inline seg operator&(const seg&a,const seg&b){return (seg){max(a.l,b.l),min(a.r,b.r)};}
inline seg operator|(const seg&a,const seg&b){return (seg){min(a.l,b.l),max(a.r,b.r)};}
inline bool E(const seg&a){return a.l>a.r;}
inline bool ck(int lm){
	int i,j,k,l,x,y,z;
	seg A=(seg){0,lm};
	for(i=n;i;--i){
		x=dfn[i];
		seg s=A;
		for(int y:e2[x])s=s&(gfa(y)==gfa(x)?(seg){f[y]+1,lm}:(seg){0,lm-f[y]-1}),rev[y]=gfa(y)==gfa(x+n);
		seg s1=s,s2=(seg){lm,0},s3;
		for(j=0;j<e[x].size();j=k){
			s3=A;
			y=e[x][j];
			for(k=j;k<e[x].size() && (z=e[x][k],gfa(z)==gfa(y) || gfa(z)==gfa(y+n));++k)
				s3=s3&(gfa(z)==gfa(y)?(seg){f[z]+1,lm}:(seg){0,lm-f[z]-1});
			if(E(s3))return 0;
			if(s3.l>lm-s3.l)s3=(seg){lm-s3.r,lm-s3.l};
			s1=s1&((seg){s3.l,lm-s3.l}|(seg){lm-s3.r,s3.r});
			if(s3.r<lm-s3.r)s2=s2|(seg){s3.r+1,lm-s3.r-1};
		}
		if(E(s1) || (s2.l<=s1.l && s1.r<=s2.r))return 0;
		if(s2.l<=s1.l && s1.l<=s2.r)f[x]=s2.r+1;else f[x]=s1.l;
		for(j=0;j<e[x].size();j=k){
			s3=A;
			y=e[x][j];
			for(k=j;k<e[x].size() && (z=e[x][k],gfa(z)==gfa(y) || gfa(z)==gfa(y+n));++k)
				s3=s3&(gfa(z)==gfa(y)?(seg){f[z]+1,lm}:(seg){0,lm-f[z]-1});
			bool bb=0;
			if(f[x]<s3.l || f[x]>s3.r)bb=1,s3=(seg){lm-s3.r,lm-s3.l};
			for(l=j;l<k;++l)z=e[x][l],rev[z]=(gfa(z)==gfa(y+n))^bb;
		}
	}
	return 1;
}
int main(){
	ios::sync_with_stdio(0);cin.tie(0);
	cin>>n>>m;build();
	int le=1,ri=n-1,md,i;
	for(i=1;i<=n;++i){
		V e3;
		for(int x:e[i])if(gfa(x)==gfa(i) || gfa(x)==gfa(i+n))e2[i].push_back(x);else if(tg2[x])e3.push_back(x);
		sort(e3.begin(),e3.end(),[&](int x,int y){return gfa(x)<gfa(y);});e[i]=e3;
	}
	for(;le<ri;){
		md=le+ri>>1;
		if(!ck(md))le=md+1;else ri=md;
	}
	cout<<le+1<<'\n';
	ck(le);
	for(i=2;i<=n;++i){int x=dfn[i];rev[x]^=rev[dad[x]];}
	for(i=1;i<=n;++i)cout<<(rev[i]?le-f[i]:f[i])+1<<(i==n?'\n':' ');
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
inline void upa(int&a,const int&b){a<b?a=b:0;}
typedef vector<int>V;
int n,m;
V e[N],e2[N];
int dfn[N],dcnt,dep[N],dad[N],anc[20][N],tg[N],tg2[N];
int g[N*2];
int gfa(int x){return g[x]==x?x:g[x]=gfa(g[x]);}
inline void uni(int x,int y){g[gfa(x)]=gfa(y);}
void dfs(int x,int fa){
	dfn[++dcnt]=x;dep[x]=dep[fa]+1;dad[x]=anc[0][x]=fa;
	if(fa)e[x].erase(find(e[x].begin(),e[x].end(),fa));
	for(int y:e[x])dfs(y,x);
}
void dfs2(int x,int fa){
	for(int y:e[x])dfs2(y,x),tg[x]+=tg[y],tg2[x]+=tg2[y];
	if(tg[x])uni(x,fa),uni(x+n,fa+n);
}
inline int lca(int x,int y){
	if(dep[x]>dep[y])swap(x,y);
	int dt=dep[y]-dep[x],i;for(i=0;1<<i<=dt;++i)if(dt>>i&1)y=anc[i][y];
	if(x==y)return x;
	for(i=19;i>=0;--i)if(anc[i][x]!=anc[i][y])x=anc[i][x],y=anc[i][y];
	return anc[0][x];
}
inline int climb(int x,int k){for(int i=0;1<<i<=k;++i)if(k>>i&1)x=anc[i][x];return x;}
inline void build(){
	int x,y,z,xx,yy,i,j;
	for(i=1;i<n;++i)cin>>x>>y,e[x].push_back(y),e[y].push_back(x);
	dfs(1,0);
	for(i=1;i<20;++i)for(j=1;j<=n;++j)anc[i][j]=anc[i-1][anc[i-1][j]];
	for(i=1;i<=n*2;++i)g[i]=i;
	for(i=1;i<=m;++i){
		cin>>x>>y;xx=yy=0;
		z=lca(x,y);++tg2[x];++tg2[y];tg2[z]-=2;
		if(dep[y]>dep[z])++tg[y],--tg[yy=climb(y,dep[y]-dep[z]-1)];
		if(dep[x]>dep[z])++tg[x],--tg[xx=climb(x,dep[x]-dep[z]-1)];
		if(xx && yy)uni(xx,yy+n),uni(xx+n,yy);
	}
	dfs2(1,0);for(i=1;i<=n;++i)if(gfa(i)==gfa(i+n)){cout<<-1<<endl;exit(0);}
}
int f[N];bool rev[N];
struct seg{int l,r;};
inline seg operator&(const seg&a,const seg&b){return (seg){max(a.l,b.l),min(a.r,b.r)};}
inline seg operator|(const seg&a,const seg&b){return (seg){min(a.l,b.l),max(a.r,b.r)};}
inline bool E(const seg&a){return a.l>a.r;}
inline bool ck(int lm){
	int i,j,k,l,x,y,z;
	seg A=(seg){0,lm};
	for(i=n;i;--i){
		x=dfn[i];
		seg s=A;
		for(int y:e2[x])s=s&(gfa(y)==gfa(x)?(seg){f[y]+1,lm}:(seg){0,lm-f[y]-1}),rev[y]=gfa(y)==gfa(x+n);
		seg s1=s,s2=(seg){lm,0},s3;
		for(j=0;j<e[x].size();j=k){
			s3=A;
			y=e[x][j];
			for(k=j;k<e[x].size() && (z=e[x][k],gfa(z)==gfa(y) || gfa(z)==gfa(y+n));++k)
				s3=s3&(gfa(z)==gfa(y)?(seg){f[z]+1,lm}:(seg){0,lm-f[z]-1});
			if(E(s3))return 0;
			if(s3.l>lm-s3.l)s3=(seg){lm-s3.r,lm-s3.l};
			s1=s1&((seg){s3.l,lm-s3.l}|(seg){lm-s3.r,s3.r});
			if(s3.r<lm-s3.r)s2=s2|(seg){s3.r+1,lm-s3.r-1};
		}
		if(E(s1) || (s2.l<=s1.l && s1.r<=s2.r))return 0;
		if(s2.l<=s1.l && s1.l<=s2.r)f[x]=s2.r+1;else f[x]=s1.l;
		for(j=0;j<e[x].size();j=k){
			s3=A;
			y=e[x][j];
			for(k=j;k<e[x].size() && (z=e[x][k],gfa(z)==gfa(y) || gfa(z)==gfa(y+n));++k)
				s3=s3&(gfa(z)==gfa(y)?(seg){f[z]+1,lm}:(seg){0,lm-f[z]-1});
			bool bb=0;
			if(f[x]<s3.l || f[x]>s3.r)bb=1,s3=(seg){lm-s3.r,lm-s3.l};
			for(l=j;l<k;++l)z=e[x][l],rev[z]=(gfa(z)==gfa(y+n))^bb;
		}
	}
	return 1;
}
int main(){
	ios::sync_with_stdio(0);cin.tie(0);
	cin>>n>>m;build();
	int le=1,ri=n-1,md,i;
	for(i=1;i<=n;++i){
		V e3;
		for(int x:e[i])if(gfa(x)==gfa(i) || gfa(x)==gfa(i+n))e2[i].push_back(x);else if(tg2[x])e3.push_back(x);
		sort(e3.begin(),e3.end(),[&](int x,int y){return gfa(x)<gfa(y);});e[i]=e3;
	}
	for(;le<ri;){
		md=le+ri>>1;
		if(!ck(md))le=md+1;else ri=md;
	}
	cout<<le+1<<'\n';
	ck(le);
	for(i=2;i<=n;++i){int x=dfn[i];rev[x]^=rev[dad[x]];}
	for(i=1;i<=n;++i)cout<<(rev[i]?le-f[i]:f[i])+1<<(i==n?'\n':' ');
	return 0;
}