#include <bits/stdc++.h>
#pragma GCC optimize ("O3")
#pragma GCC target ("popcnt")
using namespace std;
ifstream fin ("stalpi.in");
ofstream fout ("stalpi.out");
const long long INF = LONG_MAX;
const int MAX_N = 100000;
int n, l, m, r, save;
struct stalp{
int st, dr, cost, x;
inline bool operator < (const stalp &rhs) const{
return x < rhs.x;
}
} v[MAX_N + 5];
inline bool cmp(const stalp &s1, const stalp &s2){
return s1.st < s2.st;
}
struct SEGTREE{
long long aint[MAX_N + 5], lazy_update[4 * MAX_N + 5];
bitset <4 * MAX_N + 5> lazy;
inline void build(int nod=1, int st=1, int dr=n){
lazy[nod] = false;
if(st == dr){
aint[st] = INF;
}else{
int md = ((st + dr) >> 1);
build(2*nod , st , md);
build(2*nod+1, md+1, dr);
}
return;
}
inline void propag(int nod, int st, int dr){
if(lazy[nod] == true){
lazy[nod] = false;
if(st == dr){
aint[st] = min(aint[st], lazy_update[nod]);
}else{
if(lazy[2*nod] == true)
lazy_update[2*nod] = min(lazy_update[2*nod], lazy_update[nod]);
else{
lazy[2*nod] = true;
lazy_update[2*nod] = lazy_update[nod];
}
if(lazy[2*nod+1] == true)
lazy_update[2*nod+1] = min(lazy_update[2*nod+1], lazy_update[nod]);
else{
lazy[2*nod+1] = true;
lazy_update[2*nod+1] = lazy_update[nod];
}
}
}
return;
}
inline void update(int val, int ust, int udr, int nod=1, int st=1, int dr=n){
if(st > dr)
return;
propag(nod, st, dr);
if(udr < st || dr < ust)
return;
if(ust <= st && dr <= udr){
lazy[nod] = true;
lazy_update[nod] = val;
}else{
int md = ((st + dr) >> 1);
update(val, ust, udr, 2*nod , st , md);
update(val, ust, udr, 2*nod+1, md+1, dr);
}
return;
}
inline long long query(int poz, int nod=1, int st=1, int dr=n){
propag(nod, st, dr);
if(st == dr){
return aint[st];
}else{
int md = ((st + dr) >> 1);
if(poz <= md)
return query(poz, 2*nod , st , md); ///prima jumatate
else
return query(poz, 2*nod+1, md+1, dr); ///a doua jumatate
}
}
} tree;
int main (){
ios_base::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
fin>>n;
for(int i=1; i<=n; i++){
fin>>v[i].x>>v[i].cost>>v[i].st>>v[i].dr;
v[i].st = v[i].x - v[i].st;
v[i].dr = v[i].x + v[i].dr;
}
sort(v+1, v+n+1);
for(int i=1; i<=n; i++){
l = 1;
save = r = i;
while(l <= r){
m = ((l + r) >> 1);
if(v[i].st <= v[m].x){
save = m;
r = m - 1;
}else
l = m + 1;
}
v[i].st = save;
save = l = i;
r = n;
while(l <= r){
m = ((l + r) >> 1);
if(v[m].x <= v[i].dr){
save = m;
l = m + 1;
}else
r = m - 1;
}
v[i].dr = save;
}
sort(v+1, v+n+1, cmp);
/**
long long dp[MAX_N + 5];
for(int i=1; i<=n; i++)
dp[i] = INF;
dp[0] = 0;
for(int i=1; i<=n; i++)
for(int j=v[i].st; j<=v[i].dr; j++)
dp[j] = min(dp[j], dp[v[i].st-1] + v[i].cost);
fout<<dp[n];
**/
tree.build();
for(int i=1; i<=n; i++){
long long newval = v[i].cost;
if(v[i].st > 1)
newval += tree.query(v[i].st-1);
tree.update(newval, v[i].st, v[i].dr);
}
fout<<tree.query(n);
return 0;
}
/**
4
3 1 3 5
1 10 10 9
7 2 5 3
10 18 4 4
**/