#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int INF = 1e9;
struct SegMin {
int n; vector<int> st;
SegMin(){}
SegMin(const vector<int>& a){ build(a); }
void build(const vector<int>& a){
int m = a.size()-1;
n = 1; while(n < m) n <<= 1;
st.assign(2*n, INF);
for(int i=1;i<=m;i++) st[n+i-1] = a[i];
for(int i=n-1;i>=1;i--) st[i]=min(st[2*i], st[2*i+1]);
}
int query(int l,int r){
if(l>r) return INF;
l = l + n - 1; r = r + n - 1;
int res = INF;
while(l<=r){
if(l&1) res = min(res, st[l++]);
if(!(r&1)) res = min(res, st[r--]);
l >>= 1; r >>= 1;
}
return res;
}
};
struct SegMax {
int n; vector<int> st;
SegMax(){}
SegMax(const vector<int>& a){ build(a); }
void build(const vector<int>& a){
int m = a.size()-1;
n = 1; while(n < m) n <<= 1;
st.assign(2*n, 0);
for(int i=1;i<=m;i++) st[n+i-1] = a[i];
for(int i=n-1;i>=1;i--) st[i]=max(st[2*i], st[2*i+1]);
}
int query(int l,int r){
if(l>r) return 0;
l = l + n - 1; r = r + n - 1;
int res = 0;
while(l<=r){
if(l&1) res = max(res, st[l++]);
if(!(r&1)) res = max(res, st[r--]);
l >>= 1; r >>= 1;
}
return res;
}
};
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
if(!(cin >> n)) return 0;
vector<long long> x(n+1), r(n+1);
for(int i=1;i<=n;i++) cin >> x[i] >> r[i];
// direct intervals
vector<int> L0(n+1), R0(n+1);
for(int i=1;i<=n;i++){
long long leftpos = x[i] - r[i];
long long rightpos = x[i] + r[i];
int l = lower_bound(x.begin()+1, x.begin()+n+1, leftpos) - (x.begin()+1) + 1;
if(l < 1) l = 1;
int ridx = upper_bound(x.begin()+1, x.begin()+n+1, rightpos) - (x.begin()+1);
if(ridx < 1) ridx = 1;
if(ridx > n) ridx = n;
L0[i] = l;
R0[i] = ridx;
}
// binary lifting levels
int LOG = 1;
while((1<<LOG) <= n) ++LOG;
// left[k][i], right[k][i] after applying 2^k expansions starting from i (i interpreted as index interval [i,i])
// We'll store as vectors per level with 1-based indexing.
vector<vector<int>> leftk(LOG, vector<int>(n+1));
vector<vector<int>> rightk(LOG, vector<int>(n+1));
// level 0 = direct
for(int i=1;i<=n;i++){ leftk[0][i] = L0[i]; rightk[0][i] = R0[i]; }
// Build for levels k>=1
for(int k=1;k<LOG;k++){
// We need to compute for every i:
// leftk[k][i] = min_{j in [ leftk[k-1][i] .. rightk[k-1][i] ]} leftk[k-1][j]
// rightk[k][i] = max_{j in [ leftk[k-1][i] .. rightk[k-1][i] ]} rightk[k-1][j]
SegMin segmin(leftk[k-1]);
SegMax segmax(rightk[k-1]);
for(int i=1;i<=n;i++){
int l = leftk[k-1][i], r_ = rightk[k-1][i];
int nl = segmin.query(l, r_);
int nr = segmax.query(l, r_);
leftk[k][i] = nl;
rightk[k][i] = nr;
}
}
// For each i compute final closure interval by greedy binary lifting:
ll ans = 0;
for(int i=1;i<=n;i++){
int L = leftk[0][i], R = rightk[0][i]; // start from direct (one step), could also start [i,i]
// try apply larger jumps from high to low: if applying expands, take it
for(int k = LOG-1; k>=0; --k){
// compute what applying 2^k on the whole current [L..R] would produce:
// that is: nl = min leftk[k][j] for j in [L..R], nr = max rightk[k][j] for j in [L..R]
// To answer these fast we can query precomputed segment trees per level.
// But we don't want to rebuild segtrees for every i; instead build segtrees per level once:
// To avoid rebuilding here, we create segtrees outside loop. (Do it above.)
}
}
// The code above planned segtrees per level in the inner loop but we didn't build them outside.
// Let's build segtrees per level now and then re-run the final computation.
vector<SegMin> segmins(LOG);
vector<SegMax> segmaxs(LOG);
for(int k=0;k<LOG;k++){
segmins[k].build(leftk[k]);
segmaxs[k].build(rightk[k]);
}
// Now compute closures with those segtrees
ans = 0;
for(int i=1;i<=n;i++){
int L = leftk[0][i], R = rightk[0][i];
// We'll try to apply jumps to expand until fixed point
for(int k = LOG-1; k>=0; --k){
int nl = segmins[k].query(L, R);
int nr = segmaxs[k].query(L, R);
if(nl < L || nr > R){
L = nl; R = nr;
}
}
ll si = (ll)R - (ll)L + 1;
ans += (ll)i * si;
}
cout << ans << '\n';
return 0;
}