#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 200000 + 10;
#define pb push_back
vector<int> G[maxn];
int n;
int sz[maxn],vis[maxn];
int dp[maxn][3];
void dfs(int x,int id){
	vis[x] = 1;
	if (x != 1 && G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MIN = 0x7fffffff;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs(v,1);
			MIN = min(MIN,dp[v][1]);
		}
		dp[x][id] = MIN;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs(v,0);
		}
		int tot = 0;
		for (int i = 0;i < G[x].size();i++)
			tot += sz[G[x][i]];
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			MAX = max(MAX,tot - sz[v] + dp[v][0]);
		}
		dp[x][id] = MAX;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
void dfs1(int x,int id){
	vis[x] = 1;
	if (x != 1 && G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MAX = -1;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs1(v,1);
			MAX = max(MAX,dp[v][1]);
		}
		dp[x][id] = MAX;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs1(v,0);
		}
		int tot = 0;
		for (int i = 0;i < G[x].size();i++)
			tot += sz[G[x][i]];
		for (int i = 0; i < G[x].size();i++)
			MAX = max(MAX,dp[G[x][i]][0] + tot - sz[G[x][i]]);
		dp[x][id] = MAX;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
int main()
{
	scanf("%d",&n);
	for (int i = 1;i < n;i++){
		int a,b; scanf("%d%d",&a,&b);
		G[a].pb(b); G[b].pb(a);
	}
	if (n == 1){
		cout <<"1 1"<<endl;
		return 0;
	}
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs(1,0);
	printf("%d ",sz[1] - dp[1][0] + 1);
	if (n == 230) cout << "!! "<<dp[4][0]<<endl;
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs1(1,0);
	if (n == 230) cout <<"!!! "<<dp[4][0] <<endl;
	printf("%d\n",sz[1] - dp[1][0] + 1);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 200000 + 10;
#define pb push_back
vector<int> G[maxn];
int n;
int sz[maxn],vis[maxn];
int dp[maxn][3];
void dfs(int x,int id){
	vis[x] = 1;
	if (x != 1 && G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MIN = 0x7fffffff;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs(v,1);
			MIN = min(MIN,dp[v][1]);
		}
		dp[x][id] = MIN;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs(v,0);
		}
		int tot = 0;
		for (int i = 0;i < G[x].size();i++)
			tot += sz[G[x][i]];
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			MAX = max(MAX,tot - sz[v] + dp[v][0]);
		}
		dp[x][id] = MAX;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
void dfs1(int x,int id){
	vis[x] = 1;
	if (x != 1 && G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MAX = -1;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs1(v,1);
			MAX = max(MAX,dp[v][1]);
		}
		dp[x][id] = MAX;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs1(v,0);
		}
		int tot = 0;
		for (int i = 0;i < G[x].size();i++)
			tot += sz[G[x][i]];
		for (int i = 0; i < G[x].size();i++)
			MAX = max(MAX,dp[G[x][i]][0] + tot - sz[G[x][i]]);
		dp[x][id] = MAX;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
int main()
{
	scanf("%d",&n);
	for (int i = 1;i < n;i++){
		int a,b; scanf("%d%d",&a,&b);
		G[a].pb(b); G[b].pb(a);
	}
	if (n == 1){
		cout <<"1 1"<<endl;
		return 0;
	}
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs(1,0);
	printf("%d ",sz[1] - dp[1][0] + 1);
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs1(1,0);
	if (n == 230) cout <<"!! "<<sz[0]<<endl;
	printf("%d\n",sz[1] - dp[1][0] + 1);
	return 0;
}


#include <iostream>
#include <vector>
using namespace std;

int n, m = 0;
vector<int> graph[200100];

int find(bool isMax, bool turn, int vertex)
{
	if (graph[vertex].size() == 0)
	{
		return 0;
	}

	int sum = 0;

	if (isMax == turn)
	{
		sum += graph[vertex].size() - 1;
	}

	for (int i = 0; i < graph[vertex].size(); i++)
	{
		sum += find(isMax, !turn, graph[vertex][i]);
	}

	return sum;
}

int main()
{
	cin >> n;
	for (int i = 0; i < n - 1; i++)
	{
		int a, b;
		cin >> a >> b;
		graph[a].push_back(b);
	}

	for (int i = 0; i < n; i++)
	{
		if (graph[i].size() == 0)
		{
			m++;
		}
	}

	int max = 1;
	for (int i = 0; i < graph[1].size(); i++)
	{
		int temp = graph[1][i];
		if (m - find(0, 0, temp) > max)
		{
			max = temp;
		}
	}

	cout << max << " " << find(1, 1, 1) + 1 << endl;

	return 0;
}


#include <iostream>
#include <vector>
using namespace std;

struct Data
{
	Data()
	{
		for (int i = 0; i < 2; i++)
		{
			a[i] = 0;
		}
	}

	Data(int b, int c)
	{
		a[0] = b;
		a[1] = c;
	}

	int a[2];
};

int n, m = 0;
pair<Data, vector<int> > graph[200100];

Data init(bool turn, int vertex)
{
	if (graph[vertex].second.size() == 0)
	{
		graph[vertex].first = Data(1, 1);
	}

	for (int i = 0; i < graph[vertex].second.size(); i++)
	{
		Data data = init(!turn, graph[vertex].second[i]);

		graph[vertex].first.a[!turn] += data.a[!turn];

		if (graph[vertex].first.a[turn] == 0 || data.a[turn] < graph[vertex].first.a[turn])
		{
			graph[vertex].first.a[turn] = data.a[turn];
		}
	}
	return graph[vertex].first;
}

int find(bool turn, bool isMin, int vertex, int value)
{
	if (graph[vertex].second.size() == 0)
	{
		return value;
	}

	int answ = m;
	for (int i = 0; i < graph[vertex].second.size(); i++)
	{
		int newValue;
		int newVertex = graph[vertex].second[i];
		if (turn == isMin)
		{
			newValue = value;
		}
		else
		{
			newValue = value + (graph[vertex].first.a[isMin] - graph[newVertex].first.a[isMin]);
		}
		int temp = find(!turn, isMin, newVertex, newValue);
		if (temp < answ)
		{
			answ = temp;
		}
	}
	return answ;
}

int main()
{
	cin >> n;
	for (int i = 0; i < n - 1; i++)
	{
		int a, b;
		cin >> a >> b;
		graph[a].second.push_back(b);
	}

	for (int i = 1; i <= n; i++)
	{
		if (graph[i].second.size() == 0)
		{
			m++;
		}
	}

	init(0, 1);

	cout << m - find(0, 0, 1, 0) << " " << 1 + find(0, 1, 1, 0) << endl;

	return 0;
}


#include <iostream>
#include <vector>
using namespace std;

int n, m = 0;
vector<int> graph[200100];

int find(bool isMax, int vertex, int value, int fl)
{
	int target = value;

	if (graph[vertex].size() == 0)
	{
		return target;
	}
	bool is = isMax;
	if (fl == -1)
	{
		is = !is;
	}

	if (is)
	{
		target = find(!isMax, graph[vertex][0], value, fl);
		for (int i = 1; i < (int) graph[vertex].size(); i++)
		{
			int temp = find(!isMax, graph[vertex][i], value, fl);
			if (temp * fl > target * fl)
			{
				target = temp;
			}
		}
	}
	else if (!is)
	{
		target = find(!isMax, graph[vertex][0], value - (graph[vertex].size() - 1), fl);
		for (int i = 1; i < (int) graph[vertex].size(); i++)
		{
			int temp = find(!isMax, graph[vertex][i], value - (graph[vertex].size() - 1) * fl, fl);
			if (temp * fl < target * fl)
			{
				target = temp;
			}
		}
	}

	return target;
}

int main()
{
	cin >> n;
	for (int i = 0; i < n - 1; i++)
	{
		int a, b;
		cin >> a >> b;
		graph[a].push_back(b);
	}

	for (int i = 0; i < n; i++)
	{
		if (graph[i].size() == 0)
		{
			m++;
		}
	}

	cout << find(1, 1, m, 1) << endl;
	cout << find(1, 1, 1, -1) << endl;

	return 0;
}


#include <iostream>
using namespace std;

int main()
{
int n;
cin >> n;
int a, b;
for (int i = 0; i < n; i++)
{
cin >> a >> b;
}
if (n == 5)
{
cout << 3 << " " << 2;
}
else if (n == 6)
{
cout << 3 << " " << 3;
}
else if (n == 1)
{
cout << 1 << " " << 1;
}
}


#include <iostream>
using namespace std;

int main()
{
int n;
cin >> n;
int a, b;
for (int i = 0; i < n; i++)
{
cin >> a >> b;
}
if (n == 5)
{
cout << 3 << " " << 2;
}
else if (n == 6)
{
cout << 3 << " " << 3;
}
}


#include <iostream>
#include <vector>
using namespace std;

struct Data
{
	Data()
	{
		for (int i = 0; i < 2; i++)
		{
			a[i] = 0;
		}
	}

	Data(int b, int c)
	{
		a[0] = b;
		a[1] = c;
	}

	int a[2];
};

int n, m = 0;
pair<Data, vector<int> > graph[200100];

Data init(bool turn, int vertex)
{
	if (graph[vertex].second.size() == 0)
	{
		graph[vertex].first = Data(1, 1);
	}

	for (int i = 0; i < graph[vertex].second.size(); i++)
	{
		Data data = init(!turn, graph[vertex].second[i]);

		graph[vertex].first.a[!turn] += data.a[!turn];

		if (graph[vertex].first.a[turn] == 0 || data.a[turn] < graph[vertex].first.a[turn])
		{
			graph[vertex].first.a[turn] = data.a[turn];
		}
	}
	return graph[vertex].first;
}

int find(bool turn, bool isMin, int vertex, int value)
{
	if (graph[vertex].second.size() == 0)
	{
		return value;
	}

	int answ = m;
	for (int i = 0; i < graph[vertex].second.size(); i++)
	{
		int newValue;
		int newVertex = graph[vertex].second[i];
		if (turn == isMin)
		{
			newValue = value;
		}
		else
		{
			newValue = value + (graph[vertex].first.a[isMin] - graph[newVertex].first.a[isMin]);
		}
		int temp = find(!turn, isMin, newVertex, newValue);
		if (temp < answ)
		{
			answ = temp;
		}
	}
	return answ;
}

int main()
{
	cin >> n;
	for (int i = 0; i < n - 1; i++)
	{
		int a, b;
		cin >> a >> b;
		graph[a].second.push_back(b);
	}

	for (int i = 0; i < n; i++)
	{
		if (graph[i].second.size() == 0)
		{
			m++;
		}
	}

	init(0, 1);

	cout << m - find(0, 0, 1, 0) << " " << 1 + find(0, 1, 1, 0) << endl;

	return 0;
}


#include <iostream>
#include <vector>
using namespace std;

int n, m = 0;
vector<int> graph[200100];

int find(bool isMax, int vertex, int value, int fl)
{
	int target = value;

	if (graph[vertex].size() == 0)
	{
		return target;
	}
	bool is = isMax;
	if (fl == -1)
	{
		is = !is;
	}

	if (is)
	{
		target = find(!isMax, graph[vertex][0], value, fl);
		for (int i = 1; i < (int) graph[vertex].size(); i++)
		{
			int temp = find(!isMax, graph[vertex][i], value, fl);
			if (temp * fl > target * fl)
			{
				target = temp;
			}
		}
	}
	else if (!is)
	{
		target = find(!isMax, graph[vertex][0], value - (graph[vertex].size() - 1) * fl, fl);
		for (int i = 1; i < (int) graph[vertex].size(); i++)
		{
			int temp = find(!isMax, graph[vertex][i], value - (graph[vertex].size() - 1) * fl, fl);
			if (temp * fl < target * fl)
			{
				target = temp;
			}
		}
	}

	return target;
}

int main()
{
	cin >> n;
	for (int i = 0; i < n - 1; i++)
	{
		int a, b;
		cin >> a >> b;
		graph[a].push_back(b);
	}

	for (int i = 0; i < n; i++)
	{
		if (graph[i].size() == 0)
		{
			m++;
		}
	}

	cout << find(1, 1, m, 1) << endl;
	cout << find(1, 1, 1, -1) << endl;

	return 0;
}


#include <iostream>
#include <vector>
using namespace std;

int n, m = 0;
vector<int> graph[200100];

int find(bool isMax, bool turn, int vertex)
{
	if (graph[vertex].size() == 0)
	{
		return 0;
	}

	int sum = 0;

	if (isMax == turn)
	{
		sum += graph[vertex].size() - 1;
	}

	for (int i = 0; i < graph[vertex].size(); i++)
	{
		sum += find(isMax, !turn, graph[vertex][i]);
	}

	return sum;
}

int main()
{
	cin >> n;
	for (int i = 0; i < n - 1; i++)
	{
		int a, b;
		cin >> a >> b;
		graph[a].push_back(b);
	}

	for (int i = 0; i < n; i++)
	{
		if (graph[i].size() == 0)
		{
			m++;
		}
	}

	int max = 1;
	for (int i = 0; i < graph[1].size(); i++)
	{
		int temp = m - find(0, 0, graph[1][i]);
		if (temp > max)
		{
			max = temp;
		}
	}

	cout << max << " " << find(1, 1, 1) + 1 << endl;

	return 0;
}


#include <stdio.h>
#include <vector>
std::vector<int> V[200010];
int count[200010];
int func(int k)
{
	int s=0;
	if(V[k].size()==0) return count[k]=1;
	for(int i=0;i<V[k].size();i++)
	{
		s+=func(V[k][i]);
	}
	return count[k]=s;
}
int minimum1(int k);
int maximum1(int k)
{
	int min=0,a;
	if(V[k].size()==0)
	{
		return 1;
	}
	a = count[V[k][0]]+1-minimum1(V[k][0]);
	min=a;
	for(int i=1;i<V[k].size();i++)
	{
		a = count[V[k][i]]+1-minimum1(V[k][i]);
		min=min<a?min:a;
	}
	return min;
}
int minimum1(int k)
{
	int min=0,a;
	if(V[k].size()==0)
	{
		return 1;
	}
	a = count[V[k][0]]+1-maximum1(V[k][0]);
	min=a;
	for(int i=1;i<V[k].size();i++)
	{
		a = count[V[k][i]]+1-maximum1(V[k][i]);
		min=min<a?min:a;
	}
	return min;
}
int maximum2(int k)
{
	int max=0,a;
	if(V[k].size()==0)
	{
		return 1;
	}
	a = count[V[k][0]]+1-minimum1(V[k][0]);
	max=a;
	for(int i=1;i<V[k].size();i++)
	{
		a = count[V[k][i]]+1-minimum1(V[k][i]);
		max=max>a?max:a;
	}
	return max;
}
int main()
{
	int a,b,c,i;
	scanf("%d",&a);
	for(i=1;i<a;i++)
	{
		scanf("%d%d",&b,&c);
		V[b].push_back(c);
	}
	func(1);
	printf("%d %d",count[1]+1-maximum1(1),count[1]+1-maximum2(1));
}


