#include <bits/stdc++.h>   #pragma comment(linker,  /STACK:256000000 )   using namespace std;   const int maxN = 2000;   const int S_CNT = 9;   const int M_CNT = 25;   const int DIST = 60 * 60;   int n, m;   int a[maxN][maxN];   int t[maxN][maxN];   int used[maxN][maxN];   int rc[maxN][maxN];   int is_in(int x, int y) { return x >= 0 && x < n && y >= 0 && y < m; }   int get(int x, int y) {     int cnt = 0;     for (int i = x - 2; i <= x + 2; ++i) {       for (int j = y - 2; j <= y + 2; ++j) {         if (is_in(i, j)) {           cnt += a[i][j];         }       }     }     return cnt;   }   pair<int, int> choose_max(int x, int y) {     pair<int, int> res = make_pair(-1, -1);     int rs = -1;     for (int i = x - 2; i <= x + 2; ++i) {       for (int j = y - 2; j <= y + 2; ++j) {         if (is_in(i, j)) {           if (t[i][j] > rs) {             rs = t[i][j];             res = make_pair(i, j);           }         }       }     }     return res;   }   void change_used(int x, int y, int num) {     for (int i = x - 2; i <= x + 2; ++i) {       for (int j = y - 2; j <= y + 2; ++j) {         if (is_in(i, j)) {           used[i][j] = num;         }       }     }   }   int dist(pair<int, int> a, pair<int, int> b) {     return (a.first - b.first) * (a.first - b.first) +            (a.second - b.second) * (a.second - b.second);   }   pair<int, int> choose_long(int cx, int cy, int x, int y, int step) {     pair<int, int> res = make_pair(cx, cy);     int rs = -1;     for (int i = cx - 2; i <= cx + 2; ++i) {       for (int j = cy - 2; j <= cy + 2; ++j) {         if (is_in(i, j) && a[i][j] && used[i][j] != step) {           if (dist(make_pair(i, j), make_pair(x, y)) > rs) {             rs = dist(make_pair(i, j), make_pair(x, y));             res = make_pair(i, j);           }         }       }     }     return res;   }   void dfs(int x, int y, int color) {     if (rc[x][y] != 0) return;     rc[x][y] = color;     if (is_in(x + 1, y) && a[x + 1][y]) dfs(x + 1, y, color);     if (is_in(x - 1, y) && a[x - 1][y]) dfs(x - 1, y, color);     if (is_in(x, y + 1) && a[x][y + 1]) dfs(x, y + 1, color);     if (is_in(x, y - 1) && a[x][y - 1]) dfs(x, y - 1, color);   }   int main() {     scanf( %d%d , &n, &m);     for (int i = 0; i < n; ++i) {       for (int j = 0; j < m; ++j) {         scanf( %d , &a[i][j]);       }     }     int c_col = 0;     for (int i = 0; i < n; ++i) {       for (int j = 0; j < m; ++j) {         if (a[i][j] && !rc[i][j]) {           ++c_col;           dfs(i, j, c_col);         }       }     }     for (int i = 0; i < n; ++i) {       for (int j = 0; j < m; ++j) {         if (a[i][j]) {           t[i][j] = get(i, j);         }       }     }     vector<pair<int, int> > cur;     int step = 1;     for (int i = 0; i < n; ++i) {       for (int j = 0; j < m; ++j) {         if (a[i][j] && !used[i][j] && t[i][j] == S_CNT) {           ++step;           int cx = i, cy = j;           change_used(cx, cy, step);           cur.push_back(make_pair(cx, cy));         }       }     }     vector<int> col(cur.size(), 0);     for (int i = 0; i < col.size(); ++i) {       col[i] = rc[cur[i].first][cur[i].second];     }     map<int, int> res;     for (int i = 0; i < col.size(); ++i) {       ++res[col[i]];     }     cout << res.size() << endl;     vector<int> ans;     for (map<int, int>::iterator it = res.begin(); it != res.end(); ++it) {       ans.push_back(it->second);     }     sort(ans.begin(), ans.end());     for (int i = 0; i < ans.size(); ++i) {       cout << ans[i] <<    ;     }     cout << endl;     return 0;   }