#include<bits/stdc++.h>
using namespace std;
const int maxn=100100;
struct node{
	int A,B;
}a[maxn];
struct val{
	long long x,y;
	void operator = (const int &B){
		x=B,y=1;
	}
};
void print(val A){
	printf("val=%lld/%lld\n",A.x,A.y);
}
val operator + (const val &A,const int B){
	val ret=A;
	ret.x=ret.x+B*A.y;
	return ret;
}
bool operator < (const val &A,const val &B){
	long long v1=A.x/A.y,v2=B.x/B.y;
	if(v1<v2) return 1;
	else if(v1>v2) return 0;
	return (A.x%A.y)*B.y<(B.x%B.y)*A.y;
}
bool operator < (const node &A,const node &B){
	return A.A<B.A;
}
bool cmp(const node &A,const node &B){
	return A.B<B.B;
}
priority_queue<node> q;
void chkmax(val &A,val B){
	A=A<B?B:A;
}
long long gcd(long long x,long long y){
	long long r;
	while(y){
		r=x%y;
		x=y;
		y=r;
	}
	return x;
}
bool ccp(const node &A,const node &B){
	return A.B<B.B;
}
int main(){
//	freopen("D.in","r",stdin);
//	freopen("D.out","w",stdout);
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d%d",&a[i].A,&a[i].B);
	sort(a+1,a+n+1,cmp);
	long long tot=0,sum=0;
	int cnt=0;
	val ans,st;
	ans=0,st=0;
	for(int i=1;i<=n;i++)
		if(a[i].A<a[i].B)
			tot+=a[i].B-a[i].A;
	for(int i=1;i<=n;i++){
		while(sum>tot){
			sum-=(q.top()).A;
			cnt--;
			q.pop();
		}
		if(a[i].A<a[i].B){
			if(tot-sum>=a[i].B)
				st=cnt+1;
			else{
				st=(val){tot-sum,a[i].B};
				st=st+cnt;
			}
			chkmax(ans,st);
			tot-=a[i].B-a[i].A;
			while(sum>tot){
				sum-=(q.top()).A;
				cnt--;
				q.pop();
			}
		}
		if(a[i].A<=(tot-sum))
			st=cnt+1;
		else{
			st=(val){a[i].A-(tot-sum),a[i].B};
			if(st.x>st.y) st.x=0;
			else st.x=st.y-st.x;
			st=st+cnt;
		}
		chkmax(ans,st);
		q.push(a[i]);
		sum+=a[i].A;
		cnt++;
	}
	if(ans.x==0){
		printf("0 1\n");
		return 0;
	}
//	cerr<<3211685239.0/(5528829200/20)<<endl;
	ans.y*=n;
	long long r=gcd(ans.x,ans.y);
	ans.x/=r,ans.y/=r;
	printf("%lld %lld\n",ans.x,ans.y);
	return 0;
}
