#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int N=8005,M=4000005;
int n,m,tot,ans;
int fr[N],nxt[N],em[N],rd[N],out[M],u[M],v[M],t[2*M],fa[N],sf[N],dep[N];
vector<int>s[N];
bool done[M];
inline void addedge(int u,int v,int i)
{
	nxt[i]=fr[u];
	fr[u]=i;
	em[i]=v;
	rd[u]++;
}
int find(int a)
{
	if(t[a]==a)
		return a;
	return t[a]=find(t[a]);
}
inline void Union(int a,int b)
{
	int x=find(a);
	int y=find(b);
	t[x]=y;
}
void dfs0(int d)
{
	for(int j=fr[d];j!=0;j=nxt[j])
		if(em[j]!=fa[d])
		{
			fa[em[j]]=d;
			dep[em[j]]=dep[d]+1;
			dfs0(em[j]);
		}
}
inline int lca(int a,int b)
{
	if(dep[a]<dep[b])
		swap(a,b);
	while(dep[a]>dep[b])
		a=fa[a];
	while(fa[a]!=fa[b])
	{
		a=fa[a];
		b=fa[b];
	}
	if(a==b)
		return a;
	else
		return fa[a];
}
inline int getnxt(int i)
{
	while(!s[i].empty()&&done[s[i].back()])
		s[i].pop_back();
	if(s[i].empty())
		return 0;
	else
	{
		int t=s[i].back();
		s[i].pop_back();
		return t;
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&u[0],&v[0]);
		addedge(u[0],v[0],i*2);
		addedge(v[0],u[0],i*2+1);
	}
	dfs0(1);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&u[i],&v[i]);
		s[u[i]].push_back(i);
		s[v[i]].push_back(i);
		t[i*2-1]=i*2-1;
		t[i*2]=i*2;
		int e=lca(u[i],v[i]);
		for(int j=u[i];j!=e;j=fa[j])
			sf[j]++;
		for(int j=v[i];j!=e;j=fa[j])
			sf[j]++;
	}
	for(int i=2;i<=n;i++)
		ans+=min(sf[i],2);
	tot=m;
	int la=0;
	for(int i=1;i<n;i++)
	{
		int r=0;
		for(int j=1;j<=n;j++)
			if(rd[j]==1)
			{
				r=j;
				break;
			}
		if(r==0)
			break;
		int ft=0;
		for(int j=fr[r];j!=0;j=nxt[j])
			if(rd[em[j]]>0)
			{
				ft=em[j];
				break;
			}
		if(i==n-1)
			la=ft;
		for(int j=fr[r];j!=0;j=nxt[j])
			rd[em[j]]--;
		rd[r]=0;
		int ia=0,ib=0;
		ia=getnxt(r);
		ib=getnxt(r);
		if(ia==0)
			continue;
		if(ib==0)
		{
			int ig=ia;
			done[ig]=1;
			if(u[ig]==ft||v[ig]==ft)
				continue;
			++tot;
			t[tot*2-1]=tot*2-1;
			t[tot*2]=tot*2;
			u[tot]=u[ig];
			v[tot]=v[ig];
			if(u[tot]==r)
				u[tot]=ft;
			else
				v[tot]=ft;
			s[u[tot]].push_back(tot);
			s[v[tot]].push_back(tot);
			Union(ig*2-1,tot*2-1);
			Union(ig*2,tot*2);
		}
		else
		{
			int ig=0;
			while(ig=getnxt(r))
			{
				done[ig]=1;
				if(u[ig]==ft||v[ig]==ft)
					continue;
				++tot;
				t[tot*2-1]=tot*2-1;
				t[tot*2]=tot*2;
				u[tot]=u[ig];
				v[tot]=v[ig];
				if(u[tot]==r)
					u[tot]=ft;
				else
					v[tot]=ft;
				s[u[tot]].push_back(tot);
				s[v[tot]].push_back(tot);
				Union(ig*2-1,tot*2-1);
				Union(ig*2,tot*2);
			}
			done[ia]=done[ib]=1;
			int ta=0,tb=0,oka=0,okb=0;
			if(u[ia]==r)
			{
				ta=v[ia];
				oka=1;
			}
			else
				ta=u[ia];
			if(v[ib]==r)
			{
				tb=u[ib];
				okb=1;
			}
			else
				tb=v[ib];
			if(ta==tb)
			{
				if(oka==okb)
				{
					Union(ia*2-1,ib*2-1);
					Union(ia*2,ib*2);
				}
				else
				{
					Union(ia*2-1,ib*2);
					Union(ia*2,ib*2-1);
				}
				continue;
			}
			++tot;
			u[tot]=ta;
			v[tot]=tb;
			t[tot*2-1]=tot*2-1;
			t[tot*2]=tot*2;
			if(u[ia]==r)
				s[v[ia]].push_back(tot);
			else
				s[u[ia]].push_back(tot);
			if(u[ib]==r)
				s[v[ib]].push_back(tot);
			else
				s[u[ib]].push_back(tot);
			if(!oka)
			{
				Union(ia*2-1,tot*2-1);
				Union(ia*2,tot*2);
			}
			else
			{
				Union(ia*2-1,tot*2);
				Union(ia*2,tot*2-1);
			}
			if(!okb)
			{
				Union(ib*2-1,tot*2-1);
				Union(ib*2,tot*2);
			}
			else
			{
				Union(ib*2-1,tot*2);
				Union(ib*2,tot*2-1);
			}
		}
	}
	memset(out,-1,sizeof(out));
	for(int i=1;i<=2*m;i+=2)
		if(out[(find(i)+1)/2]==-1)
		{
			for(int j=1;j<=2*m;j++)
				if(find(j)==find(i))
				{
					if(j&1)
						out[(j+1)/2]=1;
					else
						out[j/2]=0;
				}
				else if(find(j)==find(i+1))
				{
					if(j&1)
						out[(j+1)/2]=0;
					else
						out[j/2]=1;
				}
		}
	printf("%d\n",ans);
	for(int i=1;i<=m;i++)
		if(out[i])
			printf("%d %d\n",u[i],v[i]);
		else
			printf("%d %d\n",v[i],u[i]);
	return 0;
}


Measured memory_bytes: 32888