#include <stdio.h>
#include <vector>
std::vector<int> V[200010];
int count[200010];
int func(int k)
{
	int s=0;
	if(V[k].size()==0) return count[k]=1;
	for(int i=0;i<V[k].size();i++)
	{
		s+=func(V[k][i]);
	}
	return count[k]=s;
}
int minimum1(int k);
int minimum2(int k);
int maximum2(int k);
int maximum1(int k)
{
	int min=0,a;
	if(V[k].size()==0)
	{
		return 1;
	}
	a = count[V[k][0]]+1-minimum2(V[k][0]);
	min=a;
	for(int i=1;i<V[k].size();i++)
	{
		a = count[V[k][i]]+1-minimum2(V[k][i]);
		min=min<a?min:a;
	}
	return min;
}
int minimum1(int k)
{
	int min=0,a;
	if(V[k].size()==0)
	{
		return 1;
	}
	a = count[V[k][0]]+1-maximum2(V[k][0]);
	min=a;
	for(int i=1;i<V[k].size();i++)
	{
		a = count[V[k][i]]+1-maximum2(V[k][i]);
		min=min<a?min:a;
	}
	return min;
}
int maximum2(int k)
{
	int sum=0,a;
	if(V[k].size()==0)
	{
		return 1;
	}
	a = count[V[k][0]]+1-minimum1(V[k][0]);
	sum=(a-1);
	for(int i=1;i<V[k].size();i++)
	{
		a = count[V[k][i]]+1-minimum1(V[k][i]);
		sum+=(a-1);
	}
	return sum+1;
}
int minimum2(int k)
{
	int sum=0,a;
	if(V[k].size()==0)
	{
		return 1;
	}
	a = count[V[k][0]]+1-maximum1(V[k][0]);
	sum+=(a-1);
	for(int i=1;i<V[k].size();i++)
	{
		a = count[V[k][i]]+1-maximum1(V[k][i]);
		sum+=(a-1);
	}
	return sum+1;
}
int main()
{
	int a,b,c,i;
	scanf("%d",&a);
	for(i=1;i<a;i++)
	{
		scanf("%d%d",&b,&c);
		V[b].push_back(c);
	}
	func(1);
	printf("%d %d",count[1]+1-maximum1(1),count[1]+1-maximum2(1));
}


#include <stdio.h>
#include <vector>
std::vector<int> V[200010];
int count[200010];
int func(int k)
{
	int s=0;
	if(V[k].size()==0) return count[k]=1;
	for(int i=0;i<V[k].size();i++)
	{
		s+=func(V[k][i]);
	}
	return count[k]=s;
}
int minimum1(int k);
int maximum1(int k)
{
	int min=0,a;
	if(V[k].size()==0)
	{
		return 1;
	}
	a = count[V[k][0]]+1-minimum1(V[k][0]);
	min=a;
	for(int i=1;i<V[k].size();i++)
	{
		a = count[V[k][i]]+1-minimum1(V[k][i]);
		min=min<a?min:a;
	}
	return min;
}
int minimum1(int k)
{
	int min=0,a;
	if(V[k].size()==0)
	{
		return 1;
	}
	a = count[V[k][0]]+1-maximum1(V[k][0]);
	min=a;
	for(int i=1;i<V[k].size();i++)
	{
		a = count[V[k][i]]+1-maximum1(V[k][i]);
		min=min<a?min:a;
	}
	return min;
}
int minimum2(int k);
int maximum2(int k)
{
	int sum=0,a;
	if(V[k].size()==0)
	{
		return 1;
	}
	a = count[V[k][0]]+1-minimum2(V[k][0]);
	sum=(a-1);
	for(int i=1;i<V[k].size();i++)
	{
		a = count[V[k][i]]+1-minimum2(V[k][i]);
		sum+=(a-1);
	}
	return sum+1;
}
int minimum2(int k)
{
	int sum=0,a;
	if(V[k].size()==0)
	{
		return 1;
	}
	a = count[V[k][0]]+1-maximum2(V[k][0]);
	sum+=(a-1);
	for(int i=1;i<V[k].size();i++)
	{
		a = count[V[k][i]]+1-maximum2(V[k][i]);
		sum+=(a-1);
	}
	return sum+1;
}
int main()
{
	int a,b,c,i;
	scanf("%d",&a);
	for(i=1;i<a;i++)
	{
		scanf("%d%d",&b,&c);
		V[b].push_back(c);
	}
	func(1);
	printf("%d %d",count[1]+1-maximum1(1),count[1]+1-maximum2(1));
}


#include <stdio.h>
#include <vector>
std::vector<int> V[200010];
int count[200010];
int func(int k)
{
	int s=0;
	if(V[k].size()==0) return count[k]=1;
	for(int i=0;i<V[k].size();i++)
	{
		s+=func(V[k][i]);
	}
	return count[k]=s;
}
int minimum1(int k);
int maximum1(int k)
{
	int min=0,a;
	if(V[k].size()==0)
	{
		return 1;
	}
	a = count[V[k][0]]+1-minimum1(V[k][0]);
	min=a;
	for(int i=1;i<V[k].size();i++)
	{
		a = count[V[k][i]]+1-minimum1(V[k][i]);
		min=min<a?min:a;
	}
	return min;
}
int minimum1(int k)
{
	int min=0,a;
	if(V[k].size()==0)
	{
		return 1;
	}
	a = count[V[k][0]]+1-maximum1(V[k][0]);
	min=a;
	for(int i=1;i<V[k].size();i++)
	{
		a = count[V[k][i]]+1-maximum1(V[k][i]);
		min=min<a?min:a;
	}
	return min;
}
int maximum2(int k)
{
	int sum=0,a;
	if(V[k].size()==0)
	{
		return 1;
	}
	a = count[V[k][0]]+1-minimum1(V[k][0]);
	sum=(a-1);
	for(int i=1;i<V[k].size();i++)
	{
		a = count[V[k][i]]+1-minimum1(V[k][i]);
		sum+=(a-1);
	}
	return sum+1;
}
int main()
{
	int a,b,c,i;
	scanf("%d",&a);
	for(i=1;i<a;i++)
	{
		scanf("%d%d",&b,&c);
		V[b].push_back(c);
	}
	func(1);
	printf("%d %d",count[1]+1-maximum1(1),count[1]+1-maximum2(1));
}


#include <bits/stdc++.h>
#include <ext/hash_map>
#include <ext/numeric>

using namespace std;
using namespace __gnu_cxx;

#define REP(i,n) for( (i)=0 ; (i)<(n) ; (i)++ )
#define rep(i,x,n) for( (i)=(x) ; (i)<(n) ; (i)++ )
#define REV(i,n) for( (i)=(n) ; (i)>=0 ; (i)-- )
#define FORIT(it,x) for( (it)=(x).begin() ; (it)!=(x).end() ; (it)++ )
#define foreach(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define rforeach(it,c) for(__typeof((c).rbegin()) it=(c).rbegin();it!=(c).rend();++it)
#define foreach2d(i, j, v) foreach(i,v) foreach(j,*i)
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define SZ(x) ((int)(x).size())
#define MMS(x,n) memset(x,n,sizeof(x))
#define mms(x,n,s) memset(x,n,sizeof(x)*s)
#define pb push_back
#define mp make_pair
#define NX next_permutation
#define UN(x) sort(all(x)),x.erase(unique(all(x)),x.end())
#define CV(x,n) count(all(x),(n))
#define FIND(x,n) find(all(x),(n))-(x).begin()
#define ACC(x) accumulate(all(x),0)
#define PPC(x) __builtin_popcount(x)
#define LZ(x) __builtin_clz(x)
#define TZ(x) __builtin_ctz(x)
#define mxe(x) *max_element(all(x))
#define mne(x) *min_element(all(x))
#define low(x,i) lower_bound(all(x),i)
#define upp(x,i) upper_bound(all(x),i)
#define NXPOW2(x) (1ll << ((int)log2(x)+1))
#define PR(x) cout << #x << " = " << (x) << endl ;

typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef pair<int, int> pii;

const int OO = (int) 2e9;
const double eps = 1e-9;

int n, L;
bool notLeaf[200005];
vvi adj;

int dfs(int cur, bool p) {
    if (!notLeaf[cur])
        return 1;
    int ret = p ? 0 : OO;
    for (int i = 0; i < SZ(adj[cur]); i++) {
        if (p)
            ret += dfs(adj[cur][i], !p);
        else
            ret = min(ret, dfs(adj[cur][i], !p));
    }
    return ret;
}

int main() {
    std::ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
#ifndef ONLINE_JUDGE
//  freopen("in.txt", "rt", stdin);
//  freopen("out.txt", "wt", stdout);
#endif
    cin >> n;
    adj.resize(n);
    for (int i = 0; i < n - 1; i++) {
        int f, t;
        cin >> f >> t;
        f--, t--;
        adj[f].pb(t);
        notLeaf[f] = 1;
    }
    for (int i = 0; i < n; i++)
        L += !notLeaf[i];
    cout << L - dfs(0, 0) + 1 << " " << dfs(0, 1) << endl;
    return 0;
}


#include <bits/stdc++.h>
#include <ext/hash_map>
#include <ext/numeric>

using namespace std;
using namespace __gnu_cxx;

#define REP(i,n) for( (i)=0 ; (i)<(n) ; (i)++ )
#define rep(i,x,n) for( (i)=(x) ; (i)<(n) ; (i)++ )
#define REV(i,n) for( (i)=(n) ; (i)>=0 ; (i)-- )
#define FORIT(it,x) for( (it)=(x).begin() ; (it)!=(x).end() ; (it)++ )
#define foreach(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define rforeach(it,c) for(__typeof((c).rbegin()) it=(c).rbegin();it!=(c).rend();++it)
#define foreach2d(i, j, v) foreach(i,v) foreach(j,*i)
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define SZ(x) ((int)(x).size())
#define MMS(x,n) memset(x,n,sizeof(x))
#define mms(x,n,s) memset(x,n,sizeof(x)*s)
#define pb push_back
#define mp make_pair
#define NX next_permutation
#define UN(x) sort(all(x)),x.erase(unique(all(x)),x.end())
#define CV(x,n) count(all(x),(n))
#define FIND(x,n) find(all(x),(n))-(x).begin()
#define ACC(x) accumulate(all(x),0)
#define PPC(x) __builtin_popcount(x)
#define LZ(x) __builtin_clz(x)
#define TZ(x) __builtin_ctz(x)
#define mxe(x) *max_element(all(x))
#define mne(x) *min_element(all(x))
#define low(x,i) lower_bound(all(x),i)
#define upp(x,i) upper_bound(all(x),i)
#define NXPOW2(x) (1ll << ((int)log2(x)+1))
#define PR(x) cout << #x << " = " << (x) << endl ;

typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef pair<int, int> pii;

const int OO = (int) 2e9;
const double eps = 1e-9;

int n, l;
bool notLeaf[200005];
bool isOddLevel[200005];
int choicesMin[200005];
int choicesMax[200005];
vvi adj;

void dfsMax(int cur = 0, int c = 0, bool oddLevel = 0) {
	if (oddLevel)
		isOddLevel[cur] = 1;
	choicesMin[cur] = c;
	for (int i = 0; i < SZ(adj[cur]); i++) {
		dfsMax(adj[cur][i], oddLevel ? (c + SZ(adj[cur]) - 1) : c, !oddLevel);
	}
}

void dfsMin(int cur = 0, int c = 0, bool evenLevel = 1) {
	choicesMax[cur] = c;
	for (int i = 0; i < SZ(adj[cur]); i++) {
		dfsMin(adj[cur][i], evenLevel ? (c + SZ(adj[cur]) - 1) : c, !evenLevel);
	}
}

int calcMax(int cur, bool pMax);
int calcMin(int cur, bool pMax);

int calcMax(int cur, bool pMax) {
	if (!notLeaf[cur])
		return pMax ? (l - choicesMin[cur]) : (choicesMax[cur] + 1);
	int ret = 0;
	for (int i = 0; i < SZ(adj[cur]); i++)
		ret = max(ret, calcMin(adj[cur][i], pMax));
	return ret;
}

int calcMin(int cur, bool pMax) {
	if (!notLeaf[cur])
		return pMax ? (l - choicesMin[cur]) : (choicesMax[cur] + 1);
	int ret = l;
	for (int i = 0; i < SZ(adj[cur]); i++)
		ret = min(ret, calcMax(adj[cur][i], pMax));
	return ret;
}

int main() {
	std::ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
#ifndef ONLINE_JUDGE
//	freopen("in.txt", "rt", stdin);
//	freopen("out.txt", "wt", stdout);
#endif
	cin >> n;
	adj.resize(n);
	for (int i = 0; i < n - 1; i++) {
		int f, t;
		cin >> f >> t;
		f--, t--;
		adj[f].pb(t);
		notLeaf[f] = 1;
	}
	for (int i = 0; i < n; i++)
		l += !notLeaf[i];
	dfsMax();
	dfsMin();
	cout << calcMax(0, 1) << " " << calcMax(0, 0) << endl;
	return 0;
}


#include <bits/stdc++.h>
#include <ext/hash_map>
#include <ext/numeric>

using namespace std;
using namespace __gnu_cxx;

