#include <bits/stdc++.h>
using namespace std;
const long long dx[4] = {-1, 0, 1, 0};
const long long dy[4] = {0, -1, 0, 1};
const long long dxx[] = {1, 1, 0, -1, -1, -1, 0, 1};
const long long dyy[] = {0, 1, 1, 1, 0, -1, -1, -1};
void err(istream_iterator<string> it) {}
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cerr << *it << " = " << a << "\n";
  err(++it, args...);
}
long long gcd(long long a, long long b) {
  if (!b) return a;
  return gcd(b, a % b);
}
long long lcm(long long a, long long b) { return (a * b) / gcd(a, b); }
long long modexpo(long long x, long long n, long long M) {
  if (n == 0)
    return 1;
  else if (n % 2 == 0)
    return modexpo((x * x) % M, n / 2, M);
  else
    return (x * modexpo((x * x) % M, (n - 1) / 2, M)) % M;
}
long long bexpo(long long x, long long n) {
  if (n == 0)
    return 1;
  else if (n % 2 == 0)
    return bexpo(x * x, n / 2);
  else
    return x * bexpo(x * x, (n - 1) / 2);
}
bool isPrime(long long n) {
  if (n <= 1) return false;
  if (n <= 3) return true;
  if (n % 2 == 0 || n % 3 == 0) return false;
  for (long long i = 5; i * i <= n; i = i + 6)
    if (n % i == 0 || n % (i + 2) == 0) return false;
  return true;
}
const long long mod = 1e9 + 7;
const long long N = 4e5 + 5;
const long long INF = 1e18;
void solve() {
  long long n;
  cin >> n;
  ;
  vector<long long> a(n);
  for (auto &i : a) cin >> i;
  ;
  sort(a.begin(), a.end());
  long long count = 0, pile = 0;
  bool check[n];
  memset(check, false, sizeof(check));
  while (count < n) {
    long long last = 0;
    pile++;
    for (long long i = 0; i < a.size(); i++) {
      if (!check[i] && last <= a[i]) {
        check[i] = true;
        last++;
        count++;
      }
    }
  }
  cout << pile << "\n";
  ;
}
int32_t main() {
  long long t;
  t = 1;
  while (t--) {
    solve();
  }
}
