#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; (i) < int(n); ++ (i))
using namespace std;

template <typename UnaryPredicate>
int binsearch(int l, int r, UnaryPredicate p) {
    assert (l <= r);
    -- l;
    while (r - l > 1) {
        int m = l + (r - l) / 2;  // avoid overflow
        (p(m) ? r : l) = m;
    }
    return r;
}

int main() {
    // input
    int n; scanf("%d", &n);
    vector<vector<int> > g(n);
    REP (i, n - 1) {
        int a, b; scanf("%d%d", &a, &b);
        -- a; -- b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    // solve
    constexpr int root = 0;
    int a = 0; {
        vector<char> used(n);
        function<void (int, int)> use_chain = [&](int i, int parent) {
            used[i] = true;
            for (int j : g[i]) if (j != parent and not used[j]) {
                use_chain(j, i);
                break;
            }
        };
        function<void (int, int)> go = [&](int i, int parent) {
            int count_not_used = 0;
            for (int j : g[i]) if (j != parent) {
                if (not used[j]) {
                    count_not_used += 1;
                    use_chain(j, i);
                }
                go(j, i);
            }
            a += (count_not_used + 1) / 2;
        };
        go(root, -1);
    }
    int b = binsearch(1, n, [&](int b) {
        int count_chain = 0;
        function<int (int, int)> go = [&](int i, int parent) {
            map<int, int> chain;
            for (int j : g[i]) if (j != parent) {
                int length = go(j, i);
                if (length - 1 >= 1) {
                    chain[length - 1] += 1;
                }
            }
            for (auto it = chain.begin(); it != chain.end(); ) {
                // pop
                int length, count; tie(length, count) = *it;
                chain[length] = 0;
                // make pairs
                while (count) {
                    it = chain.lower_bound(b - length);
                    if (it == chain.end()) break;
                    if (it->first == length) {
                        assert (it->second == 0);
                        count_chain -= count / 2;
                        count %= 2;
                    } else {
                        int delta = min(count, it->second);
                        count_chain -= delta;
                        count -= delta;
                        it->second -= delta;
                    }
                    if (not it->second) {
                        chain.erase(it);
                    }
                }
                // write back
                if (count) {
                    chain[length] = count;
                } else {
                    chain.erase(length);
                }
                // increment
                it = chain.lower_bound(length + 1);
            }
            if (chain.empty()) {
                if (i == root) {
                    return -1;
                } else {
                    count_chain += 1;
                    return b;
                }
            } else {
                return chain.rbegin()->first;
            }
        };
        go(root, -1);
        return count_chain <= a;
    });
    // output
    printf("%d %d\n", a, b);
    return 0;
}


Measured memory_bytes: 20480