#include <bits/stdc++.h>
using namespace std;
template <typename T>
T gcd(T a, T b) {
  if (a % b) return gcd(b, a % b);
  return b;
}
template <typename T>
T lcm(T a, T b) {
  return (a * (b / gcd(a, b)));
}
vector<string> tokenizer(string str, char ch) {
  std::istringstream var((str));
  vector<string> v;
  string t;
  while (getline((var), t, (ch))) {
    v.push_back(t);
  }
  return v;
}
struct custom_hash {
  static uint64_t splitmix64(uint64_t x) {
    x += 0x9e3779b97f4a7c15;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
    x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
    return x ^ (x >> 31);
  }
  size_t operator()(uint64_t x) const {
    static const uint64_t FIXED_RANDOM =
        chrono::steady_clock::now().time_since_epoch().count();
    return splitmix64(x + FIXED_RANDOM);
  }
};
void err(istream_iterator<string> it) {}
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cout << *it << " = " << a << "\n";
  err(++it, args...);
}
void file_i_o() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
}
void dfs(long long int cur, vector<long long int> adj[],
         vector<long long int> &dp) {
  if (adj[cur].size() == 0) {
    dp[cur] = 1;
    return;
  }
  for (auto ptr : adj[cur]) {
    dfs(ptr, adj, dp);
    dp[cur] += dp[ptr];
  }
}
int main(int argc, char const *argv[]) {
  clock_t begin = clock();
  file_i_o();
  long long int n;
  cin >> n;
  vector<long long int> adj[n + 1];
  for (int i = 1; i <= n - 1; i++) {
    long long int v;
    cin >> v;
    adj[v].push_back(i + 1);
  }
  vector<long long int> dp(n + 1);
  dfs(1, adj, dp);
  sort(dp.begin(), dp.end());
  int k = 0;
  for (auto x : dp) {
    if (k == 0) {
      k++;
      continue;
    }
    cout << x << " ";
  }
  cout << "\n";
  return 0;
}
