#include <bits/stdc++.h>
#define debug(x) cerr << #x << " " << (x) << endl
using namespace std;

const int N = 2005, M = 2005;

template <class T>
void read (T &x) {
	int sgn = 1;
	char ch;
	x = 0;
	for (ch = getchar(); (ch < '0' || ch > '9') && ch != '-'; ch = getchar()) ;
	if (ch == '-') ch = getchar(), sgn = -1;
	for (; '0' <= ch && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
	x *= sgn;
}

template <class T>
void write (T x) {
	if (x < 0) putchar('-'), write(-x);
	else if (x < 10) putchar(x + '0');
	else write(x / 10), putchar(x % 10 + '0');
}

struct edge {
	int to, nxt;
} tree[N << 1];
int n, m, head[N], cnt = 0;
void addedge (int u, int v) {
	edge e = {v, head[u]};
	tree[head[u] = cnt++] = e;
}

struct path {
	int u, v;
} ;
vector<path> vec;
vector<int> lch, rch, isroot;
vector<int> adj[N];

int par[N], tag[N];

void dfs1 (int u, int fa) {
	par[u] = fa;
	for (int i = head[u]; ~i; i = tree[i].nxt) {
		int v = tree[i].to;
		if (v != fa) dfs1(v, u);
	}
}

int lca (int u, int v) {
	stack<int> stk1, stk2;

	for (; u; u = par[u]) stk1.push(u);
	for (; v; v = par[v]) stk2.push(v);
	while (!stk1.empty() && !stk2.empty() && stk1.top() == stk2.top()) stk1.pop(), stk2.pop();
	if (!stk1.empty()) return par[stk1.top()];
	else return par[stk2.top()];
}

void dfs2 (int u, int fa) {
	for (int i = head[u]; ~i; i = tree[i].nxt) {
		int v = tree[i].to;
		if (v != fa) dfs2(v, u), tag[u] += tag[v];
	}
}

void dfs3 (int u, int fa) {
	for (int i = head[u]; ~i; i = tree[i].nxt) {
		int v = tree[i].to;
		if (v != fa) dfs3(v, u);
	}

	if (!fa) return ;
	vector<int> tmp;
	for (int i = 0; i < adj[u].size(); i++) {
		int id = adj[u][i];
		if (vec[id].u == vec[id].v) continue ;
		if (isroot[adj[u][i]]) tmp.push_back(adj[u][i]);
	}

	for (int i = (tmp.size() <= 1) ? 0 : 2; i < tmp.size(); i++) {
		if (vec[tmp[i]].u != u) swap(vec[tmp[i]].u, vec[tmp[i]].v);
		int v = vec[tmp[i]].v, s = vec.size();
		adj[v].push_back(s), adj[fa].push_back(s);

		path p = {fa, v};
		vec.push_back(p), lch.push_back(tmp[i]), rch.push_back(-1);
		isroot.push_back(1), isroot[tmp[i]] = 0;
	}

	if (tmp.size() <= 1) return ;
	if (vec[tmp[0]].u != u) swap(vec[tmp[0]].u, vec[tmp[0]].v);
	if (vec[tmp[1]].u != u) swap(vec[tmp[1]].u, vec[tmp[1]].v);
	int v1 = vec[tmp[0]].v, v2 = vec[tmp[1]].v, s = vec.size();
	adj[v1].push_back(s), adj[v2].push_back(s);
	path p = {v1, v2};
	vec.push_back(p), lch.push_back(tmp[0]), rch.push_back(tmp[1]);
	isroot.push_back(1), isroot[tmp[0]] = isroot[tmp[1]] = 0;
}

void dfs4 (int u) {
	if (~lch[u]) {
		if (vec[rch[u]].u == vec[u].v) swap(vec[lch[u]].u, vec[lch[u]].v);
		else if (vec[lch[u]].v == vec[u].u) swap(vec[lch[u]].u, vec[lch[u]].v);
		dfs4(lch[u]);
	}
	if (~rch[u]) {
		if (vec[rch[u]].u == vec[lch[u]].u) swap(vec[rch[u]].u, vec[rch[u]].v);
		if (vec[rch[u]].v == vec[lch[u]].v) swap(vec[rch[u]].u, vec[rch[u]].v);
		dfs4(rch[u]);
	}
}

int main () {
	read(n), read(m);
	for (int i = 1; i <= n; i++) head[i] = -1;
	for (int i = 1; i < n; i++) {
		int u, v;
		read(u), read(v);
		addedge(u, v), addedge(v, u);
	}

	dfs1(1, 0);
	for (int i = 1; i <= n; i++) tag[i] = 0;

	for (int i = 0; i < m; i++) {
		int u, v;
		read(u), read(v);
		path p = {u, v};
		vec.push_back(p), isroot.push_back(1);
		lch.push_back(-1), rch.push_back(-1);
		adj[u].push_back(i), adj[v].push_back(i);

		tag[u]++, tag[v]++, tag[lca(u, v)] -= 2;
	}

	dfs2(1, 0), dfs3(1, 0);
	for (int i = 0; i < vec.size(); i++) {
		if (isroot[i]) dfs4(i);
	}

	int ans = 0;
	for (int i = 1; i <= n; i++) ans += min(tag[i], 2);
	write(ans), putchar('\n');
	for (int i = 0; i < m; i++) {
		write(vec[i].u), putchar(' ');
		write(vec[i].v), putchar('\n');
	}
	return 0;
}

Measured memory_bytes: 11884