-
#include<iostream>
-
#include<cstdio>
-
#include<cstdlib>
-
#include<cstring>
-
#include<vector>
-
using namespace std;
-
const int MAXN = 300;
-
const int MAXL = 40;
-
-
int n;
-
int out[MAXN], in[MAXN];
-
vector<int> G[MAXN];
-
int dp[MAXN][2][MAXN];
-
-
// r: 0, b: 1
-
#define C_B 1
-
#define C_R 0
-
-
int error = 0;
-
-
void dfs(int u, int mi, int mx) {
-
if (u < mi || u > mx) {
-
error = 1;
-
}
-
if (G[u].size() == 0) { // leaf node
-
dp[u][C_B][1] = 1;
-
dp[u][C_R][0] = 1;
-
} else if (G[u].size() == 1) { // one children
-
int v = G[u][0];
-
dfs(v, mi, mx);
-
// u color C_B: child can be C_B or C_R, and only one black
-
dp[u][C_B][1] = max(dp[v][C_R][0], dp[v][C_B][0]);
-
// u color C_R: no possible for C_B
-
} else if (G[u].size() == 2) { // two children
-
int v = G[u][0];
-
int w = G[u][1];
-
if (v > w) swap(v, w);
-
-
dfs(v, mi, min(mx, u));
-
dfs(w, max(mi, u), mx);
-
-
// u color C_B: children can be black or red
-
for (int i = 0; i < MAXL; i++) {
-
dp[u][C_B][i + 1] = max(dp[u][C_B][i + 1], dp[v][C_B][i] * dp[w][C_B][i] +
-
dp[v][C_R][i] * dp[w][C_B][i] +
-
dp[v][C_B][i] * dp[w][C_R][i] +
-
dp[v][C_R][i] * dp[w][C_R][i]); // RR
-
}
-
-
// u color C_R: children can only be both black
-
for (int i = 0; i < MAXL; i++) {
-
dp[u][C_R][i] = max(dp[u][C_R][i], dp[v][C_B][i] * dp[w][C_B][i]);
-
}
-
}
-
}
-
-
int main() {
-
int kase = 1;
-
while (cin >> n) {
-
error = 0;
-
memset(out, 0, sizeof(out));
-
memset(in, 0, sizeof(in));
-
memset(dp, 0, sizeof(dp));
-
for (int i = 0 ; i < MAXN; i++) {
-
G[i].clear();
-
}
-
for (int i = 0; i < n-1; i++) {
-
int u, v;
-
cin >> u >> v;
-
G[u+100].push_back(v+100);
-
in[v+100]++;
-
out[u+100]++;
-
}
-
-
int root = 0;
-
for (int i = 0 ; i < MAXN; i++) {
-
if (in[i] == 0 && out[i] > 0) {
-
root = i;
-
}
-
}
-
-
dfs(root, -100000, 100000);
-
-
int ret = 0;
-
for (int i = 0; i < MAXL; i++) {
-
ret += dp[root][C_B][i];
-
}
-
if (error) ret = 0;
-
printf("Case %d:%d\n", kase++, ret);
-
}
-
return 0;
-
}