#include <bits/stdc++.h>
using namespace std;
int dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1};
int X, Y, C;
int a[1610][1610];
int comp[1610][1610];
int sz[10000];
double xsum[10000], ysum[100000];
bool boundary[1610][1610];
int incomp[1610][1610];
bool ray[1610][1610];
bool used[1610][1610];
int ans[1610];
bool inside(int x, int y) { return (x >= 0 && x < X && y >= 0 && y < Y); }
void dfs_comp(int x, int y, int c) {
  if (!inside(x, y) || comp[x][y] != -1 || !a[x][y]) return;
  comp[x][y] = c;
  int i;
  for ((i) = 0; (i) < (int)(4); (i)++) dfs_comp(x + dx[i], y + dy[i], c);
}
void dfs_incomp(int x, int y, int c) {
  if (!inside(x, y) || incomp[x][y] != -1 || !a[x][y] || boundary[x][y]) return;
  incomp[x][y] = c;
  int i;
  for ((i) = 0; (i) < (int)(4); (i)++) dfs_incomp(x + dx[i], y + dy[i], c);
}
void dfs_ray(int x, int y) {
  if (!inside(x, y) || !ray[x][y] || used[x][y]) return;
  used[x][y] = true;
  int i;
  for ((i) = 0; (i) < (int)(4); (i)++) dfs_ray(x + dx[i], y + dy[i]);
}
int main(void) {
  int i, j;
  cin >> X >> Y;
  for ((i) = 0; (i) < (int)(X); (i)++)
    for ((j) = 0; (j) < (int)(Y); (j)++) scanf("%d", &a[i][j]);
  for ((i) = 0; (i) < (int)(X); (i)++)
    for ((j) = 0; (j) < (int)(Y); (j)++) comp[i][j] = -1;
  for ((i) = 0; (i) < (int)(X); (i)++)
    for ((j) = 0; (j) < (int)(Y); (j)++)
      if (comp[i][j] == -1 && a[i][j]) {
        dfs_comp(i, j, C);
        C++;
      }
  for ((i) = 0; (i) < (int)(X); (i)++)
    for ((j) = 0; (j) < (int)(Y); (j)++)
      if (comp[i][j] != -1) {
        int c = comp[i][j];
        sz[c]++;
        xsum[c] += i;
        ysum[c] += j;
      }
  for ((i) = 0; (i) < (int)(C); (i)++) {
    xsum[i] /= sz[i];
    ysum[i] /= sz[i];
  }
  for ((i) = 0; (i) < (int)(X); (i)++)
    for ((j) = 0; (j) < (int)(Y); (j)++)
      if (!a[i][j]) {
        int xmin = max(i - 2, 0), xmax = min(i + 2, X - 1);
        int ymin = max(j - 2, 0), ymax = min(j + 2, Y - 1);
        for (int x = xmin; x <= xmax; x++)
          for (int y = ymin; y <= ymax; y++) boundary[x][y] = true;
      }
  for ((i) = 0; (i) < (int)(X); (i)++)
    for ((j) = 0; (j) < (int)(Y); (j)++)
      if (!a[i][j]) boundary[i][j] = false;
  for ((i) = 0; (i) < (int)(X); (i)++)
    for ((j) = 0; (j) < (int)(Y); (j)++) incomp[i][j] = -1;
  for ((i) = 0; (i) < (int)(X); (i)++)
    for ((j) = 0; (j) < (int)(Y); (j)++)
      dfs_incomp((int)xsum[i], (int)ysum[i], i);
  for ((i) = 0; (i) < (int)(X); (i)++)
    for ((j) = 0; (j) < (int)(Y); (j)++)
      if (boundary[i][j]) {
        ray[i][j] = true;
        int c = comp[i][j];
        int xmin = max(i - 4, 0), xmax = min(i + 4, X - 1);
        int ymin = max(j - 4, 0), ymax = min(j + 4, Y - 1);
        for (int x = xmin; x <= xmax; x++)
          for (int y = ymin; y <= ymax; y++)
            if (incomp[x][y] == c) ray[i][j] = false;
      }
  for ((i) = 0; (i) < (int)(X); (i)++)
    for ((j) = 0; (j) < (int)(Y); (j)++)
      if (ray[i][j] && !used[i][j]) {
        ans[comp[i][j]]++;
        dfs_ray(i, j);
      }
  sort(ans, ans + C);
  cout << C << endl;
  for ((i) = 0; (i) < (int)(C); (i)++) {
    cout << ans[i];
    if (i == C - 1)
      cout << endl;
    else
      cout << ' ';
  }
  return 0;
}
