#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; 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 int 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'; } else if(map[i][j] == 'X') { add('X', i, j); map[i][j] = 'o'; if (ch == '*') { ch = 'X'; return 1; } } return 0; } int ff1(int i, int j) { int r = 0; fb1 = fe1 = fb2 = fe2 = 0; add(map[i][j], i, j); char ch = map[i][j]; if(ch == 'X') r++; while(!empty('*') || !empty('X')) { if (empty(ch)) { ch = not(ch); continue; } int x, y; rem(ch, x ,y); r += cont(x-1, y, ch); r += cont(x+1, y, ch); r += cont(x, y-1, ch); r += cont(x, y+1, ch); } 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')) cast[clen++] = ff1(i, j); } } 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; }