#include <cstdio>
#include <cstring>
#include <algorithm>
#include <unordered_map>
#include <vector>
using namespace std;

#define FILL(a, n, x) memset((a), (x), sizeof ((a)[0]) * (n))
#define FILLA(a, x) memset((a), (x), sizeof (a))
#define COPY(a, n, b) memcpy((b), (a), sizeof ((a)[0]) * (n))
#define COPYA(a, b) memcpy((b), (a), sizeof (a))

typedef unsigned long long lu;
typedef long long li;
typedef pair<int, int> pii;
const int mod = 1e9 + 7;

inline int Add(int x) { return x >= mod ? x - mod : x; }
inline void Add(int &x, int y) { x += y; if (x >= mod) x -= mod; }
inline int Sub(int x) { return x < 0 ? x + mod : x; }
inline void Sub(int &x, int y) { x = Sub(x - y); }
inline int Mul(int x, int y) { return (int)((lu)x * y % mod); }
inline int Mul(int x, int y, int z) { return (int)((lu)x * y % mod * z % mod); }

int Pow(int x, int y) {
  int z = 1;
  for (; y; y >>= 1) {
    if (y & 1) z = Mul(z, x);
    x = Mul(x, x);
  }
  return z;
}

int Inv(int x) { return Pow(x, mod - 2); }
template <class T> inline void Max(T &x, T y) { if (y > x) x = y; }
template <class T> inline void Min(T &x, T y) { if (y < x) x = y; }

// ----------------------------------------

const int maxn = 2000;
typedef pair<int, int> pii;

int n, m, clk;
vector<int> g[maxn];

struct Path {
  int a, b, id;
} path[maxn];

vector<Path> Solve(vector<Path> A) {
  int leaf = -1, par = -1;
  for (int i = 0; i < n; ++i) {
    if (g[i].size() == 1) {
      leaf = i;
      par = g[i][0];
      break;
    }
  }
  if (leaf == -1) return A;
  g[leaf].erase(find(g[leaf].begin(), g[leaf].end(), par));
  g[par].erase(find(g[par].begin(), g[par].end(), leaf));

  int cover = 0;
  for (auto x : A) {
    if (x.a == leaf || x.b == leaf) ++cover;
  }
  if (cover == 0) {
    return Solve(A);
  }

  if (cover == 1) {
    int id = -1;
    vector<Path> fix, B;
    for (Path &x : A) {
      if (x.b == leaf) swap(x.a, x.b);
      if (x.a == leaf) {
        id = x.id;
        if (x.b == par) {
          fix.push_back({leaf, par, id});
        } else {
          B.push_back({par, x.b, id});
        }
      } else {
        B.push_back(x);
      }
    }
    B = Solve(B);
    for (Path &x : B) {
      if (x.id == id) {
        if (x.a == par) {
          x.a = leaf;
        } else {
          x.b = leaf;
        }
      }
    }
    copy(fix.begin(), fix.end(), inserter(B, B.end()));
    return B;
  }

  // cover >= 2
  int id1 = -1, id2 = -1, to1, to2;
  unordered_map<int, int> special;
  for (Path &x : A) {
    if (x.b == leaf) swap(x.a, x.b);
    if (x.a == leaf) {
      if (id1 == -1) {
        id1 = x.id;
        to1 = x.b;
      } else if (id2 == -1) {
        id2 = x.id;
        to2 = x.b;
      } else {
        special[x.id] = 1;
      }
    }
  }
  vector<Path> fix, B;
  for (Path &x : A) {
    if (x.id != id1 && x.id != id2) {
      if (special[x.id]) {
        if (x.b == par) {
          fix.push_back({leaf, par, x.id});
        } else {
          B.push_back({par, x.b, x.id});
        }
      } else {
        B.push_back(x);
      }
    }
  }
  int new_id = clk++;
  if (to1 == to2) {
    fix.push_back({leaf, to1, id1});
    fix.push_back({to2, leaf, id2});
  } else {
    B.push_back({to1, to2, new_id});
  }
  B = Solve(B);
  for (int i = 0; i < B.size(); ++i) {
    if (B[i].id == new_id) {
      if (B[i].a == to1) {
        B.push_back({to1, leaf, id1});
        B.push_back({leaf, to2, id2});
      } else {
        B.push_back({to2, leaf, id2});
        B.push_back({leaf, to1, id1});
      }
      B.erase(B.begin() + i);
      break;
    }
  }
  for (Path &x : B) {
    if (special[x.id]) {
      if (x.a == par) {
        x.a = leaf;
      } else {
        x.b = leaf;
      }
    }
  }
  copy(fix.begin(), fix.end(), inserter(B, B.end()));
  return B;
}

int color[maxn];

void Fill(int u, int p, int c) {
  color[u] = c;
  for (int v : g[u]) {
    if (v != p) {
      Fill(v, u, c);
    }
  }
}

int main(void) {
  scanf("%d%d", &n, &m);
  clk = m;
  for (int i = 0; i < n - 1; ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    --u; --v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  for (int i = 0; i < m; ++i) {
    int a, b;
    scanf("%d%d", &a, &b);
    --a; --b;
    path[i] = {a, b, i};
  }

  int sum = 0;
  for (int i = 0; i < n; ++i) {
    for (int j : g[i]) {
      if (i < j) {
        Fill(i, j, 1);
        Fill(j, i, 0);
        int cover = 0;
        for (int k = 0; k < m; ++k) {
          if (color[path[k].a] != color[path[k].b]) ++cover;
        }
        sum += min(cover, 2);
      }
    }
  }

  vector<Path> ans = Solve(vector<Path>(path, path + m));
  printf("%d\n", sum);
  for (int i = 0; i < m; ++i) {
    for (Path &x : ans) {
      if (x.id == i) {
        printf("%d %d\n", x.a + 1, x.b + 1);
      }
    }
  }
  return 0;
}


Measured memory_bytes: 145664