//実装が重そうな問題はある程度考えてから書く
//初期化を忘れずに（特に二分探索とか）
//コーナーケースを考えて（特に場合分けとか）
//不可解すぎるバグは配列外参照（配列の長さ）を検討
#include <bits/stdc++.h>
#define YES "YES"
#define NO "NO"
#define YESNO OUT(three(solve(),YES,NO))
#define ECHO OUT(solve())
#define three(A,B,C) ((A)?(B):(C))
#define FOR(i,a,b)  for(LL i=(a);i< (LL)(b);i++)
#define EFOR(i,a,b) for(LL i=(a);i<=(LL)(b);i++)
#define RFOR(i,a,b) for(LL i=(a);i>=(LL)(b);i--)
#define REP(i,b) FOR(i,zero,b)
#define EREP(i,b) EFOR(i,zero,b)
#define RREP(i,b) RFOR(i,b,zero)
#define ALL(c) c.begin(),c.end()
#define UNIQUE(c) sort(ALL(c));c.erase(unique(ALL(c)),c.end())
#define MAX(c) (*max_element(ALL(c)))
#define MIN(c) (*min_element(ALL(c)))
#define MP make_pair
#define FI first
#define SE second
#define SI(x) (LL(x.size()))
#define PB push_back
#define DEBUG(a) OUT(a)
#define DEBUG2(a,b) OUT2(a,b)
#define cat cout << __LINE__ << endl
#define OUT(a) cout << (a) << endl
#define OUT2(a,b) cout << (a) <<" "<<(b) << endl
#define int LL
#define zero 0LL
using namespace std;
template<typename T> inline void maximize(T &a,T b){a=max(a,b);}
template<typename T> inline void minimize(T &a,T b){a=min(a,b);}
template<typename T> inline bool middle(T a,T b,T c){return b<=a && a<=c;}
typedef long long LL;
typedef double ld;
typedef LL ut;
typedef vector<ut> VI;
typedef vector<VI> VII;
typedef pair<ut,ut> pr;
typedef pair<ut,pr> ppr;
typedef vector<pr> Vpr;
typedef vector<ppr> Vppr;
typedef priority_queue<pr,Vpr,greater<pr> > PQ;
inline void outputVI(VI x){REP(i,SI(x)){cout << three(i," ","") << x[i];}OUT("");}
const int SIZE1=5*1e5+1000;
const int SIZE2=5010;
const int SIZE3=400;
const int SIZE=SIZE1;
const LL p=7+1e9;
const LL INF=1LL<<60;
const long double EPS=1e-7;
string s;
ut N,M,K,X,L,Y;
// ut A,B,C,D,E,F,G,H,I,J,O,P,Q,R,T,U;
VI edges[SIZE];
LL vals[SIZE],nums[SIZE],maps[SIZE2][SIZE2],answer=zero;
 
////////////////////////////////////////////////////////////////////////////////////////////
 
////////////////////////////////////////////////////////////////////////////////////////////
void init(){
 
}
LL A[SIZE],B[SIZE],C[SIZE],ec[SIZE];
int dfs(int now,int from){
	int ans=0;
	REP(i,edges[now].size()){
		int next=edges[now][i];
		if(next==from) continue;
		maximize(ans,dfs(next,now)+1);
	}
	return ans;
}
int D[SIZE];
int dfs2(int now,int from,int x){
	if(now==-1) return 0;
	maximize(D[x],SI(edges[now]));
	REP(i,edges[now].size()){
		int next=edges[now][i];
		if(next==from) continue;
		dfs2(next,now,x+1);
	}
	return 0;
}
int solve2(int a,int b){
	REP(i,N) D[i]=0;
	dfs2(a,b,0);
	dfs2(b,a,0);
	LL ans=1;
	//if(b==-1) 	REP(i,edges[now].size()){
	//	int next=edges[now][i];
	//	cout << next << endl;
	//}
	REP(i,N+1){
	//	if(b==-1) cout << D[i] << endl;
		ans*=max(D[i]-1,1LL);
	}
	return ans;
}
LL solve(){
	cin >> N;
	REP(i,N-1){
		cin >> A[i] >> B[i];
		edges[A[i]].PB(B[i]);
		edges[B[i]].PB(A[i]);
	}
	LL rad=INF,root=0;
	
	EFOR(i,1,N){
		int r=C[i]=dfs(i,-1);
		minimize(rad,r);
		maximize(ec[C[i]],SI(edges[i]));
		if(rad==r) root=i;
	} 
	LL ans=1;
	LL roots=0;
	VI v;
	EFOR(i,1,N){
		if(rad==C[i]) {
			roots++;
			v.PB(i);		
		}
	}
	if(roots==1){
		ans=INF;
		rad++;
		REP(i,SI(edges[root])){
			int next=edges[root][i];
			minimize(ans,solve2(root,next));
		}
		ans*=2;
	//	cout << solve2(root,-1) << endl;
		minimize(ans,solve2(root,-1)/(ec[C[root]]-1)*ec[C[root]]);
	}
	else{
		ans=solve2(v[0],v[1]);
		ans*=2;
	}
	cout << rad << " "<< ans << endl;
	return 0;
}
signed main(){
//	cout << solve() << endl;
	solve();
	return 0;
}

Measured memory_bytes: 20480