#include <bits/stdc++.h>
using namespace std;
const int N = (int)1e5 + 5;
class PersistSegTree {
 private:
  struct node {
    node *lf, *rt;
    int sum;
    node() { lf = rt = 0, sum = 0; }
  };
  node *root[N];
  int n, pos[N];
  int get_sum(node *tmp) {
    if (!tmp) return 0;
    return tmp->sum;
  }
  node *update(node *cur, int l, int r, int pos, int val) {
    if (l > r || l > pos || r < pos) return cur;
    node *tmp = new node();
    if (cur) tmp->lf = cur->lf, tmp->rt = cur->rt, tmp->sum = cur->sum;
    if (l == r && l == pos) {
      tmp->sum = val;
      return tmp;
    }
    int mid = (l + r) >> 1;
    tmp->lf = update(tmp->lf, l, mid, pos, val);
    tmp->rt = update(tmp->rt, mid + 1, r, pos, val);
    tmp->sum = get_sum(tmp->lf) + get_sum(tmp->rt);
    return tmp;
  }
  int query(node *cur, int l, int r, int k) {
    if (!cur) return r + 1;
    if (l == r) return get_sum(cur) == k ? l : l + 1;
    int mid = (l + r) >> 1;
    if (get_sum(cur->lf) >= k) return query(cur->lf, l, mid, k);
    return query(cur->rt, mid + 1, r, k - get_sum(cur->lf));
  }

 public:
  void init(int _n, int a[]) {
    n = _n, root[n + 1] = new node();
    for (int i = 1; i <= n; ++i) pos[i] = n + 1;
    for (int i = n; i >= 1; --i) {
      int pre = pos[a[i]];
      root[i] = root[i + 1];
      if (pre <= n) root[i] = update(root[i], 1, n, pre, 0);
      root[i] = update(root[i], 1, n, i, 1);
      pos[a[i]] = i;
    }
  }
  void update(int id, int idx, int val) {
    root[id] = update(root[id], 1, n, idx, val);
  }
  int query(int id, int k) { return query(root[id], 1, n, k + 1); }
} tree;
int n, a[N];
void solve() {
  tree.init(n, a);
  for (int k = 1; k <= n; ++k) {
    int ans = 0;
    for (int pos = 1; pos <= n;) pos = tree.query(pos, k), ++ans;
    printf("%d ", ans);
  }
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
  solve();
  return 0;
}
