#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
#define ri register int
namespace io {
	const int SIZE = (1 << 21) + 1;
	char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c, qu[55]; int f, qr;
	// getchar
	#define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
	// print the remaining part
	inline void flush () {
		fwrite (obuf, 1, oS - obuf, stdout);
		oS = obuf;
	}
	// putchar
	inline void putc (char x) {
		*oS ++ = x;
		if (oS == oT) flush ();
	}
	// input a signed integer
	template <class I>
	inline void gi (I &x) {
		for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;
		for (x = 0; c <= '9' && c >= '0'; c = gc()) x = (x << 1) + (x << 3) + (c & 15); x *= f;
	}
	// print a signed integer
	template <class I>
	inline void print (I x) {
		if (!x) putc ('0'); if (x < 0) putc ('-'), x = -x;
		while (x) qu[++ qr] = x % 10 + '0',  x /= 10;
		while (qr) putc (qu[qr --]);
	}
	//no need to call flush at the end manually!
	struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
}
using io :: gi;
using io :: putc;
using io :: print;
const int N=4e3+5;
int tot,head[N],nxt[N<<1],adj[N<<1],f[N],dep[N],tag[N],cnt[N],ans[N],fa[N],rev[N],a[N],b[N],Ans,num;
inline void addedge(ri x,ri y){
	nxt[++tot]=head[x];
	adj[head[x]=tot]=y;
}
inline void dfs(ri x){
	for(ri y,i=head[x];i;i=nxt[i])
		if((y=adj[i])!=f[x])
			f[y]=x,
			dep[y]=dep[x]+1,
			dfs(y);
}
inline int lca(ri x,ri y){
	if(dep[x]<dep[y]) std::swap(x,y);
	while(dep[x]^dep[y]) x=f[x];
	while(x^y) x=f[x],y=f[y];
	return x;
}
inline int min(ri x,ri y){
	return x<y ? x:y;
}
struct node{
	int x,id,rev;
	inline bool operator ==(const node &rhs)const{
		return x==rhs.x&&id==rhs.id;
	}
};
vector<node> v[N];
inline void erase(vector<node> &v,node target){
	for(vector<node> ::iterator it=v.begin();it!=v.end();++it)
		if(*it==target){
			v.erase(it);
			return;
		}
//	puts("wrong");
}
inline void dfs2(ri x){
	ri i,y;
	node p,q;
	for(i=head[x];i;i=nxt[i])
		if((y=adj[i])!=f[x])
			dfs2(y),
			tag[x]+=tag[y];
	Ans+=min(2,tag[x]);
	while(v[x].size()>=2){
		p=*v[x].begin();
		v[x].erase(v[x].begin());
		q=*v[x].begin();
		v[x].erase(v[x].begin());
	//	printf("merge %d %d %d\n",x,p.x,q.x);
		erase(v[p.x],(node){x,p.id});
		erase(v[q.x],(node){x,q.id});
		if(p.x==q.x)
			ans[p.id]=p.rev,
			ans[q.id]=1^q.rev;
		else
			ans[++num]=-1,
			fa[p.id]=fa[q.id]=num,
	//		printf("new %d %d %d\n",num,p.x,q.x),
			rev[p.id]=p.rev^1,
			rev[q.id]=q.rev,
			v[p.x].push_back((node){q.x,num,0}),
			v[q.x].push_back((node){p.x,num,1});
	}
	if(!v[x].empty()){
		p=*v[x].begin();
	//	printf("rest %d %d %d %d\n",x,p.x,p.id,p.rev);
		erase(v[p.x],(node){x,p.id});
		if(p.x!=f[x])
			v[f[x]].push_back((node){p.x,p.id,p.rev}),
			v[p.x].push_back((node){f[x],p.id,p.rev^1});
		else
			ans[p.id]=0;
	}
}
int main(){
	ri n,m,i,x,y;
	gi(n);gi(m);
	for(i=1;i^n;++i) gi(x),gi(y),addedge(x,y),addedge(y,x);
	dfs(1);
	for(i=1;i<=m;++i)
		gi(a[i]),gi(b[i]),
		ans[i]=-1,
		++tag[a[i]],++tag[b[i]],tag[lca(a[i],b[i])]-=2,
		v[a[i]].push_back((node){b[i],i,0}),
		v[b[i]].push_back((node){a[i],i,1});
	num=m;
	dfs2(1);
	print(Ans);putc('\n');
//	for(i=1;i<=num;++i)
//		printf("%d %d %d\n",i,fa[i],rev[i]);
	for(i=num;i;--i)
		if(ans[i]==-1)
			ans[i]=rev[i]^ans[fa[i]];
	for(i=1;i<=m;++i){
		if(ans[i]) swap(a[i],b[i]);
		print(a[i]);putc(' ');print(b[i]);putc('\n');
	}
	return 0;
}

Measured memory_bytes: 2688