#include <cstdio>
#include <cstdlib>
#include <map>
#include <algorithm>
#include <vector>
#include <cassert>
using namespace std;
#define maxN 100100
#define maxK 300100
#define maxV 1200300
#define oo 2000000000
#undef DEBUG
struct stalp {
int P, C, St, Dr;
} A[maxN];
map < int, int > MyMap;
int N;
int start, finish, poz, level[maxN];
int Arb[maxK * 4 + 100], SolQuery, val, C[maxN];
inline bool cmp (stalp a, stalp b) {
if (a.P != b.P)
return a.P < b.P;
return a.St < b.St;
}
void normalizare () {
vector < int > Tmp;
vector < int > :: iterator it;
stalp now;
int i;
for (i = 1; i <= N; ++ i) {
Tmp.push_back(A[i].P);
Tmp.push_back(A[i].P - A[i].St);
Tmp.push_back(A[i].P + A[i].Dr);
}
sort(Tmp.begin(), Tmp.end());
it = unique(Tmp.begin(), Tmp.end());
Tmp.resize(it - Tmp.begin());
for (i = 0; i < Tmp.size(); ++ i) MyMap[Tmp[i]] = i + 1;
for (i = 1; i <= N; ++ i) {
now.P = MyMap[A[i].P];
now.St = MyMap[A[i].P - A[i].St];
now.Dr = MyMap[A[i].P + A[i].Dr];
now.C = A[i].C;
A[i] = now;
}
}
int lower_bound_x (int nr, int now) {
int st = 1, dr = now - 1, m = (st + dr) / 2;
while (st < dr) {
if (A[m].P > nr)
dr = m - 1;
else
st = m + 1;
m = (st + dr) / 2;
}
while (m > 0 && A[m].P > nr) --m;
return m;
}
inline int minim(int a, int b) {
if (a > b)
return b;
return a;
}
void query ( int frunza) {
int nod;
SolQuery = oo;
for ( nod = level[frunza]; nod; nod >>= 1)
if (Arb[nod] != oo) {
SolQuery = Arb[nod];
return ;
}
}
void update (int nod, int l, int r) {
if (start <= l && r <= finish) {
if (Arb[nod] > val)
Arb[nod] = val;
return ;
}
int m = (l + r) >> 1;
if (start <= m)
update(nod * 2, l, m);
if (m < finish)
update(nod * 2 + 1, m + 1, r);
//Arb[nod] = minIm(Arb[nod * 2], Arb[nod * 2 + 1]);
}
void explore (int nod, int l, int r) {
if (l == r) {
level[l] = nod;
return ;
}
int m = (l + r) >> 1;
explore(nod * 2, l, m);
explore(nod * 2 + 1, m + 1, r);
}
int main () {
int i, x, j;
freopen("stalpi.in", "r", stdin);
freopen("stalpi.out", "w", stdout);
scanf("%d", &N);
for (i = 1; i <= N; ++ i)
scanf("%d%d%d%d", &A[i].P, &A[i].C, &A[i].St, &A[i].Dr);
normalizare();
sort (A + 1, A + N + 1, cmp);
for (i = 1; i <= maxV; ++ i)
Arb[i] = oo;
explore(1, 1, 3 * N);
start = A[1].St; finish = A[1].Dr; val = A[1].C;
update(1, 1, 3 * N);
for (i = 2; i <= N; ++ i) {
x = lower_bound_x(A[i].St, i);
if (x) {
query (A[x].P);
if (SolQuery == oo)
SolQuery = 0;
assert (SolQuery != oo);
val = SolQuery + A[i].C;
}
else
val = A[i].C;
start = A[i].St; finish = A[i].Dr;
update (1, 1, 3 * N);
//C[i] = val;
}
#ifdef DEBUG
for (i = 1; i <= N; ++ i)
printf("%lld ", C[i]); puts("");
for (i = 0; i < 5; ++ i) {
for (j = (1 << i); j < (2 << i); ++ j)
printf("%lld ", Arb[j]);
puts("");
}
#endif
query (A[N].P);
printf("%d\n", SolQuery);
}