#include <bits/stdc++.h>
using namespace std;
int n;
struct xd {
  int x, h, id;
  xd(int _x, int _h, int _id) {
    x = _x;
    h = _h, id = _id;
  }
  bool operator<(const xd& t) const { return x < t.x; }
};
int size;
struct rtree {
  vector<int> vi;
  rtree(int _size, int dz = -1) {
    size = _size;
    if (size & (size - 1)) size <<= 1;
    while (size & (size - 1)) size -= size & -size;
    vi = vector<int>(size << 1, dz);
  }
  void update(int idx, int value) {
    idx += size;
    vi[idx] = value;
    for (idx = idx / 2; idx; idx /= 2) {
      vi[idx] = max(vi[2 * idx], vi[2 * idx + 1]);
    }
  }
  int query(int rs, int re, int s = 0, int e = size - 1, int idx = 1) {
    if (re < s || e < rs) return -1;
    if (rs <= s && e <= re) return vi[idx];
    int d1 = query(rs, re, s, (s + e) / 2, 2 * idx);
    int d2 = query(rs, re, (s + e) / 2 + 1, e, 2 * idx + 1);
    return max(d1, d2);
  }
};
vector<xd> vi;
int res[100007];
int xbsearch(int s, int e, int v) {
  int r = n;
  while (s <= e) {
    int m = (s + e) / 2;
    if (vi[m].x >= v) {
      r = min(r, m);
      e = m - 1;
    } else
      s = m + 1;
  }
  return r;
}
int zbsearch(int s, int e, int v) {
  int r = -1;
  while (s <= e) {
    int m = (s + e) / 2;
    if (vi[m].x < v) {
      r = max(r, m);
      s = m + 1;
    } else
      e = m - 1;
  }
  return r;
}
int main() {
  cin >> n;
  for (int i = 0; i < n; ++i) {
    int x, h;
    cin >> x >> h;
    vi.push_back(xd(x, h, i));
  }
  rtree rx = rtree(n);
  sort(vi.begin(), vi.end());
  for (int i = n - 1; i >= 0; --i) {
    int x = vi[i].x;
    res[vi[i].id] = 1;
    int sx = xbsearch(i + 1, n - 1, x + 1);
    int ex = zbsearch(i + 1, n - 1, x + vi[i].h);
    if (sx <= ex) {
      int lx = rx.query(sx, ex);
      rx.update(i, lx);
      res[vi[i].id] += lx - i;
    } else {
      rx.update(i, i);
    }
  }
  for (int i = 0; i < n; ++i) cout << res[i] << endl;
  return 0;
}
