#include <bits/stdc++.h>
inline void in(int &MAGNUS) { scanf("%d", &MAGNUS); }
inline void out(int MAGNUS) { printf("%d\n", MAGNUS); }
inline void in(int &MAGNUS, int &CLAR) { scanf("%d%d", &MAGNUS, &CLAR); }
inline void out(int MAGNUS, int CLAR) { printf("%d %d\n", MAGNUS, CLAR); }
inline void inl(long long &LIV) { scanf("%lld", &LIV); }
inline void inl(long long &LIV, long long &MART) {
  scanf("%lld%lld", &LIV, &MART);
}
inline void outl(long long LIV) { printf("%lld\n", LIV); }
inline void outl(long long LIV, long long MART) {
  printf("%lld %lld\n", LIV, MART);
}
using namespace std;
int x[1605][1605], sun[1605][1605];
int ccid[1605][1605], rays[1600 * 1600 + 5];
int R, C;
bool cleared[1605][1605];
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};
bool inside(int r, int c) { return 1 <= r && r <= R && 1 <= c && c <= C; }
int countSun(int r1, int c1, bool clears) {
  int r2 = r1 + 3, c2 = c1 + 3;
  if (clears) {
    for (int i = r1; i <= r2; i++) {
      for (int j = c1; j <= c2; j++) {
        cleared[i][j] = 1;
      }
    }
  }
  return sun[r2][c2] - sun[r2][c1 - 1] - sun[r1 - 1][c2] + sun[r1 - 1][c1 - 1];
}
void clearSun() {
  for (int i = 1; i <= R - 3; i++) {
    for (int j = 1; j <= C - 3; j++) {
      if (countSun(i, j, 0) == 16) countSun(i, j, 1);
    }
  }
}
void dfs(int r, int c, int id) {
  if (!inside(r, c)) return;
  if (x[r][c] != 1) return;
  if (ccid[r][c] != 0) return;
  ccid[r][c] = id;
  for (int i = 0; i <= 3; i++) {
    dfs(r + dx[i], c + dy[i], id);
  }
}
void traceRay(int sr, int sc) {
  int raystotal = 0;
  queue<pair<int, int> > q;
  q.push(make_pair(sr, sc));
  cleared[sr][sc] = 1;
  while (!q.empty()) {
    pair<int, int> cur = q.front();
    q.pop();
    int r = cur.first, c = cur.second;
    raystotal++;
    for (int i = 0; i <= 3; i++) {
      int nxr = r + dx[i], nxc = c + dy[i];
      if (!inside(nxr, nxc)) continue;
      if (x[nxr][nxc] != 1) continue;
      if (cleared[nxr][nxc]) continue;
      cleared[nxr][nxc] = 1;
      q.push(make_pair(nxr, nxc));
    }
  }
  if (raystotal >= 5) {
    rays[ccid[sr][sc]]++;
  }
}
int main() {
  in(R, C);
  for (int i = 1; i <= R; i++) {
    for (int j = 1; j <= C; j++) {
      in(x[i][j]);
      sun[i][j] = sun[i - 1][j] + sun[i][j - 1] - sun[i - 1][j - 1] + x[i][j];
    }
  }
  int ccmany = 0;
  for (int i = 1; i <= R; i++) {
    for (int j = 1; j <= C; j++) {
      if (x[i][j] == 0 || ccid[i][j] != 0) continue;
      dfs(i, j, ++ccmany);
    }
  }
  clearSun();
  for (int i = 1; i <= R; i++) {
    for (int j = 1; j <= C; j++) {
      if (ccid[i][j] == 0 || cleared[i][j]) continue;
      traceRay(i, j);
    }
  }
  sort((rays) + 1, (rays) + (ccmany) + 1);
  out(ccmany);
  for (int i = 1; i <= ccmany; i++) printf("%d ", rays[i]);
  puts("");
  return 0;
}
