#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
const int N = 100005;
struct node {
  int s;
  node *l, *r;
  node() : s(0), l(this), r(this) {}
  node(int s, node *l, node *r) : s(s), l(l), r(r) {}
};
node *empty = new node();
node *roots[N];
int arr[N];
node *add(node *cur, int s, int e, int idx, int v) {
  if (idx < s || idx > e) return cur;
  if (s == e) {
    return new node(cur->s + v, empty, empty);
  }
  int mid = s + (e - s) / 2;
  return new node(cur->s + v, add(cur->l, s, mid, idx, v),
                  add(cur->r, mid + 1, e, idx, v));
}
int query(node *a, int s, int e, int k) {
  if (s == e) return s;
  int rsz = a->r->s;
  int mid = s + (e - s) / 2;
  if (rsz >= k) {
    return query(a->r, mid + 1, e, k);
  }
  k -= rsz;
  return query(a->l, s, mid, k);
}
int mp[N];
int main() {
  int n;
  roots[0] = empty;
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", arr + i);
    int id = mp[arr[i]];
    mp[arr[i]] = i;
    roots[i] = add(roots[i - 1], 0, n, i, 1);
    if (id) {
      roots[i] = add(roots[i], 0, n, id, -1);
    }
  }
  for (int c = 1; c <= n; ++c) {
    int i = n;
    int cnt = 1;
    while (i > 0) {
      if (roots[i]->s <= c) break;
      i = query(roots[i], 0, n, c + 1);
      ++cnt;
    }
    printf("%d ", cnt);
  }
}
