#include <bits/stdc++.h>
#define pw(x) (1LL << (x))
#define db(x) cerr << #x << " = " << x << endl
#define db2(x, y) cerr << "(" << #x << ", " << #y << ") = (" << x << ", " << y << ")" << endl

using namespace std;
typedef long long ll;
typedef double dbl;
const int INF = 1.01e9;

const double EPS = 1e-9;
bool eq(double x, double y) {
    return fabs(x - y) < EPS;
}
bool ls(double x, double y) {
    return x < y && !eq(x, y);
}

vector<double> simplex(vector<vector<double> > a) {
    int n = a.size() - 1;
    int m = a[0].size() - 1;
    vector<int> left(n + 1), up(m + 1);
    iota(up.begin(), up.end(), 0);
    iota(left.begin(), left.end(), m);
    auto pivot = [&](int x, int y) {
        swap(left[x], up[y]);
        double k = a[x][y];
        a[x][y] = 1;
        vector<int> vct;
        for (int j = 0; j <= m; j++) {
            a[x][j] /= k;
            if (!eq(a[x][j], 0)) vct.push_back(j);
        }
        for (int i = 0; i <= n; i++) {
            if (eq(a[i][y], 0) || i == x) continue;
            k = a[i][y];
            a[i][y] = 0;
            for (int j : vct) a[i][j] -= k * a[x][j];
        }
    };
    while (1) {
        int x = -1;
        for (int i = 1; i <= n; i++) if (ls(a[i][0], 0) && (x == -1 || a[i][0] < a[x][0])) x = i;
        if (x == -1) break;
        int y = -1;
        for (int j = 1; j <= m; j++) if (ls(a[x][j], 0) && (y == -1 || a[x][j] < a[x][y])) y = j;
        if (y == -1) assert(0); // infeasible
        pivot(x, y);
    }
    while (1) {
        int y = -1;
        for (int j = 1; j <= m; j++) if (ls(0, a[0][j]) && (y == -1 || a[0][j] > a[0][y])) y = j;
        if (y == -1) break;
        int x = -1;
        for (int i = 1; i <= n; i++) if (ls(0, a[i][y]) && (x == -1 || a[i][0] / a[i][y] < a[x][0] / a[x][y])) x = i;
        if (x == -1) assert(0); // unbounded
        pivot(x, y);
    }
    vector<double> ans(m + 1);
    for (int i = 1; i <= n; i++) if (left[i] <= m) ans[left[i]] = a[i][0];
    ans[0] = -a[0][0];
    return ans;
}

pair<int, vector<pair<int, int>>> solve(vector<pair<int, int>> ed, vector<pair<int, int>> path) {
    int n = ed.size() + 1;
    int m = path.size();

    vector<vector<int>> e(n);
    for (int i = 0; i < n - 1; i++) {
        e[ed[i].first].push_back(i);
        e[ed[i].second].push_back(i);
    }

    vector<vector<pair<int, int>>> paths(n - 1);
    vector<vector<int>> edges(m);
    for (int i = 0; i < m; i++) {
        function<bool(int, int)> dfs = [&](int v, int pr) {
            if (v == path[i].second) {
                return true;
            }
            for (int id : e[v]) {
                int to = ed[id].first ^ ed[id].second ^ v;
                if (to == pr) continue;
                if (dfs(to, v)) {
                    edges[i].push_back(id);
                    paths[id].push_back({i, to == ed[id].first});
                    return true;
                }
            }
            return false;
        };
        dfs(path[i].first, -1);
    }

    int M = m;
    vector<vector<double>> a;
    a.push_back(vector<double>(1 + M));
    for (int i = 0; i < m; i++) {
        vector<double> cur;
        cur.assign(1 + M, 0);
        cur[0] = 1;
        cur[1 + i] = 1;
        a.push_back(cur);
    }
    for (int i = 0; i < n - 1; i++) {
        if (paths[i].size() >= 2) {
            for (int d = 0; d < 2; d++) {
                vector<double> cur;
                cur.assign(1 + M, 0);
                cur[0] = 1;
                for (auto o : paths[i]) {
                    int t = o.second ^ d;
                    cur[1 + o.first] += 2 * t - 1;
                    if (t == 0) cur[0] -= 1;
                }
                for (auto &x : cur) x *= -1;
                a.push_back(cur);
            }
        }
    }
    auto res = simplex(a);
    for (int i = 0; i < m; i++) {
        assert(eq(res[1 + i], 0) || eq(res[1 + i], 1));
        if (res[1 + i] > 0.5) {
            swap(path[i].first, path[i].second);
        }
    }
    int val = 0;
    for (int i = 0; i < n - 1; i++) {
        if (paths[i].size() >= 1) val++;
        if (paths[i].size() >= 2) val++;
    }
    return {val, path};
};

void stress() {
    for (int it = 30949;; it++ ){
        cout << it << endl;
        srand(it);

        int n = rand() % 10 + 2;
        int m = rand() % (2 * n) + 1;
        vector<pair<int, int>> ed(n - 1), path(m);
        for (int i = 0; i < n - 1; i++) {
            ed[i] = {i + 1, rand() % (i + 1)};
        }
        for (int i = 0; i < m; i++) {
            while (path[i].first == path[i].second) {
                path[i].first = rand() % n;
                path[i].second = rand() % n;
            }
        }

        /*cout << n << " " << m << endl;
        for (auto o : ed) cout << o.first << " " << o.second << endl;
        for (auto o : path) cout << o.first << " " << o.second << endl;*/
        auto o = solve(ed, path);
        //cout << solve(ed, path).first << endl;
    }
}

int main() {
#ifdef HOME
    assert(freopen("in", "r", stdin));
#endif

    ///stress();

    int n, m;
    while (scanf("%d%d", &n, &m) == 2) {
        vector<pair<int, int>> ed(n - 1);
        for (int i = 0; i < n - 1; i++) {
            scanf("%d%d", &ed[i].first, &ed[i].second);
            ed[i].first--;
            ed[i].second--;
        }
        vector<pair<int, int>> path(m);
        for (int i = 0; i < m; i++) {
            scanf("%d%d", &path[i].first, &path[i].second);
            path[i].first--;
            path[i].second--;
        }

        auto o = solve(ed, path);
        auto res = o.first;
        path = o.second;

        printf("%d\n", res);
        for (int i = 0; i < m; i++) {
            printf("%d %d\n", path[i].first + 1, path[i].second + 1);
        }
    }

#ifdef HOME
    cerr << "time = " << (clock() * 1. / CLOCKS_PER_SEC) << "\n";
#endif
    return 0;
}


Measured memory_bytes: 184320