#include <bits/stdc++.h>

using namespace std;
using ll = long long;
using PII = std::pair<int, int>;
using PLL = std::pair<ll, ll>;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep2(i, s, n) for (int i = (s); i < (int)(n); i++)


const int mod = 1e9 + 7;

void bfs(vector<vector<int>> connect, int n, vector<int> v, vector<int> &dist)
{
    vector<int> search, new_search;
    int t;
    fill(dist.begin(), dist.end(), -1);
    t = 0;
    search = v;

    for (int i : v)
    {
        dist[i] = t;
    }

    while (!search.empty())
    {
        t++;
        for (auto i : search)
        {
            for (auto j : connect[i])
                if (dist[j] == -1)
                {
                    new_search.push_back(j);
                    dist[j] = t;
                }
        }

        search.clear();
        search = new_search;
        new_search.clear();
    }
}

ll bfs2(vector<vector<int>> connect, int n, vector<int> degree, vector<int> v)
{
    ll ret = v.size();
    vector<int> search, new_search;
    int t, check[n];
    fill(check, check + n, 0);

    search = v;

    for (int i : v)
    {
        check[i]++;
    }

    while (!search.empty())
    {
        t = 0;
        for (auto i : search)
        {
            if (ret > 1)
                t = max(degree[i] - 1, t);
            else
                t = degree[i];

            for (auto j : connect[i])
                if (!check[j])
                {
                    new_search.push_back(j);
                    check[j]++;
                }
        }

        if (t)
            ret *= t;

        search.clear();
        search = new_search;
        new_search.clear();
    }
    return ret;
}

int main()
{

#ifdef DEBUG
    cout << "DEBUG MODE" << endl;
    ifstream in("input.txt"); //for debug
    cin.rdbuf(in.rdbuf());    //for debug
#endif

    int n, a, b, maxdist, diamater, colorful, maxindex;
    ll minleaf;
    cin >> n;
    vector<vector<int>> connect;
    vector<int> dist, dist2, v, u, degree;
    vector<PII> edge;
    connect.resize(n);
    dist.resize(n);
    degree.resize(n);

    rep(i, n - 1)
    {
        cin >> a >> b;
        a--, b--;
        connect[a].push_back(b);
        connect[b].push_back(a);
        edge.push_back(make_pair(a, b));
        degree[a]++, degree[b]++;
    }

    v = {0};
    bfs(connect, n, v, dist);

    maxdist = *max_element(dist.begin(), dist.end());
    rep(i, n)
    {
        if (dist[i] == maxdist)
        {
            maxindex = i;
            break;
        }
    }
    v = {maxindex};
    bfs(connect, n, v, dist);

    dist2 = dist;
    maxdist = *max_element(dist.begin(), dist.end());
    rep(i, n)
    {
        if (dist[i] == maxdist)
        {
            maxindex = i;
            break;
        }
    }
    v = {maxindex};
    bfs(connect, n, v, dist);

    diamater = maxdist;
    colorful = (2 + *max_element(dist.begin(), dist.end())) / 2;

    // for (int z : degree)
    // {
    //     cout << z << " ";
    // }
    // cout << endl;

    v.clear();
    rep(i, n)
    {
        if (dist[i] + dist2[i] == diamater && min(dist[i], dist2[i]) >= diamater / 2)
            v.push_back(i);
    }

    if (v.size() == 2)
    {
        cout << colorful << " " << bfs2(connect, n, degree, v) << endl;
    }

    else
    {
        minleaf = bfs2(connect, n, degree, v);
        for (auto i : connect[v[0]])
        {
            u = {v};
            u.push_back(i);
            minleaf = min(minleaf, bfs2(connect, n, degree, u));
        }
        cout << colorful << " " << minleaf << endl;
    }

    return 0;
}


Measured memory_bytes: 256