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

// #undef DEBUG
// #define DEBUG
/// {{{ DEBUG --- ///
template <typename T> ostream &operator<<(ostream &o, const vector<T> &v) { if(&o == &cerr) { o << '{'; for(size_t i = 0; i < v.size(); i++) o << v[i] << (i + 1 != v.size() ? ", " : ""); o << "}"; } else { for(size_t i = 0; i < v.size(); i++) o << v[i] << (i + 1 != v.size() ? " " : ""); } return o; }
#ifdef DEBUG
#ifdef USE_COUT
#define dump(...) (cout<<"["<<__LINE__<< "] "<<#__VA_ARGS__<<" = "<<make_tuple(__VA_ARGS__)<<"\n")
#else
#define dump(...) (cerr<<"["<<__LINE__<< "] "<<#__VA_ARGS__<<" = "<<make_tuple(__VA_ARGS__)<<"\n")
#endif
template<int n, class...T> typename enable_if<(n>=sizeof...(T))>::type _ot(ostream &, tuple<T...> const &){}
template<int n, class...T> typename enable_if<(n< sizeof...(T))>::type _ot(ostream & os, tuple<T...> const & t){ os << (n==0?"":", ") << get<n>(t); _ot<n+1>(os, t); }
template<class...T> ostream & operator<<(ostream &o, tuple<T...> const &t){ o << "("; _ot<0>(o, t); o << ")"; return o; }
template<class T, class U> ostream & operator<<(ostream &o, pair<T, U> const &p) { o << "(" << p.first << ", " << p.second << ")"; return o; }
#else
#define dump(...) (0)
#endif
/// }}}--- ///

const int N = 2001;
using E = tuple<int, int>;
vector<E> g[N];
int n, m;
bool ans[N];
int u[N], v[N];
vector<int> from(N, -1);

set<int> d[N];
vector<int> r[N];

bool dfs0(int i, int p, int to, int id) {
  if(i == to) return 1;
  bool f = 0;
  for(auto ed : g[i]) {
    int j, ei;
    tie(j, ei) = ed;
    if(j == p) continue;
    bool t = dfs0(j, i, to, id);
    f |= t;
    if(t) {
      d[ei].emplace(id);
      r[id].emplace_back(ei);
    }
  }
  return f;
}

bool dfs3(int i, int p, bool st, int id) {
  if(i == v[id] || i == u[id]) {
    if(u[id] == i && st) ans[id] = 1;
    return 1;
  }
  bool f = 0;
  for(auto ed : g[i]) {
    int j, ei;
    tie(j, ei) = ed;
    if(j == p) continue;
    bool t = dfs3(j, i, st, id);
    from[ei] = st ? j : i;
    f |= t;
  }
  return f;
}

int fin[N] = {};
int calc4 = -1;
int dfs4(int i, int p, int i1, int i2) {
  int f = (i == i1) + (i == i2);
  for(auto ed : g[i]) {
    int j, ei;
    tie(j, ei) = ed;
    if(j == p) continue;
    int t = dfs4(j, i, i1, i2);
    f += t;
    if(t >= 2) fin[ei] = 1;
  }
  if(f >= 2 && calc4 == -1) {
    calc4 = i;
  }
  return f;
}

ll val = 0;
int did[N];
vector<pair<int, int>> pr[N];
vector<pair<int, int>> eg[N];
int whereS[N], whereE[N];

int used[N] = {};
void dfs5(int i) {
  used[i] = 1;
  for(auto pp : eg[i]) {
    int j, t; tie(j, t) = pp;
    if(used[j]) continue;
    ans[j] = ans[i] ^ t;
    dfs5(j);
  }
}

int main() {
  ios::sync_with_stdio(false), cin.tie(0);
  cin >> n >> m;
  for(int i = 0; i < n - 1; i++) {
    int a, b; cin >> a >> b;
    a--; b--;
    g[a].emplace_back(b, i);
    g[b].emplace_back(a, i);
  }
  for(int i = 0; i < m; i++) {
    cin >> u[i] >> v[i];
    u[i]--; v[i]--;
    dfs0(u[i], -1, v[i], i);
    pr[u[i]].emplace_back(i, 0);
    pr[v[i]].emplace_back(i, 1);
    whereS[i] = u[i];
    whereE[i] = v[i];
  }
  /* for(int i = 0; i < m; i++) { */
  /*   all3 = 1;                  */
  /*   dfs1(u[i], -1, v[i]);      */
  /*   if(all3) {                 */
  /*     for(int id : r[i]) {     */
  /*       d[id].erase(i);        */
  /*     }                        */
  /*   }                          */
  /* }                            */

  queue<int> q;
  for(int i = 0; i < n; i++) if(g[i].size() == 1) q.emplace(i);
  while(q.size()) {
    int i = q.front();
    did[i] = 1;
    dump(i + 1);
    q.pop();
    for(auto ed : g[i]) {
      int j, ei; tie(j, ei) = ed;
      if(did[j]) continue;
      int cnt = 0; for(auto ed2 : g[j]) if(!did[get<0>(ed2)]) cnt++;
      if(cnt == 1) q.emplace(j);
      vector<pair<int, int>> prr;
      if(i < 0 || i >= n) return 0;
      for(auto el : pr[i]) if(whereS[el.first] != whereE[el.first]) prr.emplace_back(el);
      pr[i] = prr;
      if(pr[i].size() >= 2 && !fin[ei]) {
        int i1 = pr[i][0].second ? whereS[pr[i][0].first] : whereE[pr[i][0].first];
        int i2 = pr[i][1].second ? whereS[pr[i][1].first] : whereE[pr[i][1].first];
        calc4 = -1;
        dfs4(i, -1, i1, i2);
        eg[pr[i][0].first].emplace_back(pr[i][1].first, pr[i][0].second == pr[i][1].second);
        eg[pr[i][1].first].emplace_back(pr[i][0].first, pr[i][0].second == pr[i][1].second);
        dump(pr[i][0].first, pr[i][1].first, pr[i][0].second, pr[i][1].second);
        /* pr[i1].erase(find(begin(pr[i1]), end(pr[i1]), make_pair(pr[i][0].first, (int) !pr[i][0].second))); */
        // 見つからないことがある なんで
        auto pf = find(begin(pr[i2]), end(pr[i2]), make_pair(pr[i][1].first, int(!pr[i][1].second)));
        pr[i2].erase(pf);
        pr[i2].emplace_back(pr[i][0]);
        (!pr[i][0].second ? whereS : whereE) [pr[i][0].first] = i2; ///// 消したあとにやっていた
        pr[i].erase(begin(pr[i]), begin(pr[i]) + 2);
      }
      for(auto pp : pr[i]) {
        (!pp.second ? whereS : whereE) [pp.first] = j; ///
        pr[j].emplace_back(pp);
      }
      pr[i].clear();
    }
  }
  for(int i = 0; i < m; i++) if(!used[i]) dfs5(i);

  for(int i = 0; i < n - 1; i++) {
  val += min((int) d[i].size(), 2);
  }
  cout << val << endl;
  for(int i = 0; i < m; i++) {
  if(ans[i]) swap(v[i], u[i]);
  cout << v[i] + 1 << "  " << u[i] + 1 << endl;
  }
}



Measured memory_bytes: 76160