#include <bits/stdc++.h>
using namespace std;
FILE *in;
FILE *out;
const int MAX = 1604;
int n, m;
int a[MAX][MAX];
int dist[MAX][MAX];
int dir[8][2] = {{-1, 0},  {0, 1},  {1, 0},  {0, -1},
                 {-1, -1}, {-1, 1}, {1, -1}, {1, 1}};
const int SUN = 2;
const int RAY = 3;
const int VIS = 4;
int count(int row, int col) {
  int cnt = 0;
  for (int i = 0; i < 8; i++) {
    int nrow = row + dir[i][0];
    if (nrow < 0 || nrow >= n) continue;
    int ncol = col + dir[i][1];
    if (ncol < 0 || ncol >= m) continue;
    if (a[nrow][ncol] != 0) cnt++;
  }
  return cnt;
}
int clearRay(int row, int col) {
  int ret = 1;
  queue<pair<int, int> > q;
  q.push(make_pair(row, col));
  a[row][col] = VIS;
  while (!q.empty()) {
    row = q.front().first;
    col = q.front().second;
    q.pop();
    for (int i = 0; i < 8; i++) {
      int nrow = row + dir[i][0];
      if (nrow < 0 || nrow >= n) continue;
      int ncol = col + dir[i][1];
      if (ncol < 0 || ncol >= m) continue;
      if (a[nrow][ncol] == RAY && dist[nrow][ncol] >= 4) {
        a[nrow][ncol] = VIS;
        ret++;
        q.push(make_pair(nrow, ncol));
      }
    }
  }
  return ret;
}
int eval(int row, int col) {
  int ans = 0;
  queue<pair<int, int> > q;
  vector<pair<int, int> > v;
  q.push(make_pair(row, col));
  a[row][col] = (count(row, col) >= 8 ? SUN : RAY);
  while (!q.empty()) {
    row = q.front().first;
    col = q.front().second;
    q.pop();
    v.push_back(make_pair(row, col));
    for (int i = 0; i < 8; i++) {
      int nrow = row + dir[i][0];
      if (nrow < 0 || nrow >= n) continue;
      int ncol = col + dir[i][1];
      if (ncol < 0 || ncol >= m) continue;
      if (a[nrow][ncol] == 1) {
        a[nrow][ncol] = (count(nrow, ncol) >= 8 ? SUN : RAY);
        q.push(make_pair(nrow, ncol));
      }
    }
  }
  for (int i = 0; i < (int)v.size(); i++) {
    int row = v[i].first, col = v[i].second;
    if (a[row][col] == SUN) {
      a[row][col] = VIS;
      q.push(make_pair(row, col));
      dist[row][col] = 0;
    }
  }
  vector<pair<int, pair<int, int> > > rays;
  while (!q.empty()) {
    row = q.front().first;
    col = q.front().second;
    q.pop();
    for (int i = 0; i < 8; i++) {
      int nrow = row + dir[i][0];
      if (nrow < 0 || nrow >= n) continue;
      int ncol = col + dir[i][1];
      if (ncol < 0 || ncol >= m) continue;
      if (a[nrow][ncol] == RAY && dist[nrow][ncol] == -1) {
        dist[nrow][ncol] = dist[row][col] + 1;
        q.push(make_pair(nrow, ncol));
        if (dist[nrow][ncol] >= 4)
          rays.push_back(make_pair(dist[nrow][ncol], make_pair(nrow, ncol)));
      }
    }
  }
  sort(rays.rbegin(), rays.rend());
  for (int i = 0; i < (int)rays.size(); i++) {
    row = rays[i].second.first, col = rays[i].second.second;
    if (a[row][col] != RAY) continue;
    bool flag = true;
    for (int i = 0; i < 8; i++) {
      int nrow = row + dir[i][0];
      if (nrow < 0 || nrow >= n) continue;
      int ncol = col + dir[i][1];
      if (ncol < 0 || ncol >= m) continue;
      if (a[nrow][ncol] == VIS) {
        flag = false;
        break;
      }
    }
    if (flag) {
      ans++;
      clearRay(row, col);
    }
  }
  for (int i = 0; i < (int)v.size(); i++) a[v[i].first][v[i].second] = 0;
  return ans;
}
int main(void) {
  in = stdin;
  out = stdout;
  memset(dist, -1, sizeof(dist));
  fscanf(in, "%d %d", &n, &m);
  for (int i = 0; i < n; i++)
    for (int c = 0; c < m; c++) fscanf(in, "%d", &a[i][c]);
  for (int row = 0; row < n; row++) {
    for (int col = 0; col < m; col++) {
      if (count(row, col) < 8) a[row][col] = 2;
    }
  }
  for (int row = 0; row < n; row++)
    for (int col = 0; col < m; col++)
      if (a[row][col] == 2) a[row][col] = 0;
  vector<int> ans;
  for (int row = 0; row < n; row++) {
    for (int col = 0; col < m; col++) {
      if (a[row][col]) ans.push_back(eval(row, col));
    }
  }
  sort(ans.begin(), ans.end());
  fprintf(out, "%d\n", (int)ans.size());
  for (int i = 0; i < (int)ans.size(); i++)
    fprintf(out, "%d%c", ans[i], i + 1 == (int)ans.size() ? '\n' : ' ');
  return 0;
}