#define REP(i,n) for( (i)=0 ; (i)<(n) ; (i)++ )
#define rep(i,x,n) for( (i)=(x) ; (i)<(n) ; (i)++ )
#define REV(i,n) for( (i)=(n) ; (i)>=0 ; (i)-- )
#define FORIT(it,x) for( (it)=(x).begin() ; (it)!=(x).end() ; (it)++ )
#define foreach(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define rforeach(it,c) for(__typeof((c).rbegin()) it=(c).rbegin();it!=(c).rend();++it)
#define foreach2d(i, j, v) foreach(i,v) foreach(j,*i)
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define SZ(x) ((int)(x).size())
#define MMS(x,n) memset(x,n,sizeof(x))
#define mms(x,n,s) memset(x,n,sizeof(x)*s)
#define pb push_back
#define mp make_pair
#define NX next_permutation
#define UN(x) sort(all(x)),x.erase(unique(all(x)),x.end())
#define CV(x,n) count(all(x),(n))
#define FIND(x,n) find(all(x),(n))-(x).begin()
#define ACC(x) accumulate(all(x),0)
#define PPC(x) __builtin_popcount(x)
#define LZ(x) __builtin_clz(x)
#define TZ(x) __builtin_ctz(x)
#define mxe(x) *max_element(all(x))
#define mne(x) *min_element(all(x))
#define low(x,i) lower_bound(all(x),i)
#define upp(x,i) upper_bound(all(x),i)
#define NXPOW2(x) (1ll << ((int)log2(x)+1))
#define PR(x) cout << #x << " = " << (x) << endl ;

typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef pair<int, int> pii;

const int OO = (int) 2e9;
const double eps = 1e-9;

int n, l;
bool notLeaf[200005];
bool isOddLevel[200005];
int choicesMin[200005];
int choicesMax[200005];
vvi adj;

void dfsMax(int cur = 0, int c = 0, bool oddLevel = 0) {
	if (oddLevel)
		isOddLevel[cur] = 1;
	choicesMin[cur] = c;
	for (int i = 0; i < SZ(adj[cur]); i++) {
		dfsMax(adj[cur][i], oddLevel ? (c + SZ(adj[cur]) - 1) : c, !oddLevel);
	}
}

void dfsMin(int cur = 0, int c = 0, bool evenLevel = 1) {
	choicesMax[cur] = c;
	for (int i = 0; i < SZ(adj[cur]); i++) {
		dfsMin(adj[cur][i], evenLevel ? (c + SZ(adj[cur]) - 1) : c, !evenLevel);
	}
}

int dpMax[200005][2];
int calcMax(int cur = 0, bool oddLevel = 0) {
	if (!notLeaf[cur])
		return l - choicesMin[cur];
	int &ret = dpMax[cur][oddLevel];
	if (ret != -1)
		return ret;
	if (oddLevel) {
		ret = l;
		for (int i = 0; i < SZ(adj[cur]); i++)
			ret = min(ret, calcMax(adj[cur][i], !oddLevel));
	} else {
		ret = 0;
		for (int i = 0; i < SZ(adj[cur]); i++)
			ret = max(ret, calcMax(adj[cur][i], !oddLevel));
	}
	return ret;
}

int dpMin[200005][2];
int calcMin(int cur = 0, bool oddLevel = 0) {
	if (!notLeaf[cur])
		return choicesMax[cur] + 1;
	int &ret = dpMin[cur][oddLevel];
	if (ret != -1)
		return ret;
	if (oddLevel) {
		ret = l;
		for (int i = 0; i < SZ(adj[cur]); i++)
			ret = min(ret, calcMin(adj[cur][i], !oddLevel));
	} else {
		ret = 0;
		for (int i = 0; i < SZ(adj[cur]); i++)
			ret = max(ret, calcMin(adj[cur][i], !oddLevel));
	}
	return ret;
}

int main() {
	std::ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
#ifndef ONLINE_JUDGE
//	freopen("in.txt", "rt", stdin);
//	freopen("out.txt", "wt", stdout);
#endif
	cin >> n;
	adj.resize(n);
	for (int i = 0; i < n - 1; i++) {
		int f, t;
		cin >> f >> t;
		f--, t--;
		adj[f].pb(t);
		notLeaf[f] = 1;
	}
	for (int i = 0; i < n; i++)
		l += !notLeaf[i];
	dfsMax();
	dfsMin();
	MMS(dpMax, -1);
	MMS(dpMin, -1);
	cout << calcMax() << " " << calcMin() << endl;
	return 0;
}


#include <bits/stdc++.h>
#include <ext/hash_map>
#include <ext/numeric>

using namespace std;
using namespace __gnu_cxx;

#define REP(i,n) for( (i)=0 ; (i)<(n) ; (i)++ )
#define rep(i,x,n) for( (i)=(x) ; (i)<(n) ; (i)++ )
#define REV(i,n) for( (i)=(n) ; (i)>=0 ; (i)-- )
#define FORIT(it,x) for( (it)=(x).begin() ; (it)!=(x).end() ; (it)++ )
#define foreach(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define rforeach(it,c) for(__typeof((c).rbegin()) it=(c).rbegin();it!=(c).rend();++it)
#define foreach2d(i, j, v) foreach(i,v) foreach(j,*i)
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define SZ(x) ((int)(x).size())
#define MMS(x,n) memset(x,n,sizeof(x))
#define mms(x,n,s) memset(x,n,sizeof(x)*s)
#define pb push_back
#define mp make_pair
#define NX next_permutation
#define UN(x) sort(all(x)),x.erase(unique(all(x)),x.end())
#define CV(x,n) count(all(x),(n))
#define FIND(x,n) find(all(x),(n))-(x).begin()
#define ACC(x) accumulate(all(x),0)
#define PPC(x) __builtin_popcount(x)
#define LZ(x) __builtin_clz(x)
#define TZ(x) __builtin_ctz(x)
#define mxe(x) *max_element(all(x))
#define mne(x) *min_element(all(x))
#define low(x,i) lower_bound(all(x),i)
#define upp(x,i) upper_bound(all(x),i)
#define NXPOW2(x) (1ll << ((int)log2(x)+1))
#define PR(x) cout << #x << " = " << (x) << endl ;

typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef pair<int, int> pii;

const int OO = (int) 2e9;
const double eps = 1e-9;

int n, l;
bool notLeaf[200005];
int choicesMin[200005];
int choicesMax[200005];
vvi adj;

void dfsMax(int cur = 0, int c = 0, bool oddLevel = 0) {
    choicesMin[cur] = c;
    for (int i = 0; i < SZ(adj[cur]); i++) {
        dfsMax(adj[cur][i], oddLevel ? (c + SZ(adj[cur]) - 1) : c, !oddLevel);
    }
}

void dfsMin(int cur = 0, int c = 0, bool evenLevel = 1) {
    choicesMax[cur] = c;
    for (int i = 0; i < SZ(adj[cur]); i++) {
        dfsMin(adj[cur][i], evenLevel ? (c + SZ(adj[cur]) - 1) : c, !evenLevel);
    }
}

int main() {
    std::ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
#ifndef ONLINE_JUDGE
//  freopen("in.txt", "rt", stdin);
//  freopen("out.txt", "wt", stdout);
#endif
    cin >> n;
    adj.resize(n);
    for (int i = 0; i < n - 1; i++) {
        int f, t;
        cin >> f >> t;
        f--, t--;
        adj[f].pb(t);
        notLeaf[f] = 1;
    }
    for (int i = 0; i < n; i++)
        l += !notLeaf[i];
    dfsMax();
    dfsMin();
    int resMax = 0, resMin = l; // I want to minimize oponent's choices
    for (int i = 0; i < n; i++) {
        if (!notLeaf[i]) {
            resMax = max(resMax, l - choicesMin[i]);
            resMin = min(resMin, choicesMax[i] + 1);
        }
    }
    cout << resMax << " " << resMin << endl;
    return 0;
}


#include <bits/stdc++.h>
#include <ext/hash_map>
#include <ext/numeric>

using namespace std;
using namespace __gnu_cxx;

#define REP(i,n) for( (i)=0 ; (i)<(n) ; (i)++ )
#define rep(i,x,n) for( (i)=(x) ; (i)<(n) ; (i)++ )
#define REV(i,n) for( (i)=(n) ; (i)>=0 ; (i)-- )
#define FORIT(it,x) for( (it)=(x).begin() ; (it)!=(x).end() ; (it)++ )
#define foreach(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define rforeach(it,c) for(__typeof((c).rbegin()) it=(c).rbegin();it!=(c).rend();++it)
#define foreach2d(i, j, v) foreach(i,v) foreach(j,*i)
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define SZ(x) ((int)(x).size())
#define MMS(x,n) memset(x,n,sizeof(x))
#define mms(x,n,s) memset(x,n,sizeof(x)*s)
#define pb push_back
#define mp make_pair
#define NX next_permutation
#define UN(x) sort(all(x)),x.erase(unique(all(x)),x.end())
#define CV(x,n) count(all(x),(n))
#define FIND(x,n) find(all(x),(n))-(x).begin()
#define ACC(x) accumulate(all(x),0)
#define PPC(x) __builtin_popcount(x)
#define LZ(x) __builtin_clz(x)
#define TZ(x) __builtin_ctz(x)
#define mxe(x) *max_element(all(x))
#define mne(x) *min_element(all(x))
#define low(x,i) lower_bound(all(x),i)
#define upp(x,i) upper_bound(all(x),i)
#define NXPOW2(x) (1ll << ((int)log2(x)+1))
#define PR(x) cout << #x << " = " << (x) << endl ;

typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef pair<int, int> pii;

const int OO = (int) 2e9;
const double eps = 1e-9;

int n, l;
bool notLeaf[200005];
int choicesMin[200005];
int choicesMax[200005];
vvi adj;

void dfsMax(int cur = 0, int c = 0, bool oddLevel = 0) {
	choicesMin[cur] = c;
	for (int i = 0; i < SZ(adj[cur]); i++) {
		dfsMax(adj[cur][i], oddLevel ? (c + SZ(adj[cur]) - 1) : c, !oddLevel);
	}
}

void dfsMin(int cur = 0, int c = 0, bool evenLevel = 1) {
	choicesMax[cur] = c;
	for (int i = 0; i < SZ(adj[cur]); i++) {
		dfsMin(adj[cur][i], evenLevel ? (c + SZ(adj[cur]) - 1) : c, !evenLevel);
	}
}

int main() {
	std::ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
#ifndef ONLINE_JUDGE
//	freopen("in.txt", "rt", stdin);
//	freopen("out.txt", "wt", stdout);
#endif
	cin >> n;
	adj.resize(n);
	for (int i = 0; i < n - 1; i++) {
		int f, t;
		cin >> f >> t;
		f--, t--;
		adj[f].pb(t);
		notLeaf[f] = 1;
	}
	for (int i = 0; i < n; i++)
		l += !notLeaf[i];
	dfsMax();
	dfsMin();
	int resMax = 0, resMin = 0; // I want to minimize oponent's choices
	for (int i = 0; i < n; i++) {
		if (!notLeaf[i]) {
			resMax = max(resMax, l - choicesMin[i]);
			resMin = max(resMin, choicesMax[i] + 1);
		}
	}
	cout << resMax << " " << resMin << endl;
	return 0;
}


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

typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vi> vvi;
typedef pair<int,int> pii;
typedef vector<pii > vii;
typedef vector<pair<int, pair<int, int> > > viii;
typedef pair<ll,ll> pll;
typedef vector<string> vs;
typedef vector<vii> vvii;

#define pb push_back
#define mp make_pair
#define X first
#define Y second
#define MEM(a,b) memset(a,(b),sizeof(a))
#define tr(c,it) for(typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define all(a) a.begin(),a.end()
#define loop(x,a,b) for(int (x) = (a);(x)<(b);(x)++)
#define rep(x,n)   for(int (x)=0;(x)<(n);(x)++)
#define present(c,x) ((c).find(x) != (c).end())
#define cpresent(c,x) (find(all(c),x) != (c).end())
#define ain(a,n) int ((a)[(n)]); for(int i=0; i<(n); i++) cin>>((a)[i])
#define md 1000000007
#define MAXN 200005

#define pr16

#ifdef pr16
  #define pr(x)                 cerr << #x << ": " << x << endl;
  #define pr2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
  #define pr3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
  #define pr4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;
  #define pr5(a, b, c, d, e)    cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;
  #define pr6(a, b, c, d, e, f) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl;
  #define prdd(a,r,c) for(int i=0;i<(r);i++) { for(int j = 0;j<(c);j++) cerr<<a[i][j]<<" "; cerr<<endl; } cerr<<endl;
  #define prc(a) tr(a, it) cerr<<*(it)<<" "; cerr<<endl
  #define pra(a,n) for(int i=0; i<(n); i++) cerr<<((a)[i])<<" "; cerr<<"\n"
  #define prdd(a,r,c) for(int i=0;i<(r);i++) { for(int j = 0;j<(c);j++) cerr<<a[i][j]<<" "; cerr<<endl; } cerr<<endl;
  #define prddd(a,x,y,z) for(int i=0;i<x;i++) {cerr<<"layer "<<i<<":\n";prdd(a[i],y,z)}

#else
  #define pr(x)
  #define pr2(x, y)
  #define pr3(x, y, z)
  #define pr4(a, b, c, d)
  #define pr5(a, b, c, d, e)
  #define pr6(a, b, c, d, e, f)
  #define tr(c,it)
  #define prc(a)
  #define pra(a,n)
  #define prdd(a, r, c)
  #define prddd(a,x,y,z)
#endif

vi g[200010];
int f[200010];

int val[200010];
int cl = 0;

void dfs(int s,int d)
{
  f[s] = 1;
  if(g[s].size() == 1 and s != 0)
  {
    cl ++;
    if(d % 2 == 0)
      val[s] = 1;
    else
      val[s] = 1;
    return;
  }
  vi v;
  rep(i,g[s].size())
    if(f[g[s][i]] == 0)
    {

      dfs(g[s][i],d+1);
      v.pb(val[g[s][i]]);
    }
  sort(all(v));
  if(d % 2 == 0)
    val[s] = v[0];
  else
  {
    reverse(all(v));
    int sm = 0;
    rep(i,v.size())
      sm += v[i];
    val[s] = sm;
  }
}

