#include <bits/stdc++.h>   using namespace std;   int err;   int bitc(long long r) { return r == 0 ? 0 : (bitc(r >> 1) + (r & 1)); }   long long gcd(long long x, long long y) { return x ? gcd(y % x, x) : y; }   string cts(char c) {     string s =   ;     s += c;     return s;   }   char buf[1000000];   string getLine() {     string s;     while (!feof(stdin)) {       char c = fgetc(stdin);       if (c == 13) continue;       if (c == 10) return s;       s += c;     }     return s;   }   int getNum() {     string s = getLine();     return atoi(s.c_str());   }   vector<int> parsevi(string s) {     s = s +    ;     int q = 0;     bool minus = false;     vector<int> res;     for (typeof(0) l = (0); l < ((int(s.size()))); ++l) {       if (s[l] ==    ) {         res.push_back(minus ? -q : q);         q = 0;         minus = false;       } else if (s[l] ==  - ) {         minus = true;       } else {         q = q * 10 + s[l] -  0 ;       }     }     return res;   }   int Cases, cnum;   int K;   int X, Y;   short bmp[1600][1600];   int uds[1600][1600];   int dfsres;   void dfs1(short x, short y) {     if (bmp[y][x] != 1) return;     bmp[y][x] = 0;     dfs1(x - 1, y);     dfs1(x + 1, y);     dfs1(x, y - 1);     dfs1(x, y + 1);   }   void dfs3(short x, short y) {     if (bmp[y][x] == 0) return;     if (bmp[y][x] == 1) {       dfs1(x, y);       dfsres++;       return;     }     bmp[y][x] = 0;     dfs3(x - 1, y);     dfs3(x + 1, y);     dfs3(x, y - 1);     dfs3(x, y + 1);   }   void solveCase() {     int res = 0;     err = scanf( %d%d , &Y, &X);     for (typeof(0) y = (0); y < (Y); ++y)       for (typeof(0) x = (0); x < (X); ++x) {         int b;         err = scanf( %d , &b);         bmp[y][x] = b;       }     for (typeof(0) y = (0); y < (Y); ++y)       for (typeof(1) x = (1); x < (X); ++x)         uds[y][x] = uds[y][x - 1] + bmp[y][x - 1];     for (typeof(1) y = (1); y < (Y); ++y)       for (typeof(0) x = (0); x < (X); ++x) uds[y][x] = uds[y][x] + uds[y - 1][x];     for (typeof(0) y = (0); y < (Y); ++y)       for (typeof(0) x = (0); x < (X); ++x)         if (y == 0 || x == 0 || y == Y - 1 || x == X - 1) bmp[y][x] = 0;     for (typeof(4) y = (4); y < (Y - 4); ++y)       for (typeof(4) x = (4); x < (X - 4); ++x) {         int tot = uds[y + 4][x + 4] - uds[y - 4][x + 4] - uds[y + 4][x - 4] +                   uds[y - 4][x - 4];         if (tot == 64) bmp[y][x] = 2;       }     for (typeof(0) y = (0); y < (Y); ++y)       for (typeof(0) x = (0); x < (X); ++x) uds[y][x] = (bmp[y][x] == 2) ? 1 : 0;     for (typeof(0) y = (0); y < (Y); ++y)       for (typeof(1) x = (1); x < (X); ++x) uds[y][x] = uds[y][x - 1] + uds[y][x];     for (typeof(1) y = (1); y < (Y); ++y)       for (typeof(0) x = (0); x < (X); ++x) uds[y][x] = uds[y][x] + uds[y - 1][x];     for (typeof(6) y = (6); y < (Y - 6); ++y)       for (typeof(6) x = (6); x < (X - 6); ++x) {         int tot = uds[y + 6][x + 6] - uds[y - 6][x + 6] - uds[y + 6][x - 6] +                   uds[y - 6][x - 6];         if (tot > 0) bmp[y][x] = 3;       }     vector<int> v;     for (typeof(0) y = (0); y < (Y); ++y)       for (typeof(0) x = (0); x < (X); ++x)         if (bmp[y][x] == 3) {           dfsres = 0;           dfs3(x, y);           v.push_back(dfsres);         }     if (0)       for (typeof(0) y = (0); y < (Y); ++y) {         for (typeof(0) x = (0); x < (X); ++x) printf( %d , bmp[y][x]);         printf(  n );       }     sort(v.begin(), v.end());     printf( %d n , (int(v.size())));     for (typeof(0) a = (0); a < ((int(v.size()))); ++a)       printf( %d%c , v[a], a == (int(v.size())) - 1 ?   n  :    );   }   int main() {     if (1)       Cases = 1;     else if (0) {       string Nstr = getLine();       Cases = atoi(Nstr.c_str());     } else {       err = scanf( %d , &Cases);     }     for (cnum = 1; cnum <= Cases; cnum++) solveCase();     return 0;   }