#include <iostream>
#include <stdio.h>
#include <queue>
#include <stack>
#include <algorithm>
#define MAX_SIZE 25
using namespace std;
// up, right, down, left
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
int n; // number of rows and columns
int group_id; // apartment block id, it starts from 1
int groups[MAX_SIZE * MAX_SIZE]; // number of houses in each apartment block
int map[MAX_SIZE][MAX_SIZE]; // map
bool visited[MAX_SIZE][MAX_SIZE]; // map for visited or not
// DFS - Recursion
void dfs_recursion(int x, int y) {
// step into function -> it means visited
visited[x][y] = true;
// increase number of houses in group_id apartment block
groups[group_id]++;
// search around current x,y position
for(int i = 0; i < 4; i++){
int nx = x + dx[i];
int ny = y + dy[i];
// if nx and ny are in map
if(0 <= nx && nx < n && 0 <= ny && ny < n){
// if cur nx,ny is not visited then -> visit
if(map[nx][ny] == 1 && visited[nx][ny] == false){
dfs_recursion(nx, ny);
}
}
}
}
// DFS - Stack
void dfs_stack(int x, int y) {
stack< pair<int,int> > s; // stack for dfs, (x,y) -> (row, col)
s.push(make_pair(x,y)); // make pair data structure and push to stack
// first visit to x,y -> make x,y position visited
visited[x][y] = true;
// increase number of houses in group_id apartment block
groups[group_id]++;
while(!s.empty()){
// get top element of stack
x = s.top().first;
y = s.top().second;
s.pop();
// search around current x,y position
for(int i = 0; i < 4; i++){
int nx = x + dx[i];
int ny = y + dy[i];
// if nx and ny are in map
if(0 <= nx && nx < n && 0 <= ny && ny < n){
// if cur nx,ny is not visited then -> visit
if(map[nx][ny] == 1 && visited[nx][ny] == false){
visited[nx][ny]=true;
// increase number of houses in group_id apartment block
groups[group_id]++;
// also push current x,y and nx,ny
// because it is dfs(search around other positions after processing nx,ny then come back to x,y)
s.push(make_pair(x,y));
s.push(make_pair(nx,ny));
}
}
}
}
}
// BFS
void bfs(int x, int y){
queue< pair<int,int> > q; // queue for dfs, (x,y) -> (row, col)
q.push(make_pair(x,y)); // make pair data structure and push to queue
// first visit to x,y -> make x,y position visited
visited[x][y] = true;
// increase number of houses in group_id apartment block
groups[group_id]++;
while(!q.empty()){
// get front element of queue
x = q.front().first;
y = q.front().second;
q.pop();
// search around current x,y position
for(int i = 0; i < 4; i++){
int nx = x + dx[i];
int ny = y + dy[i];
// if nx and ny are in map
if(0 <= nx && nx < n && 0 <= ny && ny < n){
// if cur nx,ny is not visited then -> visit
if(map[nx][ny] == 1 && visited[nx][ny] == false){
visited[nx][ny]=true;
// increase number of houses in group_id apartment block
groups[group_id]++;
// push current nx,ny to queue
q.push(make_pair(nx,ny));
}
}
}
}
}
int main (){
scanf("%d", &n);
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++)
// get integer one by one -> %1d
scanf("%1d", &map[i][j]);
}
// search all values in map
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
// if cur i,j is not visited then -> visit
if(map[i][j]==1 && visited[i][j]==false){
// assign id to current position(apartment block)
group_id++;
// Search
//dfs_recursion(i, j);
//dfs_stack(i, j);
//bfs(i, j);
}
}
}
// sort number of houses in each apartment block in ascending order
// ID starts from 1
// usage: https://twpower.github.io/71-use-sort-and-stable_sort-in-cpp
sort(groups + 1, groups + group_id + 1);
printf("%d\n", group_id);
for (int i = 1; i <= group_id; i++) {
printf("%d\n", groups[i]);
}
}