unittest
{
	assert( [ "3", "2 1 2" ].parse.expand.solve == "3\n1\n0" );
	assert( [ "5", "1 2 3 4 5" ].parse.expand.solve == "5\n2\n1\n1\n1" );
	assert( [ "4", "1 3 3 3" ].parse.expand.solve == "4\n1\n0\n0" );
}



import std.algorithm;
import std.conv;
import std.range;
import std.stdio;
import std.typecons;

void main()
{
	stdin.byLineCopy.parse.expand.solve.writeln;
}

auto parse( Range )( Range input )
if( isInputRange!Range && is( ElementType!Range == string ) )
{
	input.popFront;
	auto as = input.front.split.to!( long[] );
	return tuple( as );
}

auto solve( long[] as )
{
	// 同じ数字のカードごとに集計
	// cs[ x ] = x枚以上の数字の種類数
	// rs[ x ] = x枚以下の数字の枚数合計
	auto cs = new long[ 1 + as.length ];
	auto rs = new long[ 1 + as.length ];
	foreach( g; as.sort().group )
	{
		cs[ g[ 1 ] ]++;
		rs[ g[ 1 ] ] += g[ 1 ];
	}
	foreach_reverse( x; 1L .. cs.length.signed )
	{
		cs[ x - 1 ] += cs[ x ];
	}
	foreach( x; 1L .. rs.length.signed )
	{
		rs[ x ] += rs[ x - 1 ];
	}
	
	// 最大操作回数をxとしたときの最大のkを計算
	auto anss = new long[ 1 + as.length ];
	foreach( x; 1L .. anss.length.signed )
	{
		// 操作1回分のk枚 = x枚以上の数字から1種類ごとに1枚 + x枚未満の数字から残りの枚数
		auto k = cs[ x ] + rs[ x - 1 ] / x;
		anss[ k ] = x;
	}
	anss.popFront;
	
	// 埋まらなかったkの最大操作回数はk+1の最大操作回数と同じにできる
	foreach_reverse( k; 1L .. anss.length.signed )
	{
		if( anss[ k - 1 ] == 0 ) anss[ k - 1 ] = anss[ k ];
	}
	return anss.to!( string[] ).join( "\n" );
}
