#include #include #define SIZE 300000 char map[600][600]; int cast[50000]; int fi1[SIZE]; int fj1[SIZE]; int fb1, fe1; int fi2[SIZE]; int fj2[SIZE]; int fb2, fe2; int clen; int R, S; int r; void add(char ch, int i, int j) { if (ch == '*') { fi1[fe1] = i; fj1[fe1] = j; fe1++; if(fe1 >= SIZE) fe1 = 0; } else { fi2[fe2] = i; fj2[fe2] = j; fe2++; if(fe2 >= SIZE) fe2 = 0; } } void rem(char ch, int& i, int& j) { if (ch == '*') { i = fi1[fb1]; j = fj1[fb1]; fb1++; if(fb1 >= SIZE) fb1 = 0; } else { i = fi2[fb2]; j = fj2[fb2]; fb2++; if(fb2 >= SIZE) fb2 = 0; } } bool empty(char ch) { if (ch == '*') return fb1 == fe1; else return fb2 == fe2; } inline char not(char ch) { return (ch == '*') ? 'X' : '*'; } inline bool cont(int i, int j, char ch) { if((i < 0) || (i >= R) || (j < 0) || (j >= S)) return 0; if (map[i][j] == '*') { add('*', i, j); map[i][j] = 'o'; return false; } else if(map[i][j] == 'X') { add('X', i, j); map[i][j] = 'o'; return (ch == '*'); } return false; } void fillX() { r++; while(!empty('X')) { int x, y; rem('X', x ,y); //map[x][y] = 'o'; cont(x-1, y, 'X'); cont(x+1, y, 'X'); cont(x, y-1, 'X'); cont(x, y+1, 'X'); } } int ff1(int i, int j) { r = 0; fb1 = fe1 = fb2 = fe2 = 0; if(map[i][j] == '*') add('*', i, j); while(!empty('*')) { int x, y; rem('*', x ,y); map[x][y] = 'o'; if(cont(x-1, y, '*')) fillX(); if(cont(x+1, y, '*')) fillX(); if(cont(x, y-1, '*')) fillX(); if(cont(x, y+1, '*')) fillX(); } return r; } int cmp(const void* a, const void* b) { return *((int*)a) - *((int*)b); } int OneTask() { scanf("%d %d", &R, &S); if (R == 0 && S == 0) return 0; for (int i = 0; i < R; i++) scanf("%s", map[i]); clen = 0; for(int i = 0; i < R; i++) { for(int j = 0; j < S; j++) { if((map[i][j] == '*') || (map[i][j] == 'X')) { int x = ff1(i, j); if(x > 0) cast[clen++] = x; } } } qsort(cast, clen, sizeof(cast[0]), cmp); printf("Throw:"); for(int i = 0; i < clen; i++) printf(" %d", cast[i]); printf("\n"); return 1; } int main() { while(OneTask()) ; return 0; }