/* Tue Oct 28 23:14:32 JST 2003 */ #include #define N_MAX 2048 #define PARENT 1 #define CHILD 2 int n_node[2]; unsigned int g[2][N_MAX]; int adj[2][N_MAX][N_MAX]; int root[2]; int clock; void printadj() { int i, j; for (i = 0; i < n_node[0]; i++) { for (j = 0; j < n_node[0]; j++) { printf("%d ", adj[0][i][j]); } printf("\n"); } } void print(int self, int depth) { int i; for (i = 0; i < depth; i++) { printf(" "); } printf("<%d>\n", g[0][self]); for (i = 0; i < n_node[0]; i++) { if (adj[0][self][i] == CHILD) { print(i, depth+1); } } } void buildtree(int self, int parent) { int i; for (i = 0; i < n_node[0]; i++) { if (adj[0][self][i]) { if (parent == i) { adj[0][self][i] = PARENT; } else { adj[0][self][i] = CHILD; buildtree(i, self); } } } } int newnode(int numbosome, int parent) { int i; if (parent < 0) { root[1] = n_node[1]; } g[1][n_node[1]] = numbosome; for (i = 0; i <= n_node[1]; i++) { adj[1][n_node[1]][i] = adj[1][i][n_node[1]] = 0; } if (parent >= 0) { adj[1][n_node[1]][parent] = PARENT; adj[1][parent][n_node[1]] = CHILD; } (n_node[1])++; return (n_node[1]-1); } int nextg(int g) { if (g == 11111111) { return 4320989; } g = 3 * g + 1; while (g % 2 == 0) { g /= 2; } if (g > 12345678) { g -= 12345678; } return g; } int rec(int self0, int parent0, int parent1) { int i; int self1, g1; int n_children = 0, only_child, parent; for (i = 0; i < n_node[0]; i++) { if (adj[0][self0][i] == CHILD) { n_children++; only_child = i; } if (adj[0][self0][i] == PARENT) { parent = i; } } g1 = nextg(g[0][self0]); if (g1 == 1) { /* Goint to die */ if (self0 == root[0]) { return 0; } else { if (n_children == 0) { return 1; } else if (n_children == 1) { if (0 == rec(only_child, parent0, parent1)) { return 0; } return 1; } else { return 1; } } } else { /* Survive */ self1 = newnode(g1, parent1); if (g[0][self0] < g1 && n_children == 0) { /* Leaf bonus */ newnode( ((g1+1)/2)%2==0 ? (g1+1)/2+1 : (g1+1)/2 , self1 ); } } for (i = 0; i < n_node[0]; i++) { if (adj[0][self0][i] == CHILD) { if (0 == rec(i, self0, self1)) { return 0; } } } return 1; } void newleader() { int i, maxn, maxi, n_max; maxn = 0; n_max = 0; for (i = 0; i < n_node[1]; i++) { if (maxn < g[1][i]) { maxn = g[1][i]; maxi = i; n_max = 1; } else if (maxn == g[1][i]) { n_max++; } } if (n_max == 1) { /* Leader bonus */ root[1] = maxi; newnode(((g[1][root[1]]+1)/2)%2==0 ? ((g[1][root[1]]+1)/2)-1 : ((g[1][root[1]]+1)/2), root[1]); } } void copy() { int i, j; for (i = 0; i < n_node[1]; i++) { g[0][i] = g[1][i]; for (j = 0; j < n_node[1]; j++) { adj[0][i][j] = adj[1][i][j]; } } root[0] = root[1]; n_node[0] = n_node[1]; } int main() { int ancestor; int i, j; int maxcells; while (1) { scanf("%d", &ancestor); if (ancestor == 0) break; root[0] = 0; n_node[0] = 1; g[0][0] = ancestor; for (i = 0; i < N_MAX; i++) { for (j = 0; j < N_MAX; j++) { adj[0][i][j] = adj[1][i][j] = 0; } } maxcells = 1; for (clock = 0; ; clock++) { buildtree(root[0], -1); n_node[1] = 0; if (0 == rec(root[0], -1, -1)) { break; } newleader(); copy(); if (maxcells < n_node[0]) { maxcells = n_node[0]; } } printf("%d %d\n", clock+1, maxcells); } }