#include <bits/stdc++.h>
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, bucket, aux;
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;
}
long long dp[MAX_N + 5];
struct SEGTREE{
long long aint[4 * (MAX_N+1) + 5], lazy[4 * (MAX_N+1) + 5];
inline void build(int nod=1, int st=0, int dr=n){
lazy[nod] = -1;
if(st == dr){
if(st == 0)
aint[nod] = 0;
else
aint[nod] = INF;
}else{
int md = ((st + dr) >> 1);
build(2*nod , st , md);
build(2*nod+1, md+1, dr);
aint[nod] = min(aint[2*nod], aint[2*nod+1]);
}
}
inline void propag(int nod, int st, int dr){
if(lazy[nod] != -1){
aint[nod] = min(aint[nod], lazy[nod]);
if(st != dr)
lazy[2*nod] = lazy[2*nod+1] = lazy[nod];
lazy[nod] = -1;
}
return;
}
inline void update(int ust, int udr, long long val, int nod=1, int st=0, int dr=n){
propag(nod, st, dr);
if(udr < st || dr < ust)
return;
if(ust <= st && dr <= udr){
lazy[nod] = val;
propag(nod, st, dr);
return;
}else{
int md = ((st + dr) >> 1);
update(ust, udr, val, 2*nod , st , md);
update(ust, udr, val, 2*nod+1, md+1, dr);
propag(2*nod , st , md);
propag(2*nod+1, md+1, dr);
aint[nod] = min(aint[2*nod], aint[2*nod+1]);
}
}
inline int query(int poz, int nod=1, int st=0, int dr=n){
propag(nod, st, dr);
if(st == dr){
return aint[nod];
}else{
int md = ((st + dr) >> 1);
propag(2*nod , st , md);
propag(2*nod+1, md+1, dr);
if(poz <= md)
return query(poz, 2*nod , st , md);
else
return query(poz, 2*nod+1, md+1, dr);
}
}
} tree;
int main (){
ios_base::sync_with_stdio(false);
fin.tie(nullptr), fout.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);
///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();
bucket = (int)log2(n);
for(int i=1, newval; i<=n; i++){
for(int j=1; j<=n; j+=bucket)
aux = tree.query(j);
newval = tree.query(v[i].st-1) + v[i].cost;
tree.update(v[i].st, v[i].dr, newval);
//for(int j=0; j<=n; j++)
// cout<<tree.query(j)<<"\n";
//cout<<"\n";
}
fout<<tree.query(n);
return 0;
}
/**
3 10
3 5
1 3
2 3
**/