#include <bits/stdc++.h>   #pragma comment(linker,  /stack:20000000 )   using namespace std;   template <typename T1, typename T2, typename T3>   struct triple {     T1 a;     T2 b;     T3 c;     triple(){};     triple(T1 _a, T2 _b, T3 _c) : a(_a), b(_b), c(_c) {}   };   template <typename T1, typename T2, typename T3>   bool operator<(const triple<T1, T2, T3> &t1, const triple<T1, T2, T3> &t2) {     if (t1.a != t2.a)       return t1.a < t2.a;     else       return t1.b < t2.b;   }   template <typename T1, typename T2>   inline std::ostream &operator<<(std::ostream &os, const std::pair<T1, T2> &p) {     return os <<  (  << p.first <<  ,   << p.second <<  ) ;   }   template <typename T>   inline std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {     bool first = true;     os <<  [ ;     for (unsigned int i = 0; i < v.size(); i++) {       if (!first) os <<  ,  ;       os << v[i];       first = false;     }     return os <<  ] ;   }   template <typename T>   inline std::ostream &operator<<(std::ostream &os, const std::set<T> &v) {     bool first = true;     os <<  [ ;     for (typename std::set<T>::const_iterator ii = v.begin(); ii != v.end();          ++ii) {       if (!first) os <<  ,  ;       os << *ii;       first = false;     }     return os <<  ] ;   }   template <typename T1, typename T2>   inline std::ostream &operator<<(std::ostream &os, const std::map<T1, T2> &v) {     bool first = true;     os <<  [ ;     for (typename std::map<T1, T2>::const_iterator ii = v.begin(); ii != v.end();          ++ii) {       if (!first) os <<  ,  ;       os << *ii;       first = false;     }     return os <<  ] ;   }   template <typename T, typename T2>   void printarray(T a[], T2 sz, T2 beg = 0) {     for (T2 i = beg; i < sz; i++) cout << a[i] <<    ;   }   inline long long binpow(long long x, long long n) {     long long res = 1;     while (n) {       if (n & 1) res *= x;       x *= x;       n >>= 1;     }     return res;   }   inline long long powmod(long long x, long long n, long long _mod) {     long long res = 1;     while (n) {       if (n & 1) res = (res * x) % _mod;       x = (x * x) % _mod;       n >>= 1;     }     return res;   }   inline long long mulmod(long long x, long long n, long long _mod) {     long long res = 0;     while (n) {       if (n & 1) res = (res + x) % _mod;       x = (x + x) % _mod;       n >>= 1;     }     return res;   }   inline long long gcd(long long a, long long b) {     long long t;     while (b) {       a = a % b;       t = a;       a = b;       b = t;     }     return a;   }   inline int gcd(int a, int b) {     int t;     while (b) {       a = a % b;       t = a;       a = b;       b = t;     }     return a;   }   inline long long lcm(int a, int b) { return a / gcd(a, b) * (long long)b; }   inline long long lcm(long long a, long long b) { return a / gcd(a, b) * b; }   inline long long gcd(long long a, long long b, long long c) {     return gcd(gcd(a, b), c);   }   inline int gcd(int a, int b, int c) { return gcd(gcd(a, b), c); }   inline long long lcm(long long a, long long b, long long c) {     return lcm(lcm(a, b), c);   }   inline long long lcm(int a, int b, int c) {     return lcm(lcm(a, b), (long long)c);   }   inline long long max(long long a, long long b) { return (a > b) ? a : b; }   inline int max(int a, int b) { return (a > b) ? a : b; }   inline double max(double a, double b) { return (a > b) ? a : b; }   inline long long max(long long a, long long b, long long c) {     return max(a, max(b, c));   }   inline int max(int a, int b, int c) { return max(a, max(b, c)); }   inline double max(double a, double b, double c) { return max(a, max(b, c)); }   inline long long min(long long a, long long b) { return (a < b) ? a : b; }   inline int min(int a, int b) { return (a < b) ? a : b; }   inline double min(double a, double b) { return (a < b) ? a : b; }   inline long long min(long long a, long long b, long long c) {     return min(a, min(b, c));   }   inline int min(int a, int b, int c) { return min(a, min(b, c)); }   inline double min(double a, double b, double c) { return min(a, min(b, c)); }   inline void getar(int *a, int n) {     for (int ii = 0; ii < n; ii++) {       scanf( %d , a + ii);     }   }   inline void getar(long long *a, int n) {     for (int ii = 0; ii < n; ii++) {       scanf( %I64 , a + ii);     }   }   bool a[1621][1621];   bool used[1621][1621];   bool used2[1621][1621];   bool used3[1621][1621];   const int maxl = 15;   const int maxs = 10;   int w, h;   int k = 0;   int cur = 0;   int basei, basej;   triple<int, int, int> q[10000];   int qs = 0;   void go2(int i, int j) {     if (((abs(i - basei) + abs(j - basej)) >= maxl) || (!a[i][j]) || used2[i][j])       return;     used2[i][j] = true;     qs = 0;     q[qs].a = i;     q[qs].b = j;     q[qs++].c = 0;     int qc = 0;     while (qc < qs) {       int curi = q[qc].a;       int curj = q[qc].b;       int curl = q[qc++].c;       if (curl == maxl) break;       for (int t = -1; t <= 1; t++)         for (int w = -1; w <= 1; w++) {           if (!used2[curi + t][curj + w] && a[curi + t][curj + w]) {             used2[curi + t][curj + w] = true;             q[qs].a = curi + t;             q[qs].b = curj + w;             q[qs++].c = curl + 1;           }         }     }   }   vector<pair<int, int>> v3;   bool check(int i, int j) {     int s = 0;     qs = 0;     q[qs].a = i;     q[qs].b = j;     q[qs++].c = 0;     used3[i][j] = true;     int qc = 0;     v3.clear();     while (qc < qs) {       int curi = q[qc].a;       int curj = q[qc].b;       int curl = q[qc++].c;       if (max(abs(basei - curi), abs(basej - curj)) > 2) continue;       if (a[curi][curj]) s++;       for (int t = -1; t <= 1; t++)         for (int w = -1; w <= 1; w++) {           if (!used3[curi + t][curj + w]) {             used3[curi + t][curj + w] = true;             v3.push_back(make_pair(curi + t, curj + w));             q[qs].a = curi + t;             q[qs].b = curj + w;             q[qs++].c = curl + 1;           }         }     }     for (int i = 0; i < v3.size(); i++) {       used3[v3[i].first][v3[i].second] = false;     }     return (s < maxs);   }   void go(int i, int j) {     if ((!a[i][j]) || used[i][j]) return;     used[i][j] = true;     go(i - 1, j);     go(i + 1, j);     go(i, j - 1);     go(i, j + 1);     if (used2[i][j]) return;     int t = 0;     if (a[i - 1][j] == 0) t++;     if (a[i][j - 1] == 0) t++;     if (a[i + 1][j] == 0) t++;     if (a[i][j + 1] == 0) t++;     if (t >= 2) {       basei = i;       basej = j;       if (check(i, j)) {         cur++;         go2(i, j);       }     }   }   vector<int> ans;   int main() {     scanf( %d , &w);     scanf( %d , &h);     int x;     for (int i = 5; i < w + 5; i++) {       for (int j = 5; j < h + 5; j++) {         scanf( %d , &x);         a[i][j] = x;         used[i][j] = used2[i][j] = false;       }     }     for (int i = 5; i < w + 5; i++) {       for (int j = 5; j < h + 5; j++) {         if ((!used[i][j]) && a[i][j]) {           k++;           cur = 0;           go(i, j);           ans.push_back(cur);         }       }     }     cout << k << endl;     sort(ans.begin(), ans.end());     for (int i = 0; i < k; i++) {       cout << ans[i] <<    ;     }     cout << endl;     return 0;   }