#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:65000000")
using namespace std;
template <typename T>
T mabs(const T &a) {
  return a < 0 ? -a : a;
}
const double PI = acos(-1.0);
const int mod = 1e9;
int n, m;
int P[1601][1601];
int Id[1601][1601];
char Corners[1601][1601] = {0};
int currId;
inline int Pix(int i, int j) {
  return (i >= 0 && i < n && j >= 0 && j < m ? Id[i][j] == currId : 0);
}
vector<int> detectCorners() {
  map<int, int> mp;
  const int sz = 6;
  const int psz = 4;
  const int th = 2;
  for (int i = (0), ei = (n); i < ei; i++)
    for (int j = (0), ej = (m); j < ej; j++)
      if (P[i][j] == 1 && Corners[i][j] != 2) {
        int cnt = 0;
        currId = Id[i][j];
        for (int a = (0), ea = (sz); a < ea; a++)
          cnt += Pix(i - 1 + a, j - 1) + Pix(i - 1, j - 1 + a);
        if (cnt > th) {
          cnt = 0;
          for (int a = (0), ea = (sz); a < ea; a++)
            cnt += Pix(i - 1 + a, j + 1) + Pix(i - 1, j + 1 - a);
          if (cnt > th) {
            cnt = 0;
            for (int a = (0), ea = (sz); a < ea; a++)
              cnt += Pix(i + 1 - a, j + 1) + Pix(i + 1, j + 1 - a);
            if (cnt > th) {
              cnt = 0;
              for (int a = (0), ea = (sz); a < ea; a++)
                cnt += Pix(i + 1 - a, j - 1) + Pix(i + 1, j - 1 + a);
            }
          }
        }
        if (cnt <= th) {
          mp[Id[i][j]]++;
          for (int a = (-psz), ea = (psz + 1); a < ea; a++)
            for (int b = (-psz), eb = (psz + 1); b < eb; b++)
              if (Pix(i + a, j + b)) Corners[i + a][j + b] = 2;
        }
      }
  vector<int> res;
  for (map<int, int>::iterator iter = mp.begin(); iter != mp.end(); ++iter)
    res.push_back(iter->second);
  return res;
}
void run() {
  cin >> n >> m;
  char str[10000];
  for (int i = (0), ei = (n); i < ei; i++) {
    gets(str);
    int pos = 0;
    for (int j = (0), ej = (strlen(str)); j < ej; j++)
      if (str[j] == '0' || str[j] == '1') P[i][pos++] = str[j] - '0';
  }
  int sz = 11;
  int hsz = sz / 2;
  bool was[1601][1601] = {0};
  int dx[] = {-1, 0, 1, 0};
  int dy[] = {0, -1, 0, 1};
  int lastId = 2;
  for (int i = (0), ei = (n); i < ei; i++)
    for (int j = (0), ej = (m); j < ej; j++)
      if (!was[i][j] && P[i][j] == 1) {
        queue<pair<int, int> > q;
        q.push(pair<int, int>(i, j));
        was[i][j] = 1;
        Id[i][j] = lastId;
        while (!q.empty()) {
          int x = q.front().first;
          int y = q.front().second;
          q.pop();
          for (int k = (0), ek = (4); k < ek; k++) {
            int nx = x + dx[k];
            int ny = y + dy[k];
            if (nx >= 0 && nx < n && ny >= 0 && ny < m && !was[nx][ny] &&
                P[nx][ny] == 1) {
              was[nx][ny] = 1;
              Id[nx][ny] = lastId;
              q.push(pair<int, int>(nx, ny));
            }
          }
        }
        ++lastId;
      }
  vector<int> res = detectCorners();
  sort((res).begin(), (res).end());
  printf("%d\n", res.size());
  for (int i = (0), ei = (res.size()); i < ei; i++) printf("%d ", res[i]);
  if (res.size()) puts("");
}
int main() {
  run();
  return 0;
}
