#include <bits/stdc++.h>
using namespace std;
int h, w;
char buffer[25000000];
int cur = 0;
int map[2000][2000];
int core[2000][2000];
int sun[2000][2000];
int cnt[101010];
int next_map[2000][2000];
const int dirx[] = {0, 0, 1, -1};
const int diry[] = {1, -1, 0, 0};
int cnt_sun = 0;
void del_ray(int time) {
  for (int t = 0; t < time; t++) {
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++) {
        next_map[i][j] = core[i][j];
        for (int k = 0; k < 4; k++) {
          int x = i + dirx[k];
          int y = j + diry[k];
          if (x >= 0 && x < h && y >= 0 && y < w)
            if (core[x][y] == -1) next_map[i][j] = -1;
        }
      }
    memcpy(core, next_map, sizeof(next_map));
  }
}
void search(int cur_x, int cur_y, int id) {
  core[cur_x][cur_y] = id;
  for (int i = 0; i < 4; i++) {
    int x = cur_x + dirx[i];
    int y = cur_y + diry[i];
    if (core[x][y] == 0) search(x, y, id);
  }
}
void enlarge_sun(int time) {
  for (int t = 0; t < time; t++) {
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++) {
        next_map[i][j] = max(sun[i][j], map[i][j]);
        for (int k = 0; k < 4; k++) {
          int x = i + dirx[k];
          int y = j + diry[k];
          if (x >= 0 && x < h && y >= 0 && y < w)
            if (sun[x][y] > 0 && map[i][j] >= 0) next_map[i][j] = sun[x][y];
        }
      }
    memcpy(sun, next_map, sizeof(next_map));
  }
}
int ray_size;
int get_ray(int cur_x, int cur_y) {
  int ret = 0;
  sun[cur_x][cur_y] = -1;
  ray_size++;
  for (int i = 0; i < 4; i++) {
    int x = cur_x + dirx[i];
    int y = cur_y + diry[i];
    if (x >= 0 && x < h && y >= 0 && y < w)
      if (sun[x][y] > 0)
        ret = sun[x][y];
      else if (sun[x][y] == 0) {
        int tmp = get_ray(x, y);
        if (tmp > 0) ret = tmp;
      }
  }
  return ret;
}
void find_ray() {
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      if (sun[i][j] == 0) {
        ray_size = 0;
        int tmp = get_ray(i, j);
        if (ray_size > 5) cnt[tmp]++;
      }
}
int read() {
  bool flag = true;
  int ret = 0;
  while ((buffer[cur] > '9' || buffer[cur] < '0') && buffer[cur] != '-') cur++;
  if (buffer[cur] == '-') {
    flag = false;
    cur++;
  }
  while (buffer[cur] >= '0' && buffer[cur] <= '9') {
    ret = ret * 10 + buffer[cur] - '0';
    cur++;
  }
  return flag ? ret : -ret;
}
int main() {
  memset(cnt, 0, sizeof(cnt));
  scanf("%d %d", &h, &w);
  fread(buffer, 1, 16000000, stdin);
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++) {
      map[i][j] = read();
      map[i][j]--;
    }
  memcpy(core, map, sizeof(map));
  del_ray(3);
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      if (core[i][j] == 0) search(i, j, ++cnt_sun);
  memcpy(sun, core, sizeof(core));
  enlarge_sun(3);
  find_ray();
  sort(cnt + 1, cnt + cnt_sun + 1);
  printf("%d\n", cnt_sun);
  for (int i = 1; i <= cnt_sun; i++) printf("%d ", cnt[i]);
  return 0;
}
