#include <vector>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <algorithm>
#include <utility>
#include <functional>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <climits>
#include <cassert>
using namespace std;
inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
const double EPS = 1e-7;
const double PI  = acos(-1.0);

#define EQ(a,b) (abs((a)-(b))<EPS)
#define GE(a,b) ((a)-(b)>-EPS)

const double length=1;
struct swimmer{
	int tempo,cnt,cnt_max;
	double pos;
	bool operator<(const swimmer &other) const{
		return tempo<other.tempo;
	}
};
int main(){
	int n;
	while(cin>>n,n){
		vector<swimmer> left;
		vector<swimmer> right;
		REP(i,n){
			int t,c;
			cin>>t>>c;
			left.push_back(swimmer());
			left[i].tempo=t;
			left[i].cnt_max=c;
		}
		sort(ALL(left));

		int turn;
		for(turn=1;;turn++){
			double left_prev_pos=10;
			REP(i,left.size()){
				double new_pos=left[i].pos+length/left[i].tempo;
				if(GE(new_pos,left_prev_pos)){
					left[i].pos=left_prev_pos;
				}else{
					left[i].pos=new_pos;
					left_prev_pos=new_pos;
				}
			}
			double right_prev_pos=10;
			REP(i,right.size()){
				double new_pos=right[i].pos+length/right[i].tempo;
				if(GE(new_pos,right_prev_pos)){
					right[i].pos=right_prev_pos;
				}else{
					right[i].pos=new_pos;
					right_prev_pos=new_pos;
				}
			}

			vector<swimmer> left_done_swimmers;
			REP(i,left.size()){
				if(GE(left[i].pos,length)){
					left_done_swimmers.push_back(left[i]);
				}
			}
			left.erase(left.begin(),left.begin()+left_done_swimmers.size());

			vector<swimmer> right_done_swimmers;
			int num_right_done_swimmers=0;
			REP(i,right.size()){
				if(GE(right[i].pos,length)){
					num_right_done_swimmers++;
					right[i].cnt++;
					if(right[i].cnt<right[i].cnt_max){
						right_done_swimmers.push_back(right[i]);
					}
				}
			}
			right.erase(right.begin(),right.begin()+num_right_done_swimmers);

			sort(ALL(left_done_swimmers));
			sort(ALL(right_done_swimmers));
			REP(i,left_done_swimmers.size()){
				left_done_swimmers[i].pos=0;
			}
			REP(i,right_done_swimmers.size()){
				right_done_swimmers[i].pos=0;
			}
			right.insert(right.end(),ALL(left_done_swimmers));
			left.insert(left.end(),ALL(right_done_swimmers));
			if(left.size()==0&&right.size()==0){
				break;
			}
		}
		cout<<turn<<endl;
	}
}