Takahashi has N cards, each with an integer Ai written on it. He chooses an integer K and repeats the following operation: select K cards with different integers and eat them. Find the maximum number of times Takahashi can perform this operation for each K (1 to N). Constraints: 1 ≤ N ≤ 3 × 10^5, 1 ≤ Ai ≤ N. Input format: N followed by A1 to AN. Output: N integers representing the maximum operations for each K. Example: For K=1, K=2, K=3, etc., output the maximum operations possible.

# Buggy version:
import sys
from collections import Counter
input = sys.stdin.readline
N = int(input())
a = list(map(int, input().split()))
c = Counter()
for x in a: c[x] += 1
cv = Counter()
for v in c.values(): cv[v] += 1
print(cv)

def check(x, K):
  t = 0
  for k, v in cv.items(): t += min(k, x) * v
  return t >= K * x

res = [N] * (N + 1)
for K in range(1, N):
  ok = 0
  ng = res[K] + 1
  while ng - ok > 1:
    m = (ok + ng) // 2
    if check(m, K + 1): ok = m
    else: ng = m
  res[K + 1] = ok

for r in res[1: ]: print(r)

# Fixed version:
import sys
from collections import Counter
input = sys.stdin.readline
N = int(input())
a = list(map(int, input().split()))
c = Counter()
for x in a: c[x] += 1
cv = Counter()
for v in c.values(): cv[v] += 1
#print(cv)

def check(x, K):
  t = 0
  for k, v in cv.items(): t += min(k, x) * v
  return t >= K * x

res = [N] * (N + 1)
for K in range(1, N):
  ok = 0
  ng = res[K] + 1
  while ng - ok > 1:
    m = (ok + ng) // 2
    if check(m, K + 1): ok = m
    else: ng = m
  res[K + 1] = ok

for r in res[1: ]: print(r)

# Buggy version:
def main():
    from sys import stdin
    input = stdin.readline
    from collections import Counter as ct
    from bisect import bisect_left as bl

    n = int(input())
    max_a = sorted(ct(list(map(int, input().split()))).values())
    now_a = [i for i in max_a]
    m = len(max_a)
    cnt = m
    ans = 0
    ans_list = [0]*(n-m)

    for use in range(m, 1, -1):
        rest = ans
        nex = now_a[0]
        while rest:
            val = nex
            start = bl(now_a, val+1)
            nex += 1
            q = bl(max_a, now_a[start-1]+1)-1
            for i in range(start-1, max(-1, start-1-rest, q), -1):
                now_a[i] += 1
            rest -= start-1-max(-1, start-1-rest, q)
            if now_a[start-1] == 0:
                cnt += start-1-max(-1, start-1-rest, q)
            if start != m:
                nex = now_a[start]
        while cnt >= use:
            ans += 1
            rest = use
            nex = now_a[-1]
            end = m
            while rest:
                val = nex
                start = bl(now_a, val)
                if start != 0:
                    nex = now_a[start-1]
                end = min(end, bl(now_a, val+1), start+rest)
                for i in range(start, end):
                    now_a[i] -= 1
                if now_a[start] == 0:
                    cnt -= end-start
                rest -= end-start
                end = start
        ans_list.append(ans)
    print(n)
    for i in ans_list[::-1]:
        print(i)


main()