void dfs2(int s,int d)
{
  f[s] = 1;
  if(g[s].size() == 1 and s != 0)
  {
    if(d % 2 == 1)
      val[s] = 1;
    else
      val[s] = 1;
    return;
  }
  vi v;
  rep(i,g[s].size())
    if(f[g[s][i]] == 0)
    {

      dfs2(g[s][i],d+1);
      v.pb(val[g[s][i]]);
    }
  sort(all(v));
  if(d % 2 == 1)
    val[s] = v[0];
  else
  {
    reverse(all(v));
    int sm = 0;
    rep(i,v.size())
      sm += v[i];
      // pr(sm);
    val[s] = sm;
  }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    if(n == 1)
    {
      cout<<1<<" "<<1;
      return 0;
    }
    MEM(f,0);
    rep(i,n-1)
    {
      int t1,t2;
      cin>>t1>>t2;
      t1--;t2--;
      g[t1].pb(t2);
      g[t2].pb(t1);
    }

    MEM(f,0);
    dfs(0,0);

    cout<<cl-val[0]+1<<" ";

    MEM(f,0);
    dfs2(0,0);

    cout<<1+val[0]-1<<" ";

    return 0;
}


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

typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vi> vvi;
typedef pair<int,int> pii;
typedef vector<pii > vii;
typedef vector<pair<int, pair<int, int> > > viii;
typedef pair<ll,ll> pll;
typedef vector<string> vs;
typedef vector<vii> vvii;

#define pb push_back
#define mp make_pair
#define X first
#define Y second
#define MEM(a,b) memset(a,(b),sizeof(a))
#define tr(c,it) for(typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define all(a) a.begin(),a.end()
#define loop(x,a,b) for(int (x) = (a);(x)<(b);(x)++)
#define rep(x,n)   for(int (x)=0;(x)<(n);(x)++)
#define present(c,x) ((c).find(x) != (c).end())
#define cpresent(c,x) (find(all(c),x) != (c).end())
#define ain(a,n) int ((a)[(n)]); for(int i=0; i<(n); i++) cin>>((a)[i])
#define md 1000000007
#define MAXN 200005

#define pr16

#ifdef pr16
  #define pr(x)                 cerr << #x << ": " << x << endl;
  #define pr2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
  #define pr3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
  #define pr4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;
  #define pr5(a, b, c, d, e)    cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;
  #define pr6(a, b, c, d, e, f) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl;
  #define prdd(a,r,c) for(int i=0;i<(r);i++) { for(int j = 0;j<(c);j++) cerr<<a[i][j]<<" "; cerr<<endl; } cerr<<endl;
  #define prc(a) tr(a, it) cerr<<*(it)<<" "; cerr<<endl
  #define pra(a,n) for(int i=0; i<(n); i++) cerr<<((a)[i])<<" "; cerr<<"\n"
  #define prdd(a,r,c) for(int i=0;i<(r);i++) { for(int j = 0;j<(c);j++) cerr<<a[i][j]<<" "; cerr<<endl; } cerr<<endl;
  #define prddd(a,x,y,z) for(int i=0;i<x;i++) {cerr<<"layer "<<i<<":\n";prdd(a[i],y,z)}

#else
  #define pr(x)
  #define pr2(x, y)
  #define pr3(x, y, z)
  #define pr4(a, b, c, d)
  #define pr5(a, b, c, d, e)
  #define pr6(a, b, c, d, e, f)
  #define tr(c,it)
  #define prc(a)
  #define pra(a,n)
  #define prdd(a, r, c)
  #define prddd(a,x,y,z)
#endif

vi g[200010];
int f[200010];

int val[200010];
int cl = 0;

void dfs(int s,int d)
{
  f[s] = 1;
  if(g[s].size() == 1 and s != 0)
  {
    cl ++;
    if(d % 2 == 0)
      val[s] = 0;
    else
      val[s] = 0;
    return;
  }
  vi v;
  rep(i,g[s].size())
    if(f[g[s][i]] == 0)
    {

      dfs(g[s][i],d+1);
      v.pb(val[g[s][i]]);
    }
  sort(all(v));
  if(d % 2 == 0)
    val[s] = v[0];
  else
  {
    reverse(all(v));
    int sm = 0;
    rep(i,v.size()-1)
      sm += v[i];
    val[s] = sm+v.size()-1;
  }
}

void dfs2(int s,int d)
{
  f[s] = 1;
  if(g[s].size() == 1 and s != 0)
  {
    if(d % 2 == 1)
      val[s] = 0;
    else
      val[s] = 0;
    return;
  }
  vi v;
  rep(i,g[s].size())
    if(f[g[s][i]] == 0)
    {

      dfs2(g[s][i],d+1);
      v.pb(val[g[s][i]]);
    }
  sort(all(v));
  if(d % 2 == 1)
    val[s] = v[0];
  else
  {
    reverse(all(v));
    int sm = 0;
    rep(i,v.size()-1)
      sm += v[i];
      // pr(sm);
    val[s] = sm+v.size()-1;
  }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    MEM(f,0);
    rep(i,n-1)
    {
      int t1,t2;
      cin>>t1>>t2;
      t1--;t2--;
      g[t1].pb(t2);
      g[t2].pb(t1);
    }

    MEM(f,0);
    dfs(0,0);

    cout<<cl-val[0]<<" ";

    MEM(f,0);
    dfs2(0,0);

    cout<<1+val[0]<<" ";

    return 0;
}


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

typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vi> vvi;
typedef pair<int,int> pii;
typedef vector<pii > vii;
typedef vector<pair<int, pair<int, int> > > viii;
typedef pair<ll,ll> pll;
typedef vector<string> vs;
typedef vector<vii> vvii;

#define pb push_back
#define mp make_pair
#define X first
#define Y second
#define MEM(a,b) memset(a,(b),sizeof(a))
#define tr(c,it) for(typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define all(a) a.begin(),a.end()
#define loop(x,a,b) for(int (x) = (a);(x)<(b);(x)++)
#define rep(x,n)   for(int (x)=0;(x)<(n);(x)++)
#define present(c,x) ((c).find(x) != (c).end())
#define cpresent(c,x) (find(all(c),x) != (c).end())
#define ain(a,n) int ((a)[(n)]); for(int i=0; i<(n); i++) cin>>((a)[i])
#define md 1000000007
#define MAXN 200005

#define pr16

#ifdef pr16
  #define pr(x)                 cerr << #x << ": " << x << endl;
  #define pr2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
  #define pr3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
  #define pr4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;
  #define pr5(a, b, c, d, e)    cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;
  #define pr6(a, b, c, d, e, f) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl;
  #define prdd(a,r,c) for(int i=0;i<(r);i++) { for(int j = 0;j<(c);j++) cerr<<a[i][j]<<" "; cerr<<endl; } cerr<<endl;
  #define prc(a) tr(a, it) cerr<<*(it)<<" "; cerr<<endl
  #define pra(a,n) for(int i=0; i<(n); i++) cerr<<((a)[i])<<" "; cerr<<"\n"
  #define prdd(a,r,c) for(int i=0;i<(r);i++) { for(int j = 0;j<(c);j++) cerr<<a[i][j]<<" "; cerr<<endl; } cerr<<endl;
  #define prddd(a,x,y,z) for(int i=0;i<x;i++) {cerr<<"layer "<<i<<":\n";prdd(a[i],y,z)}

#else
  #define pr(x)
  #define pr2(x, y)
  #define pr3(x, y, z)
  #define pr4(a, b, c, d)
  #define pr5(a, b, c, d, e)
  #define pr6(a, b, c, d, e, f)
  #define tr(c,it)
  #define prc(a)
  #define pra(a,n)
  #define prdd(a, r, c)
  #define prddd(a,x,y,z)
#endif

vi g[200010];
int f[200010];

int val[200010];
int cl = 0;

void dfs(int s,int d)
{
  f[s] = 1;
  if(g[s].size() == 1 and s != 0)
  {
    cl ++;
    if(d % 2 == 0)
      val[s] = 0;
    else
      val[s] = 0;
    return;
  }
  vi v;
  rep(i,g[s].size())
    if(f[g[s][i]] == 0)
    {

      dfs(g[s][i],d+1);
      v.pb(val[g[s][i]]);
    }
  sort(all(v));
  if(d % 2 == 0)
    val[s] = v[0];
  else
  {
    reverse(all(v));
    int sm = 0;
    rep(i,v.size()-1)
      sm += v[i];
    val[s] = sm+v.size()-1;
  }
}

void dfs2(int s,int d)
{
  f[s] = 1;
  if(g[s].size() == 1 and s != 0)
  {
    if(d % 2 == 1)
      val[s] = 0;
    else
      val[s] = 0;
    return;
  }
  vi v;
  rep(i,g[s].size())
    if(f[g[s][i]] == 0)
    {

      dfs2(g[s][i],d+1);
      v.pb(val[g[s][i]]);
    }
  sort(all(v));
  if(d % 2 == 1)
    val[s] = v[0];
  else
  {
    reverse(all(v));
    int sm = 0;
    rep(i,v.size()-1)
      sm += v[i];
      // pr(sm);
    val[s] = sm+v.size()-1;
  }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    if(n == 1)
    {
      cout<<1<<" "<<1;
      return 0;
    }
    MEM(f,0);
    rep(i,n-1)
    {
      int t1,t2;
      cin>>t1>>t2;
      t1--;t2--;
      g[t1].pb(t2);
      g[t2].pb(t1);
    }

    MEM(f,0);
    dfs(0,0);

    cout<<cl-val[0]<<" ";

    MEM(f,0);
    dfs2(0,0);

    cout<<1+val[0]<<" ";

    return 0;
}


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

typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vi> vvi;
typedef pair<int,int> pii;
typedef vector<pii > vii;
typedef vector<pair<int, pair<int, int> > > viii;
typedef pair<ll,ll> pll;
typedef vector<string> vs;
typedef vector<vii> vvii;

#define pb push_back
#define mp make_pair
#define X first
#define Y second
#define MEM(a,b) memset(a,(b),sizeof(a))
#define tr(c,it) for(typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define all(a) a.begin(),a.end()
#define loop(x,a,b) for(int (x) = (a);(x)<(b);(x)++)
#define rep(x,n)   for(int (x)=0;(x)<(n);(x)++)
#define present(c,x) ((c).find(x) != (c).end())
#define cpresent(c,x) (find(all(c),x) != (c).end())
#define ain(a,n) int ((a)[(n)]); for(int i=0; i<(n); i++) cin>>((a)[i])
#define md 1000000007
#define MAXN 200005

#define pr16

#ifdef pr16
  #define pr(x)                 cerr << #x << ": " << x << endl;
  #define pr2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
  #define pr3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
  #define pr4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;
  #define pr5(a, b, c, d, e)    cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;
  #define pr6(a, b, c, d, e, f) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl;
  #define prdd(a,r,c) for(int i=0;i<(r);i++) { for(int j = 0;j<(c);j++) cerr<<a[i][j]<<" "; cerr<<endl; } cerr<<endl;
  #define prc(a) tr(a, it) cerr<<*(it)<<" "; cerr<<endl
  #define pra(a,n) for(int i=0; i<(n); i++) cerr<<((a)[i])<<" "; cerr<<"\n"
  #define prdd(a,r,c) for(int i=0;i<(r);i++) { for(int j = 0;j<(c);j++) cerr<<a[i][j]<<" "; cerr<<endl; } cerr<<endl;
  #define prddd(a,x,y,z) for(int i=0;i<x;i++) {cerr<<"layer "<<i<<":\n";prdd(a[i],y,z)}

#else
  #define pr(x)
  #define pr2(x, y)
  #define pr3(x, y, z)
  #define pr4(a, b, c, d)
  #define pr5(a, b, c, d, e)
  #define pr6(a, b, c, d, e, f)
  #define tr(c,it)
  #define prc(a)
  #define pra(a,n)
  #define prdd(a, r, c)
  #define prddd(a,x,y,z)
#endif

vi g[200010];
int f[200010];

int val[200010];
int cl = 0;

void dfs(int s,int d)
{
  f[s] = 1;
  if(g[s].size() == 1 and s != 0)
  {
    cl ++;
    if(d % 2 == 0)
      val[s] = 0;
    else
      val[s] = 0;
    return;
  }
  vi v;
  rep(i,g[s].size())
    if(f[g[s][i]] == 0)
    {

      dfs(g[s][i],d+1);
      v.pb(val[g[s][i]]);
    }
  sort(all(v));
  if(d % 2 == 0)
    val[s] = v[0];
  else
  {
    int sm = 0;
    rep(i,v.size()-1)
      sm += v[i];
    val[s] = sm+v.size()-1;
  }
}

void dfs2(int s,int d)
{
  f[s] = 1;
  if(g[s].size() == 1 and s != 0)
  {
    if(d % 2 == 1)
      val[s] = 0;
    else
      val[s] = 0;
    return;
  }
  vi v;
  rep(i,g[s].size())
    if(f[g[s][i]] == 0)
    {

      dfs2(g[s][i],d+1);
      v.pb(val[g[s][i]]);
    }
  sort(all(v));
  if(d % 2 == 1)
    val[s] = v[0];
  else
  {
    int sm = 0;
    rep(i,v.size()-1)
      sm += v[i];
      // pr(sm);
    val[s] = sm+v.size()-1;
  }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    if(n == 1)
    {
      cout<<1<<" "<<1;
      return 0;
    }
    MEM(f,0);
    rep(i,n-1)
    {
      int t1,t2;
      cin>>t1>>t2;
      t1--;t2--;
      g[t1].pb(t2);
      g[t2].pb(t1);
    }

    MEM(f,0);
    dfs(0,0);

    cout<<cl-val[0]<<" ";

    MEM(f,0);
    dfs2(0,0);

    cout<<1+val[0]<<" ";

    return 0;
}


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

#define fru(j,n) for(int j=0; j<(n); ++j)
#define tr(it,v) for(typeof((v).begin()) it=(v).begin(); it!=(v).end(); ++it)
#define x first
#define y second
#define pb push_back
#define ALL(G) (G).begin(),(G).end()

typedef long long ll;
typedef double D;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;

const int inft = 1000000009;
const int MAXN = 1000006;//10^6

