#include <bits/stdc++.h>
using namespace std;
struct dat {
  int T, t, f, lap;
  dat() { T = t = f = lap = 0; }
  vector<dat> V;
  bool operator<(dat a) const { return T < a.T; }
  bool operator>(dat a) const { return T > a.T; }
};
bool onFront(dat a, dat b) {
  return a.f == b.f && 1.0 * a.t / a.T < 1.0 * b.t / b.T;
}
bool checkJam(dat a, dat b) {
  return a < b && onFront(a, b) && (a.T - a.t) + b.t < b.T;
}
int merge(vector<dat> &A, int idx) {
  for (int i = 0; i < (int)A.size(); i++) {
    dat &a = A[idx], &b = A[i];
    if (!checkJam(a, b)) continue;
    for (int j = 0; j < (int)a.V.size(); j++) b.V.push_back(a.V[j]);
    a.V.clear();
    a.t = 0, a.lap -= a.f, a.f = !a.f;
    if (a.lap) b.V.push_back(a);
    A.erase(A.begin() + idx);
    return 1;
  }
  return 0;
}
int sim(vector<dat> A) {
  int res = 0;
  while (!A.empty()) {
    sort(A.begin(), A.end(), greater<dat>());
    int mn = 1e9;
    for (int i = (int)A.size() - 1; i >= 0; i--)
      if (!merge(A, i)) mn = min(mn, A[i].T - A[i].t);
    vector<dat> nA;
    for (int i = 0; i < (int)A.size(); i++) {
      vector<dat> &V = A[i].V;
      if (A[i].t + mn < A[i].T)
        A[i].t += mn;
      else {
        for (int j = 0; j < (int)V.size(); j++) nA.push_back(V[j]);
        V.clear();
        A[i].t = 0, A[i].lap -= A[i].f, A[i].f = !A[i].f;
      }
      if (A[i].lap) nA.push_back(A[i]);
    }
    A = nA;
    res += mn;
  }
  return res;
}
int main() {
  int n;
  while (cin >> n, n) {
    vector<dat> A(n);
    for (int i = 0; i < n; i++) cin >> A[i].T >> A[i].lap;
    cout << sim(A) << endl;
  }
  return 0;
}
