#include <bits/stdc++.h>
const int MAXN = 1e6 + 17;
const int INF = 1000000000;
using namespace std;
int n, m;
int a[MAXN];
struct node {
  int sum, lazy;
  node() {
    sum = 0;
    lazy = -1;
  }
  node(int val) {
    sum = val;
    lazy = -1;
  }
};
node temp, broken;
node merge(node l, node r) {
  temp.sum = l.sum + r.sum;
  temp.lazy = -1;
  return temp;
}
struct segment_tree {
  node tr[3 * MAXN];
  void push(int l, int r, int idx) {
    if (tr[idx].lazy != -1) {
      tr[idx].sum = (r - l + 1) * tr[idx].lazy;
      if (l != r) {
        tr[2 * idx + 1].lazy = tr[idx].lazy;
        tr[2 * idx + 2].lazy = tr[idx].lazy;
      }
      tr[idx].lazy = -1;
    }
  }
  void init(int l, int r, int idx) {
    if (l == r) {
      tr[idx] = node(a[l]);
      return;
    }
    int mid = (l + r) >> 1;
    init(l, mid, 2 * idx + 1);
    init(mid + 1, r, 2 * idx + 2);
    tr[idx] = merge(tr[2 * idx + 1], tr[2 * idx + 2]);
  }
  void update(int qL, int qR, int val, int l, int r, int idx) {
    push(l, r, idx);
    if (qL > r || l > qR) return;
    if (qL <= l && r <= qR) {
      tr[idx].lazy = val;
      push(l, r, idx);
      return;
    }
    int mid = (l + r) >> 1;
    update(qL, qR, val, l, mid, 2 * idx + 1);
    update(qL, qR, val, mid + 1, r, 2 * idx + 2);
    tr[idx] = merge(tr[2 * idx + 1], tr[2 * idx + 2]);
  }
  node query(int qL, int qR, int l, int r, int idx) {
    push(l, r, idx);
    if (l > qR || r < qL) return broken;
    if (qL <= l && r <= qR) return tr[idx];
    int mid = (l + r) >> 1;
    return merge(query(qL, qR, l, mid, 2 * idx + 1),
                 query(qL, qR, mid + 1, r, 2 * idx + 2));
  }
};
segment_tree t;
void mainp() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cin >> n;
  for (int i = 0; i < MAXN; i++) a[i] = 1;
  t.init(0, n, 0);
  for (int i = 0; i < n; i++) {
    int el;
    cin >> el;
    int bord = i - el;
    bord = max(bord, 0);
    t.update(bord, i - 1, 0, 0, n, 0);
  }
  cout << t.query(0, n - 1, 0, n, 0).sum << endl;
}
int main() {
  mainp();
  return 0;
}