# Fixed version:
def main():
    from sys import stdin
    input = stdin.readline
    from collections import Counter as ct
    from bisect import bisect_left as bl

    n = int(input())
    max_a = sorted(ct(list(map(int, input().split()))).values())
    now_a = [i for i in max_a]
    m = len(max_a)
    cnt = m
    ans = 0
    ans_list = [0]*(n-m)

    for use in range(m, 1, -1):
        rest = ans
        nex = now_a[0]
        while rest:
            val = nex
            start = bl(now_a, val+1)
            nex += 1
            q = max(-1, start-1-rest, bl(max_a, now_a[start-1]+1)-1)
            for i in range(start-1, q, -1):
                now_a[i] += 1
            if now_a[start-1] == 1:
                cnt += start-1-q
            rest -= start-1-q
            if start != m:
                nex = now_a[start]
        while cnt >= use:
            ans += 1
            rest = use
            nex = now_a[-1]
            end = m
            while rest:
                val = nex
                start = bl(now_a, val)
                if start != 0:
                    nex = now_a[start-1]
                end = min(end, bl(now_a, val+1), start+rest)
                for i in range(start, end):
                    now_a[i] -= 1
                if now_a[start] == 0:
                    cnt -= end-start
                rest -= end-start
                end = start
        ans_list.append(ans)
    print(n)
    for i in ans_list[::-1]:
        print(i)


main()

# Buggy version:
import sys
stdin = sys.stdin

ni = lambda: int(ns())
na = lambda: list(map(int, stdin.readline().split()))
nn = lambda: list(stdin.readline().split())
ns = lambda: stdin.readline().rstrip()

import bisect
from collections import Counter

n = ni()
a = na()
aa = [a[0]]
for i in range(1,n):
    aa.append(aa[-1]+a[i])

c = sorted(Counter(a).values())
cc = [c[0]]
m = len(c)
for i in range(1,m):
    cc.append(cc[-1]+c[i])

for k in range(1,n+1):
    def is_ok(arg):
        b = bisect.bisect_right(c,arg)
        p = cc[b-1] + (m-b)*arg
        return True if p >= arg*k else False

    #にぶたん
    ok,ng = -1,n
    while (abs(ok - ng) > 1):
        mid = (ok + ng) // 2
        if is_ok(mid):
            ok = mid
        else:
            ng = mid
    
    print(ok)
    

# Fixed version:
import sys
stdin = sys.stdin

ni = lambda: int(ns())
na = lambda: list(map(int, stdin.readline().split()))
nn = lambda: list(stdin.readline().split())
ns = lambda: stdin.readline().rstrip()

import bisect
from collections import Counter

n = ni()
a = na()

c = sorted(Counter(a).values())
cc = [0]
m = len(c)
for i in c:
    cc.append(cc[-1]+i)

def is_ok(k,arg):
    b = bisect.bisect_right(c,arg)
    p = cc[b] + (m-b)*arg
    return True if p >= arg*k else False

for k in range(1,n+1):
    if k > m:
        print(0)
        continue
    #にぶたん
    ok,ng = -1,n//k+1
    while (abs(ok - ng) > 1):
        mid = (ok + ng) // 2
        if is_ok(k,mid):
            ok = mid
        else:
            ng = mid
    
    print(ok)

# Buggy version:
from collections import Counter as C
N = int(input())
A = sorted(list(C([int(a) for a in input().split()]).values()))
X = [0] * 303030
for a in A:
    X[a] += 1

s = 0
B = [0] * 303030
for i in range(300030)[::-1]:
    B[i] += s
    s += X[i]

def chk(k, a):
    if N - B[a] >= k * a: return 1
    return 0

for i in range(1, N+1):
    l, r = 0, N + 1
    while r-l > 1:
        m = (l+r) // 2
        if chk(i, m):
            l = m
        else:
            r = m
    print(l)

# Fixed version:
from collections import Counter as C
N = int(input())
A = sorted(list(C([int(a) for a in input().split()]).values()))
X = [0] * 303030
for a in A:
    X[a] += 1

s = 0
c = 0
B = [0] * 303030
for i in range(300030)[::-1]:
    s += c
    B[i] += s
    c += X[i]

def chk(k, a):
    if N - B[a] >= k * a: return 1
    return 0

for i in range(1, N+1):
    l, r = 0, N + 1
    while r-l > 1:
        m = (l+r) // 2
        if chk(i, m):
            l = m
        else:
            r = m
    print(l)

# Buggy version:
N = int(input())
count = {}
for x in map(int, input().split()):
    count[x] = count.get(x, 0) + 1

