#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <set>
#include <vector>
#include <map>
#include <cmath>
#include <algorithm>
#include <memory.h>
#include <string>
#include <sstream>
#include <queue>
#include <hash_set>
using namespace std;
char m[1600][1610];
int h, w;
const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, -1, 0, 1};

void Fill(int x, int y, int k = 0) {
  m[x][y] = ' ';
  for (int i = 0; i < 4; ++i) {
    int new_x = x + dx[(i + k) % 4];
    int new_y = y + dy[(i + k) % 4];
    if (new_x >= 0 && new_x < h && new_y >= 0 && new_y < w && m[new_x][new_y] != ' ') {
      Fill(new_x, new_y, k + 1);
    }
  }
}

int Count(int start_x, int start_y) {
  int direct = 0;
  int last_ray;
  int x = start_x, y = start_y;
  vector<int> figure;
  int step = 0;
  do {
    figure.push_back(x << 16 | y);
    for (int k = 0; k < 4; ++k) {
      int new_direct = (direct + 5 - k) % 4;
      int new_x = x + dx[new_direct];
      int new_y = y + dy[new_direct];
      if (new_x >= 0 && new_x < h && new_y >= 0 && new_y < w) {
        if (m[new_x][new_y] != ' ') {
          direct = new_direct;
          x = new_x;
          y = new_y;
          break;
        }
      }
    }
  } while (x != start_x || y != start_y);
  int first_corner = -1;
  int last_corner = -1;
  int ans = 0;
  for (int i = 0, j = figure.size() - 9, k = 9; i < figure.size(); ++i, ++j, ++k) {
    if (last_corner != 0 && i - last_corner < 18) continue;
    int ox = figure[i] >> 16;
    int oy = figure[i] & 65535;
    m[ox][oy] = 'X';
    int x1 = figure[j % figure.size()] >> 16;
    int y1 = figure[j % figure.size()] & 65535;
    int x2 = figure[k % figure.size()] >> 16;
    int y2 = figure[k % figure.size()] & 65535;
    
    double cross_product = (x1 - ox) * (y2 - oy) - (x2 - ox) * (y1 - oy);
    double dot_product = (x1 - ox) * (x2 - ox) + (y1 - oy) * (y2 - oy);
    if (cross_product < 0 && dot_product > 0 && -cross_product / sqrt(1.0*(x1 - ox)*(x1 - ox) + (y1 - oy)*(y1 - oy)) / sqrt(1.0*(x2 - ox)*(x2 - ox) + (y2 - oy)*(y2 - oy)) < 0.5) {
      if (first_corner == -1) {
        first_corner = i;
        ++ans;
      } else {
        if (first_corner + figure.size() - i > 18) {
          ++ans;
        }
      }
      m[ox][oy] = '?';
      last_corner = i;
    }
  }
  Fill(start_x, start_y);
  return ans;
}

void main() {
  //freopen("C:\\Users\\fzk\\Desktop\\tmp\\21.in.txt", "r", stdin);
  scanf("%d%d", &h, &w);
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      int t;
      scanf("%d", &t);
      m[i][j] = (t == 1 ? 'O' : ' ');
    }
  }
  vector<int> ans;
  
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      if (m[i][j] != ' ') {
        int t = Count(i, j);
        ans.push_back(t);
      }
    }
  }
  sort(ans.begin(), ans.end());
  printf("%d\n", ans.size());
  for (int i = 0; i < ans.size(); ++i) {
    printf("%d", ans[i]);
    if (i == ans.size() - 1) printf("\n");
    else printf(" ");
  }
  return;
}

