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

#define rep(i,n) for (int i=0;i<(n);i++)
#define rep2(i,a,b) for (int i=(a);i<(b);i++)
#define all(a) (a).begin(),(a).end()

int calcDP(const vector<int>& w, int width) {
    int N = w.size();
    vector<vector<bool>> dp(N + 1, vector<bool>(width + 1));
    dp[0][0] = true;
    int ma = 0;
    rep(i, N) {
        rep(j, width + 1) {
            if (!dp[i][j]) continue;
            dp[i + 1][j] = true;
            if (j + w[i] <= width) {
                dp[i + 1][j + w[i]] = true;
            }
        }
    }
    rep(j, width + 1) {
        if (dp[N][j]) ma = max(ma, j);
    }
    return ma;
}

int main() {
    int N;
    while (cin >> N, N) {
        vector<int> r(N), w(N);
        rep(i, N) cin >> r[i] >> w[i];
        sort(all(r));
        reverse(all(r));
        sort(all(w));
        reverse(all(w));

        int sm_r = accumulate(all(r), 0);
        int sm_w = accumulate(all(w), 0);
        int Tr = max(sm_r, 2 * r[0]);
        int Tw = sm_w;

        if (2 * r[0] > sm_r) {
            int width = 2 * r[0] - sm_r;
            int ma_1 = calcDP(w, width);
            w.erase(w.begin());
            int ma_2 = calcDP(w, width);
            Tw -= min(ma_1, ma_2);
        }

        cout << Tr + Tw << endl;

        // int sm = 0;
        // int j = 0;
        // if (2 * r[0] > sm_r) {
        //     int width = 2 * r[0] - sm_r;
        //     cout << "width = " << width << endl;
        //     while (sm < width && j < N) {
        //         sm += w[j];
        //         j++;
        //     }
        // }
        //
        // int Tw = max(sm_w - sm, 2 * w[j]);
        //
        // cout << Tr << " " << Tw << " " << j << " " << sm << endl;
        //
        // cout << Tr + Tw << endl;
    }

}