#include<bits/stdc++.h>
using namespace std;
const long long M=3e5+10,MOD=1000000007;
typedef long long ll;
vector<int>edge[M];
int level[M];
int lv[M];
int ans=1;
int target_distane=0;// using method re-rooting dp
int dp[M][2];
void dfs1(int x,int p){
for(auto u:edge[x]){
if(u!=p){
int cur_level=dp[x][0];
if(dp[x][0]==level[u]+1)cur_level=dp[x][1];
cur_level=max(cur_level,lv[x]);
int total=cur_level+level[u];
total/=2;
lv[u]=cur_level+1;// root to down length
if(total>=target_distane){
if(total==target_distane){
if(cur_level==level[u])ans=max(ans,max(u,x));
else{
int dif=cur_level-level[u];
if(dif==1)ans=max(ans,x);
if(dif==-1)ans=max(ans,u);
}
}
else{
if(cur_level==level[u]){
ans=max(u,x);
target_distane=total;
}
else{
int dif=cur_level-level[u];
if(dif==1)ans=x,target_distane=total;
if(dif==-1)ans=u,target_distane=total;
}
}
}
dfs1(u,x);
}
}
}
void dfs(int x,int p){
dp[x][1]=dp[x][0]=1;
for(auto u:edge[x]){
if(u!=p){
dfs(u,x);
}
}
level[p]=max(level[p],level[x]+1);
if(p!=0){
int cur=level[x]+1;
vector<int>v;
v.push_back(dp[p][0]);
v.push_back(dp[p][1]);
v.push_back(cur);
sort(v.rbegin(),v.rend());
dp[p][0]=v[0];// first max
dp[p][1]=v[1];//second max
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t=1;
//cin>>t;
while(t--){
int n;
cin>>n;
for(int i=1;i<n;i++){
int u,v;
cin>>u>>v;
edge[u].push_back(v);
edge[v].push_back(u);
}
for(int i=1;i<=n;i++){
level[i]=1;
}
dfs(n,0);// lower level and upper level length
dfs1(n,0);
cout<<target_distane<<" "<<ans<<"\n";
}
return 0;
}