// ./an-animal-contest-1-p6-alpaca-distancing.yml #include "bits/stdc++.h" using namespace std; using ll = long long; const ll INF = 0x3f3f3f3f, LLINF = 0x3f3f3f3f3f3f3f3f; using T = tuple<int, bool, int>; // pos, is_query, idx // template is 1-indexed template <typename T> struct Ranks { vector<T> ranks; void init() { sort(ranks.begin(), ranks.end()); ranks.resize(unique(ranks.begin(), ranks.end()) - ranks.begin()); } template <typename It> void init(It st, It en) { ranks = vector<T>(st, en); init(); } void add(T v) { ranks.push_back(v); } int get(T v) { return lower_bound(ranks.begin(), ranks.end(), v) - ranks.begin() + 1; } int size() { return ranks.size(); } }; // Template is 1-indexed (by default). Can be made 0-indexed by modifying Comp // Default: Point increment and prefix sum query struct Comp { using Data = int; const Data vdef = 0; void applyUpdate(Data &to, Data &v) { to = max(to, v); } int transformInd(int idx, int N) { return idx; } }; template <typename Comp> struct BIT { using Data = typename Comp::Data; Comp C; int N; vector<Data> bit; void init(int n0) { N = n0; bit.assign(N + 1, C.vdef); } void update(int x, Data v) { x = C.transformInd(x, N); for (; x <= N; x += x & -x) C.applyUpdate(bit[x], v); } Data query(int x) { x = C.transformInd(x, N); Data res = C.vdef; for (; x; x -= x & -x) C.applyUpdate(res, bit[x]); return res; } }; const int MN = 1e5 + 1; int N, dp[MN], B[MN], A[MN]; Ranks<int> r; BIT<Comp> bit; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> N; vector<T> evt; for (auto i = 0; i < N; i++) { int a, b; cin >> a >> b; evt.emplace_back(a, true, i); evt.emplace_back(a+b, false, i); B[i] = b; A[i] = a; r.add(a); r.add(a-b); } A[N] = -INF; r.init(); bit.init(r.size()); sort(evt.begin(), evt.end()); int ans = 0; deque<int> dq{N}; for (auto [p, is_q, idx] : evt) { if (is_q) { dp[idx] = bit.query(r.get(A[idx]-B[idx])) + 1; ans = max(ans, dp[idx]); } else bit.update(r.get(A[idx]), dp[idx]); } cout << ans << '\n'; return 0; }