Problem:
Problem C:
Swimming Jam
Despite urging requests of the townspeople, the municipal office cannot afford to improve many
of the apparently deficient city amenities under this recession. The city swimming pool is one
of the typical examples. It has only two swimming lanes. The Municipal Fitness Agency, under
this circumstances, settled usage rules so that the limited facilities can be utilized fully.
Two lanes are to be used for one-way swimming of different directions. Swimmers are requested
to start swimming in one of the lanes, from its one end to the other, and then change the lane to
swim his/her way back. When he or she reaches the original starting end, he/she should return
to his/her initial lane and starts swimming again.
Each swimmer has his/her own natural constant pace. Swimmers, however, are not permitted
to pass other swimmers except at the ends of the pool; as the lanes are not wide enough, that
might cause accidents. If a swimmer is blocked by a slower swimmer, he/she has to follow the
slower swimmer at the slower pace until the end of the lane is reached. Note that the blocking
swimmer’s natural pace may be faster than the blocked swimmer; the blocking swimmer might
also be blocked by another swimmer ahead, whose natural pace is slower than the blocked
swimmer. Blocking would have taken place whether or not a faster swimmer was between them.
Swimmers can change their order if they reach the end of the lane simultaneously. They change
their order so that ones with faster natural pace swim in front. When a group of two or more
swimmers formed by a congestion reaches the end of the lane, they are considered to reach there
simultaneously, and thus change their order there.
The number of swimmers, their natural paces in times to swim from one end to the other, and
the numbers of laps they plan to swim are given. Note that here one "lap" means swimming
from one end to the other and then swimming back to the original end. Your task is to calculate
the time required for all the swimmers to finish their plans. All the swimmers start from the
same end of the pool at the same time, the faster swimmers in front.
In solving this problem, you can ignore the sizes of swimmers' bodies, and also ignore the time
required to change the lanes and the order in a group of swimmers at an end of the lanes.
Input
The input is a sequence of datasets. Each dataset is formatted as follows.
n
t
1
c
1
...
t
n
c
n
n
is an integer (1 ≤
n
≤ 50) that represents the number of swimmers.
t
i
and
c
i
are integers
(1 ≤
t
i
≤ 300, 1 ≤
c
i
≤ 250) that represent the natural pace in times to swim from one end
to the other and the number of planned laps for the
i
-th swimmer, respectively. ti and ci are
separated by a space.
The end of the input is indicated by a line containing one zero.
Output
For each dataset, output the time required for all the swimmers to finish their plans in a line.
No extra characters should occur in the output.
Sample Input
2
10 30
15 20
2
10 240
15
...(truncated)

Submitted solutions:

code_snippet: #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

int n, tot, tot2, ans, lamp [100], lamp2 [100], Time [100], t [100];

struct data
{
	int Time, lamp;
} a [100];

bool cmpp (int x, int y)
{return a[x].Time < a[y].Time;}
bool cmp (data a, data b)
{return a.Time < b.Time;}

void work ()
{
	int tx = Time[lamp[0]];
	ans += tx;
	for (int i = 0; i < tot; ++i)
		Time[lamp[i]] -= tx;
	for (int i = 0; i < tot2; ++i)
		Time[lamp2[i]] -= tx;
	int tt = 0;
	for (int i = 0; i < tot; ++i)
		if (Time[lamp[i]] <= 0)
		{
			t[tt++] = lamp[i];
			Time[lamp[i]] = a[lamp[i]].Time;
		}
		else break;
	sort (t, t + tt, cmpp);
	for (int i = 0; i < tt; ++i)
		lamp2[tot2++] = t[i];
	for (int i = 0; i < tot - tt; ++i)
		lamp[i] = lamp[i + tt];
	tot -= tt;
}

void work2 ()
{
	int tx = Time[lamp2[0]];
	ans += tx;
	for (int i = 0; i < tot; ++i)
		Time[lamp[i]] -= tx;
	for (int i = 0; i < tot2; ++i)
		Time[lamp2[i]] -= tx;
	int tt = 0;
	for (int i = 0; i < tot2; ++i)
		if (Time[lamp2[i]] <= 0)
		{
			t[tt++] = lamp2[i];
			Time[lamp2[i]] = a[lamp2[i]].Time;
			--a[lamp2[i]].lamp;
		}
		else break;
	sort (t, t + tt, cmpp);
	for (int i = 0; i < tt; ++i)
		if (a[t[i]].lamp) lamp[tot++] = t[i];
	for (int i = 0; i < tot2 - tt; ++i)
		lamp2[i] = lamp2[i + tt];
	tot2 -= tt;
}

int main ()
{
	while (1)
	{
		scanf ("%d", &n);
		if (n == 0) break;
		for (int i = 0; i < n; ++i) scanf ("%d%d", &a[i].Time, &a[i].lamp);
		sort (a, a + n, cmp);
		memset (Time, 0, sizeof (Time));
		tot = n; tot2 = 0; ans = 0;
		for (int i = 0; i < n; ++i)
		{
			lamp[i] = i;
			Time[i] = a[i].Time;
		}
		while (1)
		{
			if (tot == 0) work2 ();
			else if (tot2 == 0) work ();
			else if (Time[lamp[0]] < Time[lamp2[0]]) work ();
			else work2 ();
			bool flag = 0;
			for (int i = 0; i < n; ++i)
				if (a[i].lamp) flag = 1;
			if (!flag) break;
		}
		printf ("%d\n", ans);
	}
}
accuracy: 1
time_ms: 10
memory_kb: 3264
final_rank: 2

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

int solve(int n) {
    using S = tuple<int, int, int, int>;
    priority_queue< S, vector< S >, greater< S > > pq;
    int m[2] = {0, 0};
    for(int _ : rep(n)) {
        int t = in(), c = in();
        pq.push({t, t, c, 0});
        chmax(m[0], t);
    }
    while(not pq.empty()) {
        auto [now, t, c, d] = pq.top(); pq.pop();
        if(d == 1) c--;
        if(c == 0) continue;
        const int nd = d ^ 1;
        const int nxt = max(now + t, m[nd]);
        chmax(m[nd], nxt);
        pq.push({nxt, t, c, nd});
    }
    return m[1];
}