a = sorted(count.values())
sums = a[:]
n = len(a)
for i in range(1, n):
    sums[i] += sums[i-1]
    
def check(k, x):
    pos = bisect.bisect_right(a, x)
    return (sums[pos-1] if pos-1 >= 0 else 0) + x * (n - pos) >= k * x

x = 0
res = []
for k in range(N, 0, -1):
    while check(k, x+1):
        x += 1
    res.append(x)
    
for x in res[::-1]:
    print(x)

# Fixed version:
import bisect
N = int(input())
count = {}
for x in map(int, input().split()):
    count[x] = count.get(x, 0) + 1

a = sorted(count.values())
sums = a[:]
n = len(a)
for i in range(1, n):
    sums[i] += sums[i-1]
    
def check(k, x):
    pos = bisect.bisect_right(a, x)
    if pos == 0:
        return x * n >= k * x
    return sums[pos-1]+ x * (n - pos) >= k * x

x = 0
res = []
for k in range(N, 0, -1):
    while check(k, x+1):
        x += 1
    res.append(x)
    
for x in res[::-1]:
    print(x)

# Buggy version:
N = int(input())
A = list(map(int, input().split()))
types = {}
for i in A: types[i] = types.get(i, 0) + 1
A = sorted([types[k] for k in types], reverse=True)
L = len(A)
cumsum = [0 for i in range(L+1)]
for i in range(L-1, -1, -1):
    cumsum[i] = A[i] + cumsum[i+1]

# Highest K for given O
def calc(O):
    def getMidPoint(lo, hi):
        if lo >= hi: return lo
        mid = lo + (hi - lo+1) // 2
        if A[mid] > O:
            return getMidPoint(mid, hi)
        else:
            return getMidPoint(lo, mid-1)

    mid = getMidPoint(0, L-1)
    return (mid+1) + cumsum[mid+1] // O

for K in range(1, N+1):
    def getO(lo, hi):
        if lo >= hi: return lo
        mid = lo + (hi - lo+1) // 2
        if calc(mid) < K:
            return getO(lo, mid - 1)
        else:
            return getO(mid, hi)
        
    print(getO(0, N))
    


# Fixed version:
N = int(input())
A = list(map(int, input().split()))
types = {}
for i in A: types[i] = types.get(i, 0) + 1
A = sorted([types[k] for k in types], reverse=True)
L = len(A)
cumsum = [0 for i in range(L+1)]
for i in range(L-1, -1, -1):
    cumsum[i] = A[i] + cumsum[i+1]



def getMidPoint(lo, hi, O):
    if lo >= hi: return lo
    mid = lo + (hi - lo+1) // 2
    if A[mid] > O:
        return getMidPoint(mid, hi, O)
    else:
        return getMidPoint(lo, mid-1, O)

getMid = [getMidPoint(0, L - 1, o) for o in range(N+1)]

# Highest K for given O
def calc(O):
    

    mid = getMid[O]
    if A[mid] < O: mid = - 1
    return (mid+1) + cumsum[mid+1] // O

for K in range(1, N+1):
    def getO(lo, hi):
        if lo >= hi: return lo
        mid = lo + (hi - lo+1) // 2
        if calc(mid) < K:
            return getO(lo, mid - 1)
        else:
            return getO(mid, hi)
        
    print(getO(0, N))

# Buggy version:
import sys
input = sys.stdin.readline

#input
N = int(input())
A = list(map(int, input().split()))

#output
from collections import Counter
import bisect
import numpy as np

l = Counter(A).most_common()
l = [b for a, b in l]
M = len(l)
np.sort(l)
m = np.cumsum(l)
p = m[-1]

maximum_operation = [0] * N

ll = []
for x in range(1, N+1):
    a = bisect.bisect_left(l, x)
    if a == 0:
        b = M*x
        c = 0
    elif a >= M:
        b = 0
        c = p
    else:
        b = (M-a)*x
        c = m[a-1] 
    ll.append((b + c)/x)