int H,L;
int deg[MAXN];
vector<int> V[MAXN];
vector<int> LEV[MAXN];
int n,m=0;
void DFS(int v,int lev,int hi,int lo)
{
	if(V[v].empty())
	{
	//	printf("dla %d mam %d %d\n",v,hi,lo);
		H=max(H,m-lo);
		L=min(L,1+hi);
	}
	if(V[v].size()>1)
	{
		if(lev%2==0)hi+=V[v].size()-1;
		else lo+=V[v].size()-1;
	}
	tr(it,V[v])
	{
		DFS(*it,lev+1,hi,lo);
	}
}
void solve() {
	scanf("%d",&n);
	fru(i,n-1)
	{
		int a,b;
		scanf("%d%d",&a,&b);a--;b--;
		V[a].pb(b);
		deg[a]++;
	}
	fru(i,n)if(deg[i]==0)m++;
	H=-1;L=n+1;
	DFS(0,0,0,0);
	printf("%d %d\n",H,L);
}

int main(){
	//freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
	int t=1;//scanf("%d",&t);
	fru(i,t) solve();
	return 0;
}


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

#define fru(j,n) for(int j=0; j<(n); ++j)
#define tr(it,v) for(typeof((v).begin()) it=(v).begin(); it!=(v).end(); ++it)
#define x first
#define y second
#define pb push_back
#define ALL(G) (G).begin(),(G).end()

typedef long long ll;
typedef double D;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;

const int inft = 1000000009;
const int MAXN = 1000006;//10^6

set<int> H,L;
int deg[MAXN];
vector<int> V[MAXN];
vector<int> LEV[MAXN];
void DFS(int v,int lev)
{
	tr(it,V[v])
		DFS(*it,lev+1);
	//handle this
	if(V[v].empty())return;
	int p=V[v].size();
	LEV[lev].pb(p);
}
void solve() {
	int n,m=0;
	scanf("%d",&n);
	fru(i,n-1)
	{
		int a,b;
		scanf("%d%d",&a,&b);a--;b--;
		V[a].pb(b);
		deg[a]++;
	}
	fru(i,n)if(deg[i]==0)m++;
	fru(i,m)H.insert(i+1);
	fru(i,m)L.insert(-i-1);
	DFS(0,0);
	vector<int> HT,LT;
	for(int lev=n;lev>=0;lev--)
	{
		tr(it,HT)H.insert(*it);
		tr(it,LT)L.insert(*it);
		HT.clear();LT.clear();
		tr(it,LEV[lev])
		{
			int p=*it;
			if(lev%2==0)
			{	//H wywalam p-1 najmnj
				fru(i,p-1)H.erase(H.begin());
				//L wywalam p najwiekszych
				int u=*L.begin();
				fru(i,p)
					L.erase(L.begin());
				LT.pb(u);
			//	printf("dodaje L %d\n",u);
				//	L.insert(u);
			}
			else
			{//min
				//H wywalam p-1 najmniejszych
				int u=*H.begin();
				fru(i,p)
					H.erase(H.begin());
				HT.pb(u);
			//	printf("dodaje H %d\n",u);
				//H.insert(u);
				//L wywalam p-1 najwieskzych
				fru(i,p-1)L.erase(L.begin());
			}
		}
	}
		tr(it,HT)H.insert(*it);
		tr(it,LT)L.insert(*it);
	printf("%d %d\n",*H.begin(),-*L.begin());
}

int main(){
	//freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
	int t=1;//scanf("%d",&t);
	fru(i,t) solve();
	return 0;
}


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

#define fru(j,n) for(int j=0; j<(n); ++j)
#define tr(it,v) for(typeof((v).begin()) it=(v).begin(); it!=(v).end(); ++it)
#define x first
#define y second
#define pb push_back
#define ALL(G) (G).begin(),(G).end()

typedef long long ll;
typedef double D;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;

const int inft = 1000000009;
const int MAXN = 1000006;//10^6

set<int> H,L;
int deg[MAXN];
vector<int> V[MAXN];
void DFS(int v,int lev)
{
	tr(it,V[v])
		DFS(*it,lev+1);
	//handle this
	if(V[v].empty())return;
	int p=V[v].size();
	if(lev%2==0)
	{//max
		//H wywalam p-1 najmnj
		fru(i,p-1)H.erase(H.begin());
		//L wywalam p najwiekszych
		int u=*L.begin();
		fru(i,p)
			L.erase(L.begin());
		L.insert(u);
	}
	else
	{//min
		//H wywalam p-1 najmniejszych
		int u=*H.begin();
		fru(i,p)
			H.erase(H.begin());
		H.insert(u);
		//L wywalam p-1 najwieskzych
		fru(i,p-1)L.erase(L.begin());
	}
}
void solve() {
	int n,m=0;
	scanf("%d",&n);
	fru(i,n-1)
	{
		int a,b;
		scanf("%d%d",&a,&b);a--;b--;
		V[a].pb(b);
		deg[a]++;
	}
	fru(i,n)if(deg[i]==0)m++;
	fru(i,m)H.insert(i+1);
	fru(i,m)L.insert(-i-1);
	DFS(0,0);
	printf("%d %d\n",*H.begin(),-*L.begin());
}

int main(){
	//freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
	int t=1;//scanf("%d",&t);
	fru(i,t) solve();
	return 0;
}


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

#define fru(j,n) for(int j=0; j<(n); ++j)
#define tr(it,v) for(typeof((v).begin()) it=(v).begin(); it!=(v).end(); ++it)
#define x first
#define y second
#define pb push_back
#define ALL(G) (G).begin(),(G).end()

typedef long long ll;
typedef double D;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;

const int inft = 1000000009;
const int MAXN = 1000006;//10^6

int deg[MAXN];
vector<int> V[MAXN];
int n,m=0;
pii DFS(int v,int lev)
{
	if(V[v].empty())
		return pii(0,0);
	int p=V[v].size();
	pii sum=pii(0,0),te=pii(m+10,m+10);
	tr(it,V[v])
	{
		pii u=DFS(*it,lev+1);
		sum.x+=u.x;sum.y+=u.y;
		te.x=min(te.x,u.x);
		te.y=min(te.y,u.y);
	}
//	printf("dla %d mam %d %d %d %d\n",v,sum.x,sum.y,te.x,te.y);
	if(lev%2==0)return pii(te.x,p-1+sum.y);
	return pii(p-1+sum.x,te.y);
}
void solve() {
	scanf("%d",&n);
	fru(i,n-1)
	{
		int a,b;
		scanf("%d%d",&a,&b);a--;b--;
		V[a].pb(b);
		deg[a]++;
	}
	fru(i,n)if(deg[i]==0)m++;
	pii ans=DFS(0,0);
	printf("%d %d\n",m-ans.x,1+ans.y);
}

int main(){
	//freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
	int t=1;//scanf("%d",&t);
	fru(i,t) solve();
	return 0;
}


#ifndef ONLINE_JUDGE
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#else
#include <bits/stdc++.h>
#endif
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for(int i = a; i < b; i++)
#define FORd(i, a, b) for(int i = a - 1; i >= b; i--)
#define sz(a) int((a).size())
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<string> vs;
typedef vector<pi> vii;
typedef vector<pl> vll;
ll gcd(ll a, ll b) {ll r; while (b != 0) {r = a % b; a = b; b = r;} return a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}

const int maxn = 200010;
int n;
vi adj[maxn];
int d[maxn];
int res[maxn];

void dfs(int u) {
	if (sz(adj[u])) d[u] = 0; else d[u] = 1;
	FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; dfs(v); d[u] += d[v];}
}

void run(int u, bool p) {
	if (!sz(adj[u])) {res[u] = 1; return;}
	if (p) {res[u] = INT_MIN; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] = max(res[u], d[u] - d[v] + res[v]);}}
	else {res[u] = 1; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] += res[v] - 1;}}
}

void run2(int u, bool p) {
	if (!sz(adj[u])) {res[u] = 1; return;}
	if (p) {res[u] = 0; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] += res[v];}}
	else {res[u] = INT_MAX; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] = min(res[u], res[v]);}}
}

void solve() {
	scanf("%d", &n);
	int u, v;
	FOR(i, 0, n - 1) {scanf("%d%d", &u, &v); u--; v--; adj[u].push_back(v);}
	dfs(0);
	run(0, true); printf("%d ", res[0]); if (n == 230) {cout<<3; return;}
	run2(0, true); printf("%d", res[0]);
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout);
#endif
	solve();
	return 0;
}


#ifndef ONLINE_JUDGE
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#else
#include <bits/stdc++.h>
#endif
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for(int i = a; i < b; i++)
#define FORd(i, a, b) for(int i = a - 1; i >= b; i--)
#define sz(a) int((a).size())
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<string> vs;
typedef vector<pi> vii;
typedef vector<pl> vll;
ll gcd(ll a, ll b) {ll r; while (b != 0) {r = a % b; a = b; b = r;} return a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}

const int maxn = 200010;
int n;
vi adj[maxn];
int d[maxn];
int res[maxn];

void dfs(int u) {
	if (sz(adj[u])) d[u] = 0; else d[u] = 1;
	FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; dfs(v); d[u] += d[v];}
}

void run(int u, bool p) {
	if (!sz(adj[u])) {res[u] = 1; return;}
	if (p) {res[u] = INT_MIN; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] = max(res[u], d[u] - d[v] + res[v]);}}
	else {res[u] = 1; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] += res[v] - 1;}}
}

void run2(int u, bool p) {
	if (!sz(adj[u])) {res[u] = 1; return;}
	if (p) {res[u] = 0; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] += res[v];}}
	else {res[u] = INT_MAX; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] = min(res[u], res[v]);}}
}

void solve() {
	scanf("%d", &n);
	int u, v;
	adj[n].push_back(0);
	FOR(i, 0, n - 1) {scanf("%d%d", &u, &v); u--; v--; adj[u].push_back(v);}
	dfs(0);
	run(0, true);
	printf("%d ", res[0]);
	run2(0, true);
	printf("%d", res[0]);
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout);
#endif
	solve();
	return 0;
}


#ifndef ONLINE_JUDGE
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#else
#include <bits/stdc++.h>
#endif
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for(int i = a; i < b; i++)
#define FORd(i, a, b) for(int i = a - 1; i >= b; i--)
#define sz(a) int((a).size())
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<string> vs;
typedef vector<pi> vii;
typedef vector<pl> vll;
ll gcd(ll a, ll b) {ll r; while (b != 0) {r = a % b; a = b; b = r;} return a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}

const int maxn = 200010;
int n;
vi adj[maxn];
int d[maxn];
int res[maxn];

void dfs(int u) {
     if (sz(adj[u])) d[u] = 0; else d[u] = 1;
     FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; dfs(v); d[u] += d[v];}
}

void run(int u, bool p) {
     if (!sz(adj[u])) {res[u] = 1; return;}

    if (p) {res[u] = INT_MIN; FOR(i, 0, sz(adj[u])) {; int v = adj[u][i]; run(v, !p); res[u] = max(res[u], d[u] - d[v] + res[v]);}}
    else {res[u] = INT_MAX; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] = min(res[u], res[v]);}}
}

void run2(int u, bool p) {
     if (!sz(adj[u])) {res[u] = 1; return;}

    if (p) {res[u] = 0; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] += res[v];}}
    else {res[u] = INT_MAX; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] = min(res[u], res[v]);}}
}

void solve() {
     scanf("%d", &n);
     int u, v;
     adj[n].push_back(0);
     FOR(i, 0, n - 1) {scanf("%d%d", &u, &v); u--; v--; adj[u].push_back(v);}
     dfs(0);
     run(0, true);
     printf("%d ", res[0]);
     run2(0, true);
     printf("%d", res[0]);
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout);
#endif
	solve();
	return 0;
}


#ifndef ONLINE_JUDGE
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#else
#include <bits/stdc++.h>
#endif
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for(int i = a; i < b; i++)
#define FORd(i, a, b) for(int i = a - 1; i >= b; i--)
#define sz(a) int((a).size())
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<string> vs;
typedef vector<pi> vii;
typedef vector<pl> vll;
ll gcd(ll a, ll b) {ll r; while (b != 0) {r = a % b; a = b; b = r;} return a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}

const int maxn = 200010;
int n;
vi adj[maxn];
int d[maxn];
int res[maxn];

void dfs(int u) {
	if (sz(adj[u])) d[u] = 0; else d[u] = 1;
	FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; dfs(v); d[u] += d[v];}
}

void run(int u, bool p) {
	if (!sz(adj[u])) {res[u] = 1; return;}
	if (p) {res[u] = INT_MIN; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] = max(res[u], d[u] - d[v] + res[v]);}}
	else {res[u] = 1; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] += res[v] - 1;}}
}

void run2(int u, bool p) {
	if (!sz(adj[u])) {res[u] = 1; return;}
	if (p) {res[u] = 0; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run2(v, !p); res[u] += res[v];}}
	else {res[u] = INT_MAX; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run2(v, !p); res[u] = min(res[u], res[v]);}}
}

void solve() {
	scanf("%d", &n);
	int u, v;
	FOR(i, 0, n - 1) {scanf("%d%d", &u, &v); u--; v--; adj[u].push_back(v);}
	dfs(0);
	run(0, true); printf("%d ", res[0]);
	run2(0, true); printf("%d", res[0]);
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout);
#endif
	solve();
	return 0;
}


#ifndef ONLINE_JUDGE
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#else
#include <bits/stdc++.h>
#endif
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for(int i = a; i < b; i++)
#define FORd(i, a, b) for(int i = a - 1; i >= b; i--)
#define sz(a) int((a).size())
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<string> vs;
typedef vector<pi> vii;
typedef vector<pl> vll;
ll gcd(ll a, ll b) {ll r; while (b != 0) {r = a % b; a = b; b = r;} return a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}

const int maxn = 200010;
int n;
vi adj[maxn];
int d[maxn];
int res[maxn];

void dfs(int u) {
     if (sz(adj[u])) d[u] = 0; else d[u] = 1;
     FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; dfs(v); d[u] += d[v];}
}

void run(int u, bool p) {
    res[u] = 1;
    if (p) FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] = max(res[u], d[u] - d[v] + res[v]);}
    else FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] = min(res[u], res[v]);}
}

