#include <bits/stdc++.h>
using namespace std;
const int MAXH = 1700;
const int MAXW = 1700;
const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, 1, 0, -1};
int f[MAXH][MAXW];
int h, w;
bool check_circ(int x0, int y0, int maxr) {
  int rs = sqrt(maxr) + 5;
  while (rs * rs > maxr) rs--;
  for (int dy = -rs; dy <= rs; dy++)
    for (int dx = -rs; dx <= rs; dx++)
      if (dx * dx + dy * dy <= maxr) {
        int x = x0 + dx, y = y0 + dy;
        if (x < 0 || y < 0 || x >= w || y >= h) return false;
        if (!f[y][x]) return false;
      }
  return true;
}
int was[MAXH][MAXW];
const int C = 5;
int sumx, sumy, sumc;
vector<pair<int, int> > pts;
void dfs(int x, int y) {
  if (x < 0 || y < 0 || x >= w || y >= h) return;
  if (was[y][x]) return;
  if (!f[y][x]) return;
  bool g = true;
  for (int y1 = -C; y1 <= C; y1++)
    for (int x1 = -C; x1 <= C; x1++) {
      int nx = x + x1, ny = y + y1;
      if (nx < 0 || ny < 0 || nx >= w || ny >= h)
        g = false;
      else
        g = g && f[ny][nx];
    }
  if (g) {
    sumx += x;
    sumy += y;
    sumc++;
  } else {
    pts.push_back(make_pair(x, y));
  }
  was[y][x] = true;
  for (int i = 0; i < 4; i++) dfs(x + dx[i], y + dy[i]);
}
double radius;
void dfs2(int x, int y) {
  if (x < 0 || y < 0 || x >= w || y >= h) return;
  if (was[y][x] >= 2) return;
  if (!f[y][x]) return;
  int curd = (x - sumx) * (x - sumx) + (y - sumy) * (y - sumy);
  if (sqrt(curd) <= radius + 5) return;
  was[y][x] = 2;
  for (int i = 0; i < 4; i++) dfs2(x + dx[i], y + dy[i]);
}
int main() {
  while (scanf("%d%d", &h, &w) >= 1) {
    for (int y = 0; y < h; y++)
      for (int x = 0; x < w; x++) scanf("%d", &f[y][x]);
    vector<int> anses;
    memset(was, 0, sizeof was);
    for (int y = 0; y < h; y++)
      for (int x = 0; x < w; x++)
        if (f[y][x] && !was[y][x]) {
          sumx = 0;
          sumy = 0;
          sumc = 0;
          pts.clear();
          dfs(x, y);
          assert(sumc);
          sumx /= sumc;
          sumy /= sumc;
          f[sumy][sumx] = 2;
          int L = 0, R = min(w, h) * min(w, h) + 100;
          while (L + 1 < R) {
            int M = (L + R) / 2;
            if (check_circ(sumx, sumy, M))
              L = M;
            else
              R = M;
          }
          radius = sqrt(L);
          int cans = 0;
          for (int i = 0; i < ((int)(pts).size()); i++) {
            int x = pts[i].first, y = pts[i].second;
            int cd = (x - sumx) * (x - sumx) + (y - sumy) * (y - sumy);
            if (sqrt(cd) <= radius + 6) continue;
            f[y][x] = 3;
            if (was[y][x] >= 2) continue;
            cans++;
            dfs2(x, y);
          }
          anses.push_back(cans);
        }
    sort(anses.begin(), anses.end());
    printf("%d\n", ((int)(anses).size()));
    for (int i = 0; i < ((int)(anses).size()); i++)
      printf("%d%c", anses[i], "\n "[i + 1 < ((int)(anses).size())]);
  }
  return 0;
}
