#include <bits/stdc++.h>
#include <tr1/unordered_map>
#define ri register int
using namespace std;
typedef double db;
typedef long double ld;
typedef long long ll;
typedef vector <int> poly;
typedef pair <int, int> pii;
typedef pair <ll, int> pli;
typedef pair <int, ll> pil;
typedef pair <ll, ll> pll;
typedef unsigned long long ulll;
typedef unsigned int uii;
typedef string strr;
#define fi first
#define se second
#define pb push_back
#define ppp pop_back
#define rez resize
#define hhh cout << '\n';
#define dhhh cerr << '\n';
#define jhhh cout << endl;
const ll Inf = 2e18;
const int rlen = 1 << 20, inf = 0x3f3f3f3f;
char buf[rlen], *ib = buf, *ob = buf;
#define gc() (((ib == ob) && (ob = (ib =  buf) + fread(buf, 1, rlen, stdin)), ib == ob) ? -1 : *ib++)
inline int read() {
  static int ans, f;
  static char ch;
  ans = 0, ch = gc(), f = 1;
  while (!isdigit(ch)) f ^= ch == '-', ch = gc();
  while (isdigit(ch)) ans = (ans << 3) + (ans << 1) + (ch ^ 48), ch = gc();
  return f ? ans: -ans;
}
inline ll readl() {
  static ll ans;
  static char ch;
  for (ans = 0, ch = gc(); !isdigit(ch); ch = gc());
  while (isdigit(ch)) ans = ((ans << 2) + ans << 1) + (ch ^ 48), ch = gc();
  return ans;
}
inline int Read(char *s) {
  static int top;
  static char ch;
  top = 0, ch = gc();
  while (!isalpha(ch) && !isdigit(ch)) ch = gc();
  while (isalpha(ch) || isdigit(ch)) s[++top] = ch, ch = gc();
  return top;
}
namespace modular {
  const int mod = 998244353;//= 1e9 + 7;
  //int mod;
  int ret;
  inline int add(int a, int b) { return a + b < mod ? a + b : a + b - mod; }
  inline int dec(int a, int b) { return a < b ? a - b + mod : a - b; }
  inline int mul(int a, int b) { return (ll) a * b % mod; }
  inline void Add(int &a, int b) { a = a + b < mod ? a + b : a + b - mod; }
  inline void Dec(int &a, int b) { a = a < b? a - b + mod : a - b; }
  inline void Mul(int &a, int b) { a = (ll) a * b % mod; }
  inline int ksm(int a, int p) {
    for (ret = 1; p; p >>= 1, Mul(a, a)) (p & 1) && (Mul(ret, a), 1);
    return ret;
  }
  inline int Inv(int a) { return ksm(a, mod - 2); }
  inline int sqr(int a) { return (ll) a * a % mod; }
  inline int cub(int a) { return (ll) a * a % mod * a % mod; }
} using namespace modular;
template <typename T> inline void ckmax(T &a, T b) { a < b ? a = b : 0; }
template <typename T> inline void ckmin(T &a, T b) { a > b ? a = b : 0; }
template <typename T> inline T Abs(T a) { return a < 0 ? -a : a; }
template <typename T> inline T gcd(T a, T b) {
  T t;
  while (b) t = a, a = b, b = t - t / a * a;
  return a;
}
template <typename T> inline void exgcd(T a, T b, T &x, T &y) {
  if (!b) {
    x = 1, y = 0;
    return;
  }
  exgcd(b, a - a / b * b, y, x);
  y -= a / b * x;
}
const int N = 1e5 + 5;
vector <int> e[N];
int n, siz[N], hson[N], dep[N], top[N], fa[N], cnt[N], tot = 0, du[N], m;
vector <pii> a;
void dfs1(int p) {
  siz[p] = 1;
  for (ri i = 0, v; i < e[p].size(); ++i) if ((v = e[p][i]) ^ fa[p]) {
    dep[v] = dep[p] + 1, fa[v] = p, dfs1(v), siz[p] += siz[v];
    if (siz[v] > siz[hson[p]]) hson[p] = v;
  }
}
void dfs2(int p, int tp) {
  top[p] = tp;
  if (!hson[p]) return;
  dfs2(hson[p], tp);
  for (ri i = 0, v; i < e[p].size(); ++i) if ((v = e[p][i]) != fa[p] && v != hson[p]) dfs2(v, v);
}
inline int lca(int x, int y) {
  while (top[x] ^ top[y]) dep[top[x]] < dep[top[y]] ? y = fa[top[y]] : x = fa[top[x]];
  return dep[x] < dep[y] ? x : y;
}
int res = 0;
void dfs(int p) {
  for (ri i = 0, v; i < e[p].size(); ++i) if ((v = e[p][i]) ^ fa[p]) {
    dfs(v), cnt[p] += cnt[v];
    res += min(cnt[v], 2);
  }
}
vector <pii> solve(vector <pii> a) {
  int x = 0, nxt = 0, sz1, sz2;
  for (ri i = 1; i <= n; ++i) if (du[i] == 1) {
    x = i;
    break;
  }
  --du[x];
  for (ri i = 0; i < e[x].size(); ++i) if (du[e[x][i]]) { nxt = e[x][i]; break; }
  if (!nxt) return a;
  --du[nxt];
  vector <pii> cur, tmp;
  vector <int> id, ps(m + 1);
  for (ri i = 0; i < a.size(); ++i) {
    if ((a[i].fi == x && a[i].se == x) || (a[i].fi != x && a[i].se != x)) ps[i] = tmp.size(), tmp.pb(a[i]);
    else cur.pb(a[i] = pii(x, a[i].fi + a[i].se - x)), id.pb(i);
  }
  if (!cur.size()) return solve(tmp);
  sz1 = tmp.size();
  for (ri i = 0; i < cur.size(); i += 2) {
    if (i + 1 >= cur.size()) break;
    if (cur[i].se == cur[i + 1].se) swap(a[id[i]].fi, a[id[i]].se);
    ps[id[i]] = ps[id[i + 1]] = tmp.size();
    tmp.pb(pii(cur[i].se, cur[i + 1].se));
  }
  sz2 = cur.size() - 1;
  bool rest = 0;
  if (!(sz2 & 1)) {
    rest = 1;
    ps[id[sz2]] = tmp.size();
    tmp.pb(pii(nxt, cur[sz2].se));
  }
  tmp = solve(tmp);
  for (ri i = 0; i < a.size(); ++i) {
    if (ps[i] < sz1) a[i] = tmp[ps[i]];
    else {
      if (rest && i == id[sz2]) { if(tmp[ps[i]].fi != nxt) swap(a[i].fi, a[i].se); }
      else { if (tmp[ps[i]].fi != tmp[ps[i]].se && tmp[ps[i]].fi == a[i].se) swap(a[i].fi, a[i].se); }
    }
  }
  return a;
}
int main() {
  #ifdef ldxcaicai
  freopen("lx.in", "r", stdin);
  #endif
  n = read(), m = read();
  for (ri i = 1, u, v; i < n; ++i) {
    u = read(), v = read();
    e[u].pb(v), e[v].pb(u);
    ++du[u], ++du[v];
  }
  dfs1(1), dfs2(1, 1);
  for (ri i = 1, u, v; i <= m; ++i) {
    u = read(), v = read();
    ++cnt[u], ++cnt[v];
    cnt[lca(u, v)] -= 2;
    a.pb(pii(u, v));
  }
  dfs(1);
  cout << res, hhh;
  a = solve(a);
  for (ri i = 0; i < m; ++i) cout << a[i].fi << ' ' << a[i].se << '\n';
  return 0;
}

Measured memory_bytes: 59392