#![allow(unused_imports)]

// language: Rust(1.42.0)
// check available crates on AtCoder at "https://atcoder.jp/contests/language-test-202001"
// My Library Repositry is at "https://github.com/Loptall/sfcpl"

/*
    青perfほしいよ〜！
*/

// from std...
use std::cmp::{
    max, min, Ordering,
    Ordering::{Equal, Greater, Less},
    Reverse,
};
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
use std::convert::TryInto;
use std::fmt;
use std::mem::swap;
use std::num::{NonZeroU32, ParseIntError};
use std::ops::{
    Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
    Index, IndexMut, Mul, MulAssign, Neg, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
    SubAssign,
};
use std::process::exit;
use std::{f32, f64, i128, i16, i32, i64, i8, isize, u128, u16, u32, u64, u8, usize};

// Dep' crates are...
use itertools::*;
use itertools_num::*;
use lazy_static::lazy_static;
use maplit::{btreemap, btreeset, hashmap, hashset};
use num_bigint::{BigInt, BigUint};
use num_complex::Complex;
use num_integer::{binomial, gcd, lcm, multinomial, Integer};
use num_rational::Rational;
use num_traits::{
    clamp, one, pow, zero, Num, NumAssignOps, NumOps, One, Pow, Signed, Unsigned, Zero,
};
use permutohedron::Heap;
use proconio::{
    derive_readable, fastout, input, is_stdin_empty,
    marker::{Bytes, Chars, Isize1, Usize1},
};
use rand::random;

pub trait Visualize {
    fn visualize(&self, split: &str);
    fn continuous(&self) {
        self.visualize("");
    }
    fn spaces(&self) {
        self.visualize(" ");
    }
    fn lines(&self) {
        self.visualize("\n");
    }
}
macro_rules! impl_vis_for_sized {
    ($($t:ty),+) => {
        $(
            impl Visualize for $t {
                fn visualize(&self, _split: &str) {
                    print!("{}", self);
                }
            }
        )+
    };
}
impl_vis_for_sized! {
    usize, u8, u16, u32, u64, u128,
    isize, i8, i16, i32, i64, i128,
    f64, f32,
    String, &str, char
}
impl<T: fmt::Display> Visualize for [T] {
    fn visualize(&self, split: &str) {
        print!("{}", self.iter().join(split));
    }
}
#[macro_export]
macro_rules! vis {
    // end
    () => {
        println!();
    };

    // last element + trailing pattern
    ($last:expr ;) => {
        $last.lines();
        vis!()
    };
    ($last:expr =>) => {
        $last.continuous();
        vis!();
    };
    ($last:expr $(,)?) => {
        $last.spaces();
        vis!();
    };

    // get first element and pass rest
    ($first:expr; $($rest:tt)*) => {
        $first.lines();
        println!();
        vis!($($rest)*);
    };
    ($first:expr => $($rest:tt)*) => {
        $first.continuous();
        vis!($($rest)*);
    };
    ($first:expr, $($rest:tt)*) => {
        $first.spaces();
        print!(" ");
        vis!($($rest)*);
    };
}
pub const MOD10E9_7: usize = 1000000007; // 10 ^ 9 + 7
pub const MOD99_: usize = 998244353;
pub const MAX: usize = std::usize::MAX; // = 2 ^ 64 - 1 = 18446744073709551615 ≈ 1.8 * 10 ^ 19
pub const INF: usize = 2000000000000000000; // MAX / 9 < 2 * 10e18 < MAX / 10
pub const PI: f64 = f64::consts::PI; // 3.141592653589793 -- 10 ^ -15
pub const ASCII_A_LARGE: u8 = 65;
pub const ASCII_A_SMALL: u8 = 97;
pub const ASCII_0: u8 = 48;
pub const ADJ4: &[(isize, isize); 4] = &[(1, 0), (0, 1), (-1, 0), (0, -1)];
pub const ADJ8: &[(isize, isize); 8] = &[
    (1, 0),
    (1, 1),
    (0, 1),
    (-1, 1),
    (-1, 0),
    (-1, -1),
    (0, -1),
    (1, -1),
];

