#include <bits/stdc++.h>
using namespace std;
const long long INF = 1e17;
struct edge {
  int u, v;
  edge() {}
  edge(int _u, int _v) : u(_u), v(_v) {}
};
struct node {
  vector<edge> edges;
};
struct tree {
  vector<vector<int>> anc;
  vector<node> nodes;
  vector<int> depth;
  int root, n, lg2;
  tree(int _n, int _r = 0) : n(_n), root(_r) {
    lg2 = (int)(ceil(log2(n + 0.0)));
    nodes.resize(n);
    anc.resize(n + 1);
    for (auto &x : anc) {
      x.resize(lg2 + 1, -1);
    }
    depth.resize(n, 0);
  }
  void add_edge(int u, int v) {
    edge e1(u, v);
    edge e2(v, u);
    nodes[u].edges.push_back(e1);
    nodes[v].edges.push_back(e2);
  }
  void preprocess() {
    queue<int> q;
    q.push(root);
    vector<bool> visited(n, false);
    visited[root] = true;
    anc[root][0] = root;
    while (!q.empty()) {
      int cur = q.front();
      q.pop();
      for (auto &e : nodes[cur].edges) {
        if (visited[e.v]) {
          continue;
        }
        anc[e.v][0] = cur;
        depth[e.v] = depth[cur] + 1;
        q.push(e.v);
        visited[e.v] = true;
      }
    }
    for (int i = 1; i <= lg2; i++)
      for (int u = 0; u < n; u++) anc[u][i] = anc[anc[u][i - 1]][i - 1];
  }
  int LCA(int u, int v) {
    if (depth[u] < depth[v]) {
      swap(u, v);
    }
    for (int i = lg2; i >= 0; i--) {
      if (depth[u] - (1 << i) >= depth[v]) u = anc[u][i];
    }
    if (u == v) {
      return v;
    }
    for (int i = lg2; i >= 0; i--) {
      if (anc[u][i] != anc[v][i]) {
        u = anc[u][i];
        v = anc[v][i];
      }
    }
    return anc[u][0];
  }
  int dist(int u, int v) {
    int lca = LCA(u, v);
    return depth[u] + depth[v] - 2 * depth[lca];
  }
};
int main() {
  int n;
  cin >> n;
  tree t(n);
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    t.add_edge(u, v);
  }
  t.preprocess();
  vector<int> leaves;
  map<int, int> p;
  for (int i = 0; i < n; i++) {
    if (t.nodes[i].edges.size() == 1) {
      leaves.push_back(i);
      p[t.nodes[i].edges[0].v]++;
    }
  }
  int fMax = n - 1;
  for (auto &el : p) {
    if (el.second > 1) {
      fMax -= (el.second - 1);
    }
  }
  bool odd = false;
  for (int i = 0; i < leaves.size() - 1; i++) {
    int curDist = t.dist(leaves[i], leaves[i + 1]);
    if (curDist % 2) {
      odd = true;
    }
  }
  cout << (odd ? 3 : 1) << " " << fMax << endl;
}
