#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <fstream>
#include <cassert>
#include <cstring>
#include <unordered_set>
#include <unordered_map>
#include <numeric>
#include <ctime>
#include <bitset>
#include <complex>
#include <functional>
#include <random>

using namespace std;

#define int long long

typedef unsigned long long ull;

const ull INF = 1e18 + 8;

ull safe_mul(ull a, ull b) {
    if (a >= (INF + b - 1) / b) return INF;
    return min(a * b, INF);
}

void relax(vector<vector<int>> g, ull &ans, int ca, int cb, int ds) {
    int n = (int)g.size();
    vector<int> used(n);
    vector<int> mxbh(n);
    vector<int> cnth(n);
    function<void(int,int)> dfs = [&](int cur, int ch) {
        used[cur] = 1;
        int cnt = 0;
        for (auto t : g[cur]) {
            if (!used[t]) {
                dfs(t, ch + 1);
                cnt++;
            }
        }
        cnth[ch]++;
        mxbh[ch] = max(mxbh[ch], cnt);
    };
    used[ca] = 1;
    used[cb] = 1;
    dfs(ca, 0);
    dfs(cb, 0);
    ull cur = 1;
    for (int i = 0; i < n; i++) {
        cur = safe_mul(cur, max((int)1, mxbh[i]));
    }
    if (ds % 2 == 0) {
        cur = safe_mul(cur, 2);
    }
    ans = min(ans, cur);
}

vector<int> path(int n, vector<vector<int>> g, int a, int b) {
    vector<int> ps(n);
    vector<int> used(n);
    function<void(int, int)> dfs = [&](int cur, int p) {
        ps[cur] = p;
        used[cur] = 1;
        for (auto t : g[cur]) {
            if (!used[t]) {
                dfs(t, cur);
            }
        } 
    };
    dfs(a, -1);
    vector<int> ans;
    int cur = b;
    while (cur != -1) {
        ans.push_back(cur);
        cur = ps[cur];
    }
    return ans;
}

void try_path(vector<int> path, vector<vector<int>> g, ull &ans) {
    int ds = (int)path.size();
    int p = (int)path.size() / 2;
    if (ds & 1) {
        relax(g, ans, path[p], path[p], ds);
    } else {
        relax(g, ans, path[p], path[p - 1], ds);
    }
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n;
    cin >> n;
    assert(n > 1);
    vector<vector<int>> g(n);
    vector<int> sz(n);
    for (int i = 0; i + 1 < n; i++) {
        int a, b;
        cin >> a >> b;
        a--;
        b--;
        g[a].push_back(b);
        g[b].push_back(a);
        sz[a]++;
        sz[b]++;
    }
    vector<int> lf;
    for (int i = 0; i < n; i++) {
        if (sz[i] == 1) {
            lf.push_back(i);
        }
    }
    vector<vector<int>> pathes;
    int d = 0;
    for (int i = 0; i < (int)lf.size(); i++) {
        for (int j = i + 1; j < (int)lf.size(); j++) {
            vector<int> p = path(n, g, lf[i], lf[j]);
            d = max(d, (int)p.size());
            pathes.push_back(p);
        }
    }
    ull ans = INF;
    if (d & 1) {
        int cen = -1;
        for (auto t : pathes) {
            if ((int)t.size() == d) {
                try_path(t, g, ans);
                cen = t[d / 2];
            }
        }
        for (auto t : g[cen]) {
            relax(g, ans, t, cen, d + 1);
        }
    } else {
        for (auto t : pathes) {
            if ((int)t.size() == d) {
                try_path(t, g, ans);
            }
        }
    }
    cout << (d + 1) / 2 << ' ' << ans << endl;
}   

Measured memory_bytes: 640