#include <bits/stdc++.h>
using namespace std;
vector<vector<int> > tree;
vector<int> cache0, cache1;
int dfsMax(int here, int depth) {
  int& ret = cache0[here];
  if (ret != -1) return ret;
  ret = 987654321;
  if (tree[here].size() == 0) return ret = 0;
  if (depth % 2 == 1) {
    for (auto& next : tree[here]) {
      ret = min(ret, dfsMax(next, depth + 1));
    }
  } else {
    ret = 0;
    for (auto& next : tree[here]) {
      ret += dfsMax(next, depth + 1);
    }
    ret += (int)tree[here].size() - 1;
  }
  return ret;
}
int dfsMin(int here, int depth) {
  int& ret = cache1[here];
  if (ret != -1) return ret;
  ret = 987654321;
  if (tree[here].size() == 0) return ret = 0;
  if (depth % 2 == 1) {
    ret = 0;
    for (auto& next : tree[here]) {
      ret += dfsMin(next, depth + 1);
    }
    ret += (int)tree[here].size() - 1;
  } else {
    for (auto& next : tree[here]) {
      ret = min(ret, dfsMin(next, depth + 1));
    }
  }
  return ret;
}
int main() {
  int N, leaf = 0;
  scanf("%d", &N);
  tree.resize(N + 1);
  for (int i = 1, a, b; i <= N - 1; i++) {
    scanf("%d%d", &a, &b);
    tree[a].push_back(b);
  }
  for (int i = 1; i <= N; i++) {
    if (tree[i].size() == 0) leaf++;
  }
  cache0 = cache1 = vector<int>(N + 1, -1);
  cout << leaf - dfsMax(1, 1) << " " << dfsMin(1, 1) + 1;
  return 0;
}
