Problem:
Score : 900 points

Problem Statement

Takahashi has decided to make a Christmas Tree for the Christmas party in AtCoder, Inc.

A Christmas Tree is a tree with N vertices numbered 1 through N and N-1 edges, whose i-th edge (1\leq i\leq N-1) connects Vertex a_i and b_i.

He would like to make one as follows:

Specify two non-negative integers A and B.

Prepare A Christmas Paths whose lengths are at most B. Here, a Christmas Path of length X is a graph with X+1 vertices and X edges such that, if we properly number the vertices 1 through X+1, the i-th edge (1\leq i\leq X) will connect Vertex i and i+1.

Repeat the following operation until he has one connected tree:

Select two vertices x and y that belong to different connected components. Combine x and y into one vertex. More precisely, for each edge (p,y) incident to the vertex y, add the edge (p,x). Then, delete the vertex y and all the edges incident to y.

Properly number the vertices in the tree.

Takahashi would like to find the lexicographically smallest pair (A,B) such that he can make a Christmas Tree, that is, find the smallest A, and find the smallest B under the condition that A is minimized.

Solve this problem for him.

Constraints

2 \leq N \leq 10^5

1 \leq a_i,b_i \leq N

The given graph is a tree.

Input

Input is given from Standard Input in the following format:

N
a_1 b_1
:
a_{N-1} b_{N-1}

Output

For the lexicographically smallest (A,B), print A and B with a space in between.

Sample Input 1

7
1 2
2 3
2 4
4 5
4 6
6 7

Sample Output 1

3 2

We can make a Christmas Tree as shown in the figure below:

Sample Input 2

8
1 2
2 3
3 4
4 5
5 6
5 7
5 8

Sample Output 2

2 5

Sample Input 3

10
1 2
2 3
3 4
2 5
6 5
6 7
7 8
5 9
10 5

Sample Output 3

3 4

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

/// Kazuki Hoshino


#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
#define int long long
typedef long double ld;
typedef vector<int> vi;
typedef pair<int,int> pi;
typedef vector<pi> vpi;
#define inf 1000000000
#define mod 1000000007
#define rep(i,a,b) for (int i = a; i <= b; i++)
#define rep1(i, a, b) for(int i =a; i >=b; i--)
#define dmp(x) cerr<<"line "<<__LINE__<<" "<<#x<<":"<<x<<endl
#define f first
#define ss second
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define mt make_tuple
//#define endl '\n'
typedef tree<
int,
null_type,less<int>,
rb_tree_tag,tree_order_statistics_node_update>
ordered_set;

int n,dp[101010],a,b,vis[101010],leaf,deg[101010];
vi adj[101010];
bool flag;

void init(){
       for(int i=1;i<=n;i++){
              dp[i]=0;
              vis[i]=0;
       }
       flag = true;
}
/*bool can2(int pos, int b){
       if(pos<0)return true;
       int k = v.size();
       int itr = k/2,mx=0;
       for(int i=0;i<k;i++){
              if(i!=pos)q.pb(v[i]);
       }
       int i=0;
       sort(all(q));
       while(itr--){
              int cur = q[i++]+q.back();
              mx = max(cur,mx);
              q.pop_back();
       }
       q.clear();
       return mx<=b;
}*/
int dfs(int s, int p){
       vi v;
       for(auto t:adj[s]){
              if(t!=p){
                    int m = dfs(t,s);
                    if(m!=inf)v.pb(m);
                    else return inf;
                     //v.pb(dp[t]);
              }
       }
       if(p==-1)return 0;
       if(v.size()==0)return 1;
       sort(all(v));
       int k = (int)v.size();
       flag = true;
       if(k%2==0){
              for(int i=0;i<k/2;i++){
                     if(v[i]+v[k-i-1]>b)flag = false;
              }
              if(flag)return 1;
              v.pop_back();
       }
       //if(!can2(k-1,b))flag=false;
       k = v.size();
       int l=-1,r=k;
       while(r-l>1){
              int mid = (l+r)/2;
              int ll=0,rr=k-1;
              flag = true;

              for(int i=0;i<k/2;i++){
                     if(ll==mid)ll++;
                     if(rr==mid)rr--;
                     if(v[ll]+v[rr]>b)flag = false;
                     ll++;rr--;
              }
              if(flag)r=mid;
              else l=mid;
       }
       if(r==k)return inf;
       if(v[r]+1>b)return inf;
       return v[r]+1;
}
bool can(int x){
       init();
       b = x;
       return dfs(leaf,-1)!=inf;
}

signed main(){
ios::sync_with_stdio(0);
cin.tie(0);

#ifndef ONLINE_JUDGE
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
#endif

cin >> n;
for(int i=1;i<n;i++){
       int x,y;
       cin >> x >> y;
       adj[x].pb(y);
       adj[y].pb(x);
       deg[x]++;
       deg[y]++;
}
for(int i=1;i<=n;i++){
       if(deg[i]%2)a++;
       if(deg[i]==1)leaf=i;
}
int l=0,r=n,ans;
while(r-l>1){
       int mid = (l+r)/2;
       if(can(mid)){
              r=mid;
       }
       else {
              l=mid;
       }
}

cout << a/2 << " " << r << endl;





return 0;}
///....