int main() {
    while(true) {
        int n = in();
        if(n == 0) return 0;
        print(solve(n));
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3400
final_rank: 12

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

const int T = 300 * 250 * 2;

int solve(int n) {
    using S = tuple<int, int, int, int>;
    priority_queue< S, vector< S >, greater< S > > pq;
    int m[2] = {0, 0};
    for(int _ : rep(n)) {
        int t = in(), c = in();
        pq.push({t, t, c, 0});
        chmax(m[0], t);
    }
    while(not pq.empty()) {
        auto [now, t, c, d] = pq.top(); pq.pop();
        if(d == 1) c--;
        if(c == 0) continue;
        const int nd = d ^ 1;
        const int nxt = max(now + t, m[nd]);
        chmax(m[nd], nxt);
        pq.push({nxt, t, c, nd});
    }
    return m[1];
}

int main() {
    while(true) {
        int n = in();
        if(n == 0) return 0;
        print(solve(n));
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3372
final_rank: 7

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
while(1) {
    int N;
    cin >> N;
    if (N == 0) return 0;
    vector<pair<int,int>> A(N);
    rep(i,0,N) cin >> A[i].first >> A[i].second, A[i].second *= 2;
    sort(ALL(A));
    reverse(ALL(A));
    vector<vector<int>> ANS(N);
    rep(i,0,N) {
        int Cur = 0;
        ANS[i].push_back(Cur);
        rep(j,0,A[i].second) {
            int Next = Cur + A[i].first;
            rep(k,0,i) {
                int l = UB(ANS[k],Cur)-1;
                if (ANS[k][l] == Cur) continue;
                if (l+1 == ANS[k].size()) continue;
                if (l % 2 != j % 2) continue;
                chmax(Next,ANS[k][l+1]);
            }
            Cur = Next;
            ANS[i].push_back(Cur);
        }
    }
    int MAX = 0;
    rep(i,0,N) chmax(MAX,ANS[i].back());
    cout << MAX << endl;
}
}
accuracy: 1
time_ms: 290
memory_kb: 3436
final_rank: 14

code_snippet: #include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

int main() {
	while (true) {
		int N;
		cin >> N;
		if (N == 0) {
			break;
		}
		vector<int> T(N), C(N);
		for (int i = 0; i < N; i++) {
			cin >> T[i] >> C[i];
		}
		vector<int> perm(N);
		for (int i = 0; i < N; i++) {
			perm[i] = i;
		}
		sort(perm.begin(), perm.end(), [&](int va, int vb) {
			return T[va] < T[vb];
		});
		const int INF = 1012345678;
		vector<priority_queue<vector<int>, vector<vector<int> >, greater<vector<int> > > > que(2);
		vector<int> last(2, -INF);
		for (int i : perm) {
			que[0].push({T[i], T[i], i});
			last[0] = max(last[0], T[i]);
		}
		int answer = 0;
		while (true) {
			vector<int> t = {INF, INF, INF};
			int id = -1;
			for (int i = 0; i < 2; i++) {
				if (!que[i].empty() && t > que[i].top()) {
					t = que[i].top();
					id = i;
				}
			}
			if (id == -1) {
				break;
			}
			answer = t[0];
			que[id].pop();
			if (id == 1) {
				C[t[2]] -= 1;
			}
			if (C[t[2]] >= 1) {
				int pre = (!que[id ^ 1].empty() ? last[id ^ 1] : -INF);
				int nt = max(pre, t[0] + t[1]);
				que[id ^ 1].push({nt, t[1], t[2]});
				last[id ^ 1] = nt;
			}
		}
		cout << answer << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3352
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int N;
int T[59], C[59];
int Lap1[150009];
int Lap2[150009];

void solve() {
	for (int i = 0; i <= 150000; i++) Lap1[i] = 0;
	for (int i = 0; i <= 150000; i++) Lap2[i] = 0;
	
	// Step 1. Sorting
	vector<pair<int, int>> vec;
	for (int i = 1; i <= N; i++) vec.push_back(make_pair(T[i], C[i]));
	sort(vec.begin(), vec.end());
	reverse(vec.begin(), vec.end());
	
	// Step 2. Simulation
	int Answer = 0;
	for (int i = 0; i < (int)vec.size(); i++) {
		int tm = 0;
		int cur1 = 0, Max1 = 0;
		int cur2 = 0, Max2 = 0;
		for (int j = 0; j < vec[i].second; j++) {
			int Act0 = tm;
			
			// First Half
			while (cur1 < Act0) { Max1 = max(Max1, Lap1[cur1]); cur1 += 1; }
			int Act1 = max(Max1, tm + vec[i].first);
			tm = Act1;
			Lap1[Act0] = max(Lap1[Act0], tm);
			
			// Second Half
			while (cur2 < Act1) { Max2 = max(Max2, Lap2[cur2]); cur2 += 1; }
			int Act2 = max(Max2, tm + vec[i].first);
			tm = Act2;
			Lap2[Act1] = max(Lap2[Act1], tm);
		}
		Answer = max(Answer, tm);
	}
	
	// Step 3. Output
	cout << Answer << endl;
}

int main() {
	while (true) {
		// Input
		cin >> N; if (N == 0) break;
		for (int i = 1; i <= N; i++) cin >> T[i] >> C[i];
		
		// Simulation
		solve();
	}
	return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 4528
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define rep(i, n) for(int i = 0; i < int(n); i++)
#define per(i, n) for(int i = (n) - 1; 0 <= i; i--)
#define rep2(i, l, r) for(int i = (l); i < int(r); i++)
#define per2(i, l, r) for(int i = (r) -1; int(l) <= i; i--)
#define MM << " " <<
#define pb push_back
#define eb emplace_back
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define sz(x) int(x.size())
#define each(e, x) for(auto &x : x)

template<class T>
void print(const vector<T> &v, T x = 0) {
    int n = sz(v);
    for(int i = 0; i < n; i++) cout << v[i] + x << (i == n - 1 ? '\n' : ' ');
    if(v.empty()) cout << '\n';
}

using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

template<class T>
bool chmax(T &x, const T &y) {
    return (x < y) ? (x = y, true) : false;
}

template<class T>
bool chmin(T &x, const T &y) {
    return (x > y) ? (x = y, true) : false;
}

template<class T>
using minheap = priority_queue<T, vector<T>, greater<T>>;

struct io_setup {
        io_setup() {
            ios_base::sync_with_stdio(false);
            cin.tie(nullptr);
            cout << fixed << setprecision(15);
        }
    } io_set;

ll solve(int n) {
    vector<pii> da(n);
    rep(i,n) {
        cin >> da[i].first >> da[i].second;
    }

    vector<deque<pair<pii, vector<int>>>> q(2);
    int k[] = {0, 0};
    vector<int> tmp(n);
    iota(all(tmp), 0);
    q[0].push_back({make_pair(0, 0), tmp});
//    q[1].push_back({make_pair(0, 1), vector<int>(0)});
    int ans = 0;
    while(!q[0].empty() || !q[1].empty()) {
        decltype(q)::value_type ::value_type now;
        if(q[0].empty()) {
            now = q[1].front();
            q[1].pop_front();
        } else if(q[1].empty()) {
            now = q[0].front();
            q[0].pop_front();
        } else if(q[0].front() <= q[1].front()) {
            now = q[0].front();
            q[0].pop_front();
        } else {
            now = q[1].front();
            q[1].pop_front();
        }
        ans = now.first.first;
//        cerr << now.first.first MM now.first.second << endl;
//        if(q[0].front() == now) q[0].pop_front();
//        else q[1].pop_front();
        sort(all(now.second), [&da](int a, int b) {
            return da[a].first < da[b].first;
        });
        for(auto &i : now.second) {
            if(now.first.second == 1) da[i].second--;
            else if(da[i].second == 0) continue;
            if(chmax(k[now.first.second^1], now.first.first + da[i].first) || q[now.first.second^1].empty()) {
                q[now.first.second^1].push_back({make_pair(
                        now.first.first + da[i].first,
                        now.first.second^1
                        ), vector<int>(1, i)});
            } else {
                q[now.first.second^1].back().second.emplace_back(i);
            }
        }
    }
    return ans;
}

int main() {
    int n;
    while(true) {
        cin >> n;
        if(n == 0) break;
        cout << solve(n) << endl;
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3388
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;

void solve(){
	int n;
	while(1){
		cin >> n;
		if(n == 0) break;
		vector<int> T(n), C(n);
		using pi = pair<int, int>;
		priority_queue<pi, vector<pi>, greater<pi>> L, R;
		int lma = 0, rma = 0;
		for(int i = 0; i < n; i++){
			cin >> T[i] >> C[i];
			R.push({T[i], i});
			rma = max(rma, T[i]);
		}

		while(!L.empty() || !R.empty()){
			if(!L.empty() && !R.empty() && L.top().first == R.top().first){
				int x = L.top().first;
				int ll = lma;
				int rr = rma;
				while(!L.empty() && L.top().first == x){
					int i = L.top().second;
					C[i]--;
					if(C[i] != 0){
						int t = max(T[i] + x, rr);
						R.push({t, i});
						rma = max(rma, t);
					};
					L.pop();
				}
				while(!R.empty() && R.top().first == x){
					int i = R.top().second;
					int t = max(T[i] + x, ll);
					L.push({t, i});
					lma = max(lma, t);
					R.pop();
				}
			}
			else if(!L.empty() && (R.empty() || L.top().first < R.top().first)){
				int x = L.top().first;
				int rr = rma;
				while(!L.empty() && L.top().first == x){
					int i = L.top().second;
					C[i]--;
					if(C[i] != 0){
						int t = max(T[i] + x, rr);
						R.push({t, i});
						rma = max(rma, t);
					};
					L.pop();
				}
			}
			else{
				int x = R.top().first;
				int ll = lma;
				while(!R.empty() && R.top().first == x){
					int i = R.top().second;
					int t = max(T[i] + x, ll);
					L.push({t, i});
					lma = max(lma, t);
					R.pop();
				}
			}
		}
		cout << max(lma, rma) << endl;
	}
}

int main(){
	solve();
}
accuracy: 1
time_ms: 20
memory_kb: 3364
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    while (1) {
        int n;
        cin >> n;
        if (n == 0) break;
        vector<int> t(n), c(n);
        rep(i,0,n) cin >> t[i] >> c[i];
        vector<int> idx(n);
        iota(all(idx), 0);
        sort(all(idx), [&](int i, int j) { return t[i] < t[j]; });
        queue<pair<int, int>> lane1, lane2;
        for (int i : idx) lane1.push({i, t[i]});
        int time1 = 0, time2 = 0;
        while (!lane1.empty() || !lane2.empty()) {
            int i, time;
            if (lane2.empty() || (!lane1.empty() && lane1.front().second < lane2.front().second)) {
                tie(i, time) = lane1.front();
                lane1.pop();
                chmax(time1, time);
                vector<int> is = {i};
                while (!lane1.empty() && lane1.front().second <= time1) {
                    is.push_back(lane1.front().first);
                    lane1.pop();
                }
                sort(all(is), [&](int i, int j) { return t[i] < t[j]; });
                for (int j : is) {
                    lane2.push({j, time1 + t[j]});
                }
            } else {
                tie(i, time) = lane2.front();
                lane2.pop();
                chmax(time2, time);
                vector<int> is = {i};
                while (!lane2.empty() && lane2.front().second <= time2) {
                    is.push_back(lane2.front().first);
                    lane2.pop();
                }
                sort(all(is), [&](int i, int j) { return t[i] < t[j]; });
                for (int j : is) {
                    --c[j];
                    if (c[j]) {
                        lane1.push({j, time2 + t[j]});
                    }
                }
            }
        }
        cout << time2 << "\n";
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3332
final_rank: 3

code_snippet: #include <cstdio>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
using namespace std;

int main() {
int n;
while (scanf("%d", &n) == 1) {
  if (n == 0) break;
  vector<int> t(n), c(n);
  for (int i = 0; i < n; i++) scanf("%d%d", &t[i], &c[i]);
  map<int, vector<int>> mp[2];
  vector<int> st(2, -1);
  set<int> have;
  
  auto insert = [&](map<int, vector<int>>& u, int time, int id) {
    have.insert(time);
    if (!u.count(time)) u[time] = vector<int> ();
    u[time].push_back(id);
  };
  
  for (int i = 0; i < n; i++) {
    insert(mp[0], 0, i);
  }
  int ans = 0;
  while (have.size() != 0) {
    int u = *(have.begin());
    have.erase(u);
    for (int i = 0; i < 2; i++) {
      int j = !i;
      if (mp[i].count(u)) {
        vector<int>& all = mp[i][u];
        sort(all.begin(), all.end(), [&](auto u, auto v) {
          return t[u] < t[v];
        });
        for (int now: all) {
          if (i == 1) c[now]--;
          st[j] = max(u + t[now], st[j]);
          int rec = st[j];
          ans = max(ans, rec);
          if (c[now] != 0) {
            insert(mp[j], rec, now); 
          }
        }
      }
    }
  }
  printf("%d\n", ans);
}
  return 0;  
}
accuracy: 1
time_ms: 100
memory_kb: 4436
final_rank: 17

code_snippet: // #pragma comment(linker, "/stack:200000000")

#include <bits/stdc++.h>

#include <limits>
#include <type_traits>

namespace suisen {
// ! utility
template <typename ...Types>
using constraints_t = std::enable_if_t<std::conjunction_v<Types...>, std::nullptr_t>;
template <bool cond_v, typename Then, typename OrElse>
constexpr decltype(auto) constexpr_if(Then&& then, OrElse&& or_else) {
    if constexpr (cond_v) {
        return std::forward<Then>(then);
    } else {
        return std::forward<OrElse>(or_else);
    }
}

// ! function
template <typename ReturnType, typename Callable, typename ...Args>
using is_same_as_invoke_result = std::is_same<std::invoke_result_t<Callable, Args...>, ReturnType>;
template <typename F, typename T>
using is_uni_op = is_same_as_invoke_result<T, F, T>;
template <typename F, typename T>
using is_bin_op = is_same_as_invoke_result<T, F, T, T>;

template <typename Comparator, typename T>
using is_comparator = std::is_same<std::invoke_result_t<Comparator, T, T>, bool>;

// ! integral
template <typename T, typename = constraints_t<std::is_integral<T>>>
constexpr int bit_num = std::numeric_limits<std::make_unsigned_t<T>>::digits;
template <typename T, unsigned int n>
struct is_nbit { static constexpr bool value = bit_num<T> == n; };
template <typename T, unsigned int n>
static constexpr bool is_nbit_v = is_nbit<T, n>::value;

// ?
template <typename T>
struct safely_multipliable {};
template <>
struct safely_multipliable<int> { using type = long long; };
template <>
struct safely_multipliable<long long> { using type = __int128_t; };
template <>
struct safely_multipliable<float> { using type = float; };
template <>
struct safely_multipliable<double> { using type = double; };
template <>
struct safely_multipliable<long double> { using type = long double; };
template <typename T>
using safely_multipliable_t = typename safely_multipliable<T>::type;

} // namespace suisen

// ! type aliases
using i128 = __int128_t;
using u128 = __uint128_t;
using ll = long long;
using uint = unsigned int;
using ull  = unsigned long long;

template <typename T> using vec  = std::vector<T>;
template <typename T> using vec2 = vec<vec <T>>;
template <typename T> using vec3 = vec<vec2<T>>;
template <typename T> using vec4 = vec<vec3<T>>;

template <typename T>
using pq_greater = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <typename T, typename U>
using umap = std::unordered_map<T, U>;

// ! macros (capital: internal macro)
#define OVERLOAD2(_1,_2,name,...) name
#define OVERLOAD3(_1,_2,_3,name,...) name
#define OVERLOAD4(_1,_2,_3,_4,name,...) name

#define REP4(i,l,r,s)  for(std::remove_reference_t<std::remove_const_t<decltype(r)>>i=(l);i<(r);i+=(s))
#define REP3(i,l,r)    REP4(i,l,r,1)
#define REP2(i,n)      REP3(i,0,n)
#define REPINF3(i,l,s) for(std::remove_reference_t<std::remove_const_t<decltype(l)>>i=(l);;i+=(s))
#define REPINF2(i,l)   REPINF3(i,l,1)
#define REPINF1(i)     REPINF2(i,0)
#define RREP4(i,l,r,s) for(std::remove_reference_t<std::remove_const_t<decltype(r)>>i=(l)+fld((r)-(l)-1,s)*(s);i>=(l);i-=(s))
#define RREP3(i,l,r)   RREP4(i,l,r,1)
#define RREP2(i,n)     RREP3(i,0,n)

#define rep(...)    OVERLOAD4(__VA_ARGS__, REP4   , REP3   , REP2   )(__VA_ARGS__)
#define rrep(...)   OVERLOAD4(__VA_ARGS__, RREP4  , RREP3  , RREP2  )(__VA_ARGS__)
#define repinf(...) OVERLOAD3(__VA_ARGS__, REPINF3, REPINF2, REPINF1)(__VA_ARGS__)

#define CAT_I(a, b) a##b
#define CAT(a, b) CAT_I(a, b)
#define UNIQVAR(tag) CAT(tag, __LINE__)
#define loop(n) for (std::remove_reference_t<std::remove_const_t<decltype(n)>> UNIQVAR(loop_variable) = n; UNIQVAR(loop_variable) --> 0;)

#define all(iterable) (iterable).begin(), (iterable).end()
#define input(type, ...) type __VA_ARGS__; read(__VA_ARGS__)

// ! I/O utilities

// pair
template <typename T, typename U>
std::ostream& operator<<(std::ostream& out, const std::pair<T, U> &a) {
    return out << a.first << ' ' << a.second;
}
// tuple
template <unsigned int N = 0, typename ...Args>
std::ostream& operator<<(std::ostream& out, const std::tuple<Args...> &a) {
    if constexpr (N >= std::tuple_size_v<std::tuple<Args...>>) {
        return out;
    } else {
        out << std::get<N>(a);
        if constexpr (N + 1 < std::tuple_size_v<std::tuple<Args...>>) {
            out << ' ';
        }
        return operator<<<N + 1>(out, a);
    }
}
// vector
template <typename T>
std::ostream& operator<<(std::ostream& out, const std::vector<T> &a) {
    for (auto it = a.begin(); it != a.end();) {
        out << *it;
        if (++it != a.end()) out << ' ';
    }
    return out;
}
inline void print() { std::cout << '\n'; }
template <typename Head, typename... Tail>
inline void print(const Head &head, const Tail &...tails) {
    std::cout << head;
    if (sizeof...(tails)) std::cout << ' ';
    print(tails...);
}
template <typename Iterable>
auto print_all(const Iterable& v, std::string sep = " ", std::string end = "\n") -> decltype(std::cout << *v.begin(), void()) {
    for (auto it = v.begin(); it != v.end();) {
        std::cout << *it;
        if (++it != v.end()) std::cout << sep;
    }
    std::cout << end;
}

// pair
template <typename T, typename U>
std::istream& operator>>(std::istream& in, std::pair<T, U> &a) {
    return in >> a.first >> a.second;
}
// tuple
template <unsigned int N = 0, typename ...Args>
std::istream& operator>>(std::istream& in, std::tuple<Args...> &a) {
    if constexpr (N >= std::tuple_size_v<std::tuple<Args...>>) {
        return in;
    } else {
        return operator>><N + 1>(in >> std::get<N>(a), a);
    }
}
// vector
template <typename T>
std::istream& operator>>(std::istream& in, std::vector<T> &a) {
    for (auto it = a.begin(); it != a.end(); ++it) in >> *it;
    return in;
}
template <typename ...Args>
void read(Args &...args) {
    ( std::cin >> ... >> args );
}

// ! integral utilities

// Returns pow(-1, n)
template <typename T>
constexpr inline int pow_m1(T n) {
    return -(n & 1) | 1;
}
// Returns pow(-1, n)
template <>
constexpr inline int pow_m1<bool>(bool n) {
    return -int(n) | 1;
}

// Returns floor(x / y)
template <typename T>
constexpr inline T fld(const T x, const T y) {
    return (x ^ y) >= 0 ? x / y : (x - (y + pow_m1(y >= 0))) / y;
}
template <typename T>
constexpr inline T cld(const T x, const T y) {
    return (x ^ y) <= 0 ? x / y : (x + (y + pow_m1(y >= 0))) / y;
}

template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int popcount(const T x) { return __builtin_popcount(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int popcount(const T x) { return __builtin_popcountll(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clz(x)   : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clzll(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctz(x)   : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctzll(x) : suisen::bit_num<T>; }
template <typename T>
constexpr inline int floor_log2(const T x) { return suisen::bit_num<T> - 1 - count_lz(x); }
template <typename T>
constexpr inline int ceil_log2(const T x)  { return floor_log2(x) + ((x & -x) != x); }
template <typename T>
constexpr inline int kth_bit(const T x, const unsigned int k) { return (x >> k) & 1; }
template <typename T>
constexpr inline int parity(const T x) { return popcount(x) & 1; }

struct all_subset {
    struct all_subset_iter {
        const int s; int t;
        constexpr all_subset_iter(int s) : s(s), t(s + 1) {}
        constexpr auto operator*() const { return t; }
        constexpr auto operator++() {}
        constexpr auto operator!=(std::nullptr_t) { return t ? (--t &= s, true) : false; }
    };
    int s;
    constexpr all_subset(int s) : s(s) {}
    constexpr auto begin() { return all_subset_iter(s); }
    constexpr auto end()   { return nullptr; }
};

// ! container

template <typename T, typename Comparator, suisen::constraints_t<suisen::is_comparator<Comparator, T>> = nullptr>
auto priqueue_comp(const Comparator comparator) {
    return std::priority_queue<T, std::vector<T>, Comparator>(comparator);
}

template <typename Iterable>
auto isize(const Iterable &iterable) -> decltype(int(iterable.size())) {
    return iterable.size();
}

template <typename T, typename Gen, suisen::constraints_t<suisen::is_same_as_invoke_result<T, Gen, int>> = nullptr>
auto generate_vector(int n, Gen generator) {
    std::vector<T> v(n);
    for (int i = 0; i < n; ++i) v[i] = generator(i);
    return v;
}

template <typename T>
void sort_unique_erase(std::vector<T> &a) {
    std::sort(a.begin(), a.end());
    a.erase(std::unique(a.begin(), a.end()), a.end());
}

// ! other utilities

// x <- min(x, y). returns true iff `x` has chenged.
template <typename T>
inline bool chmin(T &x, const T &y) {
    if (y >= x) return false;
    x = y;
    return true;
}
// x <- max(x, y). returns true iff `x` has chenged.
template <typename T>
inline bool chmax(T &x, const T &y) {
    if (y <= x) return false;
    x = y;
    return true;
}

namespace suisen {}
using namespace suisen;
using namespace std;

struct io_setup {
    io_setup(int precision = 20) {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(precision);
    }
} io_setup_ {};

// ! code from here

constexpr int T = 300 * 500 + 10;

void solve(vector<pair<int, int>> &&tc) {
    sort(all(tc), greater<pair<int, int>>());
    vector max_time(2, vector<int>(T, 0));
    int ans = 0;
    for (const auto &[t, c] : tc) {
        int time = 0, lane = 0;
        rep(i, 2 * c) {
            int reach_time = max(time + t, max_time[lane][time]);
            rep(k, time + 1, reach_time) {
                chmax(max_time[lane][k], reach_time);
            }
            time = reach_time;
            lane ^= 1;
        }
        chmax(ans, time);
    }
    print(ans);
}

int main() {
    while (true) {
        input(int, n);
        if (n == 0) break;
        vector<pair<int, int>> tc(n);
        read(tc);
        solve(move(tc));
    }
    return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 5428
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;

struct swimmer {
    int t, c, nxt;
    swimmer(int t, int c, int nxt) : t(t), c(c), nxt(nxt) {}
    constexpr bool operator<(const swimmer& rhs) const { return t < rhs.t; }
};

void solve(int n) {
    vector<queue<swimmer>> que(2);
    for (int i = 0; i < n; i++) {
        int t, c;
        cin >> t >> c;
        que[1].emplace(t, 2 * c + 1, 0);
    }

    int ans = 0;
    while (!que[0].empty() || !que[1].empty()) {
        int x = (que[0].empty() || (!que[1].empty() && que[0].front().nxt > que[1].front().nxt));
        int T = que[x].front().nxt;
        ans = T;
        vector<swimmer> start;
        while (!que[x].empty() && que[x].front().nxt <= T) {
            start.emplace_back(que[x].front());
            que[x].pop();
        }
        sort(start.begin(), start.end());
        for (auto s : start) {
            if (s.c == 1) continue;
            que[x ^ 1].emplace(s.t, s.c - 1, T + s.t);
        }
    }

    cout << ans << '\n';
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n;
    while (cin >> n, n) solve(n);
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3468
final_rank: 13

code_snippet: #define LOCAL
#include <bits/stdc++.h>
using namespace std;
#pragma region Macros
typedef long long ll;
typedef __int128_t i128;
typedef unsigned int uint;
typedef unsigned long long ull;
#define ALL(x) (x).begin(), (x).end()

template <typename T> istream& operator>>(istream& is, vector<T>& v) {
    for (T& x : v) is >> x;
    return is;
}
template <typename T> ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int)v.size(); i++) {
        os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
    }
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const unordered_map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const multiset<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const unordered_set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const deque<T>& v) {
    for (int i = 0; i < (int)v.size(); i++) {
        os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
    }
    return os;
}

template <int i, typename T> void print_tuple(ostream&, const T&) {}
template <int i, typename T, typename H, class... Args> void print_tuple(ostream& os, const T& t) {
    if (i) os << ',';
    os << get<i>(t);
    print_tuple<i + 1, T, Args...>(os, t);
}
template <typename... Args> ostream& operator<<(ostream& os, const tuple<Args...>& t) {
    os << '{';
    print_tuple<0, tuple<Args...>, Args...>(os, t);
    return os << '}';
}

void debug_out() { cerr << '\n'; }
template <class Head, class... Tail> void debug_out(Head&& head, Tail&&... tail) {
    cerr << head;
    if (sizeof...(Tail) > 0) cerr << ", ";
    debug_out(move(tail)...);
}
#ifdef LOCAL
#define debug(...)                                                                   \
    cerr << " ";                                                                     \
    cerr << #__VA_ARGS__ << " :[" << __LINE__ << ":" << __FUNCTION__ << "]" << '\n'; \
    cerr << " ";                                                                     \
    debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

template <typename T> T gcd(T x, T y) { return y != 0 ? gcd(y, x % y) : x; }
template <typename T> T lcm(T x, T y) { return x / gcd(x, y) * y; }

int topbit(signed t) { return t == 0 ? -1 : 31 - __builtin_clz(t); }
int topbit(long long t) { return t == 0 ? -1 : 63 - __builtin_clzll(t); }
int botbit(signed a) { return a == 0 ? 32 : __builtin_ctz(a); }
int botbit(long long a) { return a == 0 ? 64 : __builtin_ctzll(a); }
int popcount(signed t) { return __builtin_popcount(t); }
int popcount(long long t) { return __builtin_popcountll(t); }
bool ispow2(int i) { return i && (i & -i) == i; }

template <class T> T ceil(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <class T> T floor(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? x / y : (x - y + 1) / y);
}

template <class T1, class T2> inline bool chmin(T1& a, T2 b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T1, class T2> inline bool chmax(T1& a, T2 b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
#pragma endregion

const int INF = 1e9;
const long long IINF = 1e18;
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const char dir[4] = {'D', 'R', 'U', 'L'};
const long long MOD = 1000000007;
// const long long MOD = 998244353;

struct swimmer {
    int t, c, nxt;
    swimmer(int t, int c, int nxt) : t(t), c(c), nxt(nxt) {}
    constexpr bool operator<(const swimmer& rhs) const { return t < rhs.t; }
};

void solve(int n) {
    vector<queue<swimmer>> que(2);
    for (int i = 0; i < n; i++) {
        int t, c;
        cin >> t >> c;
        que[1].emplace(t, 2 * c + 1, 0);
    }

    int ans = 0;
    while (!que[0].empty() || !que[1].empty()) {
        int x = (que[0].empty() || (!que[1].empty() && que[0].front().nxt > que[1].front().nxt));
        int T = que[x].front().nxt;
        ans = T;
        vector<swimmer> start;
        while (!que[x].empty() && que[x].front().nxt <= T) {
            start.emplace_back(que[x].front());
            que[x].pop();
        }
        sort(start.begin(), start.end());
        for (auto s : start) {
            if (s.c == 1) continue;
            que[x ^ 1].emplace(s.t, s.c - 1, T + s.t);
        }
    }

    cout << ans << '\n';
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n;
    while (cin >> n, n) solve(n);
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3232
final_rank: 1

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
//using namespace atcoder;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
ostream &operator<<(ostream &os, const set<int> &se){
    os << '{';
    int now = 0;
    for(auto x : se){
        if(now) { os << ','; }
        os << x; 
        now++;
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-7;
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//const int mod = 1e9 + 7;
const int mod = 998244353;

int main(){
    while(1){
        int n; cin >> n;
        if(!n) break;
        vpl v(n);
        rep(i,n){
            cin >> v[i].first >> v[i].second;
        }
        int ans = 0;
        sort(all(v));
        vector<tapu> L,R;
        rep(i,n) L.emplace_back(v[i].first,v[i].second,i);
        while(!L.empty() || !R.empty()){
            int tl=inf,cl,idl,tr=inf,cr,idr;
            if(!L.empty()) tie(tl,cl,idl) = L[0];
            if(!R.empty()) tie(tr,cr,idr) = R[0];
            int t = min(tl,tr);
            ans += t;
            vl ls,rs;
            rep(i,L.size()) get<0>(L[i]) -= t;
            rep(i,R.size()) get<0>(R[i]) -= t;
            rep(i,L.size()){
                if(get<0>(L[i]) > 0) break;
                ls.push_back(get<2>(L[i]));
            }
            rep(i,R.size()){
                if(get<0>(R[i]) > 0) break;
                rs.push_back(get<2>(R[i]));
            }
            L.erase(L.begin(),L.begin()+(int)ls.size());
            R.erase(R.begin(),R.begin()+(int)rs.size());
            sort(all(ls)); sort(all(rs));
            for(auto x : ls){
                ll mx = -inf;
                if(!R.empty()) chmax(mx,get<0>(R.back()));
                R.emplace_back(max(mx,v[x].first),v[x].second,x);
            }
            for(auto x : rs){
                if(v[x].second == 1) continue;
                v[x].second--;
                ll mx = -inf;
                if(!L.empty()) chmax(mx,get<0>(L.back()));
                L.emplace_back(max(mx,v[x].first),v[x].second,x);   
            }
        }
        cout << ans << "\n";
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3332
final_rank: 4

code_snippet: #include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define Inf 1000000001

struct Data{
	int t,c;
	int remain;
};

int main(){
	
	while(true){
		int n;
		cin>>n;
		
		if(n==0)break;
		
		vector<Data> D0(n),D1(0);
		
		rep(i,n){
			cin>>D0[i].t>>D0[i].c;
			D0[i].remain = D0[i].t;
		}
		
		int ans = 0;
		
		while(D0.size()!=0 || D1.size()!=0){
			ans++;
			vector<Data> d0,d1,nd0,nd1;
			
			rep(i,D0.size()){
				D0[i].remain--;
				if(D0[i].remain==0){
					nd1.push_back(D0[i]);
				}
				else{
					d0.push_back(D0[i]);
				}
			}
			
			rep(i,D1.size()){
				D1[i].remain--;
				if(D1[i].remain==0){
					D1[i].c--;
					if(D1[i].c!=0){
						nd0.push_back(D1[i]);
					}
				}
				else{
					d1.push_back(D1[i]);
				}
			}
			
			int m0 = 0,m1 = 0;
			rep(i,d0.size()){
				m0 = max(m0,d0[i].remain);
			}
			rep(i,d1.size()){
				m1 = max(m1,d1[i].remain);
			}
			
			rep(i,nd0.size()){
				nd0[i].remain = max(nd0[i].t,m0);
				d0.push_back(nd0[i]);
			}
			
			rep(i,nd1.size()){
				nd1[i].remain = max(nd1[i].t,m1);
				d1.push_back(nd1[i]);
			}
			
			swap(d0,D0);
			swap(d1,D1);
			
			
			
		}
		
		cout<<ans<<endl;		
		
	}
	
	return 0;
}
accuracy: 1
time_ms: 1160
memory_kb: 3244
final_rank: 16

code_snippet: #include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <utility>
#include <tuple>
#include <cmath>
#include <numeric>
#include <set>
#include <map>
#include <array>
#include <complex>
#include <iomanip>
#include <cassert>
#include <random>
#include <chrono>
using ll = long long;
using std::cin;
using std::cout;
using std::endl;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
const int inf = (int)1e9 + 7;
const long long INF = 1LL << 60;

void solve()
{
  int n; cin >> n; if(n == 0) exit(0);
  std::vector<int> t(n), c(n);
  using T = std::tuple<int, int, int>;
  std::priority_queue<T, std::vector<T>, std::greater<>> pq1, pq2;
  for (int i = 0; i < n; ++i)
  {
    cin >> t[i] >> c[i];
    pq1.emplace(0, t[i], c[i]);
  }

  int t1 = 0, t2 = 0;
  while(not pq1.empty() or not pq2.empty())
  {
    bool exe1 = true;
    if(pq1.empty())
    {
      exe1 = false;
    }
    else if(not pq2.empty())
    {
      int nt1 = std::get<0>(pq1.top()) + std::get<1>(pq1.top());
      int nt2 = std::get<0>(pq2.top()) + std::get<1>(pq2.top());
      if(nt1 > nt2)
      {
        exe1 = false;
      }
      else if(nt1 == nt2 and std::get<0>(pq2.top()) < std::get<0>(pq1.top()))
      {
        exe1 = false;
      }
    }
    if(exe1)
    {
      int nt1 = std::max(t1, std::get<0>(pq1.top()) + std::get<1>(pq1.top()));
      while(not pq1.empty())
      {
        auto[T, t, c] = pq1.top();
        if(t + T <= nt1)
        {
          pq2.emplace(nt1, t, c);
          pq1.pop();
        }
        else
        {
          break;
        }
      }
      t1 = nt1;
    }
    else
    {
      int nt2 = std::max(t2, std::get<0>(pq2.top()) + std::get<1>(pq2.top()));
      while(not pq2.empty())
      {
        auto[T, t, c] = pq2.top();
        if(t + T <= nt2)
        {
          if(c > 1)
            pq1.emplace(nt2, t, c - 1);
          pq2.pop();
        }
        else
        {
          break;
        }
      }
      t2 = nt2;
    }
  }
  cout << t2 << "\n";
}
int main()
{
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);


  int kkt = 89;
  //cin >> kkt;
  while(kkt)
  {
    solve();
  }
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3392
final_rank: 11

code_snippet: #line 2 "/Users/tiramister/CompetitiveProgramming/Cpp/CppLibrary/Tools/heap_alias.hpp"

#include <queue>

template <class T>
using MaxHeap = std::priority_queue<T>;
template <class T>
using MinHeap = std::priority_queue<T, std::vector<T>, std::greater<T>>;
#line 2 "main.cpp"
#include <iostream>
#include <vector>
#include <tuple>

using namespace std;

bool solve() {
    int n;
    cin >> n;
    if (n == 0) return false;

    vector<int> tmax(2, 0);
    MinHeap<tuple<int, int, int, int>> heap;
    // time, speed, lap, lane
    while (n--) {
        int s, c;
        cin >> s >> c;
        heap.emplace(s, s, c, 0);
        tmax[0] = max(tmax[0], s);
    }

    while (!heap.empty()) {
        auto [t, s, c, l] = heap.top();
        heap.pop();

        if (l == 1) --c;
        if (c == 0) continue;

        int nl = 1 - l;
        int nt = max(t + s, tmax[nl]);
        tmax[nl] = max(tmax[nl], nt);
        heap.emplace(nt, s, c, nl);
    }

    cout << tmax[1] << "\n";
    return true;
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    while (solve()) {}

    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3388
final_rank: 8

code_snippet: #include <iostream>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <cassert>
#include <vector>
#include <list>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <string>
#include <algorithm>
#include <utility>
#include <complex>
#define rep(x, s, t) for(llint (x) = (s); (x) <= (t); (x)++)
#define chmin(x, y) (x) = min((x), (y))
#define chmax(x, y) (x) = max((x), (y))
#define all(x) (x).begin(),(x).end()
#define outl(x) cout << (x) << "\n"
#define inf 1e18

using namespace std;

typedef long long llint;
typedef long long ll;
typedef pair<int, int> P;

struct UnionFind{
	int size;
	vector<int> parent;
	vector<int> rank;
	vector<int> v, e;
	
	UnionFind(){}
	UnionFind(int size){
		this->size = size;
		parent.resize(size+1);
		v.resize(size+1);
		e.resize(size+1);
		init();
	}
	void init(){
		for(int i = 0; i <= size; i++){
			parent[i] = i;
			v[i] = 1, e[i] = 0;
		}
	}
	int root(int i){
		if(parent[i] == i) return i;
		return parent[i] = root(parent[i]);
	}
	bool same(int i, int j){
		return root(i) == root(j);
	}
	void merge(int i, int j){ // j will become new root
		parent[i] = j;
		v[j] += v[i];
		e[j] += e[i] + 1;
	}
	void unite(int i, int j){
		int root_i = root(i), root_j = root(j);
		if(root_i == root_j){
			e[root_i]++;
			return;
		}
		merge(root_i, root_j);
	}
};

int n;
P p[55];
int lane[55], pos[55];
bool check[55];
bool goal[55];
UnionFind uf(55);
const int T = 500*300;


int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	while(1){
		cin >> n;
		if(n == 0) break;
		
		int t, c; vector<P> vec;
		rep(i, 1, n){
			cin >> t >> c;
			vec.push_back(P(t, c));
		}
		sort(all(vec));
		reverse(all(vec));
		
		vector<P> vec2; ll pre = -1;
		for(auto p : vec){
			if(pre != p.first) vec2.push_back(p);
			pre = p.first;
		}
		n = vec2.size();
		rep(i, 1, n) p[i] = vec2[i-1];
		
		uf.init();
		rep(i, 1, n) lane[i] = pos[i] = 0, goal[i] = false;
		
		rep(t, 1, T){
			rep(i, 1, n){
				if(goal[i]) continue;
				rep(j, 1, n){
					if(i <= j || goal[j] || lane[i] != lane[j] || uf.parent[i] != i || uf.parent[j] != j) continue;
					int ti = p[i].first, tj = p[j].first;
					if(pos[i]*tj < pos[j]*ti && (pos[i]+1)*tj >= (pos[j]+1)*ti) uf.unite(i, j);
				}
			}
			
			
			rep(i, 1, n) check[i] = false;
			rep(i, 1, n){
				uf.root(i);
				if(uf.parent[i] == i){
					pos[i]++;
					if(pos[i] == p[i].first) check[i] = true;
				}
			}
			
			rep(i, 1, n){
				if(goal[i]) continue;
				if(check[uf.root(i)]){
					if(lane[i] == 1) p[i].second--;
					if(p[i].second == 0) goal[i] = true;
					pos[i] = 0, lane[i] = 1 - lane[i];
					uf.parent[i] = i;
				}
			}
			
			bool flag = true;
			rep(i, 1, n) flag &= goal[i];
			if(flag){
				outl(t);
				break;
			}
		}
		
	}
	
	flush(cout);
	return 0;
}
accuracy: 1
time_ms: 7360
memory_kb: 3188
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
using PII = pair<ll, ll>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
template <typename T> void chmin(T &a, const T &b) { a = min(a, b); }
template <typename T> void chmax(T &a, const T &b) { a = max(a, b); }

const ll INF = 1LL << 60;

struct FastIO {
    FastIO() {
        cin.tie(0);
        ios::sync_with_stdio(0);
    }
} fastiofastio;

int minT[50][501];

int main() {
    while (1) {
        int n;
        cin >> n;
        if (n == 0)
            break;
        vector<PII> vec;
        for (int i = 0; i < n; i++) {
            int t, c;
            cin >> t >> c;
            vec.emplace_back(t, c);
        }
        sort(ALL(vec));
        memset(minT, -1, sizeof(minT));
        for (int i = n - 1; i >= 0; i--) {
            int t = vec[i].first;
            int c = vec[i].second;
            minT[i][0] = 0;
            for (int j = 0; j < 2 * c; j++) {
                minT[i][j + 1] = minT[i][j] + t;
                for (int k = n - 1; k > i; k--) {
                    for (int l = j - 2; l >= 0; l -= 2) {
                        if (minT[k][l] < minT[i][j] &&
                            minT[i][j + 1] < minT[k][l + 1]) {
                            minT[i][j + 1] = minT[k][l + 1];
                            break;
                        }
                    }
                }
            }
        }
        int ans = -1;
        for (int i = 0; i < n; i++) {
            ans = max(ans, minT[i][2 * vec[i].second]);
        }
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 940
memory_kb: 3252
final_rank: 15

code_snippet: #include <bits/stdc++.h>

using namespace std;

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

#define eps 1e-9
#define INF 2000000000              // 2e9
#define LLINF 2000000000000000000ll // 2e18 (llmax:9e18)
#define all(x) (x).begin(), (x).end()
#define sq(x) ((x) * (x))

#ifndef LOCAL
#define dmp(...) ;
#else
#define dmp(...)                                                               \
  cerr << "[ " << #__VA_ARGS__ << " ] : " << dump_str(__VA_ARGS__) << endl
#endif

// ---------------- Utility ------------------

template <class T>
bool chmin(T &a, const T &b) {
  if (a <= b) return false;
  a = b;
  return true;
}
template <class T>
bool chmax(T &a, const T &b) {
  if (a >= b) return false;
  a = b;
  return true;
}

template <class T>
using MaxHeap = priority_queue<T>;
template <class T>
using MinHeap = priority_queue<T, vector<T>, greater<T>>;

template <class T>
vector<T> vect(int len, T elem) {
  return vector<T>(len, elem);
}

// ----------------- Input -------------------

template <class T, class U>
istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first >> p.second;
  return is;
}

template <class T>
istream &operator>>(istream &is, vector<T> &vec) {
  for (int i = 0; i < vec.size(); i++) is >> vec[i];
  return is;
}

// ----------------- Output ------------------

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << p.first << ',' << p.second;
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (const T &e : v) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const deque<T> &d) {
  for (const T &e : d) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const set<T> &s) {
  os << "{ ";
  for (const T &e : s) os << e << " ";
  os << "}";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const multiset<T> &s) {
  os << "{ ";
  for (const T &e : s) os << e << " ";
  os << "}";
  return os;
}

template <class T, class U>
ostream &operator<<(ostream &os, const map<T, U> &m) {
  os << "{ ";
  for (const auto &[key, val] : m) os << "( " << key << " -> " << val << " ) ";
  os << "}";
  return os;
}

void dump_str_rec(ostringstream &) {}

template <class Head, class... Tail>
void dump_str_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << ", " << head;
  dump_str_rec(oss, forward<Tail>(tail)...);
}

template <class T, class... U>
string dump_str(T &&arg, U &&... args) {
  ostringstream oss;
  oss << arg;
  dump_str_rec(oss, forward<T>(args)...);
  return oss.str();
}

// --------------- Fast I/O ------------------

void fastio() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cout << fixed << setprecision(20);
}

// ------------ End of template --------------

#define endl "\n"

bool solve() {
  int n;
  cin >> n;
  if (n == 0) return false;
  vector<P> a(n);
  for (int i = 0; i < n; i++) cin >> a[i];
  sort(all(a));
  vector<int> lap(n, 0), start(n, 0);
  deque<int> f, b;
  for (int i = 0; i < n; i++) f.push_back(i);
  int ans = 0;
  while (!f.empty() || !b.empty()) {
    vector<int> fts;
    for (auto id : f) { fts.push_back(start[id] + a[id].first); }
    for (int i = 1; i < fts.size(); i++) chmax(fts[i], fts[i - 1]);

    vector<int> bts;
    for (auto id : b) { bts.push_back(start[id] + a[id].first); }
    for (int i = 1; i < bts.size(); i++) chmax(bts[i], bts[i - 1]);

    int nxt = -1;
    set<P> tob, tof;
    if (f.size() > 0 && (b.empty() || fts.front() <= bts.front())) {
      nxt = fts.front();
      for (int j = 0; j < f.size(); j++) {
        int id = f[j];
        if (fts[j] == nxt) {
          start[id] = nxt;
          tob.insert(P(a[id].first, id));
        }
      }
    }

    if (b.size() > 0 && (f.empty() || bts.front() <= fts.front())) {
      if (nxt != -1) assert(nxt == bts.front());
      nxt = bts.front();
      for (int j = 0; j < b.size(); j++) {
        int id = b[j];
        if (bts[j] == nxt) {
          start[id] = nxt;
          lap[id]++;
          tof.insert(P(a[id].first, id));
        }
      }
    }

    for (auto [_, id] : tob) {
      b.push_back(id);
      f.pop_front();
    }

    for (auto [_, id] : tof) {
      if (lap[id] < a[id].second) f.push_back(id);
      b.pop_front();
    }

    assert(nxt != -1);
    ans = nxt;
    // dmp(ans);
    // dmp(f);
    // dmp(b);
    // dmp(start);
  }
  cout << ans << endl;
  return true;
}

int main() {
  fastio();
  while (solve()) {}
  // int t;
  // cin >> t;
  // while (t--) solve();

  // int t; cin >> t;
  // for(int i=1;i<=t;i++){
  //   cout << "Case #" << i << ": ";
  //   solve();
  // }
  return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 3364
final_rank: 10