#include <bits/stdc++.h>
using namespace std;
const int inf = ~0U >> 1;
const long long INF = ~0ULL >> 1;
;
const double pi = acos(-1.0);
template <class T>
inline T sqr(T a) {
  return a * a;
}
template <class T>
inline void read(T &n) {
  char c;
  for (c = getchar(); !(c >= '0' && c <= '9'); c = getchar())
    ;
  n = c - '0';
  for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) n = n * 10 + c - '0';
}
int Pow(int base, int n, int mo) {
  if (n == 0) return 1;
  if (n == 1) return base;
  int tmp = Pow(base, n >> 1, mo);
  tmp = (long long)tmp * tmp % mo;
  if (n & 1) tmp = (long long)tmp * base % mo;
  return tmp;
}
struct point {
  int x, y;
  point() {}
  point(int _x, int _y) : x(_x), y(_y) {}
};
const int N = 1800;
const int A = 4;
const int B = 7;
const int dx[8] = {1, 1, 1, -1, -1, -1, 0, 0};
const int dy[8] = {1, -1, 0, 1, -1, 0, 1, -1};
int n, m;
int G[N][N], vis[N][N], mark[N][N], vis2[N][N], vis3[N][N];
vector<int> ans;
vector<pair<int, int> > E;
queue<pair<int, int> > Q;
int outside(int x, int y) {
  for (int k = (0); k <= (7); ++k) {
    int nx = x + dx[k];
    int ny = y + dy[k];
    if (nx > 0 && ny > 0 && nx <= n && ny <= m && G[nx][ny] == 0) return 1;
  }
  return 0;
}
int outside2(int x, int y) {
  for (int k = (0); k <= (7); ++k) {
    int nx = x + dx[k];
    int ny = y + dy[k];
    if (nx > 0 && ny > 0 && nx <= n && ny <= m && (!G[nx][ny] || mark[nx][ny]))
      return 1;
  }
  return 0;
}
void BFS3(int Sx, int Sy) {
  Q.push((make_pair(Sx, Sy)));
  vis3[Sx][Sy] = 1;
  while (Q.size()) {
    pair<int, int> u = Q.front();
    Q.pop();
    int x = u.first;
    int y = u.second;
    for (int k = (0); k <= (7); ++k) {
      int nx = x + dx[k];
      int ny = y + dy[k];
      if (nx > 0 && ny > 0 && nx <= n && ny <= m && mark[nx][ny] &&
          !vis2[nx][ny] && !vis3[nx][ny]) {
        vis3[nx][ny] = 1;
        Q.push((make_pair(nx, ny)));
      }
    }
  }
}
int Index;
void BFS(int Sx, int Sy) {
  Q.push((make_pair(Sx, Sy)));
  vis[Sx][Sy] = ++Index;
  E.clear();
  E.push_back((make_pair(Sx, Sy)));
  while (Q.size()) {
    pair<int, int> u = Q.front();
    Q.pop();
    int x = u.first;
    int y = u.second;
    for (int k = (0); k <= (7); ++k) {
      int nx = x + dx[k];
      int ny = y + dy[k];
      if (nx > 0 && ny > 0 && nx <= n && ny <= m && G[nx][ny] && !vis[nx][ny]) {
        vis[nx][ny] = Index;
        Q.push((make_pair(nx, ny)));
        E.push_back((make_pair(nx, ny)));
      }
    }
  }
  for (int i = (0); i < (E.size()); ++i)
    if (outside(E[i].first, E[i].second))
      Q.push(E[i]), mark[E[i].first][E[i].second] = 1;
  while (Q.size()) {
    pair<int, int> u = Q.front();
    Q.pop();
    if (mark[u.first][u.second] == A) continue;
    int x = u.first;
    int y = u.second;
    for (int k = (0); k <= (7); ++k) {
      int nx = x + dx[k];
      int ny = y + dy[k];
      if (nx > 0 && ny > 0 && nx <= n && ny <= m && G[nx][ny] &&
          !mark[nx][ny]) {
        mark[nx][ny] = mark[x][y] + 1;
        Q.push((make_pair(nx, ny)));
      }
    }
  }
  for (int i = (0); i < (E.size()); ++i)
    if ((!mark[E[i].first][E[i].second]) && outside2(E[i].first, E[i].second)) {
      Q.push(E[i]);
      vis2[E[i].first][E[i].second] = 1;
    }
  while (Q.size()) {
    pair<int, int> u = Q.front();
    Q.pop();
    if (vis2[u.first][u.second] == B) continue;
    int x = u.first;
    int y = u.second;
    for (int k = (0); k <= (7); ++k) {
      int nx = x + dx[k];
      int ny = y + dy[k];
      if (nx > 0 && ny > 0 && nx <= n && ny <= m && mark[nx][ny] &&
          !vis2[nx][ny]) {
        vis2[nx][ny] = vis2[x][y] + 1;
        Q.push((make_pair(nx, ny)));
      }
    }
  }
  int cnt = 0;
  for (int i = (0); i < (E.size()); ++i)
    if (mark[E[i].first][E[i].second] && !vis2[E[i].first][E[i].second] &&
        !vis3[E[i].first][E[i].second])
      BFS3(E[i].first, E[i].second), cnt++;
  ans.push_back(cnt);
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = (1); i <= (n); ++i)
    for (int j = (1); j <= (m); ++j) scanf("%d", &G[i][j]);
  for (int i = (1); i <= (n); ++i)
    for (int j = (1); j <= (m); ++j)
      if (G[i][j] && !vis[i][j]) {
        BFS(i, j);
      }
  sort(ans.begin(), ans.end());
  printf("%d\n", ans.size());
  for (int i = (0); i < (ans.size()); ++i) printf("%d ", ans[i]);
  puts("");
  return 0;
}
