// #pragma GCC target("avx")  // CPU 処理並列化
// #pragma GCC optimize("O3")  // CPU 処理並列化
// #pragma GCC optimize("unroll-loops")  // 条件処理の呼び出しを減らす
// #define BEGIN_STACK_EXTEND(size) void * stack_extend_memory_ = malloc(size);void * stack_extend_origin_memory_;char * stack_extend_dummy_memory_ = (char*)alloca((1+(int)(((long long)stack_extend_memory_)&127))*16);*stack_extend_dummy_memory_ = 0;asm volatile("mov %%rsp, %%rbx\nmov %%rax, %%rsp":"=b"(stack_extend_origin_memory_):"a"((char*)stack_extend_memory_+(size)-1024));
// #define END_STACK_EXTEND asm volatile("mov %%rax, %%rsp"::"a"(stack_extend_origin_memory_));free(stack_extend_memory_);

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<deque>
#include<stack>
#include<string>
#include<string.h>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#include<stdlib.h>
#include<cassert>
#include<time.h>
#include<bitset>
#include<numeric>
#include<unordered_set>
#include<unordered_map>
#include<complex>
using namespace std;
const long long mod=998244353;
const long long inf=mod*mod;
const long long d2=(mod+1)/2;
const long double EPS=1e-9;
const long double INF=1e+10;
const long double PI=acos(-1.0);
const int C_SIZE = 3100000;
const int UF_SIZE = 3100000;
namespace{
	long long fact[C_SIZE];
	long long finv[C_SIZE];
	long long inv[C_SIZE];
	long long Comb(int a,int b){
	 	if(a<b||b<0)return 0;
	 	return fact[a]*finv[b]%mod*finv[a-b]%mod;
	}
	void init_C(int n){
		fact[0]=finv[0]=inv[1]=1;
		for(int i=2;i<n;i++){
			inv[i]=(mod-(mod/i)*inv[mod%i]%mod)%mod;
		}
		for(int i=1;i<n;i++){
			fact[i]=fact[i-1]*i%mod;
			finv[i]=finv[i-1]*inv[i]%mod;
		}
	}
	long long pw(long long a,long long b){
		if(a<0LL)return 0;
		if(b<0LL)return 0;
		long long ret=1;
		while(b){
			if(b%2)ret=ret*a%mod;
			a=a*a%mod;
			b/=2;
		}
		return ret;
	}
	long long pw_mod(long long a,long long b,long long M){
		if(a<0LL)return 0;
		if(b<0LL)return 0;
		long long ret=1;
		while(b){
			if(b%2)ret=ret*a%M;
			a=a*a%M;
			b/=2;
		}
		return ret;
	}
	int pw_mod_int(int a,int b,int M){
		if(a<0)return 0;
		if(b<0)return 0;
		int ret=1;
		while(b){
			if(b%2)ret=(long long)ret*a%M;
			a=(long long)a*a%M;
			b/=2;
		}
		return ret;
	}
	int ABS(int a){return max(a,-a);}
	long long ABS(long long a){return max(a,-a);}
	double ABS(double a){return max(a,-a);}
	int sig(double r) { return (r < -EPS) ? -1 : (r > +EPS) ? +1 : 0; }
	int UF[UF_SIZE];
	void init_UF(int n){
		for(int i=0;i<n;i++)UF[i]=-1;
	}
	int FIND(int a){
		if(UF[a]<0)return a;
		return UF[a]=FIND(UF[a]);
	}
	void UNION(int a,int b){
		a=FIND(a);b=FIND(b);if(a==b)return;
		// if(UF[a]>UF[b])swap(a,b);
		UF[a]+=UF[b];UF[b]=a;
	}
}
// ここから編集しろ
vector<pair<int,int> >g[2100];
int s[2100];
int t[2100];
set<int>S[2100];
vector<int>e[2100];
int v[2100];
int L[2100];
int R[2100];
int dfs(int a,int b,int c,int d){
	if(a==c){
		return 1;
	}
	for(int i=0;i<g[a].size();i++){
		int to=g[a][i].first;
		if(to==b)continue;
		int tmp=dfs(to,a,c,d);
		if(tmp){
			S[g[a][i].second].insert(d);
			e[d].push_back(g[a][i].second);
			return 1;
		}
	}
	return 0;
}
int n;
vector<pair<int,int> > solve(int a,vector<pair<int,int> > h){
	if(a==1)return h;
	// printf("%d\n",a);
	// for(int i=0;i<h.size();i++)printf("%d %d\n",h[i].first,h[i].second);
	// for(int i=0;i<n;i++)printf("%d ",v[i]);
	// printf("\n\n");
	int at=0;
	int to=0;
	int id=0;
	for(int i=0;i<n;i++){
		if(v[i])continue;
		int sz=0;
		int tt=0;
		int ii=0;
		for(int j=0;j<g[i].size();j++){
			if(v[g[i][j].first])continue;
			sz++;
			tt=g[i][j].first;
			ii=g[i][j].second;
		}
		if(sz==1){
			at=i;
			to=tt;
			id=ii;
			break;
		}
	}
	v[at]=1;
	int SZ=0;
	vector<int>f;
	vector<pair<int,int> > del;
	for(int i=0;i<h.size();i++){
		if(h[i].first==h[i].second){
			del.push_back(make_pair(i,h[i].first));
		}else if(h[i].first==at||h[i].second==at){
			SZ++;
			f.push_back(i);
		}
	}
	vector<pair<int,int> > ret;
	if(SZ==0){
		ret=solve(a-1,h);
	}else if(SZ==1){
		if(h[f[0]].first==at)h[f[0]].first=to;
		else h[f[0]].second=to;
		ret=solve(a-1,h);
		if(ret[f[0]].first==to)ret[f[0]].first=at;
		else ret[f[0]].second=at;
		return ret;
	}else{
		int A,B;
		if(h[f[0]].first==at)A=h[f[0]].second;
		else A=h[f[0]].first;
		if(h[f[1]].first==at)B=h[f[1]].second;
		else B=h[f[1]].first;
		h[f[0]]=make_pair(A,B);
		h[f[1]]=make_pair(-1,-1);
		for(int i=2;i<f.size();i++){
			if(h[f[i]].first==at)h[f[i]].first=to;
			else h[f[i]].second=to;
		}
		ret=solve(a-1,h);
		if(ret[f[0]].first==A){
			ret[f[0]]=make_pair(A,at);
			ret[f[1]]=make_pair(at,B);
		}else{
			ret[f[0]]=make_pair(at,A);
			ret[f[1]]=make_pair(B,at);
		}
		for(int i=2;i<f.size();i++){
			if(ret[f[i]].first==to)ret[f[i]].first=at;
			else ret[f[i]].second=at;
		}
	}
	for(int i=0;i<del.size();i++){
		ret[del[i].first]=make_pair(del[i].second,del[i].second);
	}
	return ret;
}
int main(){
	int a,b;scanf("%d%d",&a,&b);
	n=a;
	for(int i=0;i<a-1;i++){
		int p,q;scanf("%d%d",&p,&q);p--;q--;
		g[p].push_back(make_pair(q,i));
		g[q].push_back(make_pair(p,i));
	}
	for(int i=0;i<b;i++){
		scanf("%d%d",s+i,t+i);
		s[i]--;
		t[i]--;
		dfs(s[i],-1,t[i],i);
	}
	int ret=0;
	for(int i=0;i<a-1;i++){
		ret+=min(2,(int)(S[i].size()));
	}
	vector<pair<int,int> > st;
	for(int i=0;i<b;i++)st.push_back(make_pair(s[i],t[i]));
	vector<pair<int,int> > ans=solve(n,st);

	printf("%d\n",ret);
	for(int i=0;i<ans.size();i++){
		printf("%d %d\n",ans[i].first+1,ans[i].second+1);
	}
}

Measured memory_bytes: 110592