#include <bits/stdc++.h>
using namespace std;
const int maxn = 1610;
typedef int MAP[maxn][maxn];
int n, m;
MAP A, B, flag, used;
int total;
int num[maxn * maxn], que[maxn * maxn * 2];
MAP temp;
int px[] = {0, 0, 1, -1, 0}, py[] = {1, -1, 0, 0, 0};
bool isok(int x, int y) { return x >= 1 && x <= n && y >= 1 && y <= m; }
void zoomin(MAP X) {
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
      int value = 1;
      for (int x = 0; x < 5; x++)
        if (isok(i + px[x], j + py[x]) && X[i + px[x]][j + py[x]] == 0)
          value = 0;
      temp[i][j] = value;
    }
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) X[i][j] = temp[i][j];
}
void zoomout(MAP X) {
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
      int value = 0;
      for (int x = 0; x < 5; x++)
        if (isok(i + px[x], j + py[x]) && X[i + px[x]][j + py[x]] == 1)
          value = 1;
      temp[i][j] = value;
    }
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) X[i][j] = temp[i][j];
}
void bfs(int x, int y, int& index) {
  index++;
  int start = 1, tail = 0, sum = 0;
  que[++tail] = x;
  que[++tail] = y;
  used[x][y] = 1;
  while (start <= tail) {
    x = que[start++];
    y = que[start++];
    flag[x][y] = index;
    sum++;
    for (int i = 0; i < 4; i++)
      if (isok(x + px[i], y + py[i]) && !used[x + px[i]][y + py[i]] &&
          B[x + px[i]][y + py[i]] == 1) {
        used[x + px[i]][y + py[i]] = 1;
        que[++tail] = x + px[i];
        que[++tail] = y + py[i];
      }
  }
  if (sum < 100) index--;
}
void bfs(int x, int y) {
  int start = 1, tail = 0, sum = 0, index = 0;
  que[++tail] = x;
  que[++tail] = y;
  used[x][y] = 1;
  while (start <= tail) {
    x = que[start++];
    y = que[start++];
    sum++;
    for (int i = 0; i < 4; i++)
      if (isok(x + px[i], y + py[i]) && !used[x + px[i]][y + py[i]] &&
          A[x + px[i]][y + py[i]] == 1) {
        if (!flag[x + px[i]][y + py[i]]) {
          used[x + px[i]][y + py[i]] = 1;
          que[++tail] = x + px[i];
          que[++tail] = y + py[i];
        } else {
          index = flag[x + px[i]][y + py[i]];
        }
      }
  }
  if (sum > 2) num[index]++;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) scanf("%d", &A[i][j]);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) B[i][j] = A[i][j];
  for (int i = 1; i <= 3; i++) zoomin(B);
  for (int i = 1; i <= 4; i++) zoomout(B);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      if (!used[i][j] && B[i][j]) bfs(i, j, total);
  memset(used, 0, sizeof(used));
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      if (!used[i][j] && A[i][j] && !flag[i][j]) bfs(i, j);
  sort(num + 1, num + 1 + total);
  cout << total << endl;
  for (int i = 1; i <= total; i++) cout << num[i] << " ";
  return 0;
}
