#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline T Abs(T a) {
  return a > 0 ? a : -a;
}
template <typename T>
inline T sqr(T a) {
  return a * a;
}
template <typename T>
inline void relaxMin(T &a, T b) {
  if (b < a) a = b;
}
template <typename T>
inline void relaxMax(T &a, T b) {
  if (b > a) a = b;
}
const int INF = (int)1E9;
const long double EPS = 1E-6;
const long double PI = 3.1415926535897932384626433832795;
void pre() {}
int w, h;
int f[2000][2000];
int id[2000][2000];
int id2[2000][2000];
int nvalid[2000][2000];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};
vector<vector<pair<int, int> > > sall;
vector<int> ans;
bool valid(int x, int y) { return x >= 0 && x < h && y >= 0 && y < w; }
void erase(int x, int y, int len) {
  for (int dx = -len; dx <= len; dx++)
    for (int dy = -len; dy <= len; dy++)
      if (dx * dx + dy * dy <= len) {
        int px = x + dx, py = y + dy;
        if (valid(px, py)) nvalid[px][py] = 1;
      }
}
bool good(int x, int y, int len) {
  for (int dx = -len; dx <= len; dx++)
    for (int dy = -len; dy <= len; dy++)
      if (dx * dx + dy * dy <= len) {
        int px = x + dx, py = y + dy;
        if (valid(px, py) && !f[px][py]) return false;
      }
  return true;
}
int used[2000][2000];
vector<pair<int, int> > bfs(int sx, int sy, int cmp1[2000][2000], int op1,
                            int cmp2[2000][2000], int op2) {
  vector<pair<int, int> > ans;
  queue<pair<int, int> > q;
  q.push(make_pair(sx, sy));
  while (!q.empty()) {
    pair<int, int> v = q.front();
    q.pop();
    ans.push_back(v);
    int x = v.first, y = v.second;
    for (int d(0), _bb(4); d < _bb; ++d) {
      int nx = x + dx[d], ny = y + dy[d];
      if (valid(nx, ny) && !used[nx][ny] && (cmp1[nx][ny] == op1) &&
          (cmp2[nx][ny] == op2)) {
        used[nx][ny] = 1;
        q.push(make_pair(nx, ny));
      }
    }
  }
  return ans;
}
void solve() {
  scanf("%d%d", &h, &w);
  for (int i(0), _bb(h); i < _bb; ++i)
    for (int j(0), _bb(w); j < _bb; ++j) scanf("%d", &f[i][j]);
  memset(id, -1, sizeof id);
  ;
  memset(used, 0, sizeof used);
  ;
  for (int i(0), _bb(h); i < _bb; ++i) {
    for (int j(0), _bb(w); j < _bb; ++j)
      if (f[i][j] && id[i][j] == -1) {
        int sid = sall.size();
        vector<pair<int, int> > v = bfs(i, j, f, 1, f, 1);
        sall.push_back(v);
        for (int k(0), _bb(v.size()); k < _bb; ++k)
          id[v[k].first][v[k].second] = sid;
      }
  }
  memset(nvalid, 0, sizeof nvalid);
  ;
  memset(id2, -1, sizeof id2);
  ;
  memset(used, 0, sizeof used);
  ;
  for (int sid(0), _bb(sall.size()); sid < _bb; ++sid) {
    vector<pair<int, int> > g;
    for (int i(0), _bb(sall[sid].size()); i < _bb; ++i)
      if (good(sall[sid][i].first, sall[sid][i].second, 7))
        g.push_back(sall[sid][i]);
    for (int i(0), _bb(g.size()); i < _bb; ++i)
      erase(g[i].first, g[i].second, 15);
    int cnt = 0;
    for (int i(0), _bb(sall[sid].size()); i < _bb; ++i) {
      int x = sall[sid][i].first, y = sall[sid][i].second;
      if (nvalid[x][y] || id2[x][y] != -1) continue;
      vector<pair<int, int> > v = bfs(x, y, nvalid, 0, id, id[x][y]);
      cnt++;
      for (int k(0), _bb(v.size()); k < _bb; ++k)
        id2[v[k].first][v[k].second] = 1;
    }
    ans.push_back(cnt);
  }
  sort(ans.begin(), ans.end());
  cout << ans.size() << endl;
  for (int i(0), _bb(ans.size()); i < _bb; ++i) cout << ans[i] << " ";
}
int main() {
  srand(0xA1B2C3D4);
  pre();
  solve();
  return 0;
}
