#include <bits/stdc++.h>
using namespace std;
void fastIO() {
  std::ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
}
template <typename T, typename U>
inline void amin(T &x, U y) {
  if (y < x) x = y;
}
template <typename T, typename U>
inline void amax(T &x, U y) {
  if (x < y) x = y;
}
void _scan(int &x) { scanf("%d", &x); }
void _scan(long long &x) { scanf("%lld", &x); }
void _scan(double &x) { scanf("%lf", &x); }
void _scan(char &x) { scanf(" %c", &x); }
void _scan(char *x) { scanf("%s", x); }
void scan() {}
template <typename T, typename... U>
void scan(T &head, U &...tail) {
  _scan(head);
  scan(tail...);
}
template <typename T>
void _dbg(const char *sdbg, T h) {
  cerr << sdbg << "=" << h << "\n";
}
template <typename T, typename... U>
void _dbg(const char *sdbg, T h, U... t) {
  while (*sdbg != ',') cerr << *sdbg++;
  cerr << "=" << h << ",";
  _dbg(sdbg + 1, t...);
}
struct stnode {
  int sum;
  stnode *l = NULL, *r = NULL;
  void merge() { merge(*l, *r); }
  void merge(stnode &L, stnode &R) { sum = L.sum + R.sum; }
  void upd(int x) { sum = x; }
};
typedef stnode *pstnode;
struct ST {
  vector<pstnode> root, all;
  int N;
  void clear() {
    for (int i = 0; i < (int)all.size(); i++) delete all[i];
    all.clear();
    root.clear();
    N = 0;
  }
  pstnode new_node() {
    all.push_back(new stnode());
    return all.back();
  }
  void init(int n) {
    root.push_back(new_node());
    N = n;
  }
  void build() { build(root[0], 0, N); }
  void build(pstnode v, int l, int r) {
    if (r - l < 2) {
      v->upd(0);
      return;
    }
    int M = (l + r) >> 1;
    v->l = new_node();
    v->r = new_node();
    build(v->l, l, M);
    build(v->r, M, r);
    v->merge();
  }
  int query(int k, int ver) { return query(k, root[ver], 0, N); }
  int query(int k, pstnode v, int l, int r) {
    if (l == r - 1) {
      if (k > v->sum) return -1;
      return l;
    };
    int M = (l + r) >> 1;
    if (v->r->sum >= k) return query(k, v->r, M, r);
    return query(k - v->r->sum, v->l, l, M);
  }
  int update(int p, int x) {
    root.push_back(update(p, x, root.back(), 0, N));
    return root.size() - 1;
  }
  pstnode update(int p, int x, pstnode v, int l, int r) {
    pstnode u = new_node();
    if (r - l < 2) {
      u->upd(x);
      return u;
    }
    int M = (l + r) >> 1;
    u->l = v->l, u->r = v->r;
    if (p < M)
      u->l = update(p, x, v->l, l, M);
    else
      u->r = update(p, x, v->r, M, r);
    u->merge();
    return u;
  }
};
const int MAXN = 1e5 + 5;
int n, a[MAXN], lst[MAXN];
ST st;
vector<int> ver;
int main() {
  memset(lst, -1, sizeof(lst));
  scan(n);
  for (int i = 0; i < (int)n; i++) scan(a[i]);
  st.init(n);
  st.build();
  for (int i = 0; i < (int)n; i++) {
    int v = st.update(i, 1);
    if (lst[a[i]] != -1) v = st.update(lst[a[i]], 0);
    ver.push_back(v);
    lst[a[i]] = i;
  }
  for (int k = 1; k < (int)n + 1; k++) {
    int pos = n - 1, cnt = 0;
    while (pos != -1) {
      pos = st.query(k + 1, ver[pos]);
      cnt++;
    }
    printf("%d%c", cnt, " \n"[k == n]);
  }
}
