#include <bits/stdc++.h>
#define maxn 100010
#define MAX(a,b,c) max(max(a,b),max(b,c))
using namespace std;
int cnt,tot,tim;
int belong[maxn];
int dfn[maxn];
int low[maxn];
bool gedian[maxn];
int not_ge_cnt;
int ge_cnt;
int rt,rt_po;
struct edge{
int to,nxt;
}e[maxn];
int head[maxn];
void add(int x,int y){
e[++cnt].to = y;
e[cnt].nxt = head[x];
head[x] = cnt;
}
void tarjan(int x,int fa){
dfn[x] = low[x] = ++tim;
for(int i = head[x];i; i = e[i].nxt){
int u = e[i].to;
if(!dfn[u]){
tarjan(u,x);
low[x] = min(low[x],low[u]);
if(low[u] > dfn[x]){
if(x != rt) gedian[x] = true;
else rt_po++;
}
}else{
if(u != fa){
low[x] = min(low[x],dfn[u]);
}
}
}
}
void dfs(int x){
belong[x] = tot;
not_ge_cnt++;
for(int i = head[x];i;i = e[i].nxt){
int u = e[i].to;
if(gedian[u] && belong[u] != tot){
ge_cnt++;
belong[u] = tot;
}
if(!belong[u]){
dfs(u);
}
}
}
int u,v;
int m,n;
int Case = 1;
long long ans1,ans2;
void init(){
memset(head,0,sizeof head);
memset(dfn,0,sizeof dfn);
memset(low,0,sizeof low);
memset(gedian,false,sizeof gedian);
memset(belong,0,sizeof belong);
tim = cnt = tot = n = ans1 = 0;
ans2 = 1;
}
int main(){
ios::sync_with_stdio(false);
while(1){
init();
cin >> m;
if(m == 0) break;
for(int i = 1; i <= m; i++){
cin >> u >> v;
add(u,v),add(v,u);
n = MAX(n,u,v);
}
for(int i = 1; i <= n; i++){
if(!dfn[i]){
rt = i;
rt_po = 0;
tarjan(i,i);
if(rt_po >= 2) gedian[i] = true;
}
}
for(int i = 1; i <= n; i++){
if(!gedian[i] && !belong[i]){
++tot;
ge_cnt = not_ge_cnt = 0;
dfs(i);
if(ge_cnt == 0){
ans1 += 2;
ans2 *= ((not_ge_cnt - 1) * not_ge_cnt) / 2;
}
if(ge_cnt == 1){
ans1 += 1;
ans2 *= not_ge_cnt;
}
}
}
printf("Case %d: %lld %lld\n",Case++,ans1,ans2);
}
return 0;
}