Problem:
Score : 1500 points

Problem Statement

Takahashi loves walking on a tree.
The tree where Takahashi walks has N vertices numbered 1 through N.
The i-th of the N-1 edges connects Vertex a_i and Vertex b_i.

Takahashi has scheduled M walks. The i-th walk is done as follows:

The walk involves two vertices u_i and v_i that are fixed beforehand.

Takahashi will walk from u_i to v_i or from v_i to u_i along the shortest path.

The happiness gained from the i-th walk is defined as follows:

The happiness gained is the number of the edges traversed during the i-th walk that satisfies one of the following conditions:

In the previous walks, the edge has never been traversed.

In the previous walks, the edge has only been traversed in the direction opposite to the direction taken in the i-th walk.

Takahashi would like to decide the direction of each walk so that the total happiness gained from the M walks is maximized.
Find the maximum total happiness that can be gained, and one specific way to choose the directions of the walks that maximizes the total happiness.

Constraints

1 ≤ N,M ≤ 2000

1 ≤ a_i , b_i ≤ N

1 ≤ u_i , v_i ≤ N

a_i \neq b_i

u_i \neq v_i

The graph given as input is a tree.

Input

Input is given from Standard Input in the following format:

N M
a_1 b_1
:
a_{N-1} b_{N-1}
u_1 v_1
:
u_M v_M

Output

Print the maximum total happiness T that can be gained, and one specific way to choose the directions of the walks that maximizes the total happiness, in the following format:

T
u^'_1 v^'_1
:
u^'_M v^'_M

where (u^'_i,v^'_i) is either (u_i,v_i) or (v_i,u_i), which means that the i-th walk is from vertex u^'_i to v^'_i.

Sample Input 1

4 3
2 1
3 1
4 1
2 3
3 4
4 2

Sample Output 1

6
2 3
3 4
4 2

If we decide the directions of the walks as above, he gains the happiness of 2 in each walk, and the total happiness will be 6.

Sample Input 2

5 3
1 2
1 3
3 4
3 5
2 4
3 5
1 5

Sample Output 2

6
2 4
3 5
5 1

Sample Input 3

6 4
1 2
2 3
1 4
4 5
4 6
2 4
3 6
5 6
4 5

Sample Output 3

9
2 4
6 3
5 6
4 5

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#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 = 2000;
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 all3 = 1;
bool dfs1(int i, int p, int to) {
  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 = dfs1(j, i, to);
    f |= t;
    if(t) {
      int sz = d[ei].size();
      if(sz < 3) all3 = 0;
    } else {
    }
  }
  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) {
    
    calc4 = 0;
  }
  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, int p) {
  for(auto pp : eg[i]) {
    int j, t; tie(j, t) = pp;
    if(j == p) continue;
    ans[j] = ans[i] ^ t;
    dfs5(j, i);
  }
}

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), did[i] = 1;
  while(q.size()) {
    int i = q.front();
    dump(i + 1);
    q.pop();
    for(auto ed : g[i]) {
      int j, ei; tie(j, ei) = ed;
      if(did[j]) continue;
      did[j] = 1;
      int cnt = 0; for(auto ed2 : g[j]) if(!did[get<0>(ed2)]) cnt++;
      if(cnt == 1) q.push(j);
      vector<pair<int, int>> prr;
      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];
        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(i1, i2, 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)));
        pr[i2].erase(find(begin(pr[i2]), end(pr[i2]), make_pair(pr[i][1].first, (int) !pr[i][1].second)));
        pr[i2].emplace_back(pr[i][0].first, !pr[i][0].second);
        pr[i].erase(begin(pr[i]) + 1);
        (pr[i][0].second ? whereS : whereE) [pr[i][0].first] = i2;
        // calc4 = 0;
        dfs4(i, -1, i1, i2);
      }
      pr[j].insert(begin(pr[j]), begin(pr[i]), end(pr[i]));
    }
  }
  for(int i = 0; i < m; i++) if(!used[i]) dfs5(i, -1);

  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;
  }
}