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++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

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

// #define DEBUG
#define fi first
#define se second
#define be begin
#define en end
#define pb push_back 
#define eb emplace_back
#define mp make_pair 
#define ALL(a) (a).be() , (a).en()
#define REP(i,n) for(int (i)=0;(i)<(n);(i)++)        //repeat n times
#define REP2(i,s,n) for(int (i)=(s);(i)<(n);(i)++)   //repeat from s to n 
#define REPD(i,n) for(int (i)=(n);(i)>=0;(i)--)      //repeat from n to 0
#define REPD2(i,s,e) for(int (i)=(s);(i)>=(e);(i)--) //repeat from s to e
#define RANGE(i,v) for(auto &(i):v)                  //repeat range
#define ASIZE(a) (sizeof(a) / sizeof(a[0]))          //array size

#define EL cout<<endl

using LL = long long;

template<typename T1,typename T2> using P = pair< T1, T2 >;
using Pii = P<int,int>;
using Pdd = P<double,double>;

template<typename T> using V = vector< T >;
using Vi = V<int>;
using Vll = V<LL>;
using Vs = V<string>;

template<typename T1,typename T2> using M = map< T1, T2>;
using Mii = M<int, int>;
using Msi = M<string, int>;

const int MOD = 1000000007;
const int INF = 1999999999;
const LL INFLL = 999999999999999;
const double EPS = 1e-10;

const int DX[8]= {-1,0,1,0,-1,-1,1,1};
const int DY[8]= {0,-1,0,1,-1,1,1,-1};

const double PI=3.141592653589793;
//==================================================================
/* I/O */
//scan
void SCAN(int *a){scanf("%d",a);}                             //scan for type int
void SCAN(int *a,int n){REP(i,n){scanf("%d",&a[i]);}}   //scan for type int array
void SCAN(Pii *a){scanf("%d",&a->fi);scanf("%d",&a->se);}     //scan for type pair<int, int>
void SCAN(LL *a){scanf("%lld",a);}                            //scan for type long long int
void SCAN(LL *a,int n){REP(i,n){scanf("%lld",&a[i]);}}  //scan for type long long int array
void SCAN(char *c){scanf(" %c",c);}                           //scan for type char
void SCAN(char *c,int n){REP(i,n){scanf(" %c",&c[i]);}} //scan for type char array

//print 
void PRINT(int a){printf("%d\n",a);}
void PRINT(int *a,int s,char c='\n'){REP(i,s){if(i==s-1){c='\n';}printf("%d%c",a[i],c);}}
void PRINT(Vi a,char c='\n'){REP(i,a.size()){if(i==a.size()-1){c='\n';}printf("%d%c",a[i],c);}}
void PRINT(LL a){printf("%lld\n",a);}
void PRINT(LL *a,int s,char c='\n'){REP(i,s){if(i==s-1){c='\n';}printf("%lld%c",a[i],c);}}
void PRINT(double a){printf("%.15f\n",a);}
void PRINT(double *a,int s,char c='\n'){REP(i,s){if(i==s-1){c='\n';}printf("%f%c",a[i],c);}}
void PRINT(char a){printf("%c\n",a);}
void PRINT(string a){printf("%s\n",a.c_str());}
//==================================================================

//==================================================================
/* vector */
//sort and remove duplicates for type vector
template<typename A>
void UNIQUE(vector< A > &a,int mode=0){
	if(mode==0){ sort(ALL(a),greater< A >());}else{ sort(ALL(a));}
	a.erase(unique(ALL(a)),a.en());
}

//fill an N-dimensional array with val
template<typename A, size_t N, typename T>
void FILL(A (&array)[N], const T &val){
	fill((T*)array,(T*)(array+N),val);
}
//==================================================================

//==================================================================
/* math */
long double pascalTri(int n,int r){
	long double tri[n+1][n+1];
	REP(i,n+1){REP(j,n+1){tri[i][j]=0;}}
	REP(i,n+1){REP(j,n+1){
		if(j>i){break;}
		if(j==0||j==i){tri[i][j]=1;}else{tri[i][j]=(tri[i-1][j-1]+tri[i-1][j]);}
	}}
	return tri[n][r];
}

LL GCD(LL a,LL b){
	LL t; LL r;
	if(a<b){t=a;a=b;b=t;}
	if(b==0){return a;}
	while(a%b!=0){r=a%b;a=b;b=r;}
	return b;
}

LL LCM(LL a,LL b){LL ab=(a*b)%MOD;return ab/GCD(a%b,b);}

//Bipartite method : x^n
LL BMPow(int x,int n,int m=0){
	LL ans=1;LL p=x;
	if(m==0){ while(n>0){if(n&1==1){ans*=p;} p*=p; n>>=1;}}
	else{ while(n>0){if(n&1==1){ans=(ans*p)%m;} p=(p*p)%m ;n>>=1;}}
	return ans;
}