np.sort(ll)

for K in range(M):
    maximum_operation[K] = N - bisect.bisect_left(ll, K+1)

for m in maximum_operation:
    print(m)


# Fixed version:
import sys
input = sys.stdin.readline

#input
N = int(input())
A = list(map(int, input().split()))

#output
from collections import Counter
import bisect

l = Counter(A).most_common()
l = [b for a, b in l]
M = len(l)
l.sort()
p = sum(l)

maximum_operation = [0] * N

ll = []
for x in reversed(range(1, N+1)):
    a = bisect.bisect_left(l, x)
    if a == 0:
        b = M*x
        c = 0
    elif a >= M:
        b = 0
        c = p
    else:
        b = (M-a)*x
        c = sum(l[0:a]) 
    ll.append((b + c)/x)

for K in range(M):
    maximum_operation[K] = N - bisect.bisect_left(ll, K+1)

for m in maximum_operation:
    print(m)

# Buggy version:
#!/usr/bin/env python3
import sys
from collections import Counter
from itertools import accumulate
from collections import defaultdict
INF = float("inf")


def solve(N: int, A: "List[int]"):
    c = Counter(A)
    d = Counter(c.values())
    d = tuple(accumulate([d[i] for i in range(N, -1, -1)])[::-1])
    S = [0]*(N+1)
    for i in range(1, N+1):
        S[i] = S[i-1] + d[i]

    def isOK(y):
        return S[y] < K*y

    def binary_search(x):
        ng = -1
        ok = len(x)+1

        while abs(ok - ng) > 1:
            mid = (ok + ng)//2
            if isOK(mid):
                ok = mid
            else:
                ng = mid
        return ng, ok

    for K in range(1, N+1):
        ng, ok = binary_search(range(N))
        print(ng)

    return


def main():

    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    A = [int(next(tokens)) for _ in range(N)]  # type: "List[int]"
    solve(N, A)


if __name__ == '__main__':
    main()


# Fixed version:
#!/usr/bin/env python3
import sys
from collections import Counter
from itertools import accumulate
from collections import defaultdict
INF = float("inf")


def solve(N: int, A: "List[int]"):
    c = Counter(A)
    d = Counter(c.values())
    d = tuple(accumulate([d[i] for i in range(N, -1, -1)]))[::-1]
    S = [0]*(N+1)
    for i in range(1, N+1):
        S[i] = S[i-1] + d[i]

    def isOK(y):
        return S[y] < K*y

    def binary_search(x):
        ng = -1
        ok = len(x)+1

        while abs(ok - ng) > 1:
            mid = (ok + ng)//2
            if isOK(mid):
                ok = mid
            else:
                ng = mid
        return ng, ok

    for K in range(1, N+1):
        ng, ok = binary_search(range(N))
        print(ng)

    return


def main():

    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    A = [int(next(tokens)) for _ in range(N)]  # type: "List[int]"
    solve(N, A)


if __name__ == '__main__':
    main()

# Buggy version:
from collections import *
MAX = 3*pow(10,5) + 2
n = int(input())
a = list(map(int,input().split()))
b = [0 for i in range(MAX)]
c = [0 for i in range(MAX)]
for i in a:
    b[i] += 1
for i in b:
    c[i] += 1
