Problem:
Score : 1500 points

Problem Statement

Takahashi loves walking on a tree.
The tree where Takahashi walks has N vertices numbered 1 through N.
The i-th of the N-1 edges connects Vertex a_i and Vertex b_i.

Takahashi has scheduled M walks. The i-th walk is done as follows:

The walk involves two vertices u_i and v_i that are fixed beforehand.

Takahashi will walk from u_i to v_i or from v_i to u_i along the shortest path.

The happiness gained from the i-th walk is defined as follows:

The happiness gained is the number of the edges traversed during the i-th walk that satisfies one of the following conditions:

In the previous walks, the edge has never been traversed.

In the previous walks, the edge has only been traversed in the direction opposite to the direction taken in the i-th walk.

Takahashi would like to decide the direction of each walk so that the total happiness gained from the M walks is maximized.
Find the maximum total happiness that can be gained, and one specific way to choose the directions of the walks that maximizes the total happiness.

Constraints

1 ≤ N,M ≤ 2000

1 ≤ a_i , b_i ≤ N

1 ≤ u_i , v_i ≤ N

a_i \neq b_i

u_i \neq v_i

The graph given as input is a tree.

Input

Input is given from Standard Input in the following format:

N M
a_1 b_1
:
a_{N-1} b_{N-1}
u_1 v_1
:
u_M v_M

Output

Print the maximum total happiness T that can be gained, and one specific way to choose the directions of the walks that maximizes the total happiness, in the following format:

T
u^'_1 v^'_1
:
u^'_M v^'_M

where (u^'_i,v^'_i) is either (u_i,v_i) or (v_i,u_i), which means that the i-th walk is from vertex u^'_i to v^'_i.

Sample Input 1

4 3
2 1
3 1
4 1
2 3
3 4
4 2

Sample Output 1

6
2 3
3 4
4 2

If we decide the directions of the walks as above, he gains the happiness of 2 in each walk, and the total happiness will be 6.

Sample Input 2

5 3
1 2
1 3
3 4
3 5
2 4
3 5
1 5

Sample Output 2

6
2 4
3 5
5 1

Sample Input 3

6 4
1 2
2 3
1 4
4 5
4 6
2 4
3 6
5 6
4 5

Sample Output 3

9
2 4
6 3
5 6
4 5

Solution in C++ (GCC 5.4.1) (judge verdict: Accepted)

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

#define pb push_back
#define mk make_pair
#define lob lower_bound
#define upb upper_bound
#define fst first
#define scd second

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

inline int read(){
	int f=1,x=0;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
inline ll readll(){
	ll f=1,x=0;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

const int MAXN=4005;
struct EDGE{int nxt,to;}edge[MAXN];
int n,m,mm,head[MAXN],tot,ans,fa[MAXN],dep[MAXN],id1[MAXN],id2[MAXN];
inline void add_edge(int u,int v){edge[++tot].nxt=head[u];edge[tot].to=v;head[u]=tot;}
void dfs1(int u){dep[u]=dep[fa[u]]+1;for(int i=head[u];i;i=edge[i].nxt)if(edge[i].to!=fa[u])fa[edge[i].to]=u,dfs1(edge[i].to);}
pii p[MAXN],tp[MAXN];
bool used[MAXN],fl[MAXN],res[MAXN];
void del(int a,int b,int c,int d){
	static int cnt[MAXN];memset(cnt,0,sizeof(int)*(n+5));
	while(a!=b){if(dep[a]<dep[b])swap(a,b);cnt[a]++;a=fa[a];}
	while(c!=d){if(dep[c]<dep[d])swap(c,d);cnt[c]++;c=fa[c];}
	for(int i=1;i<=n;++i)if(cnt[i]>=2)fl[i]=1;
}
void dfs2(int u){
	for(int i=head[u];i;i=edge[i].nxt)if(edge[i].to!=fa[u])dfs2(edge[i].to);
	if(fa[u]){
		vector<int>vec;
		for(int i=1;i<=mm;++i)if(!used[i]&&((tp[i].fst==u)^(tp[i].scd==u))){vec.pb(i);if((int)vec.size()==2)break;}
		ans+=min(max((int)vec.size(),2*fl[u]),2);
		if((int)vec.size()<2||fl[u]){
			for(int i=1;i<=mm;++i)if(!used[i]){
				if(tp[i].fst==u)tp[i].fst=fa[u];
				if(tp[i].scd==u)tp[i].scd=fa[u];
			}
			return;
		}
		int a=vec[0],b=vec[1];
		del(tp[a].fst,tp[a].scd,tp[b].fst,tp[b].scd);
		used[a]=used[b]=1;
		++mm;
		if(tp[a].fst==u)tp[mm].fst=tp[a].scd,p[mm].fst=p[a].scd;
		else tp[mm].fst=tp[a].fst,p[mm].fst=p[a].fst;
		if(tp[b].fst==u)tp[mm].scd=tp[b].scd,p[mm].scd=p[b].scd;
		else tp[mm].scd=tp[b].fst,p[mm].scd=p[b].fst;
		id1[mm]=a;id2[mm]=b;
		for(int i=1;i<=mm;++i)if(!used[i]){
			if(tp[i].fst==u)tp[i].fst=fa[u];
			if(tp[i].scd==u)tp[i].scd=fa[u];
		}
	}
}
int main() {
	n=read();m=mm=read();
	for(int i=1,u,v;i<n;++i)u=read(),v=read(),add_edge(u,v),add_edge(v,u);
	for(int i=1;i<=m;++i)p[i].fst=tp[i].fst=read(),p[i].scd=tp[i].scd=read();
	dfs1(1);dfs2(1);
	printf("%d\n",ans);
	for(int i=mm;i>=1;--i){
		if(!used[i])res[i]=0;
		if(i>m){
			if(!res[i])res[id1[i]]=(p[i].fst!=p[id1[i]].fst),res[id2[i]]=(p[i].scd!=p[id2[i]].scd);
			else res[id1[i]]=(p[i].fst==p[id1[i]].fst),res[id2[i]]=(p[i].scd==p[id2[i]].scd);
		}
	}
	for(int i=1;i<=m;++i)if(!res[i])printf("%d %d\n",p[i].fst,p[i].scd);else printf("%d %d\n",p[i].scd,p[i].fst);
	return 0;
}