#include <bits/stdc++.h>   using namespace std;   const long long INF = 1 << 28;   const long long LINF = 1ll << 61;   inline long long getnum() {     register long long r = 0;     register bool ng = 0;     register char c;     c = getchar();     while (c !=  -  && (c <  0  || c >  9 )) c = getchar();     if (c ==  - ) ng = 1, c = getchar();     while (c !=     && c !=   n ) r = r * 10 + c -  0 , c = getchar();     if (ng) r = -r;     return r;   }   template <class T>   inline void putnum(T x) {     if (x < 0) putchar( - ), x = -x;     register short a[20] = {}, sz = 0;     while (x > 0) a[sz++] = x % 10, x /= 10;     if (sz == 0) putchar( 0 );     for (int i = sz - 1; i >= 0; i--) putchar( 0  + a[i]);   }   inline void putsp() { putchar(   ); }   inline void putendl() { putchar(  n ); }   inline char mygetchar() {     register char c = getchar();     while (c ==     || c ==   n ) c = getchar();     return c;   }   const int dx[] = {1, -1, 0, 0};   const int dy[] = {0, 0, 1, -1};   const int maxn = 1700;   int w, h, c[maxn][maxn], ans[12345];   bool g[maxn][maxn], ng[2][maxn][maxn], vis[maxn][maxn], p;   void color(int x, int y, int id) {     c[x][y] = id;     for (int i = 0; i < 4; i++) {       int nx = x + dx[i], ny = y + dy[i];       if (nx > 0 && nx <= w && ny > 0 && ny <= h && g[nx][ny] && c[nx][ny] == 0) {         color(nx, ny, id);       }     }   }   void dfs(int x, int y) {     vis[x][y] = 1;     for (int i = 0; i < 4; i++) {       int nx = x + dx[i], ny = y + dy[i];       if (nx > 0 && nx <= w && ny > 0 && ny <= h && g[nx][ny] && !vis[nx][ny]) {         dfs(nx, ny);       }     }   }   void getsmaller() {     p ^= 1;     for (int i = 1; i <= w; i++) {       for (int j = 1; j <= h; j++) {         ng[p][i][j] = ng[p ^ 1][i][j];         for (int k = 0; k < 4; k++) {           if (!ng[p ^ 1][i + dx[k]][j + dy[k]]) {             ng[p][i][j] = 0;           }         }       }     }   }   void getbigger() {     p ^= 1;     for (int i = 1; i <= w; i++) {       for (int j = 1; j <= h; j++) {         ng[p][i][j] = ng[p ^ 1][i][j];         for (int k = 0; k < 4; k++) {           if (ng[p ^ 1][i + dx[k]][j + dy[k]]) {             ng[p][i][j] = 1;           }         }       }     }   }   void see() {     for (int i = 1; i <= w; i++) {       for (int j = 1; j <= h; j++) {         putnum(g[i][j] & (!vis[i][j])), putsp();       }       putendl();     }     putendl();   }   int main() {     w = getnum(), h = getnum();     for (int i = 1; i <= w; i++) {       for (int j = 1; j <= h; j++) {         g[i][j] = getnum();       }     }     int id = 0;     for (int i = 1; i <= w; i++) {       for (int j = 1; j <= h; j++) {         if (g[i][j] && c[i][j] == 0) {           id++;           color(i, j, id);         }       }     }     for (int i = 1; i <= w; i++)       for (int j = 1; j <= h; j++) ng[p][i][j] = g[i][j];     getsmaller();     getsmaller();     getsmaller();     getbigger();     getbigger();     getbigger();     getbigger();     getbigger();     for (int i = 1; i <= w; i++) {       for (int j = 1; j <= h; j++) {         g[i][j] &= !ng[p][i][j];       }     }     for (int i = 1; i <= w; i++)       for (int j = 1; j <= h; j++) ng[p][i][j] = g[i][j];     getsmaller();     getbigger();     for (int i = 1; i <= w; i++)       for (int j = 1; j <= h; j++) g[i][j] = ng[p][i][j];     for (int i = 1; i <= w; i++) {       for (int j = 1; j <= h; j++) {         if (g[i][j] && !vis[i][j]) {           ans[c[i][j]]++;           dfs(i, j);         }       }     }     sort(ans + 1, ans + id + 1);     putnum(id), putsp(), putendl();     for (int i = 1; i <= id; i++) putnum(ans[i]), putsp();     return 0;   }