Problem:
Score : 300 points

Problem Statement

AtCoDeer the deer is seeing a quick report of election results on TV.
Two candidates are standing for the election: Takahashi and Aoki.
The report shows the ratio of the current numbers of votes the two candidates have obtained, but not the actual numbers of votes.
AtCoDeer has checked the report N times, and when he checked it for the i-th (1≦i≦N) time, the ratio was T_i:A_i.
It is known that each candidate had at least one vote when he checked the report for the first time.

Find the minimum possible total number of votes obtained by the two candidates when he checked the report for the N-th time.
It can be assumed that the number of votes obtained by each candidate never decreases.

Constraints

1≦N≦1000

1≦T_i,A_i≦1000 (1≦i≦N)

T_i and A_i (1≦i≦N) are coprime.

It is guaranteed that the correct answer is at most 10^{18}.

Input

The input is given from Standard Input in the following format:

N
T_1 A_1
T_2 A_2
:
T_N A_N

Output

Print the minimum possible total number of votes obtained by Takahashi and Aoki when AtCoDeer checked the report for the N-th time.

Sample Input 1

3
2 3
1 1
3 2

Sample Output 1

10

When the numbers of votes obtained by the two candidates change as 2,3 → 3,3 → 6,4, the total number of votes at the end is 10, which is the minimum possible number.

Sample Input 2

4
1 1
1 1
1 5
1 100

Sample Output 2

101

It is possible that neither candidate obtained a vote between the moment when he checked the report, and the moment when he checked it for the next time.

Sample Input 3

5
3 10
48 17
31 199
231 23
3 2

Sample Output 3

6930

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

//
// ABC046C
// URL : https://atcoder.jp/contests/abc046/tasks/abc046_c
// 
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;

namespace AtCoder
{
    class ABC046C
    {
        class Ratio
        {
            public long T;
            public long A;
            public Ratio() { T = A = 0; }
            public Ratio(long _T, long _A)
            {
                T = _T;
                A = _A;
            }
        }
        static void Main(string[] args)
        {
            preprocess();

            long N = long.Parse(Console.ReadLine());
            var RatioList = new List<Ratio>((int)N);
            for (int i = 0; i < N; ++i)
            {
                long[] inputLongArray = Console.ReadLine().Split(' ').Select(_inputStr => long.Parse(_inputStr)).ToArray();
                RatioList.Add(new Ratio(inputLongArray[0], inputLongArray[1]));
            }

            //初期の票数を最初の比率で与える
            long T_Vote = RatioList[0].T;
            long A_Vote = RatioList[0].A;
            //i回目の確認では、Ti,Aiの比率の倍数かつ、i-1回目の確認より0票以上互いに多く票が集まっている
            for (int i = 1; i < RatioList.Count; ++i)
            {
                //i-1回目の確認より0票以上互いに多く票が集まっている必要がある
                //上限を決めたい
                var init = (long)( Math.Max(T_Vote / RatioList[i].T, A_Vote / RatioList[i].A) );
                //long c = 0;
                for (long x = init; x < init+3; ++x) {//上限は適当
                    long t = RatioList[i].T * x;
                    long a = RatioList[i].A * x;
                    if(t >= T_Vote && a >= A_Vote)
                    {
                        T_Vote = t;
                        A_Vote = a;
                        break;
                    }
                    //++c;
                }
                //Console.WriteLine("{0}, Vote {1} {2}, {3}",i, T_Vote, A_Vote, c);
            }

            long sum = T_Vote + A_Vote;
            Console.WriteLine(sum.ToString());
            Console.Out.Flush();
        }

        //---------------------------------------------------------------------------------
        /// <summary>
        /// 
        /// </summary>
        public static void preprocess()
        {
            //出力高速化
            var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
            Console.SetOut(sw);
        }


        /// <summary>
        /// 与えられた数が素数かどうかを計算する
        /// </summary>
        /// <param name="num">対象数</param>
        /// <returns>true:素数, false:素数ではない(合成数)</returns>
        public static bool isPrime(int num)
        {
            if (num < 2) return false;
            else if (num == 2) return true;
            else if (num % 2 == 0) return false;

            double sqrtNum = Math.Sqrt(num);
            for (int i = 3; i <= sqrtNum; i += 2)
            {
                if (num % i == 0)
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 順列mPnを計算する
        /// </summary>
        /// <param name="m"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        public static long Permutation(long m, long n)
        {
            long ret = 1;
            for(var i = 0; i < n; ++i)
            {
                ret *= m - i;
            }
            return ret;
        }
        /// <summary>
        /// 組み合わせmCnを計算する
        /// </summary>
        /// <param name="m"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        public static long Combination(long m, long n)
        {
            if(m == n || n == 0)
            {
                return 1;
            }
            long ans = 1;
            for(var i = 0; i <= n; ++i)
            {
                ans *= (m - i + 1) / i;
            }
            return ans;
        }

        static long Gcd(long m, long n)
        {
            if (n == 0) return m;
            return Gcd(n, m % n);
        }

        static long Lcm(long m, long n)
        {
            var gcd = Gcd(m, n);
            //return (m * n) / gcd;
            return m / gcd * n;//桁あふれ対策
        }
    }
}