#include #include #define MAXN 256000 struct dice { unsigned p, rank; unsigned val; } dices[MAXN]; struct dot { unsigned p, rank; unsigned dice; } dots[MAXN]; unsigned num_dice, num_dots; unsigned fdots (unsigned src) { unsigned r, x; for (r = src; dots[r].p != r; r = dots[r].p) ; for (x = src; x != r; x = src) { src = dots[x].p; dots[x].p = r; } return r; } void udots (unsigned a, unsigned b) { unsigned pa, pb; if (a == b) return; pa = fdots (a); pb = fdots (b); if (dots[pa].rank < dots[pb].rank) dots[pa].p = pb; else { if (dots[pb].rank < dots[pa].rank) dots[pb].rank++; dots[pb].p = pa; } } unsigned fdice (unsigned src) { unsigned r, x; for (r = src; dices[r].p != r; r = dices[r].p) ; for (x = src; x != r; x = src) { src = dices[x].p; dices[x].p = r; } return r; } void udice (unsigned a, unsigned b) { unsigned pa, pb; if (a == b) return; pa = fdice (a); pb = fdice (b); if (dices[pa].rank < dices[pb].rank) dices[pa].p = pb; else { if (dices[pb].rank < dices[pa].rank) dices[pb].rank++; dices[pb].p = pa; } } int main (void) { for (;;) { unsigned h, w; static unsigned pdice[512], pdots[512]; unsigned cnt[10]; scanf ("%u%u", &h, &w); if (h == 0 && w == 0) break; num_dice = 1; num_dots = 1; memset (pdice, 0, w * sizeof (*pdice)); memset (pdots, 0, w * sizeof (*pdots)); while (h-- != 0) { unsigned i; for (i = 0; i < w; i++) { int in; scanf (" "); switch (in = getchar ()) { unsigned c; case '.': pdice[i] = 0; pdots[i] = 0; break; case '*': case 'X': c = pdice[i]; if (c == 0 && i != 0) c = pdice[i - 1]; if (c == 0) { dices[num_dice].p = num_dice; dices[num_dice].rank = 0; dices[num_dice].val = 0; c = num_dice++; } if (pdice[i] != 0) udice (pdice[i], c); if (i != 0 && pdice[i - 1] != 0) udice (pdice[i - 1], c); pdice[i] = c; if (in != 'X') { pdots[i] = 0; break; } c = pdots[i]; if (c == 0 && i != 0) c = pdots[i - 1]; if (c == 0) { dots[num_dots].p = num_dots; dots[num_dots].rank = 0; dots[num_dots].dice = pdice[i]; c = num_dots++; } if (pdots[i] != 0) udots (pdots[i], c); if (i != 0 && pdots[i - 1] != 0) udots (pdots[i - 1], c); pdots[i] = c; break; } } /* for (i = 0; i < w; i++) printf ("%2u,", pdice[i]); putchar ('\n'); for (i = 0; i < w; i++) printf ("%2u,", pdice[i] ? fdice (pdice[i]) : 0); putchar ('\n'); for (i = 0; i < w; i++) printf ("%2u,", pdots[i]); putchar ('\n'); for (i = 0; i < w; i++) printf ("%2u,", pdots[i] ? fdots (pdots[i]) : 0); putchar ('\n'); */ } for (h = 1; h < num_dots; h++) { if (dots[h].p == h) { /* printf ("DOT: %u -> %u\n", h, fdice (dots[h].dice)); */ dices[fdice(dots[h].dice)].val++; } } memset (cnt, 0, sizeof (cnt)); for (h = 1; h < num_dice; h++) { if (dices[h].p == h) { /* printf ("DICE %u: %u\n", h, dices[h].val); */ cnt[dices[h].val]++; } } printf ("Throw:"); for (h = 0; h < 10; h++) { while (cnt[h]-- != 0) printf (" %u", h); } putchar ('\n'); } return EXIT_SUCCESS; }