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 (GCC 5.4.1) (judge verdict: Accepted)

//tree DP
//ABC036-D
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#define inf 1072114514
#define llinf 4154118101919364364
#define mod 1000000007
#define pi 3.1415926535897932384

int max(int a,int b){if(a>b){return a;}return b;}
int min(int a,int b){if(a<b){return a;}return b;}
int zt(int a,int b){return max(a,b)-min(a,b);}
int sortfncsj(const void *a,const void *b){if(*(int *)a>*(int *)b){return 1;}if(*(int *)a==*(int *)b){return 0;}return -1;}
int sortfnckj(const void *a,const void *b){if(*(int *)a<*(int *)b){return 1;}if(*(int *)a==*(int *)b){return 0;}return -1;}

typedef struct{
int val;
int node;
}sd;

int sdsortfnc(const void *a,const void *b){
if(((sd*)a)->val > ((sd*)b)->val){return -1;}
if(((sd*)a)->val < ((sd*)b)->val){return 1;}
return 0;
}

typedef struct{
    int st;
    int fi;
    int kr;
}rs;

typedef struct{
    int st;
    int kz;
}mkj;

int sortfnc(const void *a,const void *b){
if(((rs*)a)->st == ((rs*)b)->st){return 0;}
if(((rs*)a)->st < ((rs*)b)->st){return -1;}
return 1;
}

void makemkj(rs g[],mkj x[],int n){
    int i,ms=0,nst=g[0].st;
    for(i=1;i<n;i++){
        if(g[i].st!=g[i-1].st){
            x[nst].kz=i-ms;
            x[nst].st=ms;
            nst=g[i].st;ms=i;
        }
    }
    x[nst].kz=n-ms;
    x[nst].st=ms;
}

int dist[524288],par[524288];
void dfs(int t,int l,int bp,rs g[],mkj x[]){
  int i;
  if(dist[t]<=l){return;}
  dist[t]=l;
  par[t]=bp;
  for(i=x[t].st;i<x[t].st+x[t].kz;i++){
    dfs(g[i].fi,l+1,t,g,x);
  }
}

int judge(int arr[],int n,int border){
  int st,fi,te,p,q;
  st=0;fi=n-1;
  while(st<=fi){
    p=0;q=n-1;
    te=(st+fi)/2;
    if(p==te){p++;}
    if(q==te){q--;}
    while(p<=q){
      if(arr[p]+arr[q]>border){
        st=te+1;
        break;
      }
      p++;q--;
      if(p==te){p++;}
      if(q==te){q--;}
    }
    if(p>q){fi=te-1;}
  }
  return st;
}

int main(void){
    int i,j,n,m,k,a,b,c,h,w,r=0,l,t;
    int res=0;
    int st,fi,te;
    int cnt[524288]={0};
    int dp[524288];
    int arr[524288],ac;
    rs g[524288];
    mkj x[524288];
    sd dat[524288];
    scanf("%d",&n);
    for(i=0;i<(n-1);i++){
      scanf("%d%d",&a,&b);
      cnt[a]++;cnt[b]++;
      g[2*i].st=a;
      g[2*i].fi=b;
      g[2*i].kr=1;
      g[2*i+1].st=b;
      g[2*i+1].fi=a;
      g[2*i+1].kr=1;
    }
    qsort(g,2*(n-1),sizeof(g[0]),sortfnc);
    makemkj(g,x,2*(n-1));
    for(i=0;i<=n;i++){
      dp[i]=inf;
      dist[i]=inf;
      if(cnt[i]%2==1){r++;}
    }
    dfs(1,0,-1,g,x);
    for(i=0;i<n;i++){
      dat[i].node=i+1;
      dat[i].val=dist[i+1];
    }
    qsort(dat,n,sizeof(dat[0]),sdsortfnc);
    st=1;fi=n-1;
    while(st<=fi){
      te=(st+fi)/2;
      for(i=0;i<n;i++){
        w=dat[i].node;
        ac=0;
        for(j=x[w].st;j<x[w].st+x[w].kz;j++){
          if(par[w]==g[j].fi){continue;}
          arr[ac]=dp[g[j].fi]+1;
          //printf("[%d]",arr[ac]);
          ac++;
        }
        if(cnt[w]%2==1){
          arr[ac]=0;
          //printf("[%d]",arr[ac]);
          ac++;
        }
        if(i==n-1){
          arr[ac]=-inf;
          //printf("[%d]",arr[ac]);
          ac++;
        }
        qsort(arr,ac,sizeof(int),sortfncsj);
        t=judge(arr,ac,te);
        //printf("\n<%d %d %d %d>\n",te,w,ac,t);
        if(i==n-1){
          if(t==0){fi=te-1;}
          else{st=te+1;}
          break;
        }
        if(t==ac){st=te+1;break;}
        dp[w]=arr[t];
      }
    }
    printf("%d %d\n",r/2,st);
    return 0;
}