#include <bits/stdc++.h>

using namespace std;

const int maxn = 2010;
const int inf = 0x3f3f3f3f;

typedef pair<int,int> pi;

int n, m, l[maxn], e = 0, sum;
int lca[maxn][maxn], fa[maxn], dep[maxn], sz[maxn], dfn[maxn], tot;
int fa_e[maxn], cnt[maxn<<1]; // 边覆盖次数(有向)

struct Edge {
	int v, x;
} E[maxn<<1];

inline void addEdge(int u, int v) {
	E[e].v = v, E[e].x = l[u], l[u] = e++;
	E[e].v = u, E[e].x = l[v], l[v] = e++;
}

vector<int> dfs_init(int u, int f) {
	vector<int> ret; ret.push_back(u);
	fa[u] = f; lca[u][u] = u; dfn[u] = ++ tot; sz[u] = 1;
	for (int p = l[u]; p >= 0; p = E[p].x) {
		int v = E[p].v;
		if (v != f) {
			dep[v] = dep[u] + 1;
			fa_e[v] = p^1;
			vector<int> t = dfs_init(v, u);
			sz[u] += sz[v];
			for (int i = 0; i < t.size(); i++) {
				for (int j = 0; j < ret.size(); j++) {
					lca[t[i]][ret[j]] = lca[ret[j]][t[i]] = u;
				}
			}
			for (int i = 0; i < t.size(); i++) ret.push_back(t[i]);
		}
	}
	return ret;
}

void add(int u, int v, int x) {
	int l = lca[u][v];
	while (u != l) {cnt[fa_e[u]] += x, cnt[fa_e[u]^1] += x; u = fa[u];}
	while (v != l) {cnt[fa_e[v]] += x, cnt[fa_e[v]^1] += x; v = fa[v];}
}

// 注意 ret 可能 = -1
int ask(int u, int v) {
	int ret = -1;
	int l = lca[u][v];
	while (u != l) {if (cnt[fa_e[u]] == 2) ret = fa_e[u]; u = fa[u];}
	while (v != l) {if (cnt[fa_e[v]] == 2) ret = fa_e[v]; v = fa[v];}
	return ret;
}

// x 是否在 u 的子树
int inSubtree(int x, int u) {
	return dfn[x] >= dfn[u] && dfn[x] < dfn[u] + sz[u];
}

// ed 是否在 s 到 t 路径上
int onPath(int ed, int s, int t) {
	int u = E[ed].v, v = E[ed^1].v;
	if (dep[u] < dep[v]) swap(u, v);
	return inSubtree(s, u) ^ inSubtree(t, u);
}

vector<int> solve(vector<pi> links) {
	if (links.empty()) return vector<int>();
	int s1 = -1, t1 = -1, s2 = -1, t2 = -1, p1 = -1, p2 = -1, r1 = 0, r2 = 0;
	vector<int> res;
	vector<pi> links1, links2; // -1 随便, 0-2000 代表 links1 上下标, 2001~4000 代表 links2 上下标
	for (int _ = 0; _ < links.size(); _++) {
		int s = links[_].first, t = links[_].second;
		int ed = ask(s, t);
		if (ed == -1) {
			res.push_back(-1);
			add(s, t, -1);
		} else {
			p1 = _;
			int e_u = E[ed].v, e_v = E[ed^1].v;
			s1 = s, t1 = t, s2 = -1, t2 = -1;
			for (int __  = _+1; __ < links.size(); __++) {
				int _s = links[__].first, _t = links[__].second;
				if (onPath(ed, _s, _t)) {
					s2 = _s, t2 = _t;
					p2 = __;
					break;
				}
			}
			{
				int l = lca[s][t];
				while (s != l) {if (onPath(fa_e[s], s2, t2)) cnt[fa_e[s]] = cnt[fa_e[s]^1] = inf; s = fa[s];}
				while (t != l) {if (onPath(fa_e[t], s2, t2)) cnt[fa_e[t]] = cnt[fa_e[t]^1] = inf; t = fa[t];}
			}
			if (dep[e_u] < dep[e_v]) swap(e_u, e_v);
			// 放入 l1 l2
			if (!inSubtree(s1, e_u)) {swap(s1, t1); r1 ^= 1;}
			if (!inSubtree(s2, e_u)) {swap(s2, t2); r2 ^= 1;}
			links1.push_back(pi(s1, s2));
			links2.push_back(pi(t1, t2));
			res.push_back(0);
			for (int __ = _+1; __ < links.size(); __++) {
				if (__ == p2) {
					res.push_back(2001);
					continue;
				}
				int _s = links[__].first, _t = links[__].second;
				if (inSubtree(_s, e_u)) {
					links1.push_back(links[__]);
					res.push_back(links1.size()-1);
				} else {
					links2.push_back(links[__]);
					res.push_back(2001 + links2.size() - 1);
				}
			}
			break;
		}
	}
	vector<int> res1 = solve(links1), res2 = solve(links2);
	// 判断是否需要取反
	if (s1 != -1) {
		if (!res1[0] && !res2[0]) for (int i = 0; i < res2.size(); i++) res2[i] ^= 1;
		else if (res1[0] && res2[0]) for (int i = 0; i < res1.size(); i++) res1[i] ^= 1;
		else if (res1[0] && !res2[0]) {
			for (int i = 0; i < res1.size(); i++) res1[i] ^= 1;
			for (int i = 0; i < res2.size(); i++) res2[i] ^= 1;
		}
	}
	vector<int> ret;
	for (int i = 0; i < res.size(); i++) {
		int t = res[i];
		if (t == -1) ret.push_back(0);
		else if (t == 0) {
			ret.push_back(r1);
		} else if (t == 2001) {
			ret.push_back(r2^1);
		} else if (t <= 2000) ret.push_back(res1[t]);
		else ret.push_back(res2[t-2001]);
	}
	return ret;
}

int main() {
	//freopen("data.in", "r", stdin);
	memset(l, -1, sizeof(l));
	scanf("%d%d", &n, &m);
	for (int i = 1; i < n; i++) {
		int u, v; scanf("%d%d", &u, &v);
		addEdge(u, v);
	}
	dfs_init(1, 0);
	vector<pi> links;
	for (int i = 1; i <= m; i++) {
		int u, v; scanf("%d%d", &u, &v);
		links.push_back(pi(u, v));
		add(u, v, 1);
	}
	for (int i = 0; i < e; i += 2) sum += min(cnt[i], 2);
	printf("%d\n", sum);
	vector<int> ans = solve(links);
	for (int i = 1; i <= m; i++) {
		int u = links[i-1].first, v = links[i-1].second;
		if (ans[i-1]) swap(u, v);
		printf("%d %d\n", u, v);
	}
	return 0;
}

Measured memory_bytes: 30336