#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <utility>
#include <cstdlib>
#include <memory>
#include <queue>
#include <cassert>
#include <cmath>
#include <ctime>
#include <complex>
#include <bitset>
#include <fstream>
#include <unordered_map>
#include <unordered_set>
#include <numeric>

using namespace std;

#define ws ws_____________________
#define y1 y1_____________________
#define y0 y0_____________________
#define left left_________________
#define right right_______________
#define next next_________________
#define prev prev_________________
#define hash hash_________________

#define pb push_back
#define fst first
#define snd second
#define mp make_pair 
#define sz(C) ((int) (C).size())
#define forn(i, n) for (int i = 0; i < int(n); ++i)
#define ford(i, n) for (int i = int(n) - 1; i >= 0; --i)
#define all(C) begin(C), end(C)

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int,int> pii;
typedef pair<ll, ll> pll;
typedef vector<ll> vll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef long double ld;
typedef complex<double> cd;

#ifdef LOCAL
#define eprintf(args...) fprintf(stderr, args), fflush(stderr)
#else
#define eprintf(...) ;
#endif

#define FILE_NAME "a"

const int MAXN = 1e5 + 10;

int n;
vi g[MAXN];

bool read() {
	if  (scanf("%d", &n) < 1) {
		return 0;
	}
	forn(i, n) {
		g[i].clear();
	}
	forn(i, n - 1) {
		int a, b;
		scanf("%d%d", &a, &b);
		--a;
		--b;
		g[a].pb(b);
		g[b].pb(a);
	}
	return 1;
}

const int INF = 1e9;

pii dp[MAXN];

bool can_part(const vi& lens, int B) {
	assert(is_sorted(all(lens)));
	assert(sz(lens) % 2 == 0);

	vi left;
	vi right;
	forn(i, sz(lens)) {
		if  (i < sz(lens) / 2) {
			left.pb(lens[i]);
		} else {
			right.pb(lens[i]);
		}
	}

	assert(sz(left) == sz(right));

	int l1 = 0;
	int r1 = sz(left) - 1;
	int l2 = 0;
	int r2 = sz(right) - 1;
	while (l1 <= r1) {
		assert(r1 - l1 == r2 - l2);

		int ptr = l1;
		while (ptr + 1 <= r1 && left[ptr + 1] + right[r2] <= B) {
			++ptr;
		}

		if  (left[ptr] + right[r2] > B) {
			return 0;
		}

		l1 = ptr + 1;
		r2 = l2 + (r1 - l1 + 1) - 1;
	}

	return 1;
}

void dfs(int v, int p, int B) {
	auto get_best_pos = [&](const vi& lens) -> int {
		int L = -1;
		int R = sz(lens);
		int best_pos = -1;
		while (L != R - 1) {
			int M = (L + R) / 2;
			vi nlens;
			forn(i, sz(lens)) {
				if  (i != M) {
					nlens.pb(lens[i]);
				}
			}
			if  (can_part(nlens, B)) {
				best_pos = M;
				R = M;
			} else {
				L = M;
			}
		}
		return best_pos;
	};

	int paths = 0;
	vi lens;
	for (int to : g[v]) {
		if  (to == p) {
			continue;
		}

		dfs(to, v, B);
		
		// eprintf("to=%d, dp=(%d, %d)\n", to, dp[to].fst, dp[to].snd);

		int cur_paths, cur_len;
		tie(cur_paths, cur_len) = dp[to];
		if  (cur_len > B) {
			dp[v] = mp(INF, INF);
			return;
		}	

		paths += cur_paths;
		lens.pb(cur_len);
	}

	paths -= sz(lens);
	sort(all(lens));

	// eprintf("v=%d, lens:\n", v);
	// for (int len : lens) {
	// 	eprintf("%d ", len);
	// }
	// eprintf("\n");

	if  (sz(lens) % 2 == 0) {
		if  (p == -1) {
			if  (!can_part(lens, B)) {
				dp[v] = mp(INF, INF);
				return;
			}
			dp[v] = mp(paths + sz(lens) / 2, 0);
			return;
		}

		if  (can_part(lens, B)) {
			dp[v] = mp(paths + sz(lens) / 2 + 1, 1);
			return;			
		}

		vi nlens;
		forn(i, sz(lens) - 1) {
			nlens.pb(lens[i]);
		}
		int best_pos = get_best_pos(nlens);
		if  (best_pos == -1) {
			dp[v] = mp(INF, INF);
			return;
		}

		dp[v] = mp(paths + (sz(lens) - 2) / 2 + 2, nlens[best_pos] + 1);
		return;
	}

	{
		int best_pos = get_best_pos(lens);
		// eprintf("v=%d, best_pos=%d\n", v, best_pos);
		if  (best_pos == -1) {
			dp[v] = mp(INF, INF);
			return;
		}

		if  (p == -1) {
			dp[v] = mp(paths + sz(lens) / 2 + 1, 0);
			return;
		}

		dp[v] = mp(paths + sz(lens) / 2 + 1, lens[best_pos] + 1);
		return;
	}

	assert(0);
}

bool can(int B, int& A) {
	dfs(0, -1, B);
	if  (dp[0].snd > B) {
		return 0;
	}
	A = dp[0].fst;
	return 1;
}

pii solve() {
	// {
	// 	int A;
	// 	can(2, A);
	// 	return mp(0, 0);
	// }

	int L = 0;
	int R = n + 1;
	while (L != R - 1) {
		int M = (L + R) / 2;
		int A;
		if  (can(M, A)) {
			R = M;
		} else {
			L = M;
		}
	}
	int A;
	assert(can(R, A));
	return mp(A, R);
}

int main() {
#ifdef LOCAL
	freopen(FILE_NAME ".in", "r", stdin);
	// freopen(FILE_NAME ".out", "w", stdout);
#endif

	while (read()) {
		int A, B;
		tie(A, B) = solve();
		printf("%d %d\n", A, B);
	}

#ifdef LOCAL
	eprintf("Time: %.10f\n", (double) clock() / CLOCKS_PER_SEC);
#endif
	return 0;
}


Measured memory_bytes: 22400