#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9;
const int maxn = 5e5 + 100;
int a[maxn];
int rk[maxn], who[maxn];
pair<int, int> ori[maxn];
struct BIT {
  int c[maxn];
  void add(int loc, int val) {
    for (int i = loc; i < maxn; i += i & -i) c[i] += val;
  }
  int query(int loc) {
    int res = 0;
    for (int i = loc; i; i -= i & -i) res += c[i];
    return res;
  }
} idal;
struct segment_tree {
  int mx[maxn << 2], ava[maxn << 2], tag[maxn << 2];
  void push_up(int rt) {
    if (ava[(rt << 1)] || ava[(rt << 1 | 1)]) ava[rt] = 1;
    mx[rt] = -inf;
    if (ava[(rt << 1)]) mx[rt] = max(mx[rt], mx[(rt << 1)]);
    if (ava[(rt << 1 | 1)]) mx[rt] = max(mx[rt], mx[(rt << 1 | 1)]);
  }
  void init(int l, int r, int rt) {
    if (l == r) {
      mx[rt] = 0 - abs(a[who[l]]);
      return;
    }
    int mid = (l + r) >> 1;
    init(l, mid, (rt << 1));
    init(mid + 1, r, (rt << 1 | 1));
    push_up(rt);
  }
  void push_down(int rt) {
    if (tag[rt] != 0) {
      tag[(rt << 1)] += tag[rt];
      tag[(rt << 1 | 1)] += tag[rt];
      mx[(rt << 1)] += tag[rt];
      mx[(rt << 1 | 1)] += tag[rt];
      tag[rt] = 0;
    }
  }
  void upd(int l, int r, int rt, int tl, int tr, int val) {
    if (tl <= l && r <= tr) {
      mx[rt] += val;
      tag[rt] += val;
      return;
    }
    push_down(rt);
    int mid = (l + r) >> 1;
    if (tl <= mid) upd(l, mid, (rt << 1), tl, tr, val);
    if (tr >= mid + 1) upd(mid + 1, r, (rt << 1 | 1), tl, tr, val);
    push_up(rt);
  }
  void activate(int l, int r, int rt, int tar) {
    if (l == r) {
      ava[rt] = 1;
      return;
    }
    push_down(rt);
    int mid = (l + r) >> 1;
    if (tar <= mid)
      activate(l, mid, (rt << 1), tar);
    else
      activate(mid + 1, r, (rt << 1 | 1), tar);
    push_up(rt);
  }
  int query(int l, int r, int rt) {
    if (!ava[rt]) return 0;
    if (l == r && mx[rt] >= 0) return l;
    if (l == r && mx[rt] < 0) return 0;
    push_down(rt);
    int mid = (l + r) >> 1;
    if (ava[(rt << 1)] && mx[(rt << 1)] >= 0) return query(l, mid, (rt << 1));
    if (ava[(rt << 1 | 1)] && mx[(rt << 1 | 1)] >= 0)
      return query(mid + 1, r, (rt << 1 | 1));
    return 0;
  }
} t;
bool used[maxn];
int ans = 0;
int lim = 1;
multiset<int> empty, myfill;
multiset<pair<int, int> > down;
multiset<pair<int, int> > al;
int debug = 0;
int main() {
  int n;
  scanf("%d", &n);
  for (int i = (1), iend = (n); i <= iend; i++) {
    scanf("%d", &a[i]);
    ori[i].first = a[i];
    ori[i].second = i;
  }
  sort(ori + 1, ori + 1 + n);
  for (int i = (1), iend = (n); i <= iend; i++)
    who[i] = ori[i].second, rk[ori[i].second] = i;
  t.init(1, n, 1);
  int near0 = inf, near0idx = -1;
  int lastloc = n + 1;
  for (int i = (1), iend = (maxn); i <= iend; i++) empty.insert(i);
  int down_siz = 0;
  for (int i = (1), iend = (n); i <= iend; i++) {
    al.insert(make_pair(a[i], i));
    idal.add(rk[i], 1);
    if (i == 2) {
      int ggg = 1;
    }
    if (a[i] <= 0) {
      down.insert(make_pair(a[i], i));
      if (rk[i] != n) t.upd(1, n, 1, rk[i] + 1, n, 1);
      t.activate(1, n, 1, rk[i]);
      int pp = t.query(1, n, 1);
      int loc = who[t.query(1, n, 1)];
      if (!loc) loc = near0idx;
      while (loc > 0 && down.size() && (*(--down.end())).first >= a[loc]) {
        if (debug)
          cout << "Add " << (*(--down.end())).first << " to fill set" << endl;
        myfill.insert((*(--down.end())).first);
        if (debug)
          cout << "The ans is:" << ans << "   fillsize is:" << myfill.size()
               << endl;
        down.erase(--down.end());
      }
      int newlim;
      if (loc == -1)
        newlim = 1, down_siz = i;
      else {
        down_siz = idal.query(rk[loc]) - 1;
        newlim = -down_siz + 1;
      }
      while (lim > newlim) empty.insert(lim - 1), lim--;
    } else {
      if (a[i] < near0) near0 = a[i], near0idx = i;
      if (debug) cout << "Add " << a[i] << " to fill set" << endl;
      myfill.insert(a[i]);
      if (debug)
        cout << "The ans is:" << ans << "   fillsize is:" << myfill.size()
             << endl;
    }
    if (debug && i == 2)
      cout << "GG!" << ' ' << (*(--myfill.end())) << ' ' << (*empty.begin())
           << endl;
    while (empty.size() && myfill.size() &&
           (*(--myfill.end())) >= (*empty.begin())) {
      if (debug)
        cout << "The ans is:" << ans << "   fillsize is:" << myfill.size()
             << endl;
      int x = (*(--myfill.end()));
      myfill.erase(myfill.find(*(--myfill.end())));
      if (debug)
        cout << "Use " << x << " to delete  " << *(--empty.upper_bound(x))
             << endl;
      empty.erase(--empty.upper_bound(x));
      ans++;
      if (debug)
        cout << "The ans is:" << ans << "   fillsize is:" << myfill.size()
             << endl;
    }
    cout << ans - max(down_siz, 0) << endl;
  }
  return 0;
}
