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

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

// 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>
#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>
#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>
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;

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