#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <sstream>
#include <cmath>
#include <set>
#include <iomanip>
using namespace std;

#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REMOVE(Itr,n) (Itr).erase(remove((Itr).begin(),(Itr).end(),n),(Itr).end())
#define RREP(i,n) for(int (i)=(int)(n)-1;i>=0;i--)
typedef long long ll;

template<class T> struct SparseTableMin {

   int N;
   vector<T> val;
   vector<int> log_table;
   vector< vector<int> > table;

   SparseTableMin (vector<T> &A) : N(A.size()), log_table(A.size()+1,0) ,val(A) {
    for (int i = 2; i <= N; i++) log_table[i] = log_table[i>>1] + 1;
    table.resize(log_table[N]+1, vector<int>(N));
    for (int i = 0; i < N; i++) table[0][i] = i;
    for (int k = 0; k < log_table[N] - 1; k++) {
      for (int i = 0; i + (1 << k) < N; i++) {
        int l = table[k][i];
        int r = table[k][i+(1<<k)];
        table[k+1][i] = (val[l] <= val[r]) ? l : r;
      }
    }
   }

   int get_min_index(int l, int r) {
    int k = log_table[r-l];
    int idxl = table[k][l];
    int idxr = table[k][r-(1<<k)];
    return val[idxl] <= val[idxr] ? idxl : idxr;
   }

};

template<class T> struct SparseTableMax {

   int N;
   vector<T> val;
   vector<int> log_table;
   vector< vector<int> > table;

   SparseTableMax (vector<T> &A) : N(A.size()), log_table(A.size()+1,0) ,val(A) {
    for (int i = 2; i <= N; i++) log_table[i] = log_table[i>>1] + 1;
    table.resize(log_table[N]+1, vector<int>(N));
    for (int i = 0; i < N; i++) table[0][i] = i;
    for (int k = 0; k < log_table[N] - 1; k++) {
      for (int i = 0; i + (1 << k) < N; i++) {
        int l = table[k][i];
        int r = table[k][i+(1<<k)];
        table[k+1][i] = (val[l] >= val[r]) ? l : r;
      }
    }
   }

   int get_max_index(int l, int r) {
    int k = log_table[r-l];
    int idxl = table[k][l];
    int idxr = table[k][r-(1<<k)];
    return val[idxl] >= val[idxr] ? idxl : idxr;
   }

};

int main() {

  int N; cin >> N;
  vector<ll> a(N),b(N);
  REP(i,N) cin >> a[i];
  REP(i,N) cin >> b[i];

  SparseTableMax<ll> A(a);
  SparseTableMin<ll> B(b);

  ll ans = 0;
  REP(i,N) {
    int l1 = i, r1 = N + 1;
    while(r1 - l1 > 1) {
      int mid = (l1 + r1) / 2;
      int v1 = A.get_max_index(i,mid);
      int v2 = B.get_min_index(i,mid);
      if(a[v1] < b[v2]) l1 = mid;
      else r1 = mid;
    }
    int l2 = i, r2 = N + 1;
    while(r2 - l2 > 1) {
      int mid = (l2 + r2) / 2;
      int v1 = A.get_max_index(i,mid);
      int v2 = B.get_min_index(i,mid);
      if(a[v1] <= b[v2]) l2 = mid;
      else r2 = mid;
    }
    ans += l2 - l1;
  }

  cout << ans << endl;

  return 0;
}


#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <sstream>
#include <cmath>
#include <set>
#include <iomanip>
using namespace std;

#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REMOVE(Itr,n) (Itr).erase(remove((Itr).begin(),(Itr).end(),n),(Itr).end())
#define RREP(i,n) for(int (i)=(int)(n)-1;i>=0;i--)
typedef long long ll;

template<class T> struct SparseTableMin {
   int N;
   vector<int> log_table;
   vector<T> val;
   vector< vector<int> > table;
   SparseTableMin (vector<T> &A) : N(A.size()), log_table(A.size()+1,0) ,val(A) {
    for (int i = 2; i <= N; i++) log_table[i] = log_table[i>>1] + 1;
    table.resize(log_table[N]+1, vector<int>(N));
    for (int i = 0; i < N; i++) table[0][i] = i;
    for (int k = 0; k < log_table[N]; k++) {
      for (int i = 0; i + (1 << k) < N; i++) {
        int l = table[k][i];
        int r = table[k][i+(1<<k)];
        table[k+1][i] = (A[l] < A[r]) ? l : r;
      }
    }
   }
   int get_min_index(int l, int r) {
    int k = log_table[r-l+1];
    int idxl = table[k][l];
    int idxr = table[k][r-(1<<k)];
    if (val[idxl] < val[idxr]) return idxl;
    return idxr;
   }
};

template<class T> struct SparseTableMax {
   int N;
   vector<int> log_table;
   vector<T> val;
   vector< vector<int> > table;
   SparseTableMax (vector<T> &A) : N(A.size()), log_table(A.size()+1,0) ,val(A) {
    for (int i = 2; i <= N; i++) log_table[i] = log_table[i>>1] + 1;
    table.resize(log_table[N]+1, vector<int>(N));
    val.assign(A.begin(),A.end());
    for (int i = 0; i < N; i++) table[0][i] = i;
    for (int k = 0; k < log_table[N]; k++) {
      for (int i = 0; i + (1 << k) < N; i++) {
        int l = table[k][i];
        int r = table[k][i+(1<<k)];
        table[k+1][i] = (A[l] > A[r]) ? l : r;
      }
    }
   }
   int get_max_index(int l, int r) {
    int k = log_table[r-l];
    int idxl = table[k][l];
    int idxr = table[k][r-(1<<k)];
    if (val[idxl] > val[idxr]) return idxl;
    return idxr;
   }
};

int main() {

  int N; cin >> N;
  vector<ll> a(N),b(N);
  REP(i,N) cin >> a[i];
  REP(i,N) cin >> b[i];

  SparseTableMax<ll> A(a);
  SparseTableMin<ll> B(b);

  ll ans = 0;
  REP(i,N) {
    int l1 = i, r1 = N;
    while(r1 - l1 > 1) {
      int mid = (l1 + r1) / 2;
      int v1 = A.get_max_index(i,mid);
      int v2 = B.get_min_index(i,mid);
      if(a[v1] > b[v2]) l1 = mid;
      else r1 = mid;
    }
    int l2 = i, r2 = N;
    while(r2 - l2 > 1) {
      int mid = (l2 + r2) / 2;
      int v1 = A.get_max_index(i,mid);
      int v2 = B.get_min_index(i,mid);
      if(a[v1] >= b[v2]) l2 = mid;
      else r2 = mid;
    }
    if(l1 == l2) {
      if(a[l1] == b[l2]) ans++;
    } else ans += l2 - l1 + 1;
  }

  cout << ans << endl;

  return 0;
}


#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <sstream>
#include <cmath>
#include <set>
#include <iomanip>
using namespace std;

#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REMOVE(Itr,n) (Itr).erase(remove((Itr).begin(),(Itr).end(),n),(Itr).end())
#define RREP(i,n) for(int (i)=(int)(n)-1;i>=0;i--)
typedef long long ll;

template<class T> struct SparseTableMin {
   int N;
   vector<int> log_table;
   vector<T> val;
   vector< vector<int> > table;
   SparseTableMin (vector<T> &A) : N(A.size()), log_table(A.size()+1,0) ,val(A) {
    for (int i = 2; i <= N; i++) log_table[i] = log_table[i>>1] + 1;
    table.resize(log_table[N]+1, vector<int>(N));
    for (int i = 0; i < N; i++) table[0][i] = i;
    for (int k = 1; (1<<k) <= N; k++) {
      for (int i = 0; i + (1 << k) <= N; i++) {
        int l = table[k-1][i];
        int r = table[k-1][i+(1<<(k-1))];
        table[k][i] = (val[l] < val[r]) ? l : r;
      }
    }
   }
   int get_min_index(int l, int r) {
    int k = log_table[r-l+1];
    int idxl = table[k][l];
    int idxr = table[k][r+1-(1<<k)];
    if (val[idxl] < val[idxr]) return idxl;
    return idxr;
   }
};

template<class T> struct SparseTableMax {
   int N;
   vector<int> log_table;
   vector<T> val;
   vector< vector<int> > table;
   SparseTableMax (vector<T> &A) : N(A.size()), log_table(A.size()+1,0) ,val(A) {
    for (int i = 2; i <= N; i++) log_table[i] = log_table[i>>1] + 1;
    table.resize(log_table[N]+1, vector<int>(N));
    for (int i = 0; i < N; i++) table[0][i] = i;
    for (int k = 1; (1<<k) <= N; k++) {
      for (int i = 0; i + (1 << k) <= N; i++) {
        int l = table[k-1][i];
        int r = table[k-1][i+(1<<(k-1))];
        table[k][i] = (val[l] > val[r]) ? l : r;
      }
    }
   }
   int get_max_index(int l, int r) {
    int k = log_table[r-l+1];
    int idxl = table[k][l];
    int idxr = table[k][r+1-(1<<k)];
    if (val[idxl] > val[idxr]) return idxl;
    return idxr;
   }
};

int main() {

  int N; cin >> N;
  vector<ll> a(N),b(N);
  REP(i,N) cin >> a[i];
  REP(i,N) cin >> b[i];

  SparseTableMax<ll> A(a);
  SparseTableMin<ll> B(b);

  ll ans = 0;
  REP(i,N) {
    int l1 = i, r1 = N;
    while(r1 - l1 > 1) {
      int mid = (l1 + r1) / 2;
      int v1 = A.get_max_index(i,mid);
      int v2 = B.get_min_index(i,mid);
      if(a[v1] > b[v2]) l1 = mid;
      else r1 = mid;
    }
    int l2 = i, r2 = N;
    while(r2 - l2 > 1) {
      int mid = (l2 + r2) / 2;
      int v1 = A.get_max_index(i,mid);
      int v2 = B.get_min_index(i,mid);
      if(a[v1] >= b[v2]) l2 = mid;
      else r2 = mid;
    }
    ans += l2 - l1;
    if(l2 == l1 && a[l1] == b[l2]) ans++;
  }

  cout << ans << endl;

  return 0;
}


#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <sstream>
#include <cmath>
#include <set>
#include <iomanip>
using namespace std;

#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REMOVE(Itr,n) (Itr).erase(remove((Itr).begin(),(Itr).end(),n),(Itr).end())
#define RREP(i,n) for(int (i)=(int)(n)-1;i>=0;i--)
typedef long long ll;

template<class T> struct SparseTableMin {

   int N;
   vector<T> val;
   vector<int> log_table;
   vector< vector<int> > table;

   SparseTableMin (vector<T> &A) : N(A.size()), log_table(A.size()+1,0) ,val(A) {
    for (int i = 2; i <= N; i++) log_table[i] = log_table[i>>1] + 1;
    table.resize(log_table[N]+1, vector<int>(N));
    for (int i = 0; i < N; i++) table[0][i] = i;
    for (int k = 0; k < log_table[N]; k++) {
      for (int i = 0; i + (1 << k) < N; i++) {
        int l = table[k][i];
        int r = table[k][i+(1<<k)];
        table[k+1][i] = (val[l] <= val[r]) ? l : r;
      }
    }
   }

   int get_min_index(int l, int r) {
    int k = log_table[r-l];
    int idxl = table[k][l];
    int idxr = table[k][r-(1<<k)];
    return val[idxl] <= val[idxr] ? idxl : idxr;
   }

};

template<class T> struct SparseTableMax {

   int N;
   vector<T> val;
   vector<int> log_table;
   vector< vector<int> > table;

   SparseTableMax (vector<T> &A) : N(A.size()), log_table(A.size()+1,0) ,val(A) {
    for (int i = 2; i <= N; i++) log_table[i] = log_table[i>>1] + 1;
    table.resize(log_table[N]+1, vector<int>(N));
    for (int i = 0; i < N; i++) table[0][i] = i;
    for (int k = 0; k < log_table[N]; k++) {
      for (int i = 0; i + (1 << k) < N; i++) {
        int l = table[k][i];
        int r = table[k][i+(1<<k)];
        table[k+1][i] = (val[l] >= val[r]) ? l : r;
      }
    }
   }

   int get_max_index(int l, int r) {
    int k = log_table[r-l];
    int idxl = table[k][l];
    int idxr = table[k][r-(1<<k)];
    return val[idxl] >= val[idxr] ? idxl : idxr;
   }

};

int main() {

  int N; cin >> N;
  vector<ll> a(N),b(N);
  REP(i,N) cin >> a[i];
  REP(i,N) cin >> b[i];

  SparseTableMax<ll> A(a);
  SparseTableMin<ll> B(b);

  ll ans = 0;
  REP(i,N) {
    int l1 = i, r1 = N + 1;
    while(r1 - l1 > 1) {
      int mid = (l1 + r1) / 2;
      int v1 = A.get_max_index(i,mid);
      int v2 = B.get_min_index(i,mid);
      if(a[v1] < b[v2]) l1 = mid;
      else r1 = mid;
    }
    int l2 = i, r2 = N + 1;
    while(r2 - l2 > 1) {
      int mid = (l2 + r2) / 2;
      int v1 = A.get_max_index(i,mid);
      int v2 = B.get_min_index(i,mid);
      if(a[v1] <= b[v2]) l2 = mid;
      else r2 = mid;
    }
    ans += l2 - l1;
  }

  cout << ans << endl;

  return 0;
}


#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <sstream>
#include <cmath>
#include <set>
#include <iomanip>
using namespace std;

#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REMOVE(Itr,n) (Itr).erase(remove((Itr).begin(),(Itr).end(),n),(Itr).end())
#define RREP(i,n) for(int (i)=(int)(n)-1;i>=0;i--)
typedef long long ll;

