#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include <utility>
#include <queue>
#include <set>
#include <map>
#include <deque>
#include <iomanip>
#include <cstdio>

using namespace std;
typedef  long long ll;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<VI> VVI;
#define  MP make_pair
#define  PB push_back
#define inf  1000000007
#define rep(i,n) for(int i=0;i<(int)(n);++i)

class TreeDiameter
{
public:
    vector<vector<int> > G;
    vector<int> diameter;
    int V;
    TreeDiameter(int node_size){
        V = node_size;
        G.resize(V);
    }
    void add_edge(int u,int v){
        G[u].push_back(v),G[v].push_back(u);
    }
    void dfs(int u,int p,int d,int& far,int& mx){
        if(mx < d){
            far = u;
            mx = d;
        }
        for(int v : G[u]){
            if(v != p){
                dfs(v,u,d+1,far,mx);
            }
        }
    }
    bool redfs(int u,int p,const int t){
        if(u == t){
            return true;
        }
        for(int v : G[u]){
            if(v != p){
                diameter.push_back(v);
                if(redfs(v,u,t)){
                    return true;
                }else{
                    diameter.pop_back();
                }
            }
        }
        return false;
    }
    void solve(){
        int s,t,mx;
        mx = -1;
        dfs(0,-1,0,s,mx);
        mx = -1;
        dfs(s,-1,0,t,mx);
        diameter.push_back(s);
        redfs(s,-1,t);
    }
};

void dfs(int k,vector<vector<int> > g,vector<int> &p){
    for(auto x:g[k]){
        if(p[x]==0){
            p[x] = p[k]+1;
            dfs(x,g,p);
        }
    }
    return;
}

int main(){
    int n;
    cin >> n;
    vector<vector<int> > g(n);
    TreeDiameter td(n);
    rep(i,n-1){
        int a,b;
        cin >> a >>b;
        a--,b--;
        g[a].push_back(b);
        g[b].push_back(a);
        td.add_edge(a,b);
    }
    td.solve();
    vector<int> p(n);
    int k = td.diameter.size();
    ll ans1,ans2=1;
    if(k%2==0){
        p[td.diameter[k/2]]=1;
        p[td.diameter[k/2-1]]=1;
        dfs(td.diameter[k/2],g,p);
        dfs(td.diameter[k/2-1],g,p);
        ans1 = k/2;
        vector<vector<int> > s(n+1);
        for(int i=0;i<n;i++){
            s[p[i]].push_back(g[i].size()-1);
        }
        for(int i=1;i<=n;i++){
            if(i==ans1)break;
            if(ans1==(k/2+1)&&i==1)ans2*= s[i][0]+1; 
            else ans2 *= *max_element(s[i].begin(),s[i].end()); 
        }
        if(ans1==k/2){
            ans2 *= 2;
        }
        cout << ans1 << " " << ans2 << endl;
    }else{
        p[td.diameter[k/2]]=1;
        dfs(td.diameter[k/2],g,p);
        ans1 = k/2+1;
        vector<vector<int> > s(n+1);
        for(int i=0;i<n;i++){
            s[p[i]].push_back(g[i].size()-1);
        }
        for(int i=1;i<=n;i++){
            if(i==ans1)break;
            if(ans1==(k/2+1)&&i==1)ans2*= s[i][0]+1; 
            else ans2 *= *max_element(s[i].begin(),s[i].end()); 
        }
        if(ans1==k/2){
            ans2 *= 2;
        }
        ll mx = ans2;
        for(auto x:g[td.diameter[k/2]]){
            vector<int>q(n);
            q[td.diameter[k/2]]=1;
            q[x] = 1;
            dfs(td.diameter[k/2],g,q);
            dfs(x,g,q);
            vector<vector<int> > z(n+1);
            for(int i=0;i<n;i++){
                z[q[i]].push_back(g[i].size()-1);
            }
            ans2=1;
            for(int i=1;i<=n;i++){
                if(i==ans1)break;
                ans2 *= *max_element(z[i].begin(),z[i].end()); 
            }
            ans2 *= 2;
            mx = min(mx,ans2);

        }

        cout << ans1 << " " << mx << endl;
    
    }
    return 0;
}

Measured memory_bytes: 512