s = n
last = n
print(last)
for k in range(2,n+1):
    while(s//k < last):
        for i in range(last,s//k,-1):
            s -= c[i]
            c[i-1] += c[i]
            c[i] = 0
        last = s//k
    print(last)

# Fixed version:
from collections import *
MAX = 3*pow(10,5) + 2
n = int(input())
a = list(map(int,input().split()))
b = [0 for i in range(MAX)]
c = [0 for i in range(MAX)]
for i in a:
    b[i] += 1
for i in b:
    c[i] += 1
s = n
last = n
print(last)
for k in range(2,n+1):
    while(s//k < last):
        best = min(last,s//k)
        for i in range(last,best,-1):
            s -= c[i]
            c[i-1] += c[i]
            c[i] = 0
        last = best
    print(last)

# Buggy version:
import itertools
import collections
N = int(input())
A = [int(_) for _ in input().split()]
c = sorted(collections.Counter(A).values())
acc = list(itertools.accumulate([0] + c))
n = len(acc) - 1
j = 0
for i in range(1, N + 1):
    r = 0
    while i - j > 0:
        if (i - j) * c[-1 - j] <= acc[-1 - j]:
            r = acc[-1 - j] // (i - j)
            break
        else:
            j += 1
    print(r)


# Fixed version:
import itertools
import collections
N = int(input())
A = [int(_) for _ in input().split()]
c = sorted(collections.Counter(A).values())
acc = list(itertools.accumulate([0] + c))
n = len(acc) - 1
j = 0
for i in range(1, n + 1):
    r = 0
    while i - j > 0:
        if (i - j) * c[-1 - j] <= acc[-1 - j]:
            r = acc[-1 - j] // (i - j)
            break
        else:
            j += 1
    print(r)
for _ in range(N - n):
    print(0)

# Buggy version:
#x個の列を取り出せる最大の長さf(x)を考える
#dの導入

import bisect
n = int(input())
a = list(map(int, input().split()))

c = [0]*(n+1)

for i in range(n):
    c[a[i]] += 1

d = [0]*(n+1)
for i in range(n):
    d[c[i]] += 1

sum1 = 0
sum2 =sum(d)-d[0]
ans = []
for x in range(1,n+1):
    sum1 += x*d[x]
    sum2 -= d[x]
    ans.append((sum1+x*sum2)//x)
ans.sort()
for i in range(1,n+1):
    j = bisect.bisect_left(ans,i)
    print(n-j)

# Fixed version:
#x個の列を取り出せる最大の長さf(x)を考える
#dの導入

import bisect
n = int(input())
a = list(map(int, input().split()))

c = [0]*(n+1)

for i in range(n):
    c[a[i]] += 1

d = [0]*(n+1)
for i in range(n+1):###
    d[c[i]] += 1

sum1 = 0
sum2 =sum(d)-d[0]
fx = []
for x in range(1,n+1):
    sum1 += x*d[x]
    sum2 -= d[x]
    fx.append((sum1+x*sum2)//x)
fx.sort()
for i in range(1,n+1):
    j = bisect.bisect_left(fx,i)###
    print(n-j)

# Buggy version:
from collections import Counter
from itertools import accumulate
from bisect import bisect_right
N = int(input())
As = list(map(int, input().split()))
ct = Counter(As)
ctm = [c[1] for c in ct.most_common()]
ctm.reverse()
L = len(ctm)
acc = [0] +  list(accumulate(ctm))

arr = [0]
for n in range(1, N+1):
  idx = bisect_right(ctm, n)
  arr.append(acc[idx] + n*(L-idx))

for i in range(1, N+1):
  f = 1
  t = N // i + 1
  if f +1 >= t:
    print(0)
    continue
  while f + 1 < t:
    m = f + (t-f) // 2
    if arr[m] >= m*i:
      f = m
    else:
      t = m
  print(f)

# Fixed version:
from collections import Counter
from itertools import accumulate
from bisect import bisect_right
N = int(input())
As = list(map(int, input().split()))
ct = Counter(As)
ctm = [c[1] for c in ct.most_common()]
ctm.reverse()
L = len(ctm)
acc = [0] +  list(accumulate(ctm))

arr = [0]
for n in range(1, N+1):
  idx = bisect_right(ctm, n)
  arr.append(acc[idx] + n*(L-idx))

for n in range(1, N+1):
  f = 0
  t = N // n + 1
  while f + 1 < t:
    m = f + (t-f) // 2
    if arr[m] >= m*n:
      f = m
    else:
      t = m
  print(f)