template<class T> struct SparseTableMin {
   int N;
   vector<int> log_table;
   vector<T> val;
   vector< vector<int> > table;
   SparseTableMin (vector<T> &A) : N(A.size()), log_table(A.size()+1,0) ,val(A) {
    for (int i = 2; i <= N; i++) log_table[i] = log_table[i>>1] + 1;
    table.resize(log_table[N]+1, vector<int>(N));
    for (int i = 0; i < N; i++) table[0][i] = i;
    for (int k = 0; k < log_table[N]; k++) {
      for (int i = 0; i + (1 << k) <= N; i++) {
        int l = table[k][i];
        int r = table[k][i+(1<<k)];
        table[k+1][i] = (A[l] < A[r]) ? l : r;
      }
    }
   }
   int get_min_index(int l, int r) {
    int k = log_table[r-l+1];
    int idxl = table[k][l];
    int idxr = table[k][r-(1<<k)];
    if (val[idxl] < val[idxr]) return idxl;
    return idxr;
   }
};

template<class T> struct SparseTableMax {
   int N;
   vector<int> log_table;
   vector<T> val;
   vector< vector<int> > table;
   SparseTableMax (vector<T> &A) : N(A.size()), log_table(A.size()+1,0) ,val(A) {
    for (int i = 2; i <= N; i++) log_table[i] = log_table[i>>1] + 1;
    table.resize(log_table[N]+1, vector<int>(N));
    for (int i = 0; i < N; i++) table[0][i] = i;
    for (int k = 0; k < log_table[N]; k++) {
      for (int i = 0; i + (1 << k) <= N; i++) {
        int l = table[k][i];
        int r = table[k][i+(1<<k)];
        table[k+1][i] = (A[l] > A[r]) ? l : r;
      }
    }
   }
   int get_max_index(int l, int r) {
    int k = log_table[r-l];
    int idxl = table[k][l];
    int idxr = table[k][r-(1<<k)];
    if (val[idxl] > val[idxr]) return idxl;
    return idxr;
   }
};

int main() {

  int N; cin >> N;
  vector<ll> a(N),b(N);
  REP(i,N) cin >> a[i];
  REP(i,N) cin >> b[i];

  SparseTableMax<ll> A(a);
  SparseTableMin<ll> B(b);

  ll ans = 0;
  REP(i,N) {
    int l1 = i, r1 = N;
    while(r1 - l1 > 1) {
      int mid = (l1 + r1) / 2;
      int v1 = A.get_max_index(i,mid);
      int v2 = B.get_min_index(i,mid);
      if(a[v1] > b[v2]) l1 = mid;
      else r1 = mid;
    }
    int l2 = i, r2 = N;
    while(r2 - l2 > 1) {
      int mid = (l2 + r2) / 2;
      int v1 = A.get_max_index(i,mid);
      int v2 = B.get_min_index(i,mid);
      if(a[v1] >= b[v2]) l2 = mid;
      else r2 = mid;
    }
    if(l1 == l2) {
      if(a[l1] == b[l2]) ans++;
    } else ans += l2 - l1 + 1;
  }

  cout << ans << endl;

  return 0;
}


#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <sstream>
#include <cmath>
#include <set>
#include <iomanip>
#include <deque>
#include <stdio.h>
#include <fstream>
using namespace std;

#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define RREP(i,n) for(int (i)=(int)(n)-1;i>=0;i--)
#define FILL(Itr,n) fill((Itr).begin(),(Itr).end(),n)
#define REMOVE(Itr,n) (Itr).erase(remove((Itr).begin(),(Itr).end(),n),(Itr).end())
#define UNIQUE(Itr) sort((Itr).begin(),(Itr).end()); (Itr).erase(unique((Itr).begin(),(Itr).end()),(Itr).end())
#define LBOUND(Itr,val) lower_bound((Itr).begin(),(Itr).end(),(val))
#define UBOUND(Itr,val) upper_bound((Itr).begin(),(Itr).end(),(val))
#define MOD 1000000007
typedef long long ll;
typedef pair<int,int> P;

template <class T> class SegmentTree {
private:
    vector<T> segtree_min;
    vector<T> segtree_max;
    const int N = 1<<19;
    const T limit_max = 1e9;
    const T limit_min = -1e9;
public:
    SegmentTree(){
        segtree_max = *new vector<T>(N*2,limit_min);
        segtree_min = *new vector<T>(N*2,limit_max);
    }
    void update(int idx, T val){
        idx += N-1;
        segtree_max[idx] = segtree_min[idx] = val;
        while(idx){
            idx = (idx-1)/2;
            segtree_max[idx] = max(segtree_max[idx*2+1],segtree_max[idx*2+2]);
            segtree_min[idx] = min(segtree_min[idx*2+1],segtree_min[idx*2+2]);
        }
    }
    T getmax(int a, int b) { return query_max(a,b,0,0,N); }
    T getmin(int a, int b) { return query_min(a,b,0,0,N); }
    T query_max(int a,int b,int k,int l,int r){
        if(r <= a || b <= l) return limit_min;
        if(a <= l && r <= b) return segtree_max[k];
        T vl = query_max(a,b,k*2+1,l,(l+r)/2);
        T vr = query_max(a,b,k*2+2,(l+r)/2,r);
        return max(vl,vr);
    }
    T query_min(int a,int b,int k,int l,int r){
        if(r <= a || b <= l) return limit_max;
        if(a <= l && r <= b) return segtree_min[k];
        T vl = query_min(a,b,k*2+1,l,(l+r)/2);
        T vr = query_min(a,b,k*2+2,(l+r)/2,r);
        return min(vl,vr);
    }
};

SegmentTree<int> a,b;
int aa[200010],bb[200010];

bool judge1(int x, int s){
    int va = a.getmax(s,x+1);
    int vb = b.getmin(s,x+1);
    if(va==vb)return true;
    return false;
}

int BinarySearchHighest(int low, int high){
    int start = low;
    while(high-low>1){
        int mid=(low+high)/2;
        if(judge1(mid,start))low = mid;
        else high = mid;
    }
    return low;
}

bool judge2(int x, int s){
    int va = a.getmax(x+1,s);
    int vb = b.getmin(x+1,s);
    if(va==vb)return true;
    return false;
}

int BinarySearchLowest(int low, int high){
    int start = high+1;
    while(high-low>1){
        int mid=(low+high)/2;
        if(judge2(mid,start))high = mid;
        else low = mid;
    }
    return high;
}

int main(){

    int n; cin>>n;
    REP(i,n)cin>>aa[i];
    REP(i,n)cin>>bb[i];

    REP(i,n){
        a.update(i,aa[i]);
        b.update(i,bb[i]);
    }

    ll ans = 0;
    REP(i,n){
        if(a.getmax(i,i+1)<=b.getmax(i,i+1)){
            int L = BinarySearchLowest(-1,i);
            int R = BinarySearchHighest(i,n);
            ans += L + R - 2*i + 1;
            //cout<<i<<" "<<L<<" "<<R<<endl;
        }
    }

    cout<<ans<<endl;

    return 0;
}


#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <sstream>
#include <cmath>
#include <set>
#include <iomanip>
#include <deque>
#include <stdio.h>
#include <fstream>
using namespace std;

#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define RREP(i,n) for(int (i)=(int)(n)-1;i>=0;i--)
#define FILL(Itr,n) fill((Itr).begin(),(Itr).end(),n)
#define REMOVE(Itr,n) (Itr).erase(remove((Itr).begin(),(Itr).end(),n),(Itr).end())
#define UNIQUE(Itr) sort((Itr).begin(),(Itr).end()); (Itr).erase(unique((Itr).begin(),(Itr).end()),(Itr).end())
#define LBOUND(Itr,val) lower_bound((Itr).begin(),(Itr).end(),(val))
#define UBOUND(Itr,val) upper_bound((Itr).begin(),(Itr).end(),(val))
#define MOD 1000000007
typedef long long ll;
typedef pair<int,int> P;

template <class T> class SegmentTree {
private:
    vector<T> segtree_min;
    vector<T> segtree_max;
    const int N = 1<<19;
    const T limit_max = 1e9;
    const T limit_min = -1e9;
public:
    SegmentTree(){
        segtree_max = *new vector<T>(N*2,limit_min);
        segtree_min = *new vector<T>(N*2,limit_max);
    }
    void update(int idx, T val){
        idx += N-1;
        segtree_max[idx] = segtree_min[idx] = val;
        while(idx){
            idx = (idx-1)/2;
            segtree_max[idx] = max(segtree_max[idx*2+1],segtree_max[idx*2+2]);
            segtree_min[idx] = min(segtree_min[idx*2+1],segtree_min[idx*2+2]);
        }
    }
    T getmax(int a, int b) { return query_max(a,b,0,0,N); }
    T getmin(int a, int b) { return query_min(a,b,0,0,N); }
    T query_max(int a,int b,int k,int l,int r){
        if(r <= a || b <= l) return limit_min;
        if(a <= l && r <= b) return segtree_max[k];
        T vl = query_max(a,b,k*2+1,l,(l+r)/2);
        T vr = query_max(a,b,k*2+2,(l+r)/2,r);
        return max(vl,vr);
    }
    T query_min(int a,int b,int k,int l,int r){
        if(r <= a || b <= l) return limit_max;
        if(a <= l && r <= b) return segtree_min[k];
        T vl = query_min(a,b,k*2+1,l,(l+r)/2);
        T vr = query_min(a,b,k*2+2,(l+r)/2,r);
        return min(vl,vr);
    }
};

SegmentTree<int> a,b;
int aa[200010],bb[200010];

bool judge1(int x, int s){
    int va = a.getmax(s,x+1);
    int vb = b.getmin(s,x+1);
    if(va==vb)return true;
    return false;
}

int BinarySearchHighest(int low, int high){
    int start = low;
    while(high-low>1){
        int mid=(low+high)/2;
        if(judge1(mid,start))low = mid;
        else high = mid;
    }
    return low;
}

bool judge2(int x, int s){
    int va = a.getmax(x+1,s);
    int vb = b.getmin(x+1,s);
    if(va==vb)return true;
    return false;
}

int BinarySearchLowest(int low, int high){
    int start = high;
    while(high-low>1){
        int mid=(low+high)/2;
        if(judge2(mid,start))high = mid;
        else low = mid;
    }
    return high;
}

