#include <bits/stdc++.h>

#define int long long

using namespace std;

int n, maxD, dmtr, rootA, rootB, nxtN, CF, leaves;
int mcal[105];
int dist[105];
vector<vector<int> > adj;

void diam(int u, int p, int d){
    if(d > maxD){
        nxtN = u;
        maxD = d;
    }
    dist[u] = d;
    for(int i = 0; i < adj[u].size(); i++){
        if(adj[u][i] == p) continue;
        diam(adj[u][i], u, d+1);
    }
}

int findRootS(int u, int p, int d){
    int md = d;
    for(int i = 0; i < adj[u].size(); i++){
        if(adj[u][i] == p) continue;
        md = max(md, findRootS(adj[u][i], u, d+1));
    }
    if(md == dmtr){
        if(d == dmtr/2){
            rootA = u;
        }
        else if(d == dmtr/2 +1){
            rootB = u;
        }
    }
    return md;
}

void findMCAL(int u, int p, int lvl){
    mcal[lvl] = max(mcal[lvl], (int)(adj[u].size() - 1));
    for(int i = 0; i < adj[u].size(); i++){
        if(adj[u][i] == p || adj[u][i] < 0) continue;
        findMCAL(adj[u][i], u, lvl+1);
    }
}

int findROOT(int u, int p, int d){
    int md = d;
    for(int i = 0; i < adj[u].size(); i++){
        if(adj[u][i] == p) continue;
        md = max(md, findROOT(adj[u][i], u, d+1));
    }
    if(md == dmtr){
        if(2*d == dmtr) rootA = u;
    }
    return md;
}

signed main()
{
    int a, b;
    cin >> n;
    adj.resize(205);
    for(int i = 0; i < n-1; i++){
        cin >> a >> b; a--; b--;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
    maxD = 0;
    diam(0, -1, 0);
    maxD = 0;
    diam(nxtN, -1, 0);
    dmtr = maxD;
    if(dmtr%2){ // 2 centers, divide tree in 2 and CF = dmtr/2 + 1
        CF = dmtr/2 + 1;
        findRootS(nxtN, -1, 0);
        for(int i = 0; i < adj[rootA].size(); i++) if(adj[rootA][i] == rootB) adj[rootA][i] = -1;
        for(int i = 0; i < adj[rootB].size(); i++) if(adj[rootB][i] == rootA) adj[rootB][i] = -1;

        findMCAL(rootA, -1, 0);
        findMCAL(rootB, -1, 0);

        leaves = 2;

        for(int i = 0; i < dmtr && mcal[i] > 0; i++){
            leaves*=mcal[i];
        }
        cout << CF << ' ' << leaves << endl;
    }
    else{ // either take the center OR try and take each neighbor of the center to make a pair

        int leafGuess = 1;
        findROOT(nxtN, -1, 0);
        CF = dmtr/2 + 1;
        findMCAL(rootA, -1, 0);
        mcal[0] = adj[rootA].size();
        for(int i = 0; i < dmtr && mcal[i] > 0; i++){
            leafGuess*=mcal[i];
        }

        for(int i = 0; i < adj[rootA].size(); i++){
            int v = adj[rootA][i];
            for(int j = 0; j < adj[rootA].size(); j++) if(adj[rootA][j] == v) adj[rootA][j] = -1;
            for(int j = 0; j < adj[v].size(); j++) if(adj[v][j] == rootA) adj[v][j] = -1;

            memset(mcal, 0, sizeof mcal);

            findMCAL(rootA, -1, 0);
            findMCAL(v, -1, 0);

            leaves = 2;

            for(int i = 0; i < dmtr && mcal[i] > 0; i++){
                leaves*=mcal[i];
            }

            leafGuess = min(leafGuess, leaves);

            for(int j = 0; j < adj[rootA].size(); j++) if(adj[rootA][j] == -1) adj[rootA][j] = v;
            for(int j = 0; j < adj[v].size(); j++) if(adj[v][j] == -1) adj[v][j] = rootA;

        }
        cout << CF << ' ' << leafGuess << endl;
    }
    return 0;
}


Measured memory_bytes: 256