#include <bits/stdc++.h>
using namespace std;
const int maxn = 1602;
const int fx[] = {0, -1, 0, 1}, fy[] = {-1, 0, 1, 0};
struct point {
  int x, y;
};
int a[maxn][maxn], b[maxn][maxn], temp[maxn][maxn], vis[maxn][maxn], ans[maxn];
int h, w, ans1;
int bfs(int color, int x, int y) {
  int num = 0;
  vis[x][y] = color;
  num = 1;
  queue<point> q = queue<point>();
  point p;
  p.x = x;
  p.y = y;
  q.push(p);
  while (q.size() != 0) {
    point cnt = q.front();
    for (int i = 0; i < 4; i++) {
      int tx = cnt.x + fx[i];
      int ty = cnt.y + fy[i];
      if (tx > 0 && tx <= h && ty > 0 && ty <= w && a[tx][ty] != 0 &&
          vis[tx][ty] == 0) {
        vis[tx][ty] = color;
        num++;
        p.x = tx;
        p.y = ty;
        q.push(p);
      }
    }
    q.pop();
  }
  return num;
}
void floodfill1() {
  int tot = 0, num = 0;
  memset(vis, 0, sizeof(vis));
  for (int i = 1; i <= h; i++)
    for (int j = 1; j <= w; j++)
      if (a[i][j] != 0 && vis[i][j] == 0) {
        num = bfs(++tot, i, j);
      }
  ans1 = tot;
  cout << ans1 << endl;
}
void floodfill2() {
  int num = 0;
  memset(vis, 0, sizeof(vis));
  for (int i = 1; i <= h; i++)
    for (int j = 1; j <= w; j++)
      if (a[i][j] != 0 && vis[i][j] == 0) {
        num = bfs(1, i, j);
        if (num >= 5) ans[a[i][j]]++;
      }
  sort(ans + 1, ans + 1 + ans1);
  cout << ans[1];
  for (int i = 2; i <= ans1; i++) cout << ' ' << ans[i];
  cout << endl;
}
bool check(int x, int y) {
  for (int i = 0; i < 4; i++) {
    int tx = x + fx[i];
    int ty = y + fy[i];
    if (b[tx][ty] != b[x][y]) return true;
  }
  return false;
}
void shrink() {
  for (int i = 1; i <= h; i++)
    for (int j = 1; j <= w; j++) {
      if (b[i][j] == 0)
        temp[i][j] = 0;
      else if (check(i, j))
        temp[i][j] = 0;
      else
        temp[i][j] = 1;
    }
  for (int i = 1; i <= h; i++)
    for (int j = 1; j <= w; j++) b[i][j] = temp[i][j];
}
void expand() {
  for (int i = 1; i <= h; i++)
    for (int j = 1; j <= w; j++) {
      if (b[i][j] == 1)
        temp[i][j] = 1;
      else if (check(i, j))
        temp[i][j] = 1;
      else
        temp[i][j] = 0;
    }
  for (int i = 1; i <= h; i++)
    for (int j = 1; j <= w; j++) b[i][j] = temp[i][j];
}
int main() {
  scanf("%d%d", &h, &w);
  for (int i = 1; i <= h; i++)
    for (int j = 1; j <= w; j++) scanf("%d", &a[i][j]);
  floodfill1();
  for (int i = 1; i <= h; i++)
    for (int j = 1; j <= w; j++) b[i][j] = a[i][j];
  shrink();
  shrink();
  shrink();
  shrink();
  expand();
  expand();
  expand();
  expand();
  expand();
  expand();
  for (int i = 1; i <= h; i++)
    for (int j = 1; j <= w; j++)
      if (a[i][j] == b[i][j])
        a[i][j] = 0;
      else
        a[i][j] = vis[i][j];
  floodfill2();
}
