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 (Clang 3.8.0) (judge verdict: Accepted)

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 2e3 + 5;
int read() {
	int x = 0, f = 1; char ch;
	while(! isdigit(ch = getchar())) (ch == '-') && (f = -f);
	for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 3) + (x << 1) + (ch ^ 48));
	return x * f;
}
template <class T> T Max(T a, T b) { return a > b ? a : b; }
template <class T> T Min(T a, T b) { return a < b ? a : b; }
struct Edge {
	int to;
	Edge *nxt;
	Edge(int to, Edge *nxt) : to(to), nxt(nxt) {}
} *head[N];
void add(int x, int y) {head[x] = new Edge(y, head[x]);}
int n, m, ans, fa[N], fav[N], deg[N], dep[N];
void dfs(int x) {
	dep[x] = dep[fa[x]] + 1;
	for(Edge *i = head[x]; i; i = i->nxt) {
		if(i->to == fa[x]) continue;
		fa[i->to] = x;
		dfs(i->to);
	}
}
void col(int x, int y) {
	if(dep[x] < dep[y]) swap(x, y);
	while(dep[x] > dep[y]) fav[x] ++, x = fa[x];
	while(x != y) fav[x] ++, fav[y] ++, x = fa[x], y = fa[y];
}
struct node {
	int x, y;
	node(int x = 0, int y = 0) : x(x), y(y) {}
};
bool operator == (node a, node b) {return a.x == b.x && a.y == b.y;}
vector <node> solve(vector <node> v) {
	if(v.size() == 0) return v;
	int x, u; for(x = 1; x <= n; ++ x) if(deg[x] == 1) break;
	if(x > n) return v;
	for(Edge *i = head[x]; i; i = i->nxt) {
		if(deg[i->to]) {u = i->to; break;}
	}
	deg[x] --; deg[u] --;
	vector <node> lx, nv;
	vector <int> id;
	int pos[N];
	memset(pos, -1, sizeof(pos));
	for(int i = 0; i < v.size(); ++ i) {
		if(v[i].x == x || v[i].y == x) lx.push_back(v[i]), id.push_back(i);
		else nv.push_back(v[i]), pos[i] = nv.size() - 1;
	}
	if(lx.size() == 0) return solve(v);
	for(int i = 0; i + 1 < lx.size(); i += 2) {
		if(lx[i].y == x) swap(lx[i].x, lx[i].y);
		if(lx[i + 1].y == x) swap(lx[i + 1].x, lx[i + 1].y);
		if(lx[i] == lx[i + 1]) {
			if(v[id[i]] == v[id[i + 1]]) swap(v[id[i]].x, v[id[i]].y);
			continue;
		}
		nv.push_back(node(lx[i].y, lx[i + 1].y));
		pos[id[i]] = pos[id[i + 1]] = nv.size() - 1;
	}
	if(lx.size() & 1) {
		if(lx[lx.size() - 1].y == x) swap(lx[lx.size() - 1].x, lx[lx.size() - 1].y);
		if(lx[lx.size() - 1].y != u) {
			nv.push_back(node(u, lx[lx.size() - 1].y));
			pos[id[lx.size() - 1]] = nv.size() - 1;
		}
	}
	nv = solve(nv);
	for(int i = 0; i < v.size(); ++ i) {
		if(pos[i] != -1 && !(v[i].x == nv[pos[i]].x || v[i].y == nv[pos[i]].y)) swap(v[i].x, v[i].y);
	}
	return v;
}
vector <node> v;
int main() {
//	freopen(".in", "r", stdin);
//	freopen(".out", "w", stdout);
	n = read(); m = read();
	for(int i = 1, x, y; i < n; ++ i) deg[x = read()] ++, deg[y = read()] ++, add(x, y), add(y, x);
	dfs(1);
	for(int i = 1, x, y; i <= m; ++ i) x = read(), y = read(), v.push_back(node(x, y)), col(x, y);
	v = solve(v);
	ans = 0;
	for(int i = 2; i <= n; ++ i) ans += min(2, fav[i]);
	printf("%d\n", ans);
	for(int i = 0; i < v.size(); ++ i) printf("%d %d\n", v[i].x, v[i].y);
	fclose(stdin);
	fclose(stdout);
	return 0;
}