#include <bits/stdc++.h>
using namespace std;
const int MAX = 1e5 + 9;
int n, a[MAX], tree[(MAX << 2)], idx, val, ans[MAX], lst[MAX], nxt[MAX];
vector<int> q[MAX];
void upd(int low, int high, int pos) {
  if (low == high) {
    tree[pos] = val;
    return;
  }
  int mid = ((low + high) >> 1);
  if (idx <= mid) {
    upd(low, mid, (pos << 1));
  } else {
    upd(mid + 1, high, (pos << 1 | 1));
  }
  tree[pos] = tree[(pos << 1)] + tree[(pos << 1 | 1)];
}
int qwr(int low, int high, int pos, int k) {
  if (low == high) {
    return low - 1;
  }
  int mid = ((low + high) >> 1);
  if (tree[(pos << 1)] > k) {
    return qwr(low, mid, (pos << 1), k);
  } else {
    return qwr(mid + 1, high, (pos << 1 | 1), k - tree[(pos << 1)]);
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    cin >> a[i];
    if (lst[a[i]]) {
      nxt[lst[a[i]]] = i;
    } else {
      idx = i;
      val = 1;
      upd(1, n + 1, 1);
    }
    lst[a[i]] = i;
    q[1].push_back(i);
  }
  for (int i = 1; i <= n; ++i) {
    for (int j = 0; j < q[i].size(); ++j) {
      ++ans[q[i][j]];
      int lastCan = qwr(1, n + 1, 1, q[i][j]);
      q[lastCan + 1].push_back(q[i][j]);
    }
    if (nxt[i]) {
      idx = nxt[i];
      val = 1;
      upd(1, n + 1, 1);
    }
    idx = i;
    val = 0;
    upd(1, n + 1, 1);
  }
  for (int i = 1; i <= n; ++i) {
    cout << ans[i] << " ";
  }
  return 0;
}