int main(){

    int n; cin>>n;
    REP(i,n)cin>>aa[i];
    REP(i,n)cin>>bb[i];

    REP(i,n){
        a.update(i,aa[i]);
        b.update(i,bb[i]);
    }

    ll ans = 0;
    REP(i,n){
        if(a.getmax(i,i+1)==b.getmax(i,i+1)){
            int L = BinarySearchLowest(-1,i);
            int R = BinarySearchHighest(i,n);
            ans += L + R - 2*i + 1;
            //cout<<i<<" "<<L<<" "<<R<<endl;
        }
    }

    cout<<ans<<endl;

    return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <vector>
#include <utility>
#include <string>
#include <limits>

#include<stdlib.h>
#include <iostream>     // std::cout
#include <algorithm>    // std::lower_bound, std::upper_bound, std::sort
#include <vector>       // std::vector
#include <functional>

int MAX_VAL= 2000000000;

using namespace std;

struct FenwickMin {
public:
    FenwickMin(size_t n)
        : Origin(n, MAX_VAL)
        , Left(200001, MAX_VAL)
        , Right(200001, MAX_VAL)
    {}

    void Update(int ind, int val) {
        // assert(ind > 0 && val < Origin[ind - 1]);
        size_t BITSize = Left.size();
        Origin[ind - 1] = val;
        int cur = ind;
        while (cur <= BITSize) {
            Left[cur] = min(Left[cur], val);
            cur += (cur & -cur);
        }
        cur = ind;
        while (cur > 0) {
            Right[cur] = min(Right[cur], val);
            cur -= (cur & - cur);
        }
    }

    int Min(int l, int r) const {
        // assert l > 0
        l++; r++;
        int res = MAX_VAL;
        int i = l;
        while (i + (i & -i) <= r) {
            res = std::min(res, Right[i]);
            i += (i & -i);
        }
        i = r;
        while (i - (i & -i) >= l) {
            res = std::min(res, Left[i]);
            i -= (i & -i);
        }
        res = std::min(Origin[i - 1], res);
        return res;
    }
private:
    vector<int> Origin;
    vector<int> Left;
    vector<int> Right;
};

int find_lowest(int lower, int upper, const FenwickMin& minrange, const FenwickMin& maxrange, int i) {
    while (upper - lower > 1) {
        int median = lower + (upper - lower) / 2;
        int min = minrange.Min(i, median);
        int max = -maxrange.Min(i, median);
        if (max >= min) {
            upper = median;
        } else {
            lower = median;
        }
    }
    if (minrange.Min(i, upper) == -maxrange.Min(i, upper))
        return upper;
    return -1;
}

int find_highest(int lower, int upper, const FenwickMin& minrange, const FenwickMin& maxrange, int i) {
    while (upper - lower > 1) {
        int median = lower + (upper - lower) / 2;
        int min = minrange.Min(i, median);
        int max = -maxrange.Min(i, median);
        if (max > min) {
            upper = median;
        } else {
            lower = median;
        }
    }
    if (minrange.Min(i, lower) == -maxrange.Min(i, lower))
        return lower;
    return -1;
}

int main () {
    int n;
    scanf("%d",&n);
    FenwickMin bitMin(n);
    FenwickMin bitMax(n);
    for (int i = 0; i < n; ++i) {
        int next;
        scanf("%d", &next);
        bitMax.Update(1, -1);

    }
    for (int i = 0; i < n; ++i) {
        int next;
        scanf("%d", &next);
        bitMin.Update(i + 2, next);
    }

    long long res = 0;
    for (int i = 0; i < n; ++i) {
        int lowerEq = n;
        int min = bitMin.Min(i, i);
        int max = -bitMax.Min(i, i);
        if (max > min) {
            continue;
        } else if (max == min) {
            lowerEq = i;
        } else {
            lowerEq = find_lowest(i, n - 1, bitMin, bitMax, i);
            if (lowerEq == -1)
                continue;
        }

        int upperEq = find_highest(i, n - 1, bitMin, bitMax, i);
        res += upperEq - lowerEq + 1;
    }
    return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <vector>
#include <utility>
#include <string>
#include <limits>

#include<stdlib.h>
#include <iostream>     // std::cout
#include <algorithm>    // std::lower_bound, std::upper_bound, std::sort
#include <vector>       // std::vector
#include <functional>

long long MAX_VAL= 2000000000;

using namespace std;

struct FenwickMin {
public:
    FenwickMin(size_t n)
        : Origin(n, MAX_VAL)
        , Left(n + 1, MAX_VAL)
        , Right(n + 1, MAX_VAL)
    {}

    void Update(int ind, long long val) {
        // assert(ind > 0 && val < Origin[ind - 1]);
        size_t BITSize = Origin.size() + 1;
        Origin[ind - 1] = val;
        int cur = ind;
        while (cur <= BITSize) {
            Left[cur] = min(Left[cur], val);
            cur += (cur & -cur);
        }
        cur = ind;
        while (cur > 0) {
            Right[cur] = min(Right[cur], val);
            cur -= (cur & - cur);
        }
    }

    long long Min(int l, int r) const {
        // assert l > 0
        l++; r++;
        long long res = MAX_VAL;
        int i = l;
        while (i + (i & -i) <= r) {
            res = std::min(res, Right[i]);
            i += (i & -i);
        }
        i = r;
        while (i - (i & -i) >= l) {
            res = std::min(res, Left[i]);
            i -= (i & -i);
        }
        res = std::min(Origin[i - 1], res);
        return res;
    }
private:
    vector<long long> Origin;
    vector<long long> Left;
    vector<long long> Right;
};

int find_lowest(int lower, int upper, const FenwickMin& minrange, const FenwickMin& maxrange, int i) {
    while (upper - lower > 1) {
        int median = lower + (upper - lower) / 2;
        long long min = minrange.Min(i, median);
        long long max = -maxrange.Min(i, median);
        if (max >= min) {
            upper = median;
        } else {
            lower = median;
        }
    }
    if (minrange.Min(i, upper) == -maxrange.Min(i, upper))
        return upper;
    return -1;
}

int find_highest(int lower, int upper, const FenwickMin& minrange, const FenwickMin& maxrange, int i) {
    while (upper - lower > 1) {
        int median = lower + (upper - lower) / 2;
        long long min = minrange.Min(i, median);
        long long max = -maxrange.Min(i, median);
        if (max > min) {
            upper = median;
        } else {
            lower = median;
        }
    }
    if (minrange.Min(i, lower) == -maxrange.Min(i, lower))
        return lower;
    return -1;
}

int main () {
    unsigned long long n;
    std::cin >> n;
    FenwickMin bitMin(n);
    FenwickMin bitMax(n);
    for (int i = 0; i < n; ++i) {
        int next;
        std::cin >> next;
        bitMax.Update(i + 1, -next);

    }
    for (int i = 0; i < n; ++i) {
        int next;
        std::cin >> next;
        bitMin.Update(i + 1, next);
    }

    long long res = 2;
    cout << res;
    return 0;
    for (int i = 0; i < n; ++i) {
        int lowerEq = n;
        long long min = bitMin.Min(i, i);
        long long max = -bitMax.Min(i, i);
        if (max > min) {
            continue;
        } else if (max == min) {
            lowerEq = i;
        } else {
            lowerEq = find_lowest(i, n - 1, bitMin, bitMax, i);
            if (lowerEq == -1)
                continue;
        }

        int upperEq = find_highest(i, n - 1, bitMin, bitMax, i);
        res += upperEq - lowerEq + 1;
    }
    return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <vector>
#include <utility>
#include <string>
#include <limits>

#include<stdlib.h>
#include <iostream>     // std::cout
#include <algorithm>    // std::lower_bound, std::upper_bound, std::sort
#include <vector>       // std::vector
#include <functional>

int MAX_VAL= 2000000000;

using namespace std;

struct FenwickMin {
public:
    FenwickMin(size_t n)
        : Origin(n, MAX_VAL)
        , Left(n + 1, MAX_VAL)
        , Right(n + 1, MAX_VAL)
    {}

    void Update(int ind, int val) {
        // assert(ind > 0 && val < Origin[ind - 1]);
        Origin[ind - 1] = val;
        int cur = ind;
        size_t BITSize = Origin.size();
        while (cur <= BITSize) {
            Left[cur] = min(Left[cur], val);
            cur += (cur & -cur);
        }
        cur = ind;
        while (cur > 0) {
            Right[cur] = min(Right[cur], val);
            cur -= (cur & - cur);
        }
    }

    int Min(int l, int r) const {
        // assert l > 0
        l++; r++;
        int res = MAX_VAL;
        int i = l;
        while (i + (i & -i) <= r) {
            res = std::min(res, Right[i]);
            i += (i & -i);
        }
        i = r;
        while (i - (i & -i) >= l) {
            res = std::min(res, Left[i]);
            i -= (i & -i);
        }
        res = std::min(Origin[i - 1], res);
        return res;
    }
private:
    vector<int> Origin;
    vector<int> Left;
    vector<int> Right;
};

int find_lowest(int lower, int upper, const FenwickMin& minrange, const FenwickMin& maxrange, int i) {
    while (upper - lower > 1) {
        int median = lower + (upper - lower) / 2;
        int min = minrange.Min(i, median);
        int max = -maxrange.Min(i, median);
        if (max >= min) {
            upper = median;
        } else {
            lower = median;
        }
    }
    if (minrange.Min(i, upper) == -maxrange.Min(i, upper))
        return lower;
    return -1;
}

int find_highest(int lower, int upper, const FenwickMin& minrange, const FenwickMin& maxrange, int i) {
    if (minrange.Min(i, upper) == -maxrange.Min(i, upper))
        return upper;
    while (upper - lower > 1) {
        int median = lower + (upper - lower) / 2;
        int min = minrange.Min(i, median);
        int max = -maxrange.Min(i, median);
        /*cerr << "lower index " << lower << " highest " << upper << endl;
        cerr << "min " << min << " max " << max << endl;*/
        if (max > min) {
            upper = median;
        } else {
            lower = median;
        }
    }
    if (minrange.Min(i, lower) == -maxrange.Min(i, lower))
        return lower;
    return -1;
}

int main () {
    int n;
    scanf("%d",&n);
    FenwickMin bitMin(n);
    FenwickMin bitMax(n);
    for (int i = 0; i < n; ++i) {
        int next;
        scanf("%d", &next);
        bitMax.Update(i + 1, -next);
    }
    for (int i = 0; i < n; ++i) {
        int next;
        scanf("%d", &next);
        bitMin.Update(i + 1, next);
    }

    long long res = 0;
    for (int i = 0; i < n; ++i) {
        int lowerEq = n;
        int min = bitMin.Min(i, i);
        int max = -bitMax.Min(i, i);
        if (max > min) {
            continue;
        } else if (max == min) {
            lowerEq = i;
        } else {
            lowerEq = find_lowest(i, n - 1, bitMin, bitMax, i);
            if (lowerEq == -1)
                continue;
        }

        int upperEq = find_highest(i, n - 1, bitMin, bitMax, i);
        //cerr << i << " [" << lowerEq << "," << upperEq << " ]\n";
        res += upperEq - lowerEq + 1;
    }
    cout << res;
    return 0;
}


#include<iostream>
#include<sstream>
#include<fstream>
#include<cstdio>
#include<memory.h>
#include<algorithm>
#include<string>
#include<set>
#include<map>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<cmath>
#include<ctime>
#include<bitset>
#include<assert.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
typedef double db;

#define pb push_back
#define mp make_pair
#define se second
#define fi first

#define Pi 3.1415926535
#define mod 1000000009
#define inf 2000000000
#define eps 1e-6

#define sqr(a) (a)*(a)
#define For(i,a,b) for(int i=a;i<b;i++)
#define roF(i,a,b) for(int i=a;i>=b;i--)
#define fill(a,k) memset(a,k,sizeof(a))

#define vi vector<int>
#define vii vector< pair<int,int> >
#define vdd vector< pair<dbl,dbl> >
#define pii pair<int,int>
#define pdd pair<dbl,dbl>
#define pll pair<ll,ll>

#define fr(a) freopen(a,"r",stdin)
#define fw(a) freopen(a,"w",stdout)

bool cmp(pii a,pii b){
	return a.first+a.second<b.first+b.second;
}

int main(){
	//fr("input.txt"); fw("output.txt");
	//fr("river.in"); fw("river.out");
	int x,w,n,mx=0,gh=-inf;
	vii zp;
	scanf("%d",&n);
	For(i,0,n){
		scanf("%d%d",&x,&w);
		zp.pb(mp(x,w));
	}
	sort(zp.begin(),zp.end(),cmp);
	for(size_t i=0;i<zp.size();i++){
		x=zp[i].first,w=zp[i].se;
		if(gh<=x-w){
			mx++;
			gh=w+x;
		}
	}
	cout<<mx;
    return 0;
}


#if 1
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<algorithm>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<vi> vii;
typedef pair<int, int> pii;

#define X first
#define Y second
#define file "file"
#define mp make_pair
#define pb push_back

int main()
{
    int n;
    cin>>n;
    vector<pair<int,int> >a;
    for(int i=0;i<n;i++)
    {
        int t1,t2;
        cin>>t1>>t2;
        a.pb(mp(t1,t2));
    }
    sort(a.begin(), a.end());
    pair<int,int>t;
    t = mp(1, a[0].X + a[0].Y);
    for(int i=1; i  < n; i++)
    {
        if(a[i].X >= t.Y + a[i].Y)
        {
            t.X++;
            t.Y = a[i].X + a[i].Y;
        }
        if(a[i].X + a[i].Y < t.Y)
            t.Y = a[i].X + a[i].Y;
    }
    cout<<t.X;
    return 0;
}
#endif


#include <iostream>
#include <cstdio>
#include <set>

using namespace std;

struct _line_
{
	long long L, R;
};

bool operator <(_line_ x1, _line_ x2)
{
	if (x1.R != x2.R)
		return x1.R < x2.R;
	return x1.L < x2.L;
}

set <_line_> ans;
int n, answer;

int main()
{
	scanf(" %d", &n);
	for (int i = 1; i <= n; i++)
	{
		long long x, w;
		scanf(" %lld %lld", &x, &w);
		_line_ now;
		now.L = x - w;
		now.R = x + w;
		ans.insert(now);
	}
	answer = 1;
	_line_ mom = *ans.begin();
	long long xxx = mom.R;
	ans.erase(mom);
	while (!ans.empty())
	{
		mom = *ans.begin();
		long long yyy = mom.L;
		if (yyy >= xxx)
		{
			answer++;
			xxx = mom.R;
		}
		ans.erase(mom);
	}
	printf("%d\n", answer);
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <fstream>
#include <unordered_map>
#include <string>
#include <algorithm>
#include <sstream>
#include <cmath>
#include <queue>
#include <time.h>
#include <stdio.h>
#include <list>
#include <stdlib.h>
#include <string.h>
#include <list>
#include <functional>
#include <random>
using namespace std;
#define JUDJE 1488

#ifndef JUDJE

ifstream in("D:/asd/a.txt");
ofstream out("D:/asd/a.txt");
#define cin in
#define cout out

#endif

#define ll long long
#define MOD 1000000007
#define mp(a, b) make_pair(a, b)
#define PI 3.1415926535
#define EPS 0.00000001
#define pii pair<int, int>
#define INF 1000000000

int dp[1234567];
pair<pii, int> a [1234567];
pii b[1234567];
bool cmp(pair<pii, int> a, pair<pii, int> b)
{
    return (a.first.first - a.first.second < b.first.first - b.first.second);
}

int rev[1234567];

struct Tree
{
    int mx;
    int l, r;
};

Tree tree[810000];
int l, r;
void build(int v, int tl, int tr)
{
    tree[v].l = tl;
    tree[v].r = tr;
    if(tl == tr)
        return;
    build(2*v, tl, (tl + tr) / 2);
    build(2*v+1, (tl+tr)/2+1, tr);
}

int getMax(int v)
{
    if(tree[v].l >= l && tree[v].r <= r)
        return tree[v].mx;
    if(tree[v].l > r || tree[v].r < l)
        return 0;
    return max(getMax(2*v), getMax(2*v+1));
}

void modify(int i, int x)
{
    int v = 1;
    while(tree[v].l != tree[v].r)
    {
        if((tree[v].l + tree[v].r) / 2 >= i)
            v <<= 1;
        else
            v = (v << 1) + 1;
    }
    tree[v].mx = x;
    v >>= 1;
    while(v)
    {
        tree[v].mx = max(tree[2*v].mx, tree[2*v+1].mx);
        v >>= 1;
    }
    return;
}
int n;

int getLeft(int s)
{
    if(a[n].first.first - a[n].first.second < s)
        return n+1;
    if(a[1].first.first - a[1].first.second >= s)
        return 1;
    int L = 1;
    int R = n;
    while(R - L > 1)
    {
        int M = (R + L) / 2;
        if(a[M].first.first - a[M].first.second >= s)
            R = M;
        else
            L = M;
    }
    if(a[L].first.first - a[L].first.second >= s)
        return L;
    return R;
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin >> n;
    for(int i = 1; i <= n; ++i)
    {
        cin >> a[i].first.first >> a[i].first.second;
        b[i].first = a[i].first.first;
        b[i].second = i;
        a[i].second = i;
    }
    sort(b + 1, b + n + 1);
    sort(a + 1, a + n + 1, cmp);
    for(int i = 1; i <= n; ++i)
        rev[ a[i].second ] = i;
    build(1, 1, n);
    for(int i = n; i >= 1; --i)
    {
        int ii = getLeft( a[ rev [b[i].second] ].first.first + a[ rev[b[i].second] ].first.second);
        l = ii;
        r = n;
        dp[i] = getMax(1)+1;
        modify(i, dp[i]);
    }

    cout << *max_element(dp + 1, dp + n + 1);

}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <fstream>
#include <unordered_map>
#include <string>
#include <algorithm>
#include <sstream>
#include <cmath>
#include <queue>
#include <time.h>
#include <stdio.h>
#include <list>
#include <stdlib.h>
#include <string.h>
#include <list>
#include <functional>
#include <random>
using namespace std;
#define JUDJE 1488

#ifndef JUDJE

ifstream in("D:/asd/a.txt");
ofstream out("D:/asd/a.txt");
#define cin in
#define cout out

#endif

#define ll long long
#define MOD 1000000007
#define mp(a, b) make_pair(a, b)
#define PI 3.1415926535
#define EPS 0.00000001
#define pii pair<int, int>
#define INF 1000000000

int dp[1234567];
pair<pii, int> a [1234567];
pii b[1234567];
int rev[1234567];
bool cmp(pair<pii, int> a, pair<pii, int> b)
{
    return (a.first.first - a.first.second < b.first.first - b.first.second);
}

struct Tree
{
    int mx, l, r;
};

Tree tree[1010000];
int l, r;
void build(int v, int tl, int tr)
{
    tree[v].l = tl;
    tree[v].r = tr;
    if(tl == tr)
        return;
    build(2*v, tl, (tl + tr) / 2);
    build(2*v+1, (tl+tr)/2+1, tr);
}

int getMax(int v)
{
    if(tree[v].l >= l && tree[v].r <= r)
        return tree[v].mx;
    if(tree[v].l > r || tree[v].r < l)
        return 0;
    return max(getMax(2*v), getMax(2*v+1));
}

void modify(int i, int x)
{
    int v = 1;
    while(tree[v].l != tree[v].r)
    {
        if((tree[v].l + tree[v].r) / 2 >= i)
            v <<= 1;
        else
            v = (v << 1) + 1;
    }
    tree[v].mx = x;
    v >>= 1;
    while(v)
    {
        tree[v].mx = max(tree[2*v].mx, tree[2*v+1].mx);
        v >>= 1;
    }
    return;
}
int n;

int getLeft(int s)
{
    if(a[n].first.first - a[n].first.second < s)
        return n+1;
    if(a[1].first.first - a[1].first.second >= s)
        return 1;
    int L = 1;
    int R = n;
    while(R - L > 1)
    {
        int M = (R + L) / 2;
        if(a[M].first.first - a[M].first.second >= s)
            R = M;
        else
            L = M;
    }
    if(a[L].first.first - a[L].first.second >= s)
        return L;
    return R;
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin >> n;
    for(int i = 1; i <= n; ++i)
    {
        cin >> a[i].first.first >> a[i].first.second;
        b[i].first = a[i].first.first;
        b[i].second = i;
        a[i].second = i;
    }
    sort(b + 1, b + n + 1);
    sort(a + 1, a + n + 1, cmp);
    for(int i = 1; i <= n; ++i)
        rev[ a[i].second ] = i;
    build(1, 1, n);
    for(int i = n; i >= 1; --i)
    {
        l = getLeft( a[ rev [b[i].second] ].first.first + a[ rev[b[i].second] ].first.second);
        r = n;
        dp[rev[i]] = getMax(1) + 1;
        modify(rev[i], dp[rev[i]]);
    }

    cout << *max_element(dp + 1, dp + n + 1);

}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <fstream>
#include <unordered_map>
#include <string>
#include <algorithm>
#include <sstream>
#include <cmath>
#include <queue>
#include <time.h>
#include <stdio.h>
#include <list>
#include <stdlib.h>
#include <string.h>
#include <list>
#include <functional>
#include <random>
using namespace std;
#define JUDJE 1488

#ifndef JUDJE

ifstream in("D:/asd/a.txt");
ofstream out("D:/asd/a.txt");
#define cin in
#define cout out

#endif

#define ll long long
#define MOD 1000000007
#define mp(a, b) make_pair(a, b)
#define PI 3.1415926535
#define EPS 0.00000001
#define pii pair<int, int>
#define INF 1000000000

int dp[1234567];
pair<pii, int> a [1234567];
pii b[1234567];
int rev[1234567];
bool cmp(pair<pii, int> a, pair<pii, int> b)
{
    return (a.first.first - a.first.second < b.first.first - b.first.second);
}

struct Tree
{
    int mx, l, r;
};

Tree tree[1010000];
int l, r;
void build(int v, int tl, int tr)
{
    tree[v].l = tl;
    tree[v].r = tr;
    if(tl == tr)
        return;
    build(2*v, tl, (tl + tr) / 2);
    build(2*v+1, (tl+tr)/2+1, tr);
}

int getMax(int v)
{
    if(tree[v].l >= l && tree[v].r <= r)
        return tree[v].mx;
    if(tree[v].l > r || tree[v].r < l)
        return 0;
    return max(getMax(2*v), getMax(2*v+1));
}

void modify(int i, int x)
{
    int v = 1;
    while(tree[v].l != tree[v].r)
    {
        if((tree[v].l + tree[v].r) / 2 >= i)
            v <<= 1;
        else
            v = (v << 1) + 1;
    }
    tree[v].mx = x;
    v >>= 1;
    while(v)
    {
        tree[v].mx = max(tree[2*v].mx, tree[2*v+1].mx);
        v >>= 1;
    }
    return;
}
int n;

int getLeft(int s)
{
    if(a[n].first.first - a[n].first.second < s)
        return n+1;
    if(a[1].first.first - a[1].first.second >= s)
        return 1;
    int L = 1;
    int R = n;
    while(R - L > 1)
    {
        int M = (R + L) / 2;
        if(a[M].first.first - a[M].first.second >= s)
            R = M;
        else
            L = M;
    }
    if(a[L].first.first - a[L].first.second >= s)
        return L;
    return R;
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin >> n;
    for(int i = 1; i <= n; ++i)
    {
        cin >> a[i].first.first >> a[i].first.second;
        b[i].first = a[i].first.first;
        b[i].second = i;
        a[i].second = i;
    }
    sort(b + 1, b + n + 1);
    sort(a + 1, a + n + 1, cmp);
    for(int i = 1; i <= n; ++i)
        rev[ a[i].second ] = i;
    build(1, 1, n);
    for(int i = n; i >= 1; --i)
    {
        l = getLeft( a[ rev [b[i].second] ].first.first + a[ rev[b[i].second] ].first.second);
        r = n;
        dp[rev[b[i].second]] = getMax(1) + 1;
        modify(rev[b[i].second], dp[rev[b[i].second]]);
    }

    cout << *max_element(dp + 1, dp + n + 1);

}


#if 1
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <algorithm>
#include <numeric>

using namespace std;

typedef pair<int,int> pii;

struct tree
{
    tree * l, * r;
    pii val;
    int prior;
    int maxv;
    tree() {}
    tree(pii val) : val(val), prior(rand()), l(0), r(0), maxv(0) {}
    pii get_val() { return this ? val : make_pair(0,0);}
    int get_max() { return this ? maxv : 0;}
    void update()
    {
        if(!this) return;
        maxv = val.second;
        maxv = max(maxv, l->get_max());
        maxv = max(maxv, r->get_max());
    }
};

typedef tree * ptree;

void merge(ptree &t, ptree l, ptree r)
{
    if(!l || !r) t = l ? l : r;
    else if(l->prior < r->prior)
        merge(l->r, l->r, r), t = l;
    else
        merge(r->l, l, r->l), t = r;
    t->update();
}

void split(ptree &l, ptree &r, ptree t, pii val)
{
    if(!t) l = r = 0;
    else if(t->val < val)
        split(l, t->l, t->l, val), r = t;
    else
        split(t->r, r, t->r, val), l = t;
    t->update();
}

void insert(ptree &t, pii val)
{
    ptree l, r;
    split(l, r, t, val);
    ptree p = new tree(val);
    merge(l, l, p);
    merge(t, l, r);
}

int main()
{
#ifdef _DEBUG
    freopen("input.txt", "r", stdin);
#endif
    ptree root = 0;
    int n; cin >> n;
    int answer = 1;
    vector<pii> in(n);

    for (int i = 0; i < n; ++i) cin >> in[i].first >> in[i].second;
    sort(in.begin(), in.end());

    for (int i = 0; i < n; ++i)
    {
        int x = in[i].first, w = in[i].second;
        ptree l, r;
        split(l, r, root, make_pair(x - w, 1e9));
        int maxv = l->get_max();
        answer = max(answer, maxv + 1);
        insert(root, make_pair(x + w, maxv + 1));
    }

    cout << answer << endl;
    return 0;
}
#endif


#define TEMPLATE
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <algorithm>
#include <numeric>
#include <iterator>
using namespace std;
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cassert>

typedef long long li;
typedef pair<int,int> pii;

#ifndef CARTESIOAN_TREE
struct ctr
{
    ctr * l, * r;
    pii val;
    int prior;
    int maxv;
    ctr() {}
    ctr(pii val) : val(val), prior(rand()), l(0), r(0), maxv(0) {}
    pii get_val() { return this ? val : make_pair(0,0);}
    int get_max() { return this ? maxv : 0;}
    void update()
    {
        if(!this) return;
        maxv = val.second;
        maxv = max(maxv, l->get_max());
        maxv = max(maxv, r->get_max());
    }
};
typedef ctr * ptr;
void merge(ptr &t, ptr l, ptr r)
{
    if(!l || !r) t = l ? l : r;
    else if(l->prior < r->prior)
        merge(l->r, l->r, r), t = l;
    else
        merge(r->l, l, r->l), t = r;
    t->update();
}

void split(ptr &l, ptr &r, ptr t, pii val)
{
    if(!t) l = r = 0;
    else if(t->val < val)
        split(t->r, r, t->r, val), l = t;
    else
        split(l, t->l, t->l, val), r = t;

    t->update();
}

void insert(ptr &t, pii val)
{
    ptr l, r;
    split(l, r, t, val);
    ptr p = new ctr(val);
    merge(l, l, p);
    merge(t, l, r);
}

void output(ptr &t, bool f = true)
{
    if(f) cout << "Start output" << endl;
    if(t)
    {
        output(t->l, false);
        cout << t->val.first << ' ' << t->val.second << endl;
        output(t->r, false);
    }
    if(f) cout << "End output" << endl;
}
#endif
#ifndef TEMPLATE
#include "template.h"
#endif

int main()
{
#ifdef _DEBUG
    freopen("input.txt", "r", stdin);
#endif
    ptr root = 0;
    int n; cin >> n;
    int answer = 1;
    vector<pii> in(n);

    for (int i = 0; i < n; ++i) cin >> in[i].first >> in[i].second;
    sort(in.begin(), in.end());

    for (int i = 0; i < n; ++i)
    {
        int x = in[i].first, w = in[i].second;
        ptr l, r;
        split(l, r, root, make_pair(x - w, 1e9));
        //output(l);
        //output(r);
        int maxv = l->get_max();
        answer = max(answer, maxv + 1);
        merge(root, l, r);
        insert(root, make_pair(x + w, maxv + 1));
        //output(root);
        //cout << endl << endl;
    }

    cout << answer << endl;
    return 0;
}


#if 1
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <algorithm>
#include <numeric>

using namespace std;

typedef pair<int,int> pii;

struct tree
{
    tree * l, * r;
    pii val;
    int prior;
    int maxv;
    tree() {}
    tree(pii val) : val(val), prior(rand()), l(0), r(0), maxv(0) {}
    pii get_val() { return this ? val : make_pair(0,0);}
    int get_max() { return this ? maxv : 0;}
    void update()
    {
        if(!this) return;
        maxv = val.second;
        maxv = max(maxv, l->get_max());
        maxv = max(maxv, r->get_max());
    }
};

typedef tree * ptree;

void merge(ptree &t, ptree l, ptree r)
{
    if(!l || !r) t = l ? l : r;
    else if(l->prior < r->prior)
        merge(l->r, l->r, r), t = l;
    else
        merge(r->l, l, r->l), t = r;
    t->update();
}

void split(ptree &l, ptree &r, ptree t, pii val)
{
    if(!t) l = r = 0;
    else if(t->val < val)
        split(t->r, r, t->r, val), l = t;
    else
        split(l, t->l, t->l, val), r = t;

    t->update();
}

void insert(ptree &t, pii val)
{
    ptree l, r;
    split(l, r, t, val);
    ptree p = new tree(val);
    merge(l, l, p);
    merge(t, l, r);
}

//завести свои тесты
void output(ptree &t, bool f = true)
{
    if(f) cout << "Start output" << endl;
    if(t)
    {
        output(t->l, false);
        cout << t->val.first << ' ' << t->val.second << endl;
        output(t->r, false);
    }
    if(f) cout << "End output" << endl;
}

int main()
{
#ifdef _DEBUG
    freopen("input.txt", "r", stdin);
#endif
    ptree root = 0;
    int n; cin >> n;
    int answer = 1;
    vector<pii> in(n);

    for (int i = 0; i < n; ++i) cin >> in[i].first >> in[i].second;
    sort(in.begin(), in.end());

    for (int i = 0; i < n; ++i)
    {
        int x = in[i].first, w = in[i].second;
        ptree l, r;
        split(l, r, root, make_pair(x - w, 1e9));
        //output(l);
        //output(r);
        int maxv = l->get_max();
        answer = max(answer, maxv + 1);
        merge(root, l, r);
        insert(root, make_pair(x + w, maxv + 1));
        //output(root);
        //cout << endl << endl;
    }

    cout << answer << endl;
    return 0;
}
#endif


#if 1
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <algorithm>
#include <numeric>

using namespace std;

typedef pair<int,int> pii;

struct tree
{
    tree * l, * r;
    pii val;
    int prior;
    int maxv;
    tree() {}
    tree(pii val) : val(val), prior(rand()), l(0), r(0), maxv(0) {}
    pii get_val() { return this ? val : make_pair(0,0);}
    int get_max() { return this ? maxv : 0;}
    void update()
    {
        if(!this) return;
        maxv = val.second;
        maxv = max(maxv, l->get_max());
        maxv = max(maxv, r->get_max());
    }
};

typedef tree * ptree;

void merge(ptree &t, ptree l, ptree r)
{
    if(!l || !r) t = l ? l : r;
    else if(l->prior < r->prior)
        merge(l->r, l->r, r), t = l;
    else
        merge(r->l, l, r->l), t = r;
    t->update();
}

void split(ptree &l, ptree &r, ptree t, pii val)
{
    if(!t) l = r = 0;
    else if(t->val < val)
        split(t->r, r, t->r, val), l = t;
    else
        split(l, t->l, t->l, val), r = t;

    t->update();
}

void insert(ptree &t, pii val)
{
    ptree l, r;
    split(l, r, t, val);
    ptree p = new tree(val);
    merge(l, l, p);
    merge(t, l, r);
}

//завести свои тесты
void output(ptree &t, bool f = true)
{
    if(f) cout << "Start output" << endl;
    if(t)
    {
        output(t->l, false);
        cout << t->val.first << ' ' << t->val.second << endl;
        output(t->r, false);
    }
    if(f) cout << "End output" << endl;
}

int main()
{
#ifdef _DEBUG
    freopen("input.txt", "r", stdin);
#endif
    ptree root = 0;
    int n; cin >> n;
    int answer = 1;
    vector<pii> in(n);

    for (int i = 0; i < n; ++i) cin >> in[i].first >> in[i].second;
    sort(in.begin(), in.end());

    for (int i = 0; i < n; ++i)
    {
        int x = in[i].first, w = in[i].second;
        ptree l, r;
        split(l, r, root, make_pair(x - w, 1e9));
        output(l);
        output(r);
        int maxv = l->get_max();
        answer = max(answer, maxv + 1);
        merge(root, l, r);
        insert(root, make_pair(x + w, maxv + 1));
        output(root);
        cout << endl << endl;
    }

    cout << answer << endl;
    return 0;
}
#endif


#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <sstream>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <algorithm>
#include <deque>
#define pb push_back
#define mp make_pair
#define inf 2000000000
#define Min(a,b) (a<b?a:b)
#define Max(a,b) (a>b?a:b)
#define For(i,s,n) for (int i=s;i<=n;i++)
#define FOR(i,s,n) for (int i=s;i<n;i++)
#define Ford(i,s,n) for (int i=s;i>=n;i--)
#pragma comment(linker, "/STACK:16777216")

#define MD 1000000007
#define PI 3.1415926535897932384626433832795

double eps = 1e-10;

typedef long long ll;

using namespace std;

map <int, int> m,tree;

int n, ans = 1,N;

pair <int, int> a[200005];

void update(int i, int val){
	for (; i <= N; i = (i | (i + 1)))
		tree[i] = Max(tree[i], val);
}

int getMax(int r){
	int res = 0;
	for (; r >= 0; r = (r & (r + 1)) - 1)
		res = Max(res, tree[r]);
	return res;
}

int main(){
	cin >> n;
	For(i, 1, n){
		scanf("%d%d", &a[i].first, &a[i].second);
		N = Max(N, a[i].first + a[i].second);
	}
	sort(a + 1, a + n + 1);
	update(a[0].first + a[0].second, 1);
	For(i, 2, n){
		int d = a[i].first - a[i].second;
		int sum = a[i].first + a[i].second;
		if (d <= 0)
			continue;
		int t = m[sum];
		int q = getMax(d) + 1;
		if (t < q){
			m[sum] = q;
			ans = Max(ans, q);
			update(sum, q);
		}
	}
	cout << ans << endl;
}


#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <sstream>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <algorithm>
#include <deque>
#define pb push_back
#define mp make_pair
#define inf 2000000000
#define Min(a,b) (a<b?a:b)
#define Max(a,b) (a>b?a:b)
#define For(i,s,n) for (int i=s;i<=n;i++)
#define FOR(i,s,n) for (int i=s;i<n;i++)
#define Ford(i,s,n) for (int i=s;i>=n;i--)
#pragma comment(linker, "/STACK:16777216")

#define MD 1000000007
#define PI 3.1415926535897932384626433832795

double eps = 1e-10;

typedef long long ll;

using namespace std;

map <int, int> m, tree;

int n, ans = 1, N;

pair <int, int> a[200005];

void update(int idx, int val){
	while (idx <= N){
		tree[idx] = Max(tree[idx], val);
		idx += (idx&-idx);
	}
}

int getMax(int idx){
	int res = 0;
	while (idx > 0){
		res = Max(res, tree[idx]);
		idx -= (idx&-idx);
	}
	return res;
}

int main(){
	cin >> n;
	For(i, 1, n){
		scanf("%d%d", &a[i].first, &a[i].second);
		N = Max(N, a[i].first + a[i].second);
		if (a[i].first - a[i].second <= 0)
			update(a[i].first + a[i].second, 1);
	}
	sort(a + 1, a + n + 1);
	For(i, 1, n){
		int d = a[i].first - a[i].second;
		int sum = a[i].first + a[i].second;
		if (d <= 0)
			continue;
		int t = m[sum];
		int q = getMax(d) + 1;
		if (t < q){
			m[sum] = q;
			ans = Max(ans, q);
			update(sum, q);
		}
	}
	cout << ans << endl;
}


#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <sstream>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <algorithm>
#include <deque>
#define pb push_back
#define mp make_pair
#define inf 2000000000
#define Min(a,b) (a<b?a:b)
#define Max(a,b) (a>b?a:b)
#define For(i,s,n) for (int i=s;i<=n;i++)
#define FOR(i,s,n) for (int i=s;i<n;i++)
#define Ford(i,s,n) for (int i=s;i>=n;i--)
#pragma comment(linker, "/STACK:16777216")

#define MD 1000000007
#define PI 3.1415926535897932384626433832795

double eps = 1e-10;

typedef long long ll;

using namespace std;

map <int, int> m, tree;

int n, ans = 1, N;

pair <int, int> a[200005];

void update(int i, int val){
	for (; i <= N; i = (i | (i + 1)))
		tree[i] = Max(tree[i], val);
}

int getMax(int r){
	int res = 0;
	for (; r >= 0; r = (r & (r + 1)) - 1)
		res = Max(res, tree[r]);
	return res;
}

int main(){
	cin >> n;
	For(i, 1, n){
		scanf("%d%d", &a[i].first, &a[i].second);
		N = Max(N, a[i].first + a[i].second);
		if (a[i].first - a[i].second <= 0)
			update(a[i].first + a[i].second, 1);
	}
	sort(a + 1, a + n + 1);
	For(i, 1, n){
		int d = a[i].first - a[i].second;
		int sum = a[i].first + a[i].second;
		if (d <= 0)
			continue;
		int t = m[sum];
		int q = getMax(d) + 1;
		if (t < q){
			m[sum] = q;
			ans = Max(ans, q);
			update(sum, q);
		}
	}
	cout << ans << endl;
}


#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <sstream>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <algorithm>
#include <deque>
#define pb push_back
#define mp make_pair
#define inf 2000000000
#define Min(a,b) (a<b?a:b)
#define Max(a,b) (a>b?a:b)
#define For(i,s,n) for (int i=s;i<=n;i++)
#define FOR(i,s,n) for (int i=s;i<n;i++)
#define Ford(i,s,n) for (int i=s;i>=n;i--)
#pragma comment(linker, "/STACK:16777216")

#define MD 1000000007
#define PI 3.1415926535897932384626433832795

double eps = 1e-10;

typedef long long ll;

using namespace std;

map <int, int> m,tree;

int n, ans = 1,N;

pair <int, int> a[200005];

void update(int i, int val){
	for (; i <= N; i = (i | (i + 1)))
		tree[i] = Max(tree[i], val);
}

int getMax(int r){
	int res = 0;
	for (; r >= 0; r = (r & (r + 1)) - 1)
		res = Max(res, tree[r]);
	return res;
}

int main(){
	cin >> n;
	For(i, 1, n){
		scanf("%d%d", &a[i].first, &a[i].second);
		N = Max(N, a[i].first + a[i].second);
		//update(a[i].first + a[i].second, 1);
	}
	sort(a + 1, a + n + 1);
	For(i, 1, n){
		int d = a[i].first - a[i].second;
		int sum = a[i].first + a[i].second;
		if (d <= 0)
			continue;
		int t = m[sum];
		int q = getMax(d) + 1;
		if (t < q){
			m[sum] = q;
			ans = Max(ans, q);
			update(sum, q);
		}
	}
	cout << ans + 1 << endl;
}


#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <sstream>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <algorithm>
#include <deque>
#define pb push_back
#define mp make_pair
#define inf 2000000000
#define Min(a,b) (a<b?a:b)
#define Max(a,b) (a>b?a:b)
#define For(i,s,n) for (int i=s;i<=n;i++)
#define FOR(i,s,n) for (int i=s;i<n;i++)
#define Ford(i,s,n) for (int i=s;i>=n;i--)
#pragma comment(linker, "/STACK:16777216")

#define MD 1000000007
#define PI 3.1415926535897932384626433832795

double eps = 1e-10;

typedef long long ll;

using namespace std;

map <int, int> m, tree;

int n, ans = 1, N;

pair <int, int> a[200005];

void update(int idx, int val){
	while (idx <= N){
		tree[idx] = Max(tree[idx], val);
		idx += (idx&-idx);
	}
}

int getMax(int idx){
	int res = 0;
	while (idx > 0){
		res = Max(res, tree[idx]);
		idx -= (idx&-idx);
	}
	return res;
}

int main(){
	cin >> n;
	For(i, 1, n){
		scanf("%d%d", &a[i].first, &a[i].second);
		N = Max(N, a[i].first + a[i].second);
	}
	sort(a + 1, a + n + 1);
	For(i, 1, n)
		if (a[i].first - a[i].second <= 0)
			update(a[i].first + a[i].second, 1);
	For(i, 1, n){
		int d = a[i].first - a[i].second;
		int sum = a[i].first + a[i].second;
		if (d <= 0)
			continue;
		int t = m[sum];
		int q = getMax(d) + 1;
		if (t < q){
			m[sum] = q;
			ans = Max(ans, q);
			update(sum, q);
		}
	}
	cout << ans << endl;
}


#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <sstream>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <algorithm>
#include <deque>
#define pb push_back
#define mp make_pair
#define inf 2000000000
#define Min(a,b) (a<b?a:b)
#define Max(a,b) (a>b?a:b)
#define For(i,s,n) for (int i=s;i<=n;i++)
#define FOR(i,s,n) for (int i=s;i<n;i++)
#define Ford(i,s,n) for (int i=s;i>=n;i--)
#pragma comment(linker, "/STACK:16777216")

#define MD 1000000007
#define PI 3.1415926535897932384626433832795

double eps = 1e-10;

typedef long long ll;

using namespace std;

map <int, int> m, tree;

int n, ans = 1, N;

pair <int, int> a[200005];

void update(ll idx, int val){
	while (idx <= N){
		tree[idx] = Max(tree[idx], val);
		idx += (idx&-idx);
	}
}

int getMax(int idx){
	int res = 0;
	while (idx > 0){
		res = Max(res, tree[idx]);
		idx -= (idx&-idx);
	}
	return res;
}

int main(){
	cin >> n;
	For(i, 1, n){
		scanf("%d%d", &a[i].first, &a[i].second);
		N = Max(N, a[i].first + a[i].second);
	}
	sort(a + 1, a + n + 1);
	For(i, 1, n)
		if (a[i].first - a[i].second <= 0)
			update(a[i].first + a[i].second, 1);
	For(i, 1, n){
		int d = a[i].first - a[i].second;
		int sum = a[i].first + a[i].second;
		if (d <= 0)
			continue;
		int t = m[sum];
		int q = getMax(d) + 1;
		if (t < q){
			m[sum] = q;
			ans = Max(ans, q);
			update(sum, q);
		}
	}
	cout << ans << endl;
}


#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <sstream>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <algorithm>
#include <deque>
#define pb push_back
#define mp make_pair
#define inf 2000000000
#define Min(a,b) (a<b?a:b)
#define Max(a,b) (a>b?a:b)
#define For(i,s,n) for (int i=s;i<=n;i++)
#define FOR(i,s,n) for (int i=s;i<n;i++)
#define Ford(i,s,n) for (int i=s;i>=n;i--)
#pragma comment(linker, "/STACK:16777216")

#define MD 1000000007
#define PI 3.1415926535897932384626433832795

double eps = 1e-10;

typedef long long ll;

using namespace std;

map <int, int> m,tree;

int n, ans = 1,N;

pair <int, int> a[200005];

void update(int i, int val){
	for (; i <= N; i = (i | (i + 1)))
		tree[i] = Max(tree[i], val);
}

int getMax(int r){
	int res = 0;
	for (; r >= 0; r = (r & (r + 1)) - 1)
		res = Max(res, tree[r]);
	return res;
}

int main(){
	cin >> n;
	For(i, 1, n){
		scanf("%d%d", &a[i].first, &a[i].second);
		N = Max(N, a[i].first + a[i].second);
		update(a[i].first + a[i].second, 1);
	}
	sort(a + 1, a + n + 1);
	For(i, 1, n){
		int d = a[i].first - a[i].second;
		int sum = a[i].first + a[i].second;
		if (d <= 0)
			continue;
		int t = m[sum];
		int q = getMax(d) + 1;
		if (t < q){
			m[sum] = q;
			ans = Max(ans, q);
			update(sum, q);
		}
	}
	cout << ans << endl;
}


#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <sstream>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <algorithm>
#include <deque>
#define pb push_back
#define mp make_pair
#define inf 2000000000
#define Min(a,b) (a<b?a:b)
#define Max(a,b) (a>b?a:b)
#define For(i,s,n) for (int i=s;i<=n;i++)
#define FOR(i,s,n) for (int i=s;i<n;i++)
#define Ford(i,s,n) for (int i=s;i>=n;i--)
#pragma comment(linker, "/STACK:16777216")

#define MD 1000000007
#define PI 3.1415926535897932384626433832795

double eps = 1e-10;

typedef long long ll;

using namespace std;

map <int, int> m,tree;

int n, ans = 1,N;

pair <int, int> a[200005];

void update(int i, int val){
	for (; i <= N; i = (i | (i + 1)))
		tree[i] = Max(tree[i], val);
}

int getMax(int r){
	int res = 0;
	for (; r >= 0; r = (r & (r + 1)) - 1)
		res = Max(res, tree[r]);
	return res;
}

int main(){
	cin >> n;
	For(i, 1, n){
		scanf("%d%d", &a[i].first, &a[i].second);
		N = Max(N, a[i].first + a[i].second);
	}
	sort(a + 1, a + n + 1);
	update(a[0].first + a[0].second, 1);
	For(i, 2, n){
		int d = a[i].first - a[i].second;
		if (d < 0)
			continue;
		int t = m[d];
		int q = getMax(d) + 1;
		if (t < q){
			m[d] = q;
			ans = Max(ans, q);
			update(d, q);
		}
	}
	cout << ans << endl;
}


#define _CRT_SECURE_NO_WARNINGS

#include <set>
#include <map>
#include <cmath>
#include <time.h>
#include <vector>
#include <string>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>

using namespace std;

#define ll long long
#define ld long double

const int MAXN = 200100;

int x[MAXN], w[MAXN];

int main(){
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n;
	cin >> n;
	vector<pair<int, int> > v;
	for (int i = 0; i < n; i++){
		cin >> x[i] >> w[i];
		v.push_back(make_pair(x[i] + w[i], i));
	}
	sort(v.begin(), v.end());
	int last = 0, ans = 1;
	for (int i = 1; i < n; i++){
		int a = v[last].second, b = v[i].second;
		if (x[a] + w[a] <= x[b] - w[b]){
			last = i;
			ans++;
		}
	}
	cout << ans;
	return 0;
}


#include <cstdio>
#include <algorithm>
using namespace std;

struct Seg {
    int l, r;
};
Seg a[200010];

int main() {
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i ++) {
        int x, w;
        scanf("%d%d", &x, &w);
        a[i].l = x - w;
        a[i].r = x + w;
    }
    sort(a, a + n, [&](Seg x, Seg y) {
        return x.r < y.r;
    });
    int maxn = -1000000010, res = 0;
    for (int i = 0; i < n; i ++) {
        if (a[i].l >= maxn) {
            res ++;
            maxn = max(maxn, a[i].r);
        }
    }
    printf("%d\n", res);
    return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
using namespace std;
struct Tree{
    int left,right;
    int sum;
}tree[800005];
int lisan[200005],lt[400005];
int vl,ln;
void build_tree(int id,int l,int r){
    tree[id].left = l;
    tree[id].right = r;
    if (l==r){
        tree[id].sum=0;
        return;
    }
    int mid = (l + r)>>1;
    build_tree( (id<<1),l,mid);
    build_tree( (id<<1)+1,mid+1,r);
    tree[id].sum = max(tree[id<<1].sum,tree[(id<<1)+1].sum);
};
void update(int id,int l,int r, int val){
    if (tree[id].left==l&&tree[id].right==r){
        tree[id].sum=max(tree[id].sum,val);
        return;
    }
    int mid = (tree[id].left + tree[id].right)>>1;
    if (r<=mid){
        update(id<<1,l,r,val);
    }
    else if(l>mid){
        update( (id<<1)+1,l,r,val);
    }
    else{
        update( (id<<1),l,mid,val);
        update( (id<<1)+1,mid+1,r,val);
    }
};
__int64 query(int id,int l,int r){
    if (tree[id].left==l&&tree[id].right==r){
        return tree[id].sum;
    }
    int mid = (tree[id].left+tree[id].right)>>1;
    if (r<=mid){
        return query(id<<1,l,r);
    }
    else if(l>mid){
        return query( (id<<1)+1,l,r);
    }
    else{
        return max(query(id<<1,l,mid),query( (id<<1)+1,mid+1,r));
    }
};
struct thanks{
    int sum,vs,x;
}p[200005];
int vid,vans,ans;
bool cmp(thanks x,thanks y){
    return x.x<y.x;
}
int main(){
    int i,j,n,m,w,h,a,b;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        scanf("%d%d",&a,&b);
        p[i].x=a;
        p[i].sum=a+b;
        lisan[++vl]=p[i].sum;
        lisan[++vl]=p[i].vs;
        p[i].vs=a-b;
        lisan[++vl]=p[i].vs;
    }
    sort(p+1,p+n+1,cmp);
    sort(lisan+1,lisan+vl+1);
    for(i=1;i<=vl;i++){
        if(lisan[i]!=lisan[i-1]) lt[++ln]=lisan[i];
    }
    build_tree(1,1,n);
    for(i=1;i<=n;i++){
        vid=lower_bound(lt+1,lt+ln+1,p[i].vs)-lt;
        vans=query(1,vid,vid);
        vid=lower_bound(lt+1,lt+ln+1,p[i].sum)-lt;
        update(1,vid,vid,vans+1);
        ans=max(vans+1,ans);
    }
    printf("%d\n",ans);
    //system("pause");
    return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
using namespace std;
struct Tree{
    int left,right;
    int sum;
}tree[800005];
int lisan[200005],lt[200005];
int vl,ln;
void build_tree(int id,int l,int r){
    tree[id].left = l;
    tree[id].right = r;
    if (l==r){
        tree[id].sum=0;
        return;
    }
    int mid = (l + r)>>1;
    build_tree( (id<<1),l,mid);
    build_tree( (id<<1)+1,mid+1,r);
    tree[id].sum = max(tree[id<<1].sum,tree[(id<<1)+1].sum);
};
void update(int id,int l,int r, int val){
    if (tree[id].left==l&&tree[id].right==r){
        tree[id].sum=max(tree[id].sum,val);
        return;
    }
    int mid = (tree[id].left + tree[id].right)>>1;
    if (r<=mid){
        update(id<<1,l,r,val);
    }
    else if(l>mid){
        update( (id<<1)+1,l,r,val);
    }
    else{
        update( (id<<1),l,mid,val);
        update( (id<<1)+1,mid+1,r,val);
    }
};
__int64 query(int id,int l,int r){
    if (tree[id].left==l&&tree[id].right==r){
        return tree[id].sum;
    }
    int mid = (tree[id].left+tree[id].right)>>1;
    if (r<=mid){
        return query(id<<1,l,r);
    }
    else if(l>mid){
        return query( (id<<1)+1,l,r);
    }
    else{
        return max(query(id<<1,l,mid),query( (id<<1)+1,mid+1,r));
    }
};
struct thanks{
    int sum,vs,x;
}p[200005];
int vid,vans,ans;
bool cmp(thanks x,thanks y){
    return x.x<y.x;
}
int main(){
    int i,j,n,m,w,h,a,b;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        scanf("%d%d",&a,&b);
        p[i].x=a;
        p[i].sum=a+b;
        lisan[++vl]=p[i].sum;
        p[i].vs=a-b;
    }
    sort(p+1,p+n+1,cmp);
    sort(lisan+1,lisan+vl+1);
    for(i=1;i<=vl;i++){
        if(lisan[i]!=lisan[i-1]) lt[++ln]=lisan[i];
    }
    build_tree(1,1,n);
    for(i=1;i<=n;i++){
        vid=lower_bound(lt+1,lt+ln+1,p[i].vs)-lt;
        vans=query(1,vid,vid);
        vid=lower_bound(lt+1,lt+ln+1,p[i].sum)-lt;
        update(1,vid,vid,vans+1);
        ans=max(vans+1,ans);
    }
    printf("%d\n",ans);
    //system("pause");
    return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
using namespace std;
struct Tree{
    int left,right;
    int sum;
}tree[800005];
int lisan[200005],lt[200005];
int vl,ln;
void build_tree(int id,int l,int r){
    tree[id].left = l;
    tree[id].right = r;
    if (l==r){
        tree[id].sum=0;
        return;
    }
    int mid = (l + r)>>1;
    build_tree( (id<<1),l,mid);
    build_tree( (id<<1)+1,mid+1,r);
    tree[id].sum = max(tree[id<<1].sum,tree[(id<<1)+1].sum);
};
void update(int id,int l,int r, int val){
    if (tree[id].left==l&&tree[id].right==r){
        tree[id].sum=max(tree[id].sum,val);
        return;
    }
    int mid = (tree[id].left + tree[id].right)>>1;
    if (r<=mid){
        update(id<<1,l,r,val);
    }
    else if(l>mid){
        update( (id<<1)+1,l,r,val);
    }
    else{
        update( (id<<1),l,mid,val);
        update( (id<<1)+1,mid+1,r,val);
    }
};
__int64 query(int id,int l,int r){
    if (tree[id].left==l&&tree[id].right==r){
        return tree[id].sum;
    }
    int mid = (tree[id].left+tree[id].right)>>1;
    if (r<=mid){
        return query(id<<1,l,r);
    }
    else if(l>mid){
        return query( (id<<1)+1,l,r);
    }
    else{
        return max(query(id<<1,l,mid),query( (id<<1)+1,mid+1,r));
    }
};
struct thanks{
    int sum,vs,x;
}p[200005];
int vid,vans,ans;
bool cmp(thanks x,thanks y){
    return x.x<y.x;
}
int main(){
    int i,j,n,m,w,h,a,b;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        scanf("%d%d",&a,&b);
        p[i].x=a;
        p[i].sum=a+b;
        lisan[++vl]=p[i].sum;
        p[i].vs=a-b;
    }
    sort(p+1,p+n+1,cmp);
    sort(lisan+1,lisan+vl+1);
    for(i=1;i<=vl;i++){
        if(lisan[i]!=lisan[i-1]) lt[++ln]=lisan[i];
    }
    build_tree(1,1,n);
    for(i=1;i<=n;i++){
        vid=upper_bound(lt+1,lt+ln+1,p[i].vs)-lt;
        vans=query(1,vid,vid);
        vid=lower_bound(lt+1,lt+ln+1,p[i].sum)-lt;
        update(1,vid,vid,vans+1);
        ans=max(vans+1,ans);
    }
    printf("%d\n",ans);
    //system("pause");
    return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
using namespace std;
struct Tree{
    int left,right;
    int sum;
}tree[800005];
int lisan[200005],lt[200005];
int vl,ln;
void build_tree(int id,int l,int r){
    tree[id].left = l;
    tree[id].right = r;
    if (l==r){
        tree[id].sum=0;
        return;
    }
    int mid = (l + r)>>1;
    build_tree( (id<<1),l,mid);
    build_tree( (id<<1)+1,mid+1,r);
    tree[id].sum = max(tree[id<<1].sum,tree[(id<<1)+1].sum);
};
void update(int id,int l,int r, int val){
    if (tree[id].left==l&&tree[id].right==r){
        tree[id].sum=max(tree[id].sum,val);
        return;
    }
    int mid = (tree[id].left + tree[id].right)>>1;
    if (r<=mid){
        update(id<<1,l,r,val);
    }
    else if(l>mid){
        update( (id<<1)+1,l,r,val);
    }
    else{
        update( (id<<1),l,mid,val);
        update( (id<<1)+1,mid+1,r,val);
    }
    tree[id].sum = max(tree[id<<1].sum,tree[(id<<1)+1].sum);
};
__int64 query(int id,int l,int r){
    if (tree[id].left==l&&tree[id].right==r){
        return tree[id].sum;
    }
    int mid = (tree[id].left+tree[id].right)>>1;
    if (r<=mid){
        return query(id<<1,l,r);
    }
    else if(l>mid){
        return query( (id<<1)+1,l,r);
    }
    else{
        return max(query(id<<1,l,mid),query( (id<<1)+1,mid+1,r));
    }
};
struct thanks{
    int sum,vs,x;
}p[200005];
int vid,vans,ans;
bool cmp(thanks x,thanks y){
    return x.x<y.x;
}
int main(){
    int i,j,n,m,w,h,a,b;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        scanf("%d%d",&a,&b);
        p[i].x=a;
        p[i].sum=a+b;
        lisan[++vl]=p[i].sum;
        p[i].vs=a-b;
    }
    sort(p+1,p+n+1,cmp);
    sort(lisan+1,lisan+vl+1);
    for(i=1;i<=vl;i++){
        if(lisan[i]!=lisan[i-1]) lt[++ln]=lisan[i];
    }
    build_tree(1,1,ln);
    for(i=1;i<=n;i++){
        vid=lower_bound(lt+1,lt+ln+1,p[i].vs)-lt;
        if(lt[vid]!=p[i].vs) vid--;
        if(vid>0) vans=query(1,1,vid);
        else vans=0;
        vid=lower_bound(lt+1,lt+ln+1,p[i].sum)-lt;
        update(1,vid,vid,vans+1);
        ans=max(vans+1,ans);
    }
    printf("%d\n",ans);
    //system("pause");
    return 0;
}


#include <cstdio>
#include <iostream>
#include <map>
#include <hash_map>
#include <algorithm>
#include <cstring>
#include <utility>
using namespace std;
const int MAXN = 200005;
pair <int, int> myPr[MAXN];
int N;
int main() {
	while (~scanf("%d", &N)) {
		for (int i = 0; i < N; ++i) {
			int x, y;
			scanf("%d%d", &x, &y);
			myPr[i] = make_pair(x - y, x + y);
		}
		sort(myPr, myPr + N);
		int now = 0, ans = 1;
		for (int i = 1; i < N; ++i) {
			if (myPr[i].first >= myPr[now].second) {
				now = i;
				++ans;
			}
			else if (myPr[i].second <= myPr[now].second) {
				now = i;
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}


#pragma comment(linker, "/STACK:134217728")

#include <cstdio>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <string>
#include <algorithm>
#include <numeric>
#include <functional>
#include <cmath>
#include <memory.h>
#include <time.h>

using namespace std;

typedef long long LL;

const int N = 1 << 19;

int n;

pair<int, int> a[1 << 18];
map<int, int> ID;
int Q[2 * N];
int t[N];

int get(int L, int R)
{
	int res = 0;
	for(L += N, R += N; L < R; L >>= 1, R >>= 1)
	{
		if (L & 1)
			res = max(res, Q[L++]);
		if (R & 1)
			res = max(res, Q[--R]);
	}
	return res;
}

void put(int pos, int val)
{
	pos += N;
	Q[pos] = max(Q[pos], val);
	pos >>= 1;
	while (pos)
	{
		Q[pos] = max(Q[2 * pos], Q[2 * pos + 1]);
		pos >>= 1;
	}
}

int main()
{
	scanf("%d", &n);
	for(int i = 0; i < n; ++i)
	{
		scanf("%d%d", &a[i].first, &a[i].second);
		t[i] = a[i].first - a[i].second;
		t[n + i] = a[i].first + a[i].second;
	}

	sort(a, a + n);
	sort(t, t + 2 * n);

	for(int i = 0; i < 2 * n; ++i)
		ID[t[i]] = i;

	for(int i = n - 1; i >= 0; --i)
		put(ID[a[i].first - a[i].second], get(ID[a[i].first + a[i].second], N) + 1);

	printf("%d\n", get(0, N));
	return 0;
}


#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
typedef long long ll;

struct Tree {
	ll n;
	vector<ll> tree;
	Tree() {}
	Tree(ll n): n(n), tree(n * 2, 0) {}
	void set(ll index, ll value) {
		index += n;
		tree[index] = max(tree[index], value);
		for (index >>= 1; index > 0; index >>= 1)
			tree[index] = max(tree[index], value);
	}
	ll get(ll l, ll r) {
		ll res = 0;
		for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
			if (l & 1)
				res = max(res, tree[l++]);
			if (r & 1)
				res = max(res, tree[--r]);
		}
		return res;
	}
};

bool comp(pair<ll, ll> const &a, pair<ll, ll> const &b) {
	return (a.first < b.first);
}

int main() {
	/*ifstream in;
	ofstream out;
	in.open("input.txt");
	out.open("output.txt");*/

	ll n, i, j, k, x, w;
	cin >> n;
	vector<pair<ll, ll> > starts(n);
	vector<pair<ll, ll> > ends(n);
	vector<ll> movedto(n);
	for (i = 0; i < n; i++) {
		cin >> x >> w;
		starts[i] = make_pair(x - w, i);
		ends[i] = make_pair(x + w, i);
	}

	sort(starts.begin(), starts.end(), comp);
	sort(ends.begin(), ends.end(), comp);
	for (i = 0; i < n; i++)
		movedto[starts[i].second] = i;
	for (i = 0; i < n; i++)
		starts[movedto[ends[i].second]].second = i;
	for (i = 1, j = 0, k = 0; i <= n; i++)
		if ((i == n) || (ends[i].first != ends[i - 1].first)) {
			for (; j < i; j++)
				ends[j].second = k;
			k++;
			j = i;
		}

	Tree tree(k);
	for (i = 0; i < n; i++) {
		j = lower_bound(ends.begin(), ends.end(), starts[i], comp)->second;
		tree.set(ends[starts[i].second].second, tree.get(0, j + 1) + 1);
	}

	cout << tree.get(0, k);

	return 0;
}


#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
typedef long long ll;

struct Tree {
	ll n;
	vector<ll> tree;
	Tree() {}
	Tree(ll n): n(n), tree(n * 2, 0) {}
	void set(ll index, ll value) {
		index += n;
		tree[index] = max(tree[index], value);
		for (index >>= 1; index > 0; index >>= 1)
			tree[index] = max(tree[index], value);
	}
	ll get(ll l, ll r) {
		ll res = 0;
		for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
			if (l & 1)
				res = max(res, tree[l++]);
			if (r & 1)
				res = max(res, tree[--r]);
		}
		return res;
	}
};

bool comp(pair<ll, ll> const &a, pair<ll, ll> const &b) {
	return (a.first < b.first);
}

int main() {
	/*ifstream in;
	ofstream out;
	in.open("input.txt");
	out.open("output.txt");*/

	ll n, i, j, k, x, w;
	cin >> n;
	vector<pair<ll, ll> > starts(n);
	vector<pair<ll, ll> > ends(n);
	vector<ll> movedto(n);
	for (i = 0; i < n; i++) {
		cin >> x >> w;
		starts[i] = make_pair(x - w, i);
		ends[i] = make_pair(x + w, i);
	}

	sort(starts.begin(), starts.end(), comp);
	sort(ends.begin(), ends.end(), comp);
	for (i = 0; i < n; i++)
		movedto[starts[i].second] = i;
	for (i = 0; i < n; i++)
		starts[movedto[ends[i].second]].second = i;
	for (i = 1, j = 0, k = 0; i <= n; i++)
		if ((i == n) || (ends[i].first != ends[i - 1].first)) {
			for (; j < i; j++)
				ends[j].second = k;
			k++;
			j = i;
		}

	Tree tree(k);
	for (i = 0; i < n; i++) {
		auto it = upper_bound(ends.begin(), ends.end(), starts[i], comp);
		if (it == ends.begin())
			j = -1;
		else
			j = (--it)->second;
		tree.set(ends[starts[i].second].second, tree.get(0, j + 1) + 1);
	}

	cout << tree.get(0, k);

	return 0;
}


#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
typedef long long ll;

struct Tree {
	ll n;
	vector<ll> tree;
	Tree() {}
	Tree(ll n): n(n), tree(n * 2, 0) {}
	void set(ll index, ll value) {
		index += n;
		tree[index] = max(tree[index], value);
		for (index >>= 1; index > 0; index >>= 1)
			tree[index] = max(tree[index], value);
	}
	ll get(ll l, ll r) {
		ll res = 0;
		for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
			if (l & 1)
				res = max(res, tree[l++]);
			if (r & 1)
				res = max(res, tree[--r]);
		}
		return res;
	}
};

bool comp(pair<ll, ll> const &a, pair<ll, ll> const &b) {
	return (a.first < b.first);
}

int main() {
	/*ifstream in;
	ofstream out;
	in.open("input.txt");
	out.open("output.txt");*/

	ll n, i, j, k, x, w;
	//in >> n;
	vector<pair<ll, ll> > starts(n);
	vector<pair<ll, ll> > ends(n);
	vector<ll> movedto(n);
	for (i = 0; i < n; i++) {
		//in >> x >> w;
		starts[i] = make_pair(x - w, i);
		ends[i] = make_pair(x + w, i);
	}

	sort(starts.begin(), starts.end(), comp);
	sort(ends.begin(), ends.end(), comp);
	for (i = 0; i < n; i++)
		movedto[starts[i].second] = i;
	for (i = 0; i < n; i++)
		starts[movedto[ends[i].second]].second = i;
	for (i = 1, j = 0, k = 0; i <= n; i++)
		if ((i == n) || (ends[i].first != ends[i - 1].first)) {
			for (; j < i; j++)
				ends[j].second = k;
			k++;
			j = i;
		}

	Tree tree(k);
	for (i = 0; i < n; i++) {
		j = lower_bound(ends.begin(), ends.end(), starts[i], comp)->second;
		tree.set(ends[starts[i].second].second, tree.get(0, j + 1) + 1);
	}

	//out << tree.get(0, k);

	return 0;
}


#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <cstring>
#include <algorithm>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <sstream>
using namespace std;
#pragma comment(linker, "/STACK:255000000")

typedef long long ll;

#define rep(i, a, b) for(i = (a); i < (b); ++i)
#define repb(i, a, b) for(i = (a) - 1; i >= (b); --i)
#define repd(i, a, b, d) for(i = (a); i < (b); i += (d))
#define repbd(i, a, b, d) for(i = (a) - 1; i >= (b); i -= (d))
#define reps(i, s) for(i = 0; (s)[i]; ++i)
#define repl(i, l) for(i = l.begin(); i != l.end(); ++i)

#define in(f, a) scanf("%"#f, &(a))

bool firstout = 1;

#define out(f, a) printf("%"#f, (a))
#define outf(f, a) printf((firstout) ? "%"#f : " %"#f, (a)), firstout = 0
#define nl printf("\n"), firstout = 1

#define all(x) (x).begin(),(x).end()
#define sqr(x) ((x) * (x))
#define mp make_pair

template<class T>
T &minn(T &a, T b)
{
    if(b < a) a = b;
    return a;
}

template<class T>
T &maxx(T &a, T b)
{
    if(a < b) a = b;
    return a;
}

#define inf 1012345678
#define eps 1e-9

#ifdef XDEBUG
#define mod 23
#else
#define mod 1000000007
#endif

int &madd(int &a, int b)
{
    a += b;
    if(a >= mod) a -= mod;
    return a;
}

int &msub(int &a, int b)
{
    a -= b;
    if(a < 0) a += mod;
    return a;
}

int &mmult(int &a, int b)
{
    return a = (ll)a * b % mod;
}

int mdiv(ll a, ll b, ll m)
{
    a = (a % m + m) % m;
    b = (b % m + m) % m;
    if(a % b == 0) return a / b;
    return (a + m * mdiv(-a, m, b)) / b;
}

#define N 401234
#define M 1012

int n, m, q;
pair<int, int> A[N];
pair<int, pair<int, int> > X[N];
int D[N], DD[N];
int P0[N], PP[N];

int fnd(int i);

int fndd(int i) {
    int &res = DD[i];
    if (res >= 0) return res;
    if (i == m) return res = 0;
    return maxx(res = fndd(i + 1), X[i].second.first == 1 ? fnd(P0[i]) : 0);
}

int fnd(int i) {
    int &res = D[i];
    if (res >= 0) return res;
    if (i == n) return res = 0;
    res = 1;
    int j = PP[i];
    res += fndd(j);
    return res;
}

int main()
{
#ifdef XDEBUG
	freopen("in.txt", "rt", stdin);
#else
#endif

    int i, j, k;
    char c;
    int a, d;

    int ts;
#if 0
	int tss;
	in(d, tss);
	rep(ts, 1, tss + 1)
#else
    for(ts = 1; in(d, n) > 0; ++ts)
#endif
    {
        rep(i, 0, n) in(d, A[i].first), in(d, A[i].second);
        m = 0;
        sort(A, A + n);
        rep(i, 0, n) X[m++] = mp(A[i].first + A[i].second, mp(-1, i)), X[m++] = mp(A[i].first - A[i].second, mp(1, i));
        sort(X, X + m);
        rep(i, 0, m) if(X[i].second.first == -1) PP[X[i].second.second] = i;
        else P0[i] = X[i].second.second;
        rep(i, 0, n + 1) D[i] = -1;
        rep(i, 0, m + 1) DD[i] = -1;
        int res = 0;
        rep(i, 0, n) maxx(res, fnd(i));
        out(d, res); nl;
    }

    return 0;
}


#include <sstream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <string>
#include <cassert>
#include <ctime>
#include <map>
#include <math.h>
#include <cstdio>
#include <set>
#include <deque>
#include <memory.h>
#include <queue>

#pragma comment(linker, "/STACK:50000000")
typedef long long ll;

using namespace std;

const int maxn = 1 << 18;
const int inf = 1e9;

int n;
pair<int, int> a[maxn], b[maxn];

int main() {
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
#endif

	while (scanf("%d", &n) == 1) {
		for (int i = 0; i < n; i++) {
			scanf("%d%d", &a[i].first, &a[i].second);
			b[i] = make_pair(a[i].first + a[i].second, a[i].first - a[i].second);
		}
		sort(b, b + n);

		int last = -2e9;
		int ans = 0;
		for (int i = 0; i < n; i++) {
			if (b[i].second >= last) {
				ans++;
				last = b[i].first;
			}
		}
		printf("%d\n", ans);
	}

	return 0;
}


#include <sstream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <string>
#include <cassert>
#include <ctime>
#include <map>
#include <math.h>
#include <cstdio>
#include <set>
#include <deque>
#include <memory.h>
#include <queue>

#pragma comment(linker, "/STACK:50000000")
typedef long long ll;

using namespace std;

const int maxn = 1 << 18;
const int inf = 1e9;

int n;
pair<int, int> a[maxn], b[maxn];

int main() {
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
#endif

	while (scanf("%d", &n) == 1) {
		for (int i = 0; i < n; i++) {
			scanf("%d%d", &a[i].first, &a[i].second);
			b[i] = make_pair(a[i].first - a[i].second, a[i].first + a[i].second);
		}
		sort(b, b + n);

		int last = -2e9;
		int ans = 0;
		for (int i = 0; i < n; i++) {
			if (a[i].first >= last) {
				ans++;
				last = a[i].second;
			}
		}
		printf("%d\n", ans);
	}

	return 0;
}


#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <algorithm>
#include <math.h>
#include <memory.h>

using namespace std;
#define MAX 200000

int main()
{
    int N;
    cin >> N;
    vector<pair<int, int> > v;
    for (int i = 0; i < N; i++)
    {
        int a, b;
        cin >>  a >> b;
        v.push_back(make_pair(a + b, a - b));
    }
    sort(v.begin(), v.end());
    vector<pair<int, int> > res;
    for (int i = 0; i < N; i++)
    {
        vector<pair<int, int> >::iterator it = upper_bound(res.begin(), res.end(), make_pair(v[i].second, 2000000000));
        int cnt = 1;
        if (it != res.begin())
        {
            it--;
            cnt += it->second;
        }
        if (res.size() == 0 || res[res.size() - 1].second < cnt)
            res.push_back(make_pair(v[i].first, cnt));
    }
    cout << res[res.size() - 1].second << "\n";
    return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <climits>
#include <string>
#include <vector>
#include <cassert>
#include <ctime>
#include <cmath>
#include <queue>
#include <deque>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <map>
#include <set>
#include <stack>

const long long MOD = 1000000000 + 7;
const long long MAXN = 100000 + 100;
const long long MAGIC = 123123123;

const double EPS = 1E-7;
#define TASK "taskname"

using namespace std;

struct cmp {
	bool operator()(const int & a, const int & b){
		return a > b;
	}
};

bool cmp(pair<int, int> a, pair<int, int> b) {
	if (a.second == b.second) {
		return a.first > b.first;
	}
	return a.second < b.second;
}

bool isInside(int w, pair<int, int>a) {
	return w > a.first && w < a.second;
}

bool good(pair<int, int>a, pair<int, int> b) {
	if (a.first > b.first){
		swap(a, b);
	}
	return !isInside(a.second, b) && !isInside(b.first, a);
}

int main(){
	//freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
	//freopen(TASK".in", "r", stdin);freopen(TASK".out", "w", stdout);
	int n;
	cin >> n;
	vector<pair<int, int>>vec(n);
	int c, r;
	for (int i = 0; i < n; ++i){
		scanf("%d%d", &c, &r);
		vec[i].first = c - r;
		vec[i].second = c + r;
	}
	sort(vec.begin(), vec.end(), cmp);
	pair<int, int>last = make_pair(-1000000000 - 1, -1000000000 - 1);
	int res = 0;
	for (int i = 0; i < n; ++i) {
		if (good(last, vec[i])) {
			last = vec[i];
			res++;
		}
	}
	cout << res;

	return 0;
}


#include <cstdio>
#include <algorithm>

using namespace std;

typedef pair < int, int > pii;

const int MAX = 200020, GAP = 262144;

int n, renum[MAX*2], rFull;
pii data[MAX];

void input() {
	scanf("%d", &n);

	int i;
	for (i = 0; i < n; i++) {
		scanf("%d%d", &data[i].first, &data[i].second);

		renum[rFull++] = data[i].first - data[i].second;
		renum[rFull++] = data[i].first + data[i].second;
	}

	sort(data, data+n);

	sort(renum, renum+rFull);
	rFull = unique(renum, renum+rFull) - renum;
}

int TREE[GAP << 1];

int getMax(int l, int r) {
	l += GAP;
	r += GAP;

	int ans = 0;
	while (l <= r) {
		if (l%2 == 1) {
			ans = max(ans, TREE[l]);
			l++;
		} else if (r%2 == 0) {
			ans = max(ans, TREE[r]);
			r--;
		} else {
			l >>= 1;
			r >>= 1;
		}
	}

	return ans;
}

void update(int pos, int val) {
	pos += GAP;

	while (TREE[pos] < val && pos >= 1) {
		TREE[pos] = val;
		pos >>= 1;
	}
}

int getIndex(int val) {
	return find(renum, renum+rFull, val) - renum;
}

void solve() {
	int ans = 1;

	int i;
	for (i = 0; i < n; i++) {
		auto &now = data[i];

		int curMax = getMax(0, getIndex(now.first - now.second)) + 1;
		ans = max(ans, curMax);

		update(getIndex(now.first + now.second), curMax);
	}

	printf("%d\n", ans);
}

int main() {
	input();

	solve();

	return 0;
}


#include <cstdio>
#include <algorithm>

using namespace std;

typedef pair < int, int > pii;

const int MAX = 200020, GAP = 524288;

int n, renum[MAX*2], rFull;
pii data[MAX];

void input() {
	scanf("%d", &n);

	int i;
	for (i = 0; i < n; i++) {
		scanf("%d%d", &data[i].first, &data[i].second);

		renum[rFull++] = data[i].first - data[i].second;
		renum[rFull++] = data[i].first + data[i].second;
	}

	sort(data, data+n);

	sort(renum, renum+rFull);
	rFull = unique(renum, renum+rFull) - renum;
}

int TREE[GAP << 1];

int getMax(int l, int r) {
	l += GAP;
	r += GAP;

	int ans = 0;
	while (l <= r) {
		if (l%2 == 1) {
			ans = max(ans, TREE[l]);
			l++;
		} else if (r%2 == 0) {
			ans = max(ans, TREE[r]);
			r--;
		} else {
			l >>= 1;
			r >>= 1;
		}
	}

	return ans;
}

void update(int pos, int val) {
	pos += GAP;

	while (TREE[pos] < val && pos >= 1) {
		TREE[pos] = val;
		pos >>= 1;
	}
}

int getIndex(int val) {
	return lower_bound(renum, renum+rFull, val) - renum;
}

void solve() {
	int ans = 1;

	int i;
	for (i = 0; i < n; i++) {
		auto &now = data[i];

		int curMax = getMax(0, getIndex(now.first - now.second)) + 1;
		ans = max(ans, curMax);

		update(getIndex(now.first + now.second), curMax);
	}

	printf("%d\n", ans);
}

int main() {
	input();

	solve();

	return 0;
}


#include <cstdio>
#include <algorithm>

using namespace std;

typedef pair < int, int > pii;

const int MAX = 200020, GAP = 262144;

int n, renum[MAX*2], rFull;
pii data[MAX];

void input() {
	scanf("%d", &n);

	int i;
	for (i = 0; i < n; i++) {
		scanf("%d%d", &data[i].first, &data[i].second);

		renum[rFull++] = data[i].first - data[i].second;
		renum[rFull++] = data[i].first + data[i].second;
	}

	sort(data, data+n);

	sort(renum, renum+rFull);
	rFull = unique(renum, renum+rFull) - renum;
}

int TREE[GAP << 1];

int getMax(int l, int r) {
	l += GAP;
	r += GAP;

	int ans = 0;
	while (l <= r) {
		if (l%2 == 1) {
			ans = max(ans, TREE[l]);
			l++;
		} else if (r%2 == 0) {
			ans = max(ans, TREE[r]);
			r--;
		} else {
			l >>= 1;
			r >>= 1;
		}
	}

	return ans;
}

void update(int pos, int val) {
	pos += GAP;

	while (TREE[pos] < val && pos >= 1) {
		TREE[pos] = val;
		pos >>= 1;
	}
}

int getIndex(int val) {
	return lower_bound(renum, renum+rFull, val) - renum;
}

void solve() {
	int ans = 1;

	int i;
	for (i = 0; i < n; i++) {
		auto &now = data[i];

		int curMax = getMax(0, getIndex(now.first - now.second)) + 1;
		ans = max(ans, curMax);

		update(getIndex(now.first + now.second), curMax);
	}

	printf("%d\n", ans);
}

int main() {
	input();

	solve();

	return 0;
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<stack>
#include<cstdlib>
#include<string>
#include<bitset>
#define INF 1000000000
#define N 400005
#define fi first
#define se second
#define debug(x) cout<<#x<<"="<<x<<endl
#define MP(x,y) make_pair(x,y)
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
int n;
int dp[N],b[N*2],c[N],z;
map<int,int> mp;
pii p[N];
void add(int w,int x)
{
    for(;x<=z;x+=x&-x)
        c[x]=max(c[x],w);
}

int get(int x)
{
    int ans=0;
    for(;x;x-=x&-x)
        ans=max(ans,c[x]);
    return ans;
}
int main()
{
    int i,ans=1,now;
    cin>>n;
    for(i=1;i<=n;i++)
    {
        scanf("%d%d",&p[i].fi,&p[i].se);
        b[i]=p[i].fi+p[i].se;
        b[i+n]=p[i].fi-p[i].se;
    }
    sort(b+1,b+1+n*2);
    z=unique(b+1,b+1+n*2)-(b+1);
    for(i=1;i<=z;i++)
        mp[b[i]]=i;
    sort(p+1,p+1+n);
    for(i=1;i<=n;i++)
    {
        now=get(mp[p[i].fi-p[i].se]);
        dp[i]=now+1;
        add(dp[i],mp[p[i].fi+p[i].se]);
        ans=max(ans,dp[i]);
    }
    cout<<ans<<endl;
    return 0;
}
// davidlee1999WTK 2015/
// srO myk Orz
//ios::sync_with_stdio(false);
//#pragma comment(linker, "/STACK:102400000,102400000")


#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <climits>

using namespace std;

vector<pair<int, int>> pts;

const int SIZE = 2e5+100;

int dp[SIZE];

int dfs(int pos)
{
	if (dp[pos] != -1)
		return dp[pos];
	int max = 0, min_ = INT_MAX;
	for (int i = pos+1; i < pts.size(); i++)
	{
		if (pts[pos].second > pts[i].first)
			continue;
		min_ = min(min_, pts[i].second);
		if (min_ < pts[i].first)
			break;
		int cur = 1 + dfs(i);
		if (max < cur)
			max = cur;
	}
	return (dp[pos] = max);
}

int main()
{
#ifdef LOCAL
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		int x, w;
		cin >> x >> w;
		pts.push_back(make_pair(x-w, x+w));
	}
	sort(pts.begin(), pts.end());
	for (int i = 0; i < n; i++)
		dp[i] = -1;
	int max = 0;
	for (int i = 0; i < pts.size(); i++)
	{
		int cur = dfs(i) + 1;
		if (cur > max)
			max = cur;
	}
	cout << max;
}


#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <climits>

using namespace std;

vector<pair<int, int>> pts;

const int SIZE = 2e5+100;
const int INF = -INT_MAX;

int dp[SIZE];

int main()
{
#ifdef LOCAL
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		int x, w;
		cin >> x >> w;
		pts.push_back(make_pair(x+w, x-w));
	}
	sort(pts.begin(), pts.end());
	for (int i = 0; i < n; i++)
	{
		int pos = lower_bound(pts.begin(), pts.end(), make_pair(pts[i].second, -INF)) - pts.begin();
		if (pos == 0)
			dp[i] = 1;
		else
		{
			if (pts[i].second != pts[i].first)
				dp[i] = dp[pos-1] + 1;
			else
				dp[i] = dp[pos] + 1;
		}
		if (i > 0)
			dp[i] = max(dp[i], dp[i-1]);
	}
	cout << dp[n-1];
}


#include <iostream>
#include <vector>
#include <set>
#include <algorithm>

using namespace std;

vector<pair<int, int>> pts;

const int SIZE = 2e5+100;

int dp[SIZE];

int dfs(int pos)
{
	if (dp[pos] != -1)
		return dp[pos];
	int max = 0;
	for (int i = pos+1; i < pts.size(); i++)
	{
		if (pts[pos].second > pts[i].first)
			continue;
		int cur = 1 + dfs(i);
		if (max < cur)
			max = cur;
	}
	return (dp[pos] = max);
}

int main()
{
#ifdef LOCAL
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		int x, w;
		cin >> x >> w;
		pts.push_back(make_pair(x-w, x+w));
	}
	sort(pts.begin(), pts.end());
	for (int i = 0; i < n; i++)
		dp[i] = -1;
	int max = 0;
	for (int i = 0; i < pts.size(); i++)
	{
		int cur = dfs(i) + 1;
		if (cur > max)
			max = cur;
	}
	cout << max;
}


#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <climits>

using namespace std;

vector<pair<int, int>> pts;

const int SIZE = 2e5+100;
const int INF = -INT_MAX;

int dp[SIZE];

int main()
{
#ifdef LOCAL
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		int x, w;
		cin >> x >> w;
		pts.push_back(make_pair(x+w, x-w));
	}
	sort(pts.begin(), pts.end());
	for (int i = 0; i < n; i++)
	{
		int pos = lower_bound(pts.begin(), pts.end(), make_pair(pts[i].second+1, -INF)) - pts.begin();
		if (pos == 0)
			dp[i] = 1;
		else
			dp[i] = dp[pos-1] + 1;
		dp[i] = max(dp[i], dp[i-1]);
	}
	cout << dp[n-1];
}


#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <climits>

using namespace std;

vector<pair<int, int>> pts;

const int SIZE = 2e5+100;
const int INF = -INT_MAX;

int dp[SIZE];

int main()
{
#ifdef LOCAL
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		int x, w;
		cin >> x >> w;
		pts.push_back(make_pair(x+w, x-w));
	}
	sort(pts.begin(), pts.end());
	int ans = 1, l = 0;
	for (int i = 1; i < n; i++)
	{
		if (pts[i].second >= pts[l].first)
		{
			ans++;
			l = i;
		}
	}
	cout << ans;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <stdio.h>
using namespace std;

typedef long long ll;
typedef std::vector<int> vi;
typedef std::vector<bool> vb;
typedef std::vector<long long> vll;
typedef std::vector<std::vector<int> > vvi;

#define all(c) (c).begin(),(c).end()
#define sz(c) (int)(c).size()

#define pb push_back
#define mp make_pair

long long gcd(long long a, long long b){
    if(a==0) return b;
    if(b==0) return a;
    if(a>b) return gcd(b, a%b);
    return gcd(a,b%a);
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "rt", stdin);
    freopen("output.txt", "wt", stdout);
    #endif
    int n, x, w;
    cin >> n;
    set<pair<int,int> > seg;
    for(int i=0; i<n; i++) {
        cin>>x>>w;
        seg.insert(mp(x+w, x-w));
    }
    //sort(all(seg));
    vi ms(n+1,0);
    map<pair<int,int>, int> maxnum;
    auto it = seg.begin();
    for(int i=1; i<=n; i++) {
        int y = (*it).first;
        x = (*it).second;
        if (x==y) {
            ms[i] = ms[i-1] + 1;
            maxnum[mp(x,x)] = ms[i];
        }
        else {
            auto it2 = seg.upper_bound(mp(x,x+1));
            it2--;
            //cout<<i<<"   "<< (*it2).
            int m = max(maxnum[*it2]+1, ms[i-1]);
            maxnum[mp(y,x)] = m;
            ms[i]=m;
        }
        it++;
    }
    cout << ms[n];
}


