#include<bits/stdc++.h>
using namespace std;

#define INF 1234567890
#define ll long long

ll sum = 0;
int N;
int A[100101], C[100101];
ll dp[100101];

// 압축 20만개
ll seg1[530000], seg2[530000];

ll Update(ll seg[], int idx, ll val, int n, int l, int r) // min update
{
	if (r < idx || idx < l) return seg[n];
	if (l == r) return seg[n] = min(seg[n], val);
	int mid = l+r>>1;
	return seg[n] = min(Update(seg, idx, val, n<<1, l, mid), Update(seg, idx, val, n<<1|1, mid+1, r));
}

ll Query(ll seg[], int L, int R, int n, int l, int r) // min
{
	if (r < L || R < l) return (ll)1e18;
	if (L <= l && r <= R) return seg[n];
	int mid = l+r>>1;
	return min(Query(seg, L, R, n<<1, l, mid), Query(seg, L, R, n<<1|1, mid+1, r));
}

int main()
{
	memset(seg1, 0x3f, sizeof(seg1));
	memset(seg2, 0x3f, sizeof(seg2));
	scanf("%d", &N);
	vector<int> com;
	vector<pair<int, int> > v;
	for(int i=1; i<=N; i++)
	{
		scanf("%d %d", &A[i], &C[i]);
		com.push_back(A[i]);
		com.push_back(A[i]+C[i]);
		sum += C[i];

		v.push_back({A[i], i});
	}
	sort(com.begin(), com.end());
	com.erase(unique(com.begin(), com.end()), com.end());
	sort(v.rbegin(), v.rend());

	vector<int> upd;
	for(int i=0; i<v.size(); i++)
	{
		int k = v[i].second;
		int nx = lower_bound(com.begin(), com.end(), A[k]) - com.begin();
		int nnx = lower_bound(com.begin(), com.end(), A[k]+C[k]) - com.begin();

		if (v[i].first == v[0].first) // rightmost
		{
			dp[k] = 0;
		}
		else
		{
			dp[k] = Query(seg1, nx+1, nnx, 1, 0, (int)com.size()-1);
			dp[k] = min(dp[k], Query(seg2, nnx+1, (int)com.size()-1, 1, 0, (int)com.size()-1) - A[k] - C[k]);
		}

		upd.push_back(v[i].second);
		if (i+1 == v.size() || v[i].first != v[i+1].first) // 업뎃 몰아서 하기
		{
			for(int j : upd)
			{
				int x = lower_bound(com.begin(), com.end(), A[j]) - com.begin();
				Update(seg1, x, dp[j], 1, 0, (int)com.size()-1);
				Update(seg2, x, dp[j]+A[j], 1, 0, (int)com.size()-1);
			}			
			upd.clear();
		}
	}
	// mid -> rightmost
	ll res = (ll)1e18;
	for(int i=1; i<=N; i++)
		if (A[i] <= A[1])
			res = min(res, dp[i]);

	memset(seg1, 0x3f, sizeof(seg1));
	memset(seg2, 0x3f, sizeof(seg2));

	for(int i=0; i<v.size(); i++)
	{
		int k = v[i].second;
		int nx = lower_bound(com.begin(), com.end(), A[k]) - com.begin();
		int nnx = lower_bound(com.begin(), com.end(), A[k]+C[k]) - com.begin();

		if (v[i].first >= A[1]) // rightmost
		{
			dp[k] = 0;
		}
		else
		{
			dp[k] = Query(seg1, nx+1, nnx, 1, 0, (int)com.size()-1);
			dp[k] = min(dp[k], Query(seg2, nnx+1, (int)com.size()-1, 1, 0, (int)com.size()-1) - A[k] - C[k]);
		}

		upd.push_back(v[i].second);
		if (i+1 == v.size() || v[i].first != v[i+1].first) // 업뎃 몰아서 하기
		{
			for(int j : upd)
			{
				int x = lower_bound(com.begin(), com.end(), A[j]) - com.begin();
				Update(seg1, x, dp[j], 1, 0, (int)com.size()-1);
				Update(seg2, x, dp[j]+A[j], 1, 0, (int)com.size()-1);
			}			
			upd.clear();
		}
	}
	// leftmost -> mid
	ll res2 = (ll)1e18;
	for(int i=1; i<=N; i++)
		if (A[i] == v.back().first) // leftmost
			res2 = min(res2, dp[i]);

	printf("%lld\n", res + res2 + sum);
	return 0;
}