#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cmath>
#include <map>
#include <queue>
#include <iomanip>
#include <set>
#include <tuple>
#define mkp make_pair
#define mkt make_tuple
#define rep(i,n) for(int i = 0; i < (n); ++i)
using namespace std;
typedef long long ll;
const ll MOD=1e9+7;
template<class T> void chmin(T &a,const T &b){if(a>b) a=b;}
template<class T> void chmax(T &a,const T &b){if(a<b) a=b;}

pair<int,int> findFar(int now,int par,vector<vector<int>> &g){
    pair<int,int> res=mkp(0,now);
    for(auto nex:g[now]){
        if(nex==par) continue;
        auto neco=findFar(nex,now,g);
        neco.first++;
        chmax(res,neco);
    }
    return res;
}

bool setPath(int now,int par,int goal,vector<int> &path,vector<vector<int>> &g){
    if(now==goal){
        path.push_back(now);
        return true;
    }
    for(auto nex:g[now]){
        if(nex==par) continue;
        if(setPath(nex,now,goal,path,g)){
            path.push_back(now);
            return true;
        }
    }
    return false;
}

vector<int> getDiameter(vector<vector<int>> &g){
    int N=g.size();
    int a=findFar(0,-1,g).second;
    int b=findFar(a,-1,g).second;
    vector<int> diam;
    setPath(a,-1,b,diam,g);
    return diam;
}

const ll INF=2e18;

ll calc(vector<int> &diam,vector<vector<int>> &g){
    int N=g.size();
    int M=diam.size();
    vector<int> dep(N,MOD);
    int sta=diam[M/2];
    int stb=sta;
    if(M%2==0) stb=diam[M/2-1];
    dep[sta]=0;dep[stb]=0;
    queue<int> Q;
    Q.push(sta);Q.push(stb);
    while(!Q.empty()){
        int now=Q.front();
        Q.pop();

        for(auto nex:g[now]){
            if(dep[nex]==MOD){
                dep[nex]=dep[now]+1;
                Q.push(nex);
            }
        }
    }

    int D=0;
    rep(i,N) chmax(D,dep[i]);
    vector<vector<int>> v(D+1);
    rep(i,N) v[dep[i]].push_back(i);

    vector<ll> deg(N,0);
    rep(i,N) deg[i]=g[i].size();

    ll prenum=0;
    for(int i=0;i<D;i++){
        ll madeg=1;
        for(auto j:v[i]) chmax(madeg,deg[j]);
        ll nexnum=0;
        for(auto j:v[i]) nexnum+=madeg-deg[j];
        nexnum+=prenum*(madeg-1);
        prenum=nexnum;
    }
    rep(i,N) if(dep[i]==D) prenum++;
    return prenum;
}

pair<int,ll> solve(vector<vector<int>> &g){
    ll res=MOD;
    vector<int> diam=getDiameter(g);
    /*for(auto v:diam) cout<<v+1<<" ";
    cout<<endl;*/
    int M=diam.size();
    int N=g.size();

    if(M%2){
        vector<int> p;
        p.push_back(diam[M/2]);
        chmin(res,calc(p,g));
    }

    map<pair<int,int>,int> mp;
    rep(i,N) rep(j,g[i].size()) mp[mkp(i,g[i][j])]=1;

    for(int i=0;i<N;i++){
        int a=findFar(i,-1,g).first;
        if((M+1)/2<a) continue;
        for(int j=i+1;j<N;j++){
            if(mp.count(mkp(i,j))==false) continue;
            vector<int> p={i,j};
            int b=findFar(j,-1,g).first;
            if((M+1)/2<b) continue;
            chmin(res,calc(p,g));
        }
    }

    return mkp((M+1)/2,res);
}


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

  int N;
  cin>>N;
  vector<vector<int>> g(N);
  rep(i,N-1){
      int a,b;
      cin>>a>>b;
      a--;b--;
      g[a].push_back(b);
      g[b].push_back(a);
  }

  pair<int,ll> ans=solve(g);
  cout<<ans.first<<" "<<ans.second<<endl;

  return 0;
}


Measured memory_bytes: 256