#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

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

const int maxn = 2015;
const int maxm = 4e6 + 10;

struct route
{
	int u, v, l, r;
	route() {l = r = -1;}
	route(int u, int v): u(u), v(v) {}
	route(int u, int v, int l, int r): u(u), v(v), l(l), r(r) {}
} a[maxm];

int n, m, deg[maxn], fa[maxn], dfn[maxn], mn[maxn << 2][15], dep[maxn], tot, ans[maxm];
bool cover[maxn], vis[maxn];
vector<int> linker[maxn];

inline int mymin(int u, int v) {return dep[u] <= dep[v] ? u : v;}

int ind = 0, mylog[maxn << 1], cnt[maxn];
set<int> foo[maxn];

void dfs(int x, int pre)
{
	fa[x] = pre, dfn[x] = ++ ind;
	dep[x] = dep[pre] + 1;
	mn[ind][0] = x;
	for (int cur : linker[x])
		if (cur != pre) deg[x] ++, dfs(cur, x), mn[++ ind][0] = x;
}

void rmq_init()
{
	mylog[1] = 0; for (int i = 2; i <= ind; i ++) mylog[i] = mylog[i >> 1] + 1;
	for (int j = 1; j <= 13; j ++)
		for (int i = 1; i + (1 << j) - 1 <= ind; i ++)
			mn[i][j] = mymin(mn[i][j - 1], mn[i + (1 << (j - 1))][j - 1]);
}

int lca(int u, int v)
{
	u = dfn[u], v = dfn[v];
	if (u > v) swap(u, v);
	int w = mylog[v - u + 1];
	return mymin(mn[u][w], mn[v - (1 << w) + 1][w]);
}


int check_ans()
{
	static int cnt1[maxn], cnt2[maxn];
	int ans = 0;
	memset(cnt1, 0, sizeof cnt1);
	memset(cnt2, 0, sizeof cnt2);
	for (int i = 1; i <= m; i ++)
	{
		int u = a[i].u, v = a[i].v;
		int up = lca(u, v);
		for (; u != up; u = fa[u]) cnt1[u] ++;
		for (; v != up; v = fa[v]) cnt2[v] ++;
	}
	for (int i = 1; i <= n; i ++)
	{
		ans += (cnt1[i] >= 1) + (cnt2[i] >= 1);
		if (cover[i] && ((!cnt1[i]) || (!cnt2[i])))
			cerr << " i = " << i << endl;
		if (cnt[i] >= 2 && !cover[i])
			cerr << " now  i = " << i << endl;
	}
	return ans;
}

int Ans = 0;

int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
	n = read(), m = read();
	for (int i = 1; i <  n; i ++)
	{
		int u = read(), v = read();
		linker[u].push_back(v);
		linker[v].push_back(u);
	}
	dfs(1, 0), rmq_init();
	static int q[maxn];
	int head = 1, tail = 0;
	for (int i = 1; i <= n; i ++) if (!deg[i]) q[++ tail] = i;
	for (int i = 1; i <= m; i ++)
	{
		int u = read(), v = read();
		if (u == v) continue;
		a[++ tot] = route(u, v);
		foo[u].insert(tot);
		foo[v].insert(tot);
		int up = lca(u, v);
		for (int j = u; j != up; j = fa[j]) cnt[j] ++;
		for (int j = v; j != up; j = fa[j]) cnt[j] ++;
	}
	for (int i = 2; i <= n; i ++) Ans += min(2, cnt[i]);
	printf("%d\n", Ans);
	while (head <= tail)
	{
		int x = q[head ++];
		deg[fa[x]] --;
		if (!deg[fa[x]]) q[++ tail] = fa[x];
		for (auto it = foo[x].begin(); it != foo[x].end(); )
		{
			auto cur = a[*it];
//			if (x == 36)
//				cerr << " cur = " << *it << endl;
			if (cur.u == cur.v)
			{
				auto it2 = it;
				it2 ++;
				ans[*it] = 0;
				foo[x].erase(it);
				it = it2;
			}
			else it ++;
		}
//		if (cnt[x] >= 2 && !cover[x])
//			cerr << foo[x].size() << endl;
		if (foo[x].empty()) continue;
		if (foo[x].size() >= 2 && !cover[x])
		{
			auto it = foo[x].begin(), it2 = it;
			it2 ++;
			auto cur1 = *it, cur2 = *it2;
			foo[x].erase(it), foo[x].erase(it2);
			int p = a[cur1].u ^ a[cur1].v ^ x, q = a[cur2].u ^ a[cur2].v ^ x;
			memset(vis, 0, sizeof vis);
			int up1 = lca(x, p), up2 = lca(x, q);
			for (int i = x; i != up1; i = fa[i]) vis[i] = 1;
			for (int i = p; i != up1; i = fa[i]) vis[i] = 1;
			for (int i = x; i != up2; i = fa[i]) if (vis[i]) cover[i] = 1;
			for (int i = q; i != up2; i = fa[i]) if (vis[i]) cover[i] = 1;
			a[++ tot] = route(p, q, cur1, cur2);
			foo[p].erase(cur1), foo[q].erase(cur2);
			foo[p].insert(tot), foo[q].insert(tot);
		}
		while (foo[x].size())
		{
			int id = *foo[x].begin();
			foo[x].erase(foo[x].begin());
			if (a[id].u == x)
			{
				int other = a[id].v;
				foo[other].erase(id);
				a[++ tot] = route(fa[x], other, id, -1);
				foo[other].insert(tot);
				foo[fa[x]].insert(tot);
			}
			else
			{
				int other = a[id].u;
				foo[other].erase(id);
				a[++ tot] = route(other, fa[x], id, -1);
				foo[other].insert(tot);
				foo[fa[x]].insert(tot);
			}
		}

	}
	for (int i = tot; i > m; i --) if (~a[i].l)
	{
		if (~a[i].r)
		{
			int p = a[i].u, q = a[i].v;
			ans[a[i].l] = ans[i] ^ (a[a[i].l].u != p);
			ans[a[i].r] = ans[i] ^ (a[a[i].r].v != q);
		}
		else ans[a[i].l] = ans[i];
	}
	for (int i = 1; i <= m; i ++)
	{
		if (ans[i]) swap(a[i].u, a[i].v);
		printf("%d %d\n", a[i].u, a[i].v);
	}
//	cerr << check_ans() << " " << Ans << endl;
	return 0;
}


Measured memory_bytes: 71168