//made by Sert
#include <bits/stdc++.h>
using namespace std;
const int INF = (int)1e9 + 34;
const int N = (int)1e6 + 34;

typedef long long ll;

vector<int> es[N], ep[N];
vector<pair<int, int>> paths;
vector<bool> swp;
int tin[N], tout[N];
int tme;

bool isPar(int pr, int v) {
    return (tin[pr] < tin[v] && tout[pr] > tout[v]);
}

bool isIn(int a, int b, int v) {
    if (v == a) return !isPar(a, b);
    if (v == b) return !isPar(b, a);
    bool pva = isPar(v, a);
    bool pvb = isPar(v, b);
    if (pva && pvb) return false;
    return (pva || pvb);
}

void dfs(int v, int par, vector<int> &ord, vector<int> &pr) {
    tin[v] = ++tme;
    pr[v] = par;
    for (int w: es[v]) {
        if (w == par) continue;
        dfs(w, v, ord, pr);
    }
    ord.push_back(v);
    tout[v] = ++tme;
}

bool swapPath(int id) {
    swp[id] = !swp[id];
    swap(paths[id].first, paths[id].second);
}

vector<bool> up, is2;

void go(int ord_ind, const vector<int> &ord, const vector<int> &pr) {
    int n = ord.size();
    if (ord_ind + 1 == n) return;
    int v = ord[ord_ind];

    vector<int> mpaths;
    for (int path: ep[v]) {
        if (up[path]) continue;
        mpaths.push_back(path);
    }

    bool big = ((int)mpaths.size() >= 2 && !is2[v]);

    for (int i = 0; i < (int)mpaths.size(); i++) {
        int path = mpaths[i];
        if (big && i < 2) continue;
        int v1 = paths[path].first;
        int v2 = paths[path].second;
        if (v1 != v) swap(v1, v2);
        if (!isPar(v1, v2) && v2 != pr[v]) {
            if (paths[path].first == v) paths[path].first = pr[v];
            if (paths[path].second == v) paths[path].second = pr[v];
            ep[pr[v]].push_back(path);
        } else {
            up[path] = true;
        }
    }

    if (big) {
        int p1 = mpaths[0];
        int p2 = mpaths[1];
        int a = paths[p1].first + paths[p1].second - v;
        int b = paths[p2].first + paths[p2].second - v;
        up[p1] = up[p2] = true;
        int w = v;
        for (int i = 1; i < n; i++) {
            if (isIn(a, v, i) && isIn(b, v, i)) is2[i] = true;
        }
        if (a == b) {
            go(ord_ind + 1, ord, pr);
            if (paths[p1].first == paths[p2].first) {
                swapPath(p2);
            }
        } else {
            int path_sz = paths.size();
            ep[a].push_back(path_sz);
            ep[b].push_back(path_sz);
            paths.emplace_back(a, b);
            go(ord_ind + 1, ord, pr);

            if ((!swp[path_sz]) != (paths[p1].first == a)) {
                swapPath(p1);
            }
            if ((swp[path_sz]) != (paths[p2].first == b)) {
                swapPath(p2);
            }
        }
    } else {
        go(ord_ind + 1, ord, pr);
    }
}

vector<pair<int, int>> G, Q;
bool solve(bool D = false) {
    tme = 1;
    paths.clear();
    int n, m;
    if (D) {
        n = G.size() + 1;
        m = Q.size();
    } else {
        scanf("%d%d", &n, &m);
    }

    for (int i = 0; i < n; i++) {
        es[i].clear();
        ep[i].clear();
    }
    for (int i = 0; i < n - 1; i++) {
        int v1, v2;
        if (D) {
            v1 = G[i].first;
            v2 = G[i].second;
        } else {
            scanf("%d%d", &v1, &v2);
        }
        v1--;
        v2--;
        es[v1].push_back(v2);
        es[v2].push_back(v1);
    }
    vector<int> ord, pr(n);
    //cerr << "kek b dfs\n";

    dfs(0, -1, ord, pr);

    //cerr << "kek a dfs\n";

    for (int i = 0; i < m; i++) {
        int v1, v2;
        if (D) {
            v1 = Q[i].first;
            v2 = Q[i].second;
        } else {
            scanf("%d%d", &v1, &v2);
        }
        v1--;
        v2--;
        paths.emplace_back(v1, v2);
        ep[v1].push_back(i);
        ep[v2].push_back(i);
    }

    int T = 0;
    for (int i = 1; i < n; i++) {
        int num = 0;
        for (int j = 0; j < m; j++) {
            num += (int)isIn(paths[j].first, paths[j].second, i);
        }
        T += min(num, 2);
    }
    if (!D) printf("%d\n", T);

    is2.clear();
    up.clear();
    swp.clear();
    for (int i = 0; i < n; i++) is2.push_back(false);
    for (int i = 0; i < n + m; i++) up.push_back(false);
    for (int i = 0; i < n + m; i++) swp.push_back(false);
    auto kk = paths;
    go(0, ord, pr);
    //for (int i = 0; i < n; i++) cout << ord[i] + 1 << " "; cout << "\n";
    for (int i = 0; i < m; i++) {
        if (swp[i]) swap(kk[i].first, kk[i].second);
    }

    if (D) {
        if (G[5].second == 1) {
            int q = 4;
        }
        vector<int> nout(n, 0), nin(n, 0);
        for (int i = 1; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int a = kk[j].first;
                int b = kk[j].second;
                if (i == a) {
                    nout[i] += (int)(!isPar(a, b));
                } else {
                    nout[i] += (int)(isPar(i, a) && !isPar(i, b) && i != b);
                }

                if (i == b) {
                    nin[i] += (int)(!isPar(b, a));
                } else {
                    nin[i] += (int)(isPar(i, b) && !isPar(i, a) && i != a);
                }
            }
        }
        int tot = 0;
        for (int i = 0; i < n; i++) {
            tot += min(1, nout[i]);
            tot += min(1, nin[i]);
        }
        if (tot != T) {
            printf("nid %d. got %d\n", T, tot);
            for (int i = 0; i < n - 1; i++) {
                printf("%d %d\n", G[i].first, G[i].second);
            }
            printf("\n");
            for (int i = 0; i < m; i++) {
                printf("%d %d\n", kk[i].first + 1, kk[i].second + 1);
            }
            return false;
        }
    } else {
        for (int i = 0; i < m; i++) {
            printf("%d %d\n", kk[i].first + 1, kk[i].second + 1);
        }
    }
    return true;
}

void gen(int n, int q) {
    G.resize(n - 1);
    Q.resize(q);
    for (int i = 1; i < n; i++) {
        G[i - 1] = make_pair(i + 1, rand() % i + 1);
    }
    for (int i = 0; i < q; i++) {
        int v1 = rand() % n;
        int v2 = rand() % (n - 1);
        if (v2 >= v1) v2++;
        Q[i] = make_pair(v1 + 1, v2 + 1);
    }
}

int main() {
    srand(3431);
#ifdef SERT
    freopen("a.in", "r", stdin);
    //freopen("a.out", "w", stdout);
    //solve();
    //solve();
    //solve();
    //solve();
#endif

    solve();
    return 0;

    int it = 0;
    while (clock() < CLOCKS_PER_SEC * 2.2) {
        it++;
        gen(7, 4);
        if (!solve(true)) {
            printf("at it %d\n", it);
            return 0;
        }
    }

    return 0;
}

Measured memory_bytes: 63744