#include <bits/stdc++.h>
using namespace std;
struct Chair_man {
  int lazy[100005 * 40], rt[100005], lson[100005 * 40], rson[100005 * 40],
      Sum[100005 * 40];
  int tot;
  void up(int p) { Sum[p] = min(Sum[lson[p]], Sum[rson[p]]) + lazy[p]; }
  void insert(int &rt, int pas, int L, int R, int l, int r) {
    rt = ++tot;
    lazy[rt] = lazy[pas];
    lson[rt] = lson[pas];
    rson[rt] = rson[pas];
    Sum[rt] = Sum[pas] + 1;
    if (L == l && R == r) {
      lazy[rt]++;
      return;
    }
    int mid = (l + r) >> 1;
    if (mid >= R)
      insert(lson[rt], lson[pas], L, R, l, mid);
    else if (mid < L)
      insert(rson[rt], rson[pas], L, R, mid + 1, r);
    else {
      insert(lson[rt], lson[pas], L, mid, l, mid);
      insert(rson[rt], rson[pas], mid + 1, R, mid + 1, r);
    }
    up(rt);
  }
  int query(int p, int k, int l, int r) {
    if (l == r) return l;
    int mid = (l + r) >> 1;
    k -= lazy[p];
    if (Sum[rson[p]] <= k) return query(rson[p], k, mid + 1, r);
    return query(lson[p], k, l, mid);
  }
} T;
int pre[100005], A[100005], Rs[100005];
int n;
int deal(int k) {
  int now = 1, ans = 0;
  while (now <= n) {
    now = T.query(T.rt[now], k, 1, n) + 1;
    ans++;
  }
  return ans;
}
int main() {
  scanf("%d", &n);
  for (int i = (1), i_END = (n); i <= i_END; i++) scanf("%d", &A[i]);
  for (int i = (1), i_END = (n); i <= i_END; i++) pre[i] = n + 1;
  for (int i = (n), i_END = (1); i >= i_END; i--) {
    Rs[i] = pre[A[i]] - 1;
    pre[A[i]] = i;
  }
  for (int i = (n), i_END = (1); i >= i_END; i--)
    T.insert(T.rt[i], T.rt[i + 1], i, Rs[i], 1, n);
  for (int i = (1), i_END = (n); i <= i_END; i++) printf("%d ", deal(i));
  return 0;
}
