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++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>
 
using namespace std;
 
const int N=2000000+5;
const int LOG=23;
 
vector<int> g[N];
 
inline void add(int u,int v) {
	g[u].push_back(v);
	g[v].push_back(u);
}
 
int n;
int m;
 
vector<pair<int,int> > out[N];
 
bool del[N];
 
int fa[N][LOG];
int dep[N];
 
void dfs(int u,int pre) {
	memset(fa[u],-1,sizeof(fa[u]));
	fa[u][0]=pre;
	for (int i=1;i<LOG;++i) {
		if (fa[u][i-1]!=-1) {
			fa[u][i]=fa[fa[u][i-1]][i-1];
		}
	}
	for (auto v:g[u]) {
		if (v!=pre) {
			dep[v]=dep[u]+1;
			dfs(v,u);
		}
	}
}
 
int lca(int a,int b) {
	if (dep[a]<dep[b]) {
		swap(a,b);
	}
	for (int i=LOG-1;i>=0;--i) {
		if (fa[a][i]!=-1&&dep[fa[a][i]]>=dep[b]) {
			a=fa[a][i];
		}
	}
	if (a==b) {
		return a;
	}
	for (int i=LOG-1;i>=0;--i) {
		if (fa[a][i]!=-1&&fa[b][i]!=-1&&fa[a][i]!=fa[b][i]) {
			a=fa[a][i];
			b=fa[b][i];
		}
	}
	return fa[a][0];
}
 
int ans;
int t[N];
 
int dfs1(int u,int pre) {
	int tot=t[u];
	for (auto v:g[u]) {
		if (v!=pre) {
			int now=dfs1(v,u);
			ans+=(now>=1)+(now>=2);
			tot+=now;
		}
	}
	return tot;
}
 
int pre[N];
int turn[N];
int rem[N];
int tot;
int ch[N][2];
 
int x[N];
int y[N];
 
bool cmp(int a,int b) {
	return dep[a]==dep[b]?a<b:dep[a]<dep[b];
}
 
void dfs2(int u,int fa) {
	for (auto v:g[u]) {
		if (v!=fa) {
			dfs2(v,u);
		}
	}
	deque<pair<int,int> > real;
	for (auto i:out[u]) {
		if (del[i.second]) {
			continue;
		}
		real.push_back(i);
	}
	if ((int)real.size()==0) {
		return;
	}
	while ((int)real.size()>1) {
		pair<int,int> a=real[0];
		pair<int,int> b=real[1];
		real.pop_front();
		real.pop_front();
		++tot;
		out[a.first].push_back(make_pair(b.first,tot));
		out[b.first].push_back(make_pair(a.first,tot));
		x[tot]=a.first;
		y[tot]=b.first;
		ch[tot][0]=a.second;
		ch[tot][1]=b.second;
		pre[a.second]=tot;
		pre[b.second]=tot;
		del[a.second]=del[b.second]=1;
	}
	if (real.size()==1) {
		int k=real[0].first;
		if (k==u) {
			return;
		}
		++tot; 
		out[k].push_back(make_pair(fa,tot));
		out[fa].push_back(make_pair(k,tot));
		del[real[0].second]=1;
		x[tot]=k;
		y[tot]=fa;
		pre[real[0].second]=tot;
		ch[tot][0]=real[0].second; 
		return;
	}
}
 
bool vis[N];
 
void doswap(int r){
 	swap(x[r],y[r]);
 	swap(ch[r][0],ch[r][1]);
}
 
void dfs4(int r) {
	vis[r]=1;
	if (ch[r][0]!=-1) { 
		if (x[r]==y[ch[r][0]]) {
		 	doswap(ch[r][0]);
		}
		assert(x[r]==x[ch[r][0]]);
		dfs4(ch[r][0]);
	}
	if (ch[r][1]!=-1) { 
		if (y[r]==x[ch[r][1]]){
		 	doswap(ch[r][1]);
		}
		assert(y[r]==y[ch[r][1]]);
		dfs4(ch[r][1]);
	} 
	
}
	
int deg[N];
 
int main() {
	scanf("%d %d",&n,&m);
	for (int i=0,u,v;i<n-1;++i) {
		scanf("%d %d",&u,&v);
		--u;
		--v;
		add(u,v);
		++deg[u];
		++deg[v];
	}
	int r=0;
	for (int i=0;i<n;++i) {
	  if (deg[i]==1) {
			r=i;
			break;
		}
	}
	dfs(r,-1);
	for (int i=0,u,v;i<m;++i) {
		scanf("%d %d",&u,&v);
		--u;
		--v;
		if (cmp(u,v)) {
			swap(u,v);
		}
		out[u].push_back(make_pair(v,i));
		out[v].push_back(make_pair(u,i));
		t[u]++;
		t[v]++;
		t[lca(u,v)]-=2;
		x[i]=u;
		y[i]=v;
	}
	for (int i=0;i<N;++i) {
		pre[i]=i;
	}
	tot=m;
	dfs1(r,-1);
	
	printf("%d\n",ans);
	memset(ch,-1,sizeof(ch));
	dfs2(r,-1);
	for (int i=0;i<=tot;++i) {
		if (!vis[i]) {
			int root=i;
			while (pre[root]!=root) {
				root=pre[root];
			}
			dfs4(root);
		}
	}
	
	for (int i=0;i<m;++i) {
 
			printf("%d %d\n",x[i]+1,y[i]+1);
 
	}
	return 0;
}