pub type BitSet = Vec<bool>;
/// bitの数を持つ
#[derive(Debug, Copy, Clone)]
pub struct BitSetsGen {
    size: usize,
}
impl BitSetsGen {
    /// サイズを指定してコンストラクト
    pub fn new(n: usize) -> Self {
        Self { size: n }
    }
    /// サイズを返す
    pub fn len(&self) -> usize {
        self.size
    }
    /// 合計で生成される組み合わせの数、`(2 ^ size)`
    pub fn combinations(&self) -> usize {
        1 << self.size
    }
}
impl IntoIterator for BitSetsGen {
    type Item = BitSet;
    type IntoIter = IntoIterBitSet;
    fn into_iter(self) -> Self::IntoIter {
        IntoIterBitSet {
            size: self.len(),
            current: 0,
        }
    }
}
/// BitSetの所有権を奪ったIterator
///(実際にはコピートレイトにより`into_iter()`後もBitSetは有効である)
/// 保持するのはサイズと次に生成する数字だけ
/// Iteratorは長さ`2 ^ size`で、
/// はじめは`[false, false, ..., false, false]`から始まり、
/// `[false, false, ..., false, true]`
/// `[false, false, ..., true, false]`
/// `[false, false, ..., true, true]`のように右詰で続く。
/// 最後は`[true, true, ..., true, true]`である。
#[derive(Copy, Clone, Debug)]
pub struct IntoIterBitSet {
    size: usize,
    current: usize,
}
impl Iterator for IntoIterBitSet {
    type Item = BitSet;
    fn next(&mut self) -> Option<Self::Item> {
        if self.current == (1 << self.size) {
            None
        } else {
            let res = Some(
                (0..self.size)
                    .rev()
                    .map(|x| self.current & (1 << x) != 0)
                    .collect::<Vec<_>>(),
            );
            self.current += 1;
            res
        }
    }
}
pub trait BitsOps {
    fn new(n: usize) -> Self;
    fn count_zeros(&self) -> usize;
    fn count_ones(&self) -> usize;
    fn grow(&mut self, bits: usize);
    fn put(&mut self, bits: usize) -> bool;
    fn toggle(&mut self, bit: usize);
    fn set(&mut self, bit: usize, into: bool);
    fn shl(&mut self, rhs: usize);
    fn shr(&mut self, rhs: usize);
    fn format(&self) -> String;
}
impl BitsOps for BitSet {
    fn new(n: usize) -> Self {
        let mut b = 1;
        let mut res = Vec::new();
        while b <= n {
            res.push(b & n != 0);
            b <<= 1;
        }
        res.reverse();
        res
    }
    fn count_zeros(&self) -> usize {
        self.iter().filter(|x| !**x).count()
    }
    fn count_ones(&self) -> usize {
        self.iter().filter(|x| **x).count()
    }
    fn grow(&mut self, bits: usize) {
        self.reverse();
        self.append(&mut vec![false; bits]);
        self.reverse();
    }
    fn put(&mut self, bits: usize) -> bool {
        let prev = self[bits];
        self[bits] = true;
        prev
    }
    fn toggle(&mut self, bit: usize) {
        self[bit] = !self[bit];
    }
    fn set(&mut self, bit: usize, into: bool) {
        self[bit] = into;
    }
    fn shl(&mut self, rhs: usize) {
        self.append(&mut vec![false; rhs]);
    }
    fn shr(&mut self, rhs: usize) {
        let len = self.len();
        let mut res = vec![false; rhs];
        res.append(&mut self[..len - rhs].to_vec());
        *self = res;
    }
    fn format(&self) -> String {
        self.iter().map(|x| if *x { '1' } else { '0' }).collect()
    }
}

// code...
// #[fastout]
fn main() {
    input! {
        n: usize,
        r: [(i64, i64); n]
    }

    let s = r.iter().sorted_by_key(|x| x.0 + x.1).collect_vec();
    let mut cur = -(INF as i64);

    let mut ans = 0usize;
    for (x, l) in s {
        if x - l >= cur {
            ans += 1;
            cur = x + l;
        }
    }

    vis!(ans);
}


Measured memory_bytes: 6724