//x^-1=x^(m-2) mod m
LL modInv(LL x,int m){return BMPow(x,m-2,m);}

//x! or x! mod m
LL factorial(int x,int m=0){
	LL a=1;
	if(m==0){REPD2(i,x,1){a*=i;}}else{REPD2(i,x,1){a=(a*i)%m;}}
	return a;
}

// sign of val
template <typename T> int sgn(T val){return (T(0) < val) - (val < T(0));}
//==================================================================

//==================================================================
/* geometry */
template<typename T> using coordinate = P< T, T >;
template<typename T> using coordinateSet = V<coordinate< T >>;

//centroid of polygon
template<typename T>
coordinate<double> centroidPolygon(coordinateSet<T> &a){
	coordinate<double> G; G.fi=0.; G.se=0.;
	int n = a.size();
	RANGE(i,a){G.fi+=i.fi; G.se+=i.se;}
	G.fi/=n;G.se/=n;
	return G;
}

double area(coordinate<int> a,coordinate<int> b,coordinate<int> c){ 
	return ((b.fi-a.fi)*(c.se-a.se)-(b.se-a.se)*(c.fi-a.fi))/2.;
}

int checkCross(coordinate<int> v1,coordinate<int> v2,coordinate<int> a,coordinate<int> b){
	if(area(a,b,v1)*area(a,b,v2)>=0){return 0;}
	if(area(v1,v2,a)*area(v1,v2,b)>=0){return 0;}
	return 1;
}
//==================================================================

//==================================================================
/* graph */
struct edge{
	int src; int dst; int weight;
	edge() : src(0), dst(0), weight(0) {}
	edge(int s, int d, int w) : src(s), dst(d), weight(w) {}
};

using edges = V<edge>;
using graph = V<edges>;

void add_edge(edges &g,int s, int d, int w=1){g.pb(edge(s,d,w));}
void add_edge(graph &g,int s, int d, int w=1){g[s].pb(edge(s,d,w));}

V<Vi> floyd(const graph &g){
	int i,j,k; int n = g.size();
	V<Vi> dist(n,Vi(n,INF/2));
	REP(i,n){dist[i][i]=0;}
	REP(i,n){for(auto &e:g[i]){dist[e.src][e.dst]=e.weight;}}
	REP(k,n){REP(i,n){REP(j,n){dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);}}}
	return dist;
}

Vi dijkstra(graph &g,int s){
	int i,j,k; int n=g.size(); int visit[n]; Vi dist(n);
	priority_queue<Pii,V<Pii>,greater<Pii>> q;
	REP(i,n){visit[i]=0; dist[i]=INF/2;}
	dist[s]=0;
	q.push(mp(0,s));
	int nv; int min_cost=0;
	while(!q.empty()){
		int d,t; tie(d,t)=q.top(); q.pop();
		if(visit[t]==1){continue;}
		visit[t]=1; dist[t]=d;
		for(auto &e:g[t]){
			if(dist[e.dst]<=d+e.weight){continue;}
			q.push(mp(d+e.weight,e.dst));
		}
	}
	return dist;
}
//==================================================================

//==================================================================
/* data structure */
// binary indexed tree
template<typename T>
struct binaryIndexedTree{
	private:
		int n;
		V<T> x;
	public:
		binaryIndexedTree(int num=0) : n(num), x(n,0){}
		void add(int a, T w){for(int i=a;i<n;i|=i+1){ if(x[i]<w){x[i]=w;}}}
		T maximum(int a){ T m = -1;for(int k=a-1; k>=0;k=(k&(k+1))-1){ m=max(m,x[k]);} return m;}
};

// union find
struct unionFind{
	private:
		Vi data;
	public:
		unionFind(int size) : data(size,-1){}
		bool unionSet(int x,int y){
			x=root(x);y=root(y);
			if(x!=y){
				if(data[y]<data[x]){swap(x,y);}
				data[x]+=data[y]; data[y]=x;
			}
			return x!=y;
		}
		bool findSet(int x,int y){ return root(x)==root(y);}
		int root(int x){return ((data[x]<0)?x:(data[x]=root(data[x])));}
		int size(int x){return -data[root(x)];}
};
//==================================================================


int main(){
	// cin.tie(0);
	// ios::sync_with_stdio(false);
	int n;
	SCAN(&n);
	LL t[n],a[n];
	REP(i,n){
		SCAN(&t[i]); SCAN(&a[i]);
	}

	LL takahashi=1,aoki=1;
	REP(i,n){
		LL h=max(((double)takahashi/t[i])+0.9,((double)aoki/a[i])+0.9);
		takahashi=h*t[i];
		aoki=h*a[i];
	}

	PRINT(takahashi+aoki);
	return 0;
}