#include <iostream>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll dist[105][105];
ll seen[105];

int main()
{
    ll N,a,b;
    cin>>N;
    vector<ll> graph[N];
    for(ll i=0; i<N-1; i++){
        cin>>a>>b;
        a--,b--;
        graph[a].push_back(b);
        graph[b].push_back(a);
    }

    //DFS
    for(ll i=0; i<N; i++){
        vector<ll> DFS;
        for(ll j=0; j<N; j++){
            seen[j] = 0;
        }
        ll start = i;
        seen[start] = 1;
        dist[i][start] = 0;
        DFS.push_back(start);
        while(!DFS.empty()){
            ll current = DFS.back();
            DFS.pop_back();
            seen[current] = 1;
            for(ll j=0; j<graph[current].size(); j++){
                if(seen[graph[current][j]]==0){
                    DFS.push_back(graph[current][j]);
                    dist[i][graph[current][j]] = dist[i][current]+1;
                }
            }
        }
    }

    ll gmax = 0;
    for(ll i=0; i<N; i++){
        for(ll j=0; j<N; j++){
            gmax = max(gmax, dist[i][j]);
        }
    }
    if(N==2){
        cout<<1<<" "<<2<<endl;
        return 0;
    }

    if(gmax%2==0){
        ll good;
        for(ll i=0; i<N; i++){
            ll vmax = 0;
            for(ll j=0; j<N; j++){
                vmax = max(vmax,dist[i][j]);
            }
            if(vmax<=gmax/2)
                good = i;

        }
        ll overans = 1000000000;
        ll carry[gmax/2+1];
        for(ll i=1; i<gmax/2+1; i++)
            carry[i] = 0;

        for(ll i=0; i<N; i++){
            ll z =  graph[i].size()-1;
            carry[dist[good][i]] = max(carry[dist[good][i]],z);
        }
        ll firstans = graph[good].size();
        for(ll i=1; i<gmax/2; i++){
                firstans*=carry[i];
            }
        overans = min(firstans, overans);


        for(ll j=0; j<graph[good].size(); j++){

            ll c = good, d = graph[good][j];

            ll answers[gmax/2+1];
            for(ll i=1; i<gmax/2+1; i++)
                answers[i] = 0;
            for(ll i=0; i<N; i++){
                if(dist[c][i]<dist[d][i]){
                    ll z =  graph[i].size()-1;
                    answers[dist[c][i]] = max(answers[dist[c][i]],z);
                }
                else{
                    ll z =  graph[i].size()-1;
                    answers[dist[d][i]] = max(answers[dist[d][i]],z);
                }
            }
            ll finalans = 2*(max(graph[c].size(),graph[d].size())-1);
            for(ll i=1; i<gmax/2; i++){
                finalans*=answers[i];
            }
            overans = min(finalans, overans);

        }
        cout<<gmax/2+1<<" "<<overans<<endl;


    }
    else{
        vector<ll> good;
        for(ll i=0; i<N; i++){
            ll vmax = 0;
            for(ll j=0; j<N; j++){
                vmax = max(vmax,dist[i][j]);
            }
            if(vmax<=(gmax+1)/2)
                good.push_back(i);
        }
        ll c = good[0], d = good[1];

        ll answers[gmax/2+1];
        for(ll i=1; i<gmax/2+1; i++)
            answers[i] = 0;
        for(ll i=0; i<N; i++){
            if(dist[c][i]<dist[d][i]){
                ll z =  graph[i].size()-1;
                answers[dist[c][i]] = max(answers[dist[c][i]],z);
            }
            else{
                ll z =  graph[i].size()-1;
                answers[dist[d][i]] = max(answers[dist[d][i]],z);
            }
        }
        ll finalans = 2*(max(graph[c].size(),graph[d].size())-1);
        for(ll i=1; i<gmax/2; i++){
            finalans*=answers[i];
        }
        cout<<gmax/2+1<<" "<<finalans<<endl;


    }


    return 0;
}


Measured memory_bytes: 384