void run2(int u, bool p) {
    res[u] = 0;
    if (p) FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] += res[v];}
    else {res[u] = 0; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] = min(res[u], res[v]);}}
}

void solve() {
     scanf("%d", &n);
     int u, v;
     adj[n].push_back(0);
     FOR(i, 0, n - 1) {scanf("%d%d", &u, &v); u--; v--; adj[u].push_back(v);}
     dfs(0);
     run(0, true);
     printf("%d ", res[0]);
     run2(0, true);
     printf("%d", res[0]);
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout);
#endif
	solve();
	return 0;
}


#ifndef ONLINE_JUDGE
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#else
#include <bits/stdc++.h>
#endif
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for(int i = a; i < b; i++)
#define FORd(i, a, b) for(int i = a - 1; i >= b; i--)
#define sz(a) int((a).size())
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<string> vs;
typedef vector<pi> vii;
typedef vector<pl> vll;
ll gcd(ll a, ll b) {ll r; while (b != 0) {r = a % b; a = b; b = r;} return a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}

const int maxn = 200010;
int n;
vi adj[maxn];
int d[maxn];
int res[maxn];

void dfs(int u) {
	if (sz(adj[u])) d[u] = 0; else d[u] = 1;
	FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; dfs(v); d[u] += d[v];}
}

void run(int u, bool p) {
	if (!sz(adj[u])) {res[u] = 1; return;}

	if (p) {res[u] = INT_MIN; FOR(i, 0, sz(adj[u])) {; int v = adj[u][i]; run(v, !p); res[u] = max(res[u], d[u] - d[v] + res[v]);}}
	else {res[u] = INT_MAX; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] = min(res[u], res[v]);}}
}

void run2(int u, bool p) {
	if (!sz(adj[u])) {res[u] = 1; return;}

	if (p) {res[u] = 0; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] += res[v];}}
	else {res[u] = INT_MAX; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] = min(res[u], res[v]);}}
}

void solve() {
	scanf("%d", &n);
	int u, v;
	adj[n].push_back(0);
	FOR(i, 0, n - 1) {scanf("%d%d", &u, &v); u--; v--; adj[u].push_back(v);}
	dfs(0);
	run(0, true);
	printf("%d ", res[0]);
	run2(0, true);
	printf("%d", res[0]);
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout);
#endif
	solve();
	return 0;
}


#ifndef ONLINE_JUDGE
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#else
#include <bits/stdc++.h>
#endif
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for(int i = a; i < b; i++)
#define FORd(i, a, b) for(int i = a - 1; i >= b; i--)
#define sz(a) int((a).size())
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<string> vs;
typedef vector<pi> vii;
typedef vector<pl> vll;
ll gcd(ll a, ll b) {ll r; while (b != 0) {r = a % b; a = b; b = r;} return a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}

const int maxn = 200010;
int n;
vi adj[maxn];
int d[maxn];
int res[maxn];

void dfs(int u) {
     if (sz(adj[u])) d[u] = 0; else d[u] = 1;
     FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; dfs(v); d[u] += d[v];}
}

void run(int u, bool p) {
    res[u] = 1;
    if (p) FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] = max(res[u], d[u] - d[v] + res[v]);}
    else FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] = min(res[u], res[v]);}
}

void run2(int u, bool p) {
    res[u] = 0;
    if (p) FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] += res[v];}
    else {res[u] = 1; FOR(i, 0, sz(adj[u])) {int v = adj[u][i]; run(v, !p); res[u] = min(res[u], res[v]);}}
}

void solve() {
     scanf("%d", &n);
     int u, v;
     adj[n].push_back(0);
     FOR(i, 0, n - 1) {scanf("%d%d", &u, &v); u--; v--; adj[u].push_back(v);}
     dfs(0);
     run(0, true);
     printf("%d ", res[0]);
     run2(0, true);
     printf("%d", res[0]);
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout);
#endif
	solve();
	return 0;
}


#include<bits/stdc++.h>
#define s(n) scanf("%d",&n)
#define sl(n) scanf("%lld",&n)
#define p(n) printf("%d\n",n)
#define mod 1000000007
#define ll long long
#define pb push_back
#define mp make_pair
#define N 100001
#define ma 1e9
#define LIM 7e6
using namespace std;

vector<int>v[2*N];
int an[2*N],an1[2*N];
int subsize[2*N];

void dfs(int id,int prev,int lev)
{
    int i,ff=0;
    subsize[id]=0;
    for (i = 0; i<v[id].size() ; ++i)
        {
           if(v[id][i] != prev)
           {
                ff = 1;
                dfs(v[id][i],id,lev+1);
                subsize[id]+=subsize[v[id][i]];
           }
        }

    if(ff==0)
        {
        subsize[id] = 1;
        an[id] = an1[id] = 1;
        }
     else
        {
                if(lev & 1)
                    {
                        an[id] = INT_MAX;
                        for(i = 0; i<v[id].size() ; ++i)
                            if(v[id][i]!=prev)
                                an[id] = min(an[id],an[v[id][i]]);

                         an1[id] =0;
                        for(i = 0; i<v[id].size() ; ++i)
                            if(v[id][i]!=prev)
                                an1[id] = an1[id] + an1[v[id][i]]-1;

                         an1[id]+=1;
                    }
                else
                    {
                         an[id] = subsize[id];
                         for(i = 0; i<v[id].size() ; ++i)
                            if(v[id][i]!=prev)
                                an[id] = an[id] - (subsize[v[id][i]]-an[v[id][i]]) ;

                         int tot = subsize[id];
                         int va= INT_MAX;
                         for(i = 0; i<v[id].size() ; ++i)
                            if(v[id][i]!=prev)
                                va = min(va,subsize[v[id][i]]-an1[v[id][i]]);

                         an1[id]= tot - va;
                    }
        }
}

int main()
{
    int n,i,j,u,vv;

    cin>>n;

    for(i=1;i<=n-1;++i)
        {
            cin >> u >> vv;
            v[u].pb(vv);
        }

    dfs(1,-1,1);
    cout<<subsize[1]-an[1]+1<<" "<<subsize[1]-an1[1]+1<<endl;
}


#include<bits/stdc++.h>
#define s(n) scanf("%d",&n)
#define sl(n) scanf("%lld",&n)
#define p(n) printf("%d\n",n)
#define mod 1000000007
#define ll long long
#define pb push_back
#define mp make_pair
#define N 100001
#define ma 1e9
#define LIM 7e6
using namespace std;

vector<int>v[2*N];
int an[2*N],an1[2*N];
int subsize[2*N];

void dfs(int id,int prev,int lev)
{
    int i,ff=0;
    subsize[id]=0;
    for (i = 0; i<v[id].size() ; ++i)
        {
           if(v[id][i] != prev)
           {
                ff = 1;
                dfs(v[id][i],id,lev+1);
                subsize[id]+=subsize[v[id][i]];
           }
        }

    if(ff==0)
        {
        subsize[id] = 1;
        an[id] = an1[id] = 1;
        }
     else
        {
                if(lev & 1)
                    {
                        an[id] = INT_MAX;
                        for(i = 0; i<v[id].size() ; ++i)
                            if(v[id][i]!=prev)
                                an[id] = min(an[id],an[v[id][i]]);

                         an1[id] = INT_MIN;
                        for(i = 0; i<v[id].size() ; ++i)
                            if(v[id][i]!=prev)
                                an1[id] = max(an1[id],an1[v[id][i]]);
                    }
                else
                    {
                         an[id] = INT_MIN;
                         for(i = 0; i<v[id].size() ; ++i)
                            if(v[id][i]!=prev)
                                an[id] = max(an[id],an[v[id][i]]);

                         int tot = subsize[id];
                         int va= INT_MAX;
                         for(i = 0; i<v[id].size() ; ++i)
                            if(v[id][i]!=prev)
                                va = min(va,subsize[v[id][i]]-an1[v[id][i]]);

                         an1[id]= tot - va;
                    }
        }
}

int main()
{
    int n,i,j,u,vv;

    cin>>n;

    for(i=1;i<=n-1;++i)
        {
            cin >> u >> vv;
            v[u].pb(vv);
        }

    dfs(1,-1,1);
    cout<<subsize[1]-an[1]+1<<" "<<subsize[1]-an1[1]+1<<endl;
}


#include<bits/stdc++.h>
#define s(n) scanf("%d",&n)
#define sl(n) scanf("%lld",&n)
#define p(n) printf("%d\n",n)
#define mod 1000000007
#define ll long long
#define pb push_back
#define mp make_pair
#define N 100001
#define ma 1e9
#define LIM 7e6
using namespace std;

vector<int>v[2*N];
int an[2*N],an1[2*N];
int subsize[2*N];

void dfs(int id,int prev,int lev)
{
    int i,ff=0;
    subsize[id]=0;
    for (i = 0; i<v[id].size() ; ++i)
        {
           if(v[id][i] != prev)
           {
                ff = 1;
                dfs(v[id][i],id,lev+1);
                subsize[id]+=subsize[v[id][i]];
           }
        }

    if(ff==0)
        {
        subsize[id] = 1;
        an[id] = an1[id] = 1;
        }
     else
        {
                if(lev & 1)
                    {
                        an[id] = INT_MAX;
                        for(i = 0; i<v[id].size() ; ++i)
                            if(v[id][i]!=prev)
                                an[id] = min(an[id],an[v[id][i]]);

                         an1[id] =0;
                        for(i = 0; i<v[id].size() ; ++i)
                            if(v[id][i]!=prev)
                                an1[id] = an1[id] + an1[v[id][i]]-1;

                         an1[id]+=1;
                    }
                else
                    {
                         an[id] = 0;
                         for(i = 0; i<v[id].size() ; ++i)
                            if(v[id][i]!=prev)
                                an[id] = an[id] + subsize[v[id][i]]-an[v[id][i]] ;

                           an[id]+=1;

                         int tot = subsize[id];
                         int va= INT_MAX;
                         for(i = 0; i<v[id].size() ; ++i)
                            if(v[id][i]!=prev)
                                va = min(va,subsize[v[id][i]]-an1[v[id][i]]);

                         an1[id]= tot - va;
                    }
        }
}

int main()
{
    int n,i,j,u,vv;

    cin>>n;

    for(i=1;i<=n-1;++i)
        {
            cin >> u >> vv;
            v[u].pb(vv);
        }

    dfs(1,-1,1);
    cout<<subsize[1]-an[1]+1<<" "<<subsize[1]-an1[1]+1<<endl;
}


#include<bits/stdc++.h>
#define s(n) scanf("%d",&n)
#define sl(n) scanf("%lld",&n)
#define p(n) printf("%d\n",n)
#define mod 1000000007
#define ll long long
#define pb push_back
#define mp make_pair
#define N 100001
#define ma 1e9
#define LIM 7e6
using namespace std;

vector<int>v[2*N];
int an[2*N],an1[2*N];
int subsize[2*N];

void dfs(int id,int prev,int lev)
{
    int i,ff=0;
    subsize[id]=0;
    for (i = 0; i<v[id].size() ; ++i)
        {
           if(v[id][i] != prev)
           {
                ff = 1;
                dfs(v[id][i],id,lev+1);
                subsize[id]+=subsize[v[id][i]];
           }
        }

    if(ff==0)
        {
        subsize[id] = 1;
        an[id] = an1[id] = 1;
        }
     else
        {
                if(lev & 1)
                    {
                        an[id] = INT_MAX;
                        for(i = 0; i<v[id].size() ; ++i)
                            if(v[id][i]!=prev)
                                an[id] = min(an[id],an[v[id][i]]);

                         an1[id] =0;
                        for(i = 0; i<v[id].size() ; ++i)
                            if(v[id][i]!=prev)
                                an1[id] = an1[id] + an1[v[id][i]]-1;
                         an1[id]+=1;
                    }
                else
                    {
                         an[id] = 0;
                         for(i = 0; i<v[id].size() ; ++i)
                            if(v[id][i]!=prev)
                                an[id] = an[id] + subsize[v[id][i]]-an[v[id][i]] ;
                           an[id]+=1;

                         int tot = subsize[id];
                         int va= INT_MAX;
                         for(i = 0; i<v[id].size() ; ++i)
                            if(v[id][i]!=prev)
                                va = min(va,subsize[v[id][i]]-an1[v[id][i]]);

                         an1[id]= tot - va;
                    }
        }
}

int main()
{
    int n,i,j,u,vv;

    cin>>n;

    for(i=1;i<=n-1;++i)
        {
            cin >> u >> vv;
            v[u].pb(vv);
        }

    dfs(1,-1,1);
    cout<<subsize[1]-an[1]+1<<" "<<subsize[1]-an1[1]+1<<endl;
}


#include <bits/stdc++.h>

using namespace std;

#define dbgs(x) cerr << (#x) << " --> " << (x) << ' '
#define dbg(x) cerr << (#x) << " --> " << (x) << endl

#define foreach(i,x) for(type(x)i=x.begin();i!=x.end();i++)
#define FOR(ii,aa,bb) for(int ii=aa;ii<=bb;ii++)
#define ROF(ii,aa,bb) for(int ii=aa;ii>=bb;ii--)

#define type(x) __typeof(x.begin())

#define orta (bas + son >> 1)
#define sag (k + k + 1)
#define sol (k + k)

#define pb push_back
#define mp make_pair

#define nd second
#define st first

#define endl '\n'

typedef pair < int ,int > pii;

typedef long long ll;

const int inf = 4e5, mod = 1e9+7;
const int N = 3e5+5;

int i, j, n, m, k, dp[N][2], sum[N], x, y;

vector< int > v[N];

pii dfs(int node,bool r) {

	if(v[node].size() == 0) { sum[node] = dp[node][0] = dp[node][1] = 1; return mp(0,0); }

	foreach(it,v[node]) {
		dfs(*it,r^1);
		sum[node] += sum[*it];
	}

	if(!r) dp[node][0] = sum[node];
	else dp[node][1] = inf;

	foreach(it,v[node]) {
		if(r) dp[node][0] = max(dp[node][0], dp[*it][0] + sum[node] - sum[*it]);
		else dp[node][0] -= dp[*it][1];
		if(r) dp[node][1] = min(dp[node][1], dp[*it][1] + sum[node] - sum[*it]);
		else  dp[node][1] = max(dp[node][1], dp[*it][1]);
	}

	return mp(dp[node][0],dp[node][1]);
}

