#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <numeric>
#include <cctype>
#include <tuple>
#include <array>
#include <cassert>

// BEGIN CUT HERE
#ifdef _MSC_VER
#include <agents.h>
#endif
// END CUT HERE 

#define FOR(i, a, b) for(int i = (int)(a); i < (int)(b); ++i)
#define rep(i, n) FOR(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define REV(v) v.rbegin(), v.rend()
#define MEMSET(v, s) memset(v, s, sizeof(v))
#define MP make_pair
#define MT make_tuple

using namespace std;

typedef long long ll;
typedef pair<int, int> P;
typedef unsigned long long ull;

typedef tuple<int, int, int, int> T;


int main(){
	int n;
	while (cin >> n, n){
		vector<int> t(n), c(n);
		rep(i, n) cin >> t[i] >> c[i];

		// time, t, rem, pos
		priority_queue<T, vector<T>, greater<T>> q;
		rep(i, n) q.push(MT(0, t[i], c[i], 0));

		int lim[2] = {};
		while (!q.empty()){
			auto t = q.top();
			q.pop();
			int curtime, time, rem, pos;
			tie(curtime, time, rem, pos) = t;
			if (!rem) continue;

			int npos = pos ^ 1;
			int nxttime = max(curtime+time, lim[npos]);
			if (!npos) --rem;
			lim[npos] = max(lim[npos], nxttime);
			q.push(MT(nxttime, time, rem, npos));
		}
		cout << *max_element(lim, lim + 2) << endl;
	}


	return 0;
}