#include <bits/stdc++.h>
using namespace std;
template <typename T, typename S>
inline bool REMIN(T &a, const S &b) {
  return a > b ? a = b, 1 : 0;
}
template <typename T, typename S>
inline bool REMAX(T &a, const S &b) {
  return a < b ? a = b, 1 : 0;
}
int toint(const string &s) {
  stringstream ss;
  ss << s;
  int x;
  ss >> x;
  return x;
}
string tostring(int number) {
  stringstream ss;
  ss << number;
  return ss.str();
}
int bit(long long x, int pos) { return ((1ll << pos) & x) ? 1 : 0; }
const int INF = 1e9;
const int NMAX = 1e5 + 5;
const long long MOD = 1000000007;
const long double PI = 2 * acos(0);
long long power(long long base, long long exp, long long c = MOD) {
  if (!exp) return 1;
  long long r = power(base, exp / 2, c);
  r = (r * r) % c;
  if (exp & 1) r = (r * base) % c;
  return r;
}
int T, N, M;
int a, b, c;
string s1, s2;
void nope(int dec = 0) {
  if (!dec) cout << "NO";
  exit(0);
}
struct Node {
  int L, R, V;
  Node() : L(-1), R(-1), V(0) {}
};
vector<Node> tree;
int root[NMAX];
int last[NMAX];
int ar[NMAX];
int build(int l, int r) {
  int v = ((int)(tree.size()));
  tree.push_back(Node());
  if (l != r) {
    int m = (l + r) >> 1;
    a = build(l, m);
    tree[v].L = a;
    a = build(m + 1, r);
    tree[v].R = a;
  }
  return v;
}
int addNode(int id, int l, int r, int u, int del) {
  if (u < l || u > r) return id;
  int v = ((int)(tree.size()));
  tree.push_back(tree[id]);
  tree[v].V += del;
  if (l != r) {
    int m = (l + r) >> 1;
    a = addNode(tree[id].L, l, m, u, del);
    tree[v].L = a;
    a = addNode(tree[id].R, m + 1, r, u, del);
    tree[v].R = a;
  }
  return v;
}
int nextNode(int id, int l, int r, int k) {
  if (k > tree[id].V) return r;
  if (l == r) {
    if (k < tree[id].V) return l - 1;
    return l;
  }
  int m = (l + r) >> 1;
  if (k < tree[tree[id].L].V) {
    return nextNode(tree[id].L, l, m, k);
  } else {
    return nextNode(tree[id].R, m + 1, r, k - tree[tree[id].L].V);
  }
}
int solve(int k) {
  int curr = 1;
  int cn = 0;
  while (curr <= N) {
    cn++;
    curr = nextNode(root[curr], 1, N, k) + 1;
  }
  return cn;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> N;
  for (int(i) = int(1); (i) <= int(N); ++(i)) cin >> ar[i];
  memset(last, -1, sizeof(last));
  root[N + 1] = build(1, N);
  for (int(i) = int(N); (i) >= int(1); --(i)) {
    int temp = root[i + 1];
    if (last[ar[i]] != -1) {
      temp = addNode(temp, 1, N, last[ar[i]], -1);
    }
    root[i] = addNode(temp, 1, N, i, 1);
    last[ar[i]] = i;
  }
  for (int(i) = int(1); (i) <= int(N); ++(i)) {
    cout << solve(i) << ' ';
  }
  return 0;
}
