#include <iostream>
#include<unordered_map>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
#include <queue>
#include <deque>
#include <bitset>
#include <iterator>
#include <list>
#include <stack>
#include <map>
#include <set>
#include <functional>
#include <numeric>
#include <utility>
#include <limits>
#include <time.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define ff(i,a,n) for(int i=a; i<n; i++)
#define fb(i,a,n) for(int i=a; i>n; i--)
#define ll long long int
#define lc(x) (2*x)+1
#define rc(x) (2*x)+2
using namespace std;
typedef vector<int> vi;
typedef vector<vi> vvi;
/* -------SEGMENT TREE------------------------------
ll n;
const int N = 2e5;
vector<ll> st(4 * N);
vector<ll> a(N);

ll combine(ll a, ll b) {
    return a + b;
}

void build(ll x = 0, ll l = 0, ll r = n) {
    if (l == r - 1) return void(st[x] = a[l]);
    ll mid = (l + r) / 2;
    build(lc(x), l, mid);
    build(rc(x), mid, r);
    st[x] = combine(st[lc(x)], st[rc(x)]);
}

void update(ll pos, ll val, ll x = 0, ll l = 0, ll r = n) {
    if (l > pos || r <= pos) return;
    if (l == r - 1) {
        st[x] = val;
        a[pos] = val;
        return;
    }
    ll mid = (l + r) / 2;
    update(pos, val, lc(x), l, mid);
    update(pos, val, rc(x), mid, r);
    st[x] = combine(st[lc(x)], st[rc(x)]);
}

ll query(ll L, ll R, ll x = 0, ll l = 0, ll r = n) {
    if (R <= l || r <= L) return 0;
    if (l >= L && r<= R) return st[x];
    ll mid = (l + r) / 2;
    return combine(query(L, R, lc(x), l, mid), query(L, R, rc(x), mid, r));
}
*/

/* -----BIT or Fenwick Tree----- */

//void update(vector<ll> &BIT, int index, ll x) {
//    index++; // 1 based indexing for BIT
//    while (index < BIT.size()) {
//        BIT[index] += x;
//        index += (index & (-index));
//    }
//}
//
//ll getSum(vector<ll>& BIT, int l) {
//    l++;  // 1 based indexing for BIT
//    ll sum = 0;
//    while (l > 0) {
//        sum += BIT[l];
//        l -= (l & (-l));
//    }
//    return sum;
//}
//
//ll getRangeSum(vector<ll>& BIT, int l, int r) {
//    return getSum(BIT, r) - getSum(BIT, l - 1);
//}
//
//vector<ll> buildBIT(vector<ll>& a) {
//    int n = a.size();
//    vector<ll> BIT(n + 1,0); // 1 based indexing for BIT
//    ff(i, 0, n ) {
//        update(BIT,i,a[i]);
//    }
//    return BIT;
//}
//int gcd(int a, int b) {
//    if (b == 0) return a;
//    return gcd(b, a % b);
//}

bool compare(pair<ll, ll>a, pair<ll, ll>b) {
    return (a.second < b.second);
}

void solve() {
    int n;
    cin >> n;
    vector <pair<ll,ll>> a(n);
    ff(i, 0, n) {
        cin >> a[i].first >> a[i].second;
    }
    sort(a.begin(), a.end(),compare);
    int i = 0, j = n - 1;
    ll tot = 0;
    ll cost = 0;
    while (i <= j) {
        if (a[i].second <= tot) {
            tot += a[i].first;
            cost+=a[i].first;
            i++;
        }
        else {
            ll need = a[i].second-tot;
            while (a[i].second > tot and i<=j) {
                if (need >= a[j].first) {
                    tot += a[j].first;
                    need -= a[j].first;
                    cost += 2 * a[j].first;
                    j--;
                }
                else {
                    tot += need;
                    a[j].first -= need;
                    cost += 2 * need;
                }
            }
        }
    }
    cout << cost;

}

int main() {
    int t = 1;
    //cin >> t;
    while (t--) {
        solve();
        cout << endl;
    }
    return 0;
}