#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define rnt re int
#define re register
#define LL inline ll
#define I inline int
#define V inline void
#define B inline bool
#define ll long long int
#define isnum(ch) ('0'<=ch&&ch<='9')
#define FOR(i,a,b) for(rnt i=a;i<=b;i++)
#define gc (_op==_ed&&(_ed=(_op=_buf)+fread(_buf,1,100000,stdin),_op==_ed)?EOF:*_op++)
char _buf[100000],*_op(_buf),*_ed(_buf);
I getint(){
	rnt _s=0;re char _ch=gc;
	while(!isnum(_ch))_ch=gc;
	while(isnum(_ch))_s=_s*10+_ch-48,_ch=gc;
	return _s;
}
const int N=1e5+1;
int n,k;
ll S,up=1,dw=1;
struct node{
	ll x,y;
	V input(){x=getint(),y=getint();}
	B operator<(const node&u)const{
		return x>u.x;
	}
}a[N];
LL gcd(ll x,ll y){return !y?x:gcd(y,x%y);}
int main(){
	n=getint();
	FOR(i,1,n)a[i].input(),S+=a[i].x,a[i].x=max(a[i].x,a[i].y);
	sort(a+1,a+1+n);ll now=0,dis;
	while(now<S)now+=a[++k].x;
	FOR(i,1,n){
		dis=S-now+a[min(i,k)].x;
		if(dis<=a[i].y&&dis*dw<a[i].y*up)
			up=dis,dw=a[i].y;
	}
	up=(dw-up)+dw*(n-k),dw*=n,now=gcd(up,dw);
	cout<<up/now<<' '<<dw/now;
	return 0;
}