#include <stdio.h>
#include <set>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;

int n;
struct pt
{
	int x, w;
} p[200010];
bool cmp(pt a, pt b)
{
	return a.x < b.x;
}

set <int> sums;
int sorted[200010], pt = 0;
map <int, int> mapped;

int t[800010];

void build(int v, int l, int r)
{
	if (l == r)
		t[v] = -1;
	else
	{
		int mid = (l + r) >> 1;
		build(v << 1, l, mid);
		build((v << 1) + 1, mid + 1, r);
		t[v] = -1;
	}
}

int query(int v, int tl, int tr, int l, int r)
{
	if (l > r)
		return -1;
	if (tl == l && tr == r)
		return t[v];
	int mid = (tl + tr) >> 1;
	return max(query(v << 1, tl, mid, l, min(r, mid)), query((v << 1) + 1, mid + 1, tr, max(l, mid + 1), r));
}

void update(int v, int l, int r, int x, int val)
{
	if (l == r)
		t[v] = max(t[v], val);
	else
	{
		int mid = (l + r) >> 1;
		if (x <= mid)
			update(v << 1, l, mid, x, val);
		else
			update((v << 1) + 1, mid + 1, r, x, val);
		t[v] = max(t[v << 1], t[(v << 1) + 1]);
	}
}

int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	scanf("%d", &n);
	for (int i = 0; i < n; ++i)
		scanf("%d %d", &p[i].x, &p[i].w);
	sort(p, p + n, cmp);
	for (int i = 0; i < n; ++i)
		sums.insert(p[i].x + p[i].w);
	while (!sums.empty())
	{
		sorted[pt] = *sums.begin();
		sums.erase(sums.begin());
		++pt;
	}
	for (int i = 0; i < pt; ++i)
		mapped[sorted[pt]] = i;
	build(1, 0, n - 1);
	update(1, 0, n - 1, mapped[p[0].x + p[0].w], 1);
	for (int i = 1; i < n; ++i)
	{
		int ll = -1, rr = pt;
		while (ll < rr - 1)
		{
			int mid = (ll + rr) >> 1;
			if (sorted[mid] <= p[i].x - p[i].w)
				ll = mid;
			else
				rr = mid;
		}
		int z = query(1, 0, n - 1, 0, ll);
		if (z > -1)
			update(1, 0, n - 1, mapped[p[i].x + p[i].w], z + 1);
		else
			update(1, 0, n - 1, mapped[p[i].x + p[i].w], 1);
	}
	printf("%d\n", t[1]);
	return 0;
}