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

typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;
typedef pair<int, ii> iii;
typedef pair<ii, int> ri3;
#define mp make_pair
#define pb push_back
#define fi first
#define sc second
#define SZ(x) (int)(x).size()
#define ALL(x) begin(x), end(x) 
#define REP(i, n) for (int i = 0; i < n; ++i) 
#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define RFOR(i, a, b) for (int i = a; i >= b; --i)

const int MX_N = 2005;
const int LG_N = log2(MX_N)+2;
const int MX_M = 2005;

int N, M;
set<int> al[MX_N];
int pa[MX_N][LG_N], dep[MX_N];

struct Walk {
    int u, v;
} walk[MX_M];

struct D {
    int ans, itx;
    set<array<int,2>> walks;
} dp[MX_N];

void dfs(int u, int p) {
    pa[u][0] = p;
    FOR(k,1,LG_N-1) pa[u][k] = (pa[u][k-1] == 0 ? 0 : pa[pa[u][k-1]][k-1]);
    dep[u] = dep[p]+1;
    for (int v : al[u]) if (v != p) dfs(v,u);
}

int lca(int a, int b) {
    if (dep[a] < dep[b]) swap(a,b);
    RFOR(k,LG_N-1,0) if (pa[a][k] != 0 && dep[pa[a][k]] >= dep[b]) a = pa[a][k];
    if (a == b) return a;
    RFOR(k,LG_N-1,0) if (pa[a][k] != 0 && pa[b][k] != 0 && pa[a][k] != pa[b][k])
        a = pa[a][k], b = pa[b][k];
    return pa[a][0];
}

struct WalkGraph {
    int color[2*MX_M];
    vector<int> al[2*MX_M];

    WalkGraph() { 
        memset(color,-1,sizeof color);
    }

    void link(int a, int b) {
        //cout << "LINK " << a << " " << b << endl;
        al[a].push_back(b);
        al[b].push_back(a);
    }

    void dfs(int u) {
        for (int v : al[u]) {
            if (color[v] == -1) {
                color[v] = !color[u];
                dfs(v);
            } else assert(color[v] == !color[u]);
        }
    }
} graph;


D solve(int u, int p) {
    dp[u].ans = 0;
    dp[u].itx = u;
    for (int v : al[u]) if (v != p) {
        auto cur = solve(v,u);
        dp[u].ans += cur.ans;
        if (dp[u].itx == -1 || dep[cur.itx] < dep[dp[u].itx]) dp[u].itx = cur.itx;
        if (SZ(dp[u].walks) < SZ(cur.walks)) swap(dp[u].walks,cur.walks);
        for (auto w : cur.walks) dp[u].walks.insert(w);
    }

    if (dp[u].itx == u) {
        //cout << "WALKS " << u << " :: ";
        //for (auto& w : dp[u].walks) cout << w[0] << ":" << w[1] << " ";
        //cout << endl;

        while (!dp[u].walks.empty() && dep[(*dp[u].walks.begin())[0]] >= dep[u])
            dp[u].walks.erase(dp[u].walks.begin());
        while (SZ(dp[u].walks) > 1 && dep[(*next(dp[u].walks.begin()))[0]] >= dep[u])
            dp[u].walks.erase(next(dp[u].walks.begin()));

        if (SZ(dp[u].walks) < 2) dp[u].ans += SZ(dp[u].walks);
        else {
            dp[u].ans += 2;
            auto a = dp[u].walks.begin();
            auto b = next(dp[u].walks.begin());
            graph.link((*a)[1],(*b)[1]);
            if (dep[(*a)[0]] < dep[(*b)[0]]) {
                dp[u].itx = (*b)[0];
                dp[u].walks.erase(b);
            } else {
                dp[u].itx = (*a)[0];
                dp[u].walks.erase(a);
            }
        }
    } else {
        dp[u].ans += 2;
    }

    //cout << u << " :: " << dp[u].ans << " " << dp[u].itx << " " << SZ(dp[u].walks) << endl;
    return dp[u];
}

int main() {
    //freopen("in.txt", "r", stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin >> N >> M;
    FOR(i,1,N-1){
        int a, b; cin >> a >> b;
        al[a].insert(b);
        al[b].insert(a);
    }
    dep[0] = 0; dfs(1,0);
    FOR(i,1,M){
        int u, v; cin >> u >> v; 
        walk[i] = {u,v};
        int high = lca(u,v);
        dp[u].walks.insert({high,i});
        dp[v].walks.insert({high,i+M});
    }

    FOR(i,1,M) graph.link(i,i+M);
    D res = solve(1,0);
    cout << res.ans << '\n';
    FOR(i,1,M) if (graph.color[i] == -1) graph.color[i] = 1, graph.dfs(i);
    FOR(i,1,M) {
        if (graph.color[i]) cout << walk[i].u << " " << walk[i].v << '\n';
        else cout << walk[i].v << " " << walk[i].u << '\n';
    }
}



Measured memory_bytes: 102272