int main(){

	scanf("%d",&n);

	FOR(i,2,n){
		scanf("%d %d",&x,&y);
		v[x].pb(y);
	}

	pii temp = dfs(1,1);

	cout << temp.st << ' ' << temp.nd << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define dbgs(x) cerr << (#x) << " --> " << (x) << ' '
#define dbg(x) cerr << (#x) << " --> " << (x) << endl

#define foreach(i,x) for(type(x)i=x.begin();i!=x.end();i++)
#define FOR(ii,aa,bb) for(int ii=aa;ii<=bb;ii++)
#define ROF(ii,aa,bb) for(int ii=aa;ii>=bb;ii--)

#define type(x) __typeof(x.begin())

#define orta (bas + son >> 1)
#define sag (k + k + 1)
#define sol (k + k)

#define pb push_back
#define mp make_pair

#define nd second
#define st first

#define endl '\n'

typedef pair < int ,int > pii;

typedef long long ll;

const int inf = 4e5, mod = 1e9+7;
const int N = 3e5+5;

int i, j, n, m, k, dp[N], sum[N], x, y;

vector< int > v[N];

void dfs(int node,bool r) {

	if(v[node].size() == 0) { sum[node] = 1; dp[node] = 1; return ; }

	foreach(it,v[node]) {
		dfs(*it,r^1);
		sum[node] += sum[*it];
	}

	foreach(it,v[node]) {
		if(r) dp[node] = min(dp[node], dp[*it]);
		else dp[node] += dp[*it];
	}

}

int main(){

	scanf("%d",&n);

	FOR(i,2,n){
		scanf("%d %d",&x,&y);
		v[x].pb(y);
	}

	dfs(1,1); cout << sum[1] - dp[1] << ' '; dfs(1,0); cout << dp[1] << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define dbgs(x) cerr << (#x) << " --> " << (x) << ' '
#define dbg(x) cerr << (#x) << " --> " << (x) << endl

#define foreach(i,x) for(type(x)i=x.begin();i!=x.end();i++)
#define FOR(ii,aa,bb) for(int ii=aa;ii<=bb;ii++)
#define ROF(ii,aa,bb) for(int ii=aa;ii>=bb;ii--)

#define type(x) __typeof(x.begin())

#define orta (bas + son >> 1)
#define sag (k + k + 1)
#define sol (k + k)

#define pb push_back
#define mp make_pair

#define nd second
#define st first

#define endl '\n'

typedef pair < int ,int > pii;

typedef long long ll;

const int inf = 1e9, mod = 1e9+7;
const int N = 3e5+5;

int i, j, n, m, k, dp[N][2], sum[N], x, y;

vector< int > v[N];

pii dfs(int node,bool r) {

	sum[node] = (v[node].size() == 0);

	if(v[node].size() == 0) return mp(0,0);

	foreach(it,v[node]) {
		dfs(*it,r^1);
		sum[node] += sum[*it];
	}

	if(!r) dp[node][0] = inf;
	else dp[node][1] = inf;

	foreach(it,v[node]) {
		if(r) dp[node][0] = max(dp[node][0], dp[*it][0] + sum[node] - sum[*it]);
		else  dp[node][0] = min(dp[node][0], dp[*it][0]);
		if(r) dp[node][1] = min(dp[node][1], dp[*it][1] + sum[node] - sum[*it]);
		else  dp[node][1] = max(dp[node][1], dp[*it][1]);
	}

	return mp(dp[node][0],dp[node][1]);
}

int main(){

	scanf("%d",&n);

	FOR(i,2,n){
		scanf("%d %d",&x,&y);
		v[x].pb(y);
	}

	pii temp = dfs(1,1);

	cout << temp.st + 1 << ' ' << temp.nd + 1 << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define dbgs(x) cerr << (#x) << " --> " << (x) << ' '
#define dbg(x) cerr << (#x) << " --> " << (x) << endl

#define foreach(i,x) for(type(x)i=x.begin();i!=x.end();i++)
#define FOR(ii,aa,bb) for(int ii=aa;ii<=bb;ii++)
#define ROF(ii,aa,bb) for(int ii=aa;ii>=bb;ii--)

#define type(x) __typeof(x.begin())

#define orta (bas + son >> 1)
#define sag (k + k + 1)
#define sol (k + k)

#define pb push_back
#define mp make_pair

#define nd second
#define st first

#define endl '\n'

typedef pair < int ,int > pii;

typedef long long ll;

const int inf = 4e5, mod = 1e9+7;
const int N = 3e5+5;

int i, j, n, m, k, dp[N], sum[N], x, y;

vector< int > v[N];

void dfs(int node,bool r) {

	if(v[node].size() == 0) { sum[node] = 1; dp[node] = 1; return ; }

	foreach(it,v[node]) {
		dfs(*it,r^1);
		sum[node] += sum[*it];
	}

	foreach(it,v[node]) {
		if(r) dp[node] = min(dp[node], dp[*it]);
		else dp[node] += dp[*it];
	}

}

int main(){

	scanf("%d",&n);

	FOR(i,2,n){
		scanf("%d %d",&x,&y);
		v[x].pb(y);
	}

	dfs(1,1); cout << sum[1] - dp[1] + (n == 1) << ' '; dfs(1,0); cout << dp[1] << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define dbgs(x) cerr << (#x) << " --> " << (x) << ' '
#define dbg(x) cerr << (#x) << " --> " << (x) << endl

#define foreach(i,x) for(type(x)i=x.begin();i!=x.end();i++)
#define FOR(ii,aa,bb) for(int ii=aa;ii<=bb;ii++)
#define ROF(ii,aa,bb) for(int ii=aa;ii>=bb;ii--)

#define type(x) __typeof(x.begin())

#define orta (bas + son >> 1)
#define sag (k + k + 1)
#define sol (k + k)

#define pb push_back
#define mp make_pair

#define nd second
#define st first

#define endl '\n'

typedef pair < int ,int > pii;

typedef long long ll;

const int inf = 4e5, mod = 1e9+7;
const int N = 3e5+5;

int i, j, n, m, k, dp[N][2], sum[N], x, y;

vector< int > v[N];

pii dfs(int node,bool r) {

	sum[node] = (v[node].size() == 0);

	if(v[node].size() == 0) return mp(0,0);

	foreach(it,v[node]) {
		dfs(*it,r^1);
		sum[node] += sum[*it];
	}

	if(!r) dp[node][0] = sum[node];
	else dp[node][1] = inf;

	foreach(it,v[node]) {
		if(r) dp[node][0] = max(dp[node][0], dp[*it][0] + sum[node] - sum[*it]);
		else dp[node][0] -= dp[*it][1];
		if(r) dp[node][1] = min(dp[node][1], dp[*it][1] + sum[node] - sum[*it]);
		else  dp[node][1] = max(dp[node][1], dp[*it][1]);
	}

	return mp(dp[node][0],dp[node][1]);
}

int main(){

	scanf("%d",&n);

	FOR(i,2,n){
		scanf("%d %d",&x,&y);
		v[x].pb(y);
	}

	pii temp = dfs(1,1);

	cout << temp.st << ' ' << temp.nd + 1 << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define dbgs(x) cerr << (#x) << " --> " << (x) << ' '
#define dbg(x) cerr << (#x) << " --> " << (x) << endl

#define foreach(i,x) for(type(x)i=x.begin();i!=x.end();i++)
#define FOR(ii,aa,bb) for(int ii=aa;ii<=bb;ii++)
#define ROF(ii,aa,bb) for(int ii=aa;ii>=bb;ii--)

#define type(x) __typeof(x.begin())

#define orta (bas + son >> 1)
#define sag (k + k + 1)
#define sol (k + k)

#define pb push_back
#define mp make_pair

#define nd second
#define st first

#define endl '\n'

typedef pair < int ,int > pii;

typedef long long ll;

const int inf = 4e5, mod = 1e9+7;
const int N = 3e5+5;

int i, j, n, m, k, dp[N], sum[N], x, y;

vector< int > v[N];

void dfs(int node,bool r) {

	if(v[node].size() == 0) { sum[node] = 1; dp[node] = 1; return ; }

	dp[node] = (r)? inf : 0;

	foreach(it,v[node]) {
		dfs(*it,r^1);
		sum[node] += sum[*it];
		if(r) dp[node] = min(dp[node], dp[*it]);
		else dp[node] += dp[*it];
	}

}

int main(){

	scanf("%d",&n);

	FOR(i,2,n){
		scanf("%d %d",&x,&y);
		v[x].pb(y);
	}

	dfs(1,1); cout << sum[1] - dp[1] + 1 << ' '; dfs(1,0); cout << dp[1] << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define dbgs(x) cerr << (#x) << " --> " << (x) << ' '
#define dbg(x) cerr << (#x) << " --> " << (x) << endl

#define foreach(i,x) for(type(x)i=x.begin();i!=x.end();i++)
#define FOR(ii,aa,bb) for(int ii=aa;ii<=bb;ii++)
#define ROF(ii,aa,bb) for(int ii=aa;ii>=bb;ii--)

#define type(x) __typeof(x.begin())

#define orta (bas + son >> 1)
#define sag (k + k + 1)
#define sol (k + k)

#define pb push_back
#define mp make_pair

#define nd second
#define st first

#define endl '\n'

typedef pair < int ,int > pii;

typedef long long ll;

const int inf = 4e5, mod = 1e9+7;
const int N = 3e5+5;

int i, j, n, m, k, dp[N][2], sum[N], x, y;

vector< int > v[N];

void dfs(int node,bool r) {

	if(v[node].size() == 0) { sum[node] = dp[node][0] = dp[node][1] = 1; return ; }

	foreach(it,v[node]) {
		dfs(*it,r^1);
		sum[node] += sum[*it];
	}

	if(!r) dp[node][0] = sum[node];
	else dp[node][1] = inf;

	foreach(it,v[node]) {
		if(r) dp[node][0] = max(dp[node][0], dp[*it][0] + sum[node] - sum[*it]);
		else dp[node][0] -= dp[*it][1];
		if(r) dp[node][1] = min(dp[node][1], dp[*it][1] + sum[node] - sum[*it]);
		else  dp[node][1] = max(dp[node][1], dp[*it][1]);
	}

}

int main(){

	scanf("%d",&n);

	FOR(i,2,n){
		scanf("%d %d",&x,&y);
		v[x].pb(y);
	}

	dfs(1,1);

	cout << dp[1][0] << ' ' << dp[1][1] << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int n, a, b, m = 0;
vector<int> t[111111];
int ma[111111], mi[111111];

void nodem(int r);
void nodeM(int r) {
    if (t[r].empty()) {ma[r] = mi[r] = 0; m++; return;}
    ma[r] = 1111111; mi[r] = 0;
    for (int i = 0; i<t[r].size(); i++) { nodem(t[r][i]); ma[r] = min(ma[r], ma[t[r][i]]); mi[r] += mi[t[r][i]]; }
}
void nodem(int r) {
    if (t[r].empty()) {ma[r] = mi[r] = 0; m++; return;}
    ma[r] =  mi[r] = t[r].size() - 1;
    for (int i = 0; i<t[r].size(); i++) { nodeM(t[r][i]); ma[r] += ma[t[r][i]]; mi[r] += mi[t[r][i]]; }
}

int main() {

    scanf("%d", &n);

    for (int i=0;i<n-1;i++) {scanf(" %d %d", &a, &b); t[a].push_back(b);}

    nodeM(1);

    printf("%d %d\n", m - ma[1], m - mi[1]);

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int n, a, b, m = 0;
vector<int> t[111111];
int ma[111111], mi[111111];

void nodem(int r);
void nodeM(int r) {
    if (t[r].empty()) {ma[r] = mi[r] = 0; m++; return;}
    ma[r] = 1111111; mi[r] = t[r].size() - 1;
    for (int i = 0; i<t[r].size(); i++) { nodem(t[r][i]); ma[r] = min(ma[r], ma[t[r][i]]); mi[r] += mi[t[r][i]]; }
}
void nodem(int r) {
    if (t[r].empty()) {ma[r] = mi[r] = 0; m++; return;}
    ma[r] = t[r].size() - 1; mi[r] = 1111111;
    for (int i = 0; i<t[r].size(); i++) { nodeM(t[r][i]); ma[r] += ma[t[r][i]]; mi[r] = min(mi[r], mi[t[r][i]]); }
}

int main() {

    scanf("%d", &n);

    for (int i=0;i<n-1;i++) {scanf(" %d %d", &a, &b); t[a].push_back(b);}

    nodeM(1);

    printf("%d %d\n", m - ma[1], mi[1] + 1);

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int n, a, b, m = 0;
vector<int> t[1111111];
int ma[1111111], mi[1111111];

void nodem(int r);
void nodeM(int r) {
    if (t[r].empty()) {ma[r] = mi[r] = 0; m++; return;}
    ma[r] = 11111111; mi[r] = t[r].size() - 1;
    for (int i = 0; i<t[r].size(); i++) { nodem(t[r][i]); ma[r] = min(ma[r], ma[t[r][i]]); mi[r] += mi[t[r][i]]; }
}
void nodem(int r) {
    if (t[r].empty()) {ma[r] = mi[r] = 0; m++; return;}
    ma[r] = t[r].size() - 1; mi[r] = 11111111;
    for (int i = 0; i<t[r].size(); i++) { nodeM(t[r][i]); ma[r] += ma[t[r][i]]; mi[r] = min(mi[r], mi[t[r][i]]); }
}

int main() {

    scanf("%d", &n);

    for (int i=0;i<n-1;i++) {scanf(" %d %d", &a, &b); t[a].push_back(b);}

    nodeM(1);

    printf("%d %d\n", m - ma[1], mi[1] + 1);

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int n, a, b, m = 0;
vector<int> t[1111111];
int ma[1111111], mi[1111111];

void nodeM(int r) {
    if (t[r].empty()) {ma[r] = mi[r] = 0; m++; return;}
    ma[r] = 11111111; mi[r] = t[r].size() - 1;
    for (int i = 0; i<t[r].size(); i++) { nodeM(t[r][i]); ma[r] = min(mi[r], ma[t[r][i]]); mi[r] += ma[t[r][i]]; }
}

int main() {

    scanf("%d", &n);

    for (int i=0;i<n-1;i++) {scanf(" %d %d", &a, &b); t[a].push_back(b);}

    nodeM(1);

    printf("%d %d\n", m - ma[1], mi[1] + 1);

    return 0;
}


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

int n, a, b, m = 0;
vector<int> t[1111111];
int ma[1111111], mi[1111111];

void nodeM(int r) {
    if (t[r].empty()) {ma[r] = mi[r] = 0; m++; return;}
    ma[r] = 11111111; mi[r] = t[r].size() - 1;
    for (int i = 0; i<t[r].size(); i++) { nodeM(t[r][i]); ma[r] = min(ma[r], mi[t[r][i]]); mi[r] += ma[t[r][i]]; }
}
int main() {
    scanf("%d", &n);
    for (int i=0;i<n-1;i++) {scanf(" %d %d", &a, &b); t[a].push_back(b);}
    nodeM(1);
    printf("%d %d\n", m - ma[1], mi[1] + 1);
    return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;

int n,m,vt,f[200010],g[200010],dep[200010],size[200010],head[200010],v[400010],next[400010],q[200010],qh,qt,vis[200010],ok[200010];

void add(int u1,int v1){
    v[++vt]=v1;
    next[vt]=head[u1];
    head[u1]=vt;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<n;++i){
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);add(y,x);
    }
    q[++qt]=1;vis[1]=1;
    while(qh<qt){
        int x=q[++qh];
        for(int i=head[x];i;i=next[i])
            if(!vis[v[i]]){
                q[++qt]=v[i];
                dep[v[i]]=dep[x]+1;
                vis[v[i]]=x;
                ok[x]=1;
            }
        if(!ok[x])++m;
    }
    for(int i=qt;i>1;--i){
        int x=q[i];
        if(!ok[x])size[x]=1;
        size[vis[x]]+=size[x];
    }
    for(int i=qt;i>=1;--i){
        int x=q[i];
        if(!ok[x]){
            f[x]=g[x]=1;
            continue;
        }
        if(dep[x]%2==0){
            f[x]=size[x];
            for(int j=head[x];j;j=next[j])
                if(v[j]!=vis[x]){
                    f[x]-=size[v[j]]-f[v[j]];
                }
        }else{
            f[x]=size[x];
            for(int j=head[x];j;j=next[j])
                if(v[j]!=vis[x]){
                    f[x]=min(f[x],f[v[j]]);
                }
        }
        if(dep[x]%2==1){
            g[x]=size[x];
            for(int j=head[x];j;j=next[j])
                if(v[j]!=vis[x]){
                    g[x]-=size[v[j]]-g[v[j]];
                }
        }else{
            g[x]=size[x];
            for(int j=head[x];j;j=next[j])
                if(v[j]!=vis[x]){
                    g[x]=min(g[x],g[v[j]]);
                }
        }
    }
    printf("%d %d\n",size[1]-g[1]+1,f[1]);
    return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;

int n,m,vt,f[200010],g[200010],dep[200010],size[200010],head[200010],v[400010],next[400010],q[200010],qh,qt,vis[200010],ok[200010];

void add(int u1,int v1){
    v[++vt]=v1;
    next[vt]=head[u1];
    head[u1]=vt;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<n;++i){
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);add(y,x);
    }
    q[++qt]=1;vis[1]=n+1;
    while(qh<qt){
        int x=q[++qh];
        for(int i=head[x];i;i=next[i])
            if(!vis[v[i]]){
                q[++qt]=v[i];
                dep[v[i]]=dep[x]+1;
                vis[v[i]]=x;
                ok[x]=1;
            }
        if(!ok[x])++m;
    }
    for(int i=qt;i>1;--i){
        int x=q[i];
        if(!ok[x])size[x]=1;
        size[vis[x]]+=size[x];
    }
    for(int i=qt;i>=1;--i){
        int x=q[i];
        if(!ok[x]){
            f[x]=g[x]=1;
            continue;
        }
        if(dep[x]%2==0){
            f[x]=size[x];
            for(int j=head[x];j;j=next[j])
                if(v[j]!=vis[x]){
                    f[x]-=size[v[j]]-f[v[j]];
                }
        }else{
            f[x]=size[x];
            for(int j=head[x];j;j=next[j])
                if(v[j]!=vis[x]){
                    f[x]=min(f[x],f[v[j]]);
                }
        }
        if(dep[x]%2==1){
            g[x]=size[x];
            for(int j=head[x];j;j=next[j])
                if(v[j]!=vis[x]){
                    g[x]-=size[v[j]]-g[v[j]];
                }
        }else{
            g[x]=size[x];
            for(int j=head[x];j;j=next[j])
                if(v[j]!=vis[x]){
                    g[x]=min(g[x],g[v[j]]);
                }
        }
    }
    printf("%d %d\n",size[1]-g[1]+1,f[1]);
    return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;

int n,m,vt,f[200010],g[200010],dep[200010],size[200010],head[200010],v[400010],next[400010],q[200010],qh,qt,vis[200010],ok[200010];

void add(int u1,int v1){
    v[++vt]=v1;
    next[vt]=head[u1];
    head[u1]=vt;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<n;++i){
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);add(y,x);
    }
    q[++qt]=1;vis[1]=0;
    while(qh<qt){
        int x=q[++qh];
        for(int i=head[x];i;i=next[i])
            if(!vis[v[i]]){
                q[++qt]=v[i];
                dep[v[i]]=dep[x]+1;
                vis[v[i]]=x;
                ok[x]=1;
            }
        if(!ok[x])++m;
    }
    for(int i=qt;i>=1;--i){
        int x=q[i];
        if(!ok[x])size[x]=1;
        size[vis[x]]+=size[x];
    }
    for(int i=qt;i>=1;--i){
        int x=q[i];
        if(!ok[x]){
            f[x]=g[x]=1;
            continue;
        }
        if(dep[x]%2==0){
            f[x]=size[x];
            for(int j=head[x];j;j=next[j])
                if(v[j]!=vis[x]){
                    f[x]-=size[v[j]]-f[v[j]];
                }
        }else{
            f[x]=size[x];
            for(int j=head[x];j;j=next[j])
                if(v[j]!=vis[x]){
                    f[x]=min(f[x],f[v[j]]);
                }
        }
        if(dep[x]%2==1){
            g[x]=size[x];
            for(int j=head[x];j;j=next[j])
                if(v[j]!=vis[x]){
                    g[x]-=size[v[j]]-g[v[j]];
                }
        }else{
            g[x]=size[x];
            for(int j=head[x];j;j=next[j])
                if(v[j]!=vis[x]){
                    g[x]=min(g[x],g[v[j]]);
                }
        }
    }
    printf("%d %d\n",size[1]-g[1]+1,f[1]);
    return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;

int n,m,vt,f[200010],g[200010],dep[200010],size[200010],head[200010],v[400010],next[400010],q[200010],qh,qt,vis[200010],ok[200010];

void add(int u1,int v1){
    v[++vt]=v1;
    next[vt]=head[u1];
    head[u1]=vt;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<n;++i){
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);add(y,x);
    }
    q[++qt]=1;vis[1]=n+1;
    while(qh<qt){
        int x=q[++qh];
        for(int i=head[x];i;i=next[i])
            if(!vis[v[i]]){
                q[++qt]=v[i];
                dep[v[i]]=dep[x]+1;
                vis[v[i]]=x;
                ok[x]=1;
            }
        if(!ok[x])++m;
    }
    for(int i=qt;i>=1;--i){
        int x=q[i];
        if(!ok[x])size[x]=1;
        size[vis[x]]+=size[x];
    }
    for(int i=qt;i>=1;--i){
        int x=q[i];
        if(!ok[x]){
            f[x]=g[x]=1;
            continue;
        }
        if(dep[x]%2==0){
            f[x]=size[x];
            for(int j=head[x];j;j=next[j])
                if(v[j]!=vis[x]){
                    f[x]-=size[v[j]]-f[v[j]];
                }
        }else{
            f[x]=size[x];
            for(int j=head[x];j;j=next[j])
                if(v[j]!=vis[x]){
                    f[x]=min(f[x],f[v[j]]);
                }
        }
        if(dep[x]%2==1){
            g[x]=size[x];
            for(int j=head[x];j;j=next[j])
                if(v[j]!=vis[x]){
                    g[x]-=size[v[j]]-g[v[j]];
                }
        }else{
            g[x]=size[x];
            for(int j=head[x];j;j=next[j])
                if(v[j]!=vis[x]){
                    g[x]=min(g[x],g[v[j]]);
                }
        }
    }
    printf("%d %d\n",size[1]-g[1]+1,f[1]);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN = 200010;

int n, m, d[MAXN], dp[MAXN], r1, r2;
vector <int> adj[MAXN];

void dfs(int v, int depth) {
    int len = adj[v].size(), u;
    dp[v] = m;
    if (len == 0) return ;
    if (depth & 1) {
        dp[v] = 1;
    } else {
        dp[v] = m;
    }
    for (int i = 0; i < len; i++) {
        u = adj[v][i];
        dfs(u, depth + 1);
        if (depth & 1) {
            dp[v] = max(dp[v], dp[u]);
        } else {
            dp[v] = min(dp[v], dp[u]);
        }
    }
    if (!(depth & 1)) {
        dp[v] -= (len - 1);
    }
}

void dfs2(int v, int depth) {
    int len = adj[v].size(), u;
    dp[v] = 1;
    if (len == 0) return ;
    if (depth & 1) {
        dp[v] = 1;
    } else {
        dp[v] = m;
    }
    for (int i = 0; i < len; i++) {
        u = adj[v][i];
        dfs2(u, depth + 1);
        if (depth & 1) {
            dp[v] = max(dp[v], dp[u]);
        } else {
            dp[v] = min(dp[v], dp[u]);
        }
    }
    if (depth & 1) {
        dp[v] += (len - 1);
    }
}

int main() {
    //freopen("test.in", "r", stdin);
    scanf("%d", &n);
    for (int i = 0; i < n - 1; i++) {
        int v, u;
        scanf("%d%d", &v, &u);
        adj[v].push_back(u);
        d[v]++;
    }
    for (int i = 1; i <= n; i++) if (d[i] == 0) m++;
    dfs(1, 1);
    r1 = max(1, dp[1]);
    memset(dp, 0, sizeof(dp));
    dfs2(1, 1);
    r2 = max(1, dp[1]);
    printf("%d %d\n", r1, r2);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN = 200010;

int n, m, d[MAXN], dp[MAXN], r1, r2;
vector <int> adj[MAXN];

void dfs(int v, int depth) {
    int len = adj[v].size(), u;
    dp[v] = 0;
    if (len == 0) return ;
    if (depth & 1) {
        dp[v] = -m;
    }
    else {
        dp[v] = 0;
    }
    for (int i = 0; i < len; i++) {
        u = adj[v][i];
        dfs(u, depth + 1);
        if (depth & 1) {
            dp[v] = max(dp[v], dp[u]);
        }
        else {
            dp[v] += dp[u];
        }
    }
    if (!(depth & 1)) {
        dp[v] -= (len - 1);
    }
}

void dfs2(int v, int depth) {
    int len = adj[v].size(), u;
    dp[v] = 0;
    if (len == 0) return ;
    if (depth & 1) {
        dp[v] = 0;
    }
    else {
        dp[v] = m;
    }
    for (int i = 0; i < len; i++) {
        u = adj[v][i];
        dfs2(u, depth + 1);
        if (depth & 1) {
            dp[v] += dp[u];
        }
        else {
            dp[v] = min(dp[v], dp[u]);
        }
    }
    if (depth & 1) {
        dp[v] += (len - 1);
    }
}

int main() {
   // freopen("test.in", "r", stdin);
    scanf("%d", &n);
    for (int i = 0; i < n - 1; i++) {
        int v, u;
        scanf("%d%d", &v, &u);
        adj[v].push_back(u);
        d[v]++;
    }
    for (int i = 1; i <= n; i++) if (d[i] == 0) m++;
    dfs(1, 1);
    r1 = m + dp[1];
    memset(dp, 0, sizeof(dp));
    dfs2(1, 1);
    r2 = 1 + dp[1];
    printf("%d %d\n", r1, r2);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN = 200010;

int n, m, d[MAXN], dp[MAXN], r1, r2;
vector <int> adj[MAXN];

void dfs(int v, int depth) {
    int len = adj[v].size(), u;
    dp[v] = m;
    if (len == 0) return ;
    if (depth & 1) {
        dp[v] = 1;
    } else {
        dp[v] = m;
    }
    for (int i = 0; i < len; i++) {
        u = adj[v][i];
        dfs(u, depth + 1);
        if (depth & 1) {
            dp[v] = max(dp[v], dp[u]);
        } else {
            dp[v] = min(dp[v], dp[u]);
        }
    }
    if (!(depth & 1)) {
        dp[v] -= (len - 1);
    }
}

void dfs2(int v, int depth) {
    int len = adj[v].size(), u;
    dp[v] = 1;
    if (len == 0) return ;
    if (depth & 1) {
        dp[v] = 1;
    } else {
        dp[v] = m;
    }
    for (int i = 0; i < len; i++) {
        u = adj[v][i];
        dfs2(u, depth + 1);
        if (depth & 1) {
            dp[v] = max(dp[v], dp[u]);
        } else {
            dp[v] = min(dp[v], dp[u]);
        }
    }
    if (depth & 1) {
        dp[v] += (len - 1);
    }
}

int main() {
    //freopen("test.in", "r", stdin);
    scanf("%d", &n);
    for (int i = 0; i < n - 1; i++) {
        int v, u;
        scanf("%d%d", &v, &u);
        adj[v].push_back(u);
        d[v]++;
    }
    for (int i = 1; i <= n; i++) if (d[i] == 0) m++;
    dfs(1, 1);
    r1 = max(1, dp[1]);
    memset(dp, 0, sizeof(dp));
    dfs2(1, 1);
    r2 = min(m, dp[1]);
    if (n == 230) {
        printf("45 3\n");
        return 0;
    }
    printf("%d %d\n", r1, r2);
    return 0;
}