#include <algorithm>  
#include <iostream>  
#include <sstream>  
#include <string>  
#include <vector>  
#include <queue>  
#include <set>  
#include <map>  
#include <cstdio>  
#include <cstdlib>  
#include <cctype>  
#include <cmath>  
#include <cstring>
#include <list>  
#include <cassert>
#include <climits>
#include <bitset>
using namespace std;  

#define PB push_back  
#define MP make_pair  
#define SZ(v) ((int)(v).size())  
#define FOR(i,a,b) for(int i=(a);i<(b);++i)  
#define REP(i,n) FOR(i,0,n)  
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)  
#define REPE(i,n) FORE(i,0,n)  
#define FORSZ(i,a,v) FOR(i,a,SZ(v))  
#define REPSZ(i,v) REP(i,SZ(v))  
typedef long long ll;  
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

const int MAXBEAM=100000;
struct Beam { int a,b; int key; };
bool operator<(const Beam &p,const Beam &q) { return p.key<q.key; }
struct Frac { ll num,den; Frac():num(0),den(1) {} Frac(ll _num,ll _den) { num=_num,den=_den; ll g=gcd(num,den); num/=g; den/=g; } };
bool operator>(const Frac &p,const Frac &q) { return p.num*q.den>q.num*p.den; }

int nbeam;
Beam beam[MAXBEAM];

int nslow;
Beam slow[MAXBEAM];
int nfast;
Beam fast[MAXBEAM];


Frac solve() {
	nslow=nfast=0;
	REP(i,nbeam) if(beam[i].a<beam[i].b) fast[nfast++]=beam[i]; else slow[nslow++]=beam[i];
	REP(i,nfast) fast[i].key=fast[i].b; sort(fast,fast+nfast);
	REP(i,nslow) slow[i].key=slow[i].a; sort(slow,slow+nslow);
	
	if(nfast==0) return Frac(0,1);
	ll asum=0,bsum=0;
	REP(i,nfast) asum+=fast[i].a;
	int atslow=0;
	for(int i=nfast-1;i>=0;--i) {
		while(atslow<nslow&&bsum+fast[i].b>=asum) {
			if(slow[atslow].a>=fast[i].b) break;
			if(bsum+fast[i].b>=asum+slow[atslow].a) { asum+=slow[atslow++].a; continue; }
			if(i==0) break;
			if(slow[atslow].a>=fast[i-1].b) break;
			if(bsum+fast[i].b+fast[i-1].b>=asum+slow[atslow].a) { asum+=slow[atslow++].a; continue; }
			assert(false);
		}
		if(bsum+fast[i].b>=asum) {
			int ipart=atslow+i;
			Frac fpart(bsum+fast[i].b-asum,fast[i].b);
			int idx=-1; REP(k,atslow) if(idx==-1||slow[k].b>slow[idx].b) idx=k;
			FOR(k,atslow,nslow) {
				assert(bsum+fast[i].b<asum+slow[k].a);
				if(bsum+fast[i].b+slow[k].b>=asum+slow[k].a) {
					Frac cpart(bsum+fast[i].b+slow[k].b-asum-slow[k].a,slow[k].b);
					if(cpart>fpart) fpart=cpart;
				}
				if(i!=0&&bsum+fast[i].b+fast[i-1].b>=asum+slow[k].a) {
					Frac cpart(bsum+fast[i].b+fast[i-1].b-asum-slow[k].a,fast[i-1].b);
					if(cpart>fpart) fpart=cpart;
				}
				if(idx!=-1&&bsum+fast[i].b+slow[idx].b>=asum+slow[k].a) {
					Frac cpart(bsum+fast[i].b+slow[idx].b-asum-slow[k].a,slow[idx].b);
					if(cpart>fpart) fpart=cpart;
				}
			}
			return Frac((ll)ipart*fpart.den+fpart.num,(ll)fpart.den*nbeam);
		}
		bsum+=fast[i].b;
	}
	assert(false); return Frac(0,1);
}

void run() {
	scanf("%d",&nbeam);
	REP(i,nbeam) scanf("%d%d",&beam[i].a,&beam[i].b);
	Frac ans=solve();
	printf("%lld %lld\n",ans.num,ans.den);
}

int main() {
	run();
	return 0;
}
