#include<bits/stdc++.h>
#define a first
#define b second
#define pb push_back
#define SZ(x) ((int)x.size())
#define L(i,u) for (register int i=head[u]; i; i=nxt[i])
#define rep(i,a,b) for (register int i=(a); i<=(b); i++)
#define per(i,a,b) for (register int i=(a); i>=(b); i--)
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef pair<int,int> Pii;
typedef vector<int> Vi;
template<class T> inline void read(T &x){
	x=0; char c=getchar(); int f=1;
	while (!isdigit(c)) {if (c=='-') f=-1; c=getchar();}
	while (isdigit(c)) {x=x*10+c-'0'; c=getchar();} x*=f;
}
template<class T> inline void umin(T &x, T y){x=x<y?x:y;}
template<class T> inline void umax(T &x, T y){x=x>y?x:y;}
inline ui R() {
	static ui seed=416;
	return seed^=seed>>5,seed^=seed<<17,seed^=seed>>13;
}
const int N = 266666;
int n,v[N];Pii s[N];
struct Frac{
	ll a,b;// a/b
	Frac(ll A=0,ll B=1){a=A;b=B;}
}ans;
ll gcd(ll a, ll b){return !b?a:gcd(b,a%b);}
inline Frac Norm(Frac y){
	ll g=gcd(y.a,y.b);y.a/=g;y.b/=g;return y;
}
inline void upd(Frac &x, Frac y){
	y=Norm(y);if(1.0*x.a/x.b>1.0*y.a/y.b)x=y;
}
bool cmp(Pii x, Pii y){return x.a+max(x.b-x.a,0)<y.a+max(y.b-y.a,0);}
bool ck(int k){
	ll tot=0;rep(i,1,n)tot+=max(s[i].b-s[i].a,0);
	rep(i,1,k)tot-=v[i];return tot>=0;
}
int main() {
	read(n);rep(i,1,n)read(s[i].a),read(s[i].b);
	sort(s+1,s+n+1,cmp);
	rep(i,1,n)v[i]=s[i].a+max(s[i].b-s[i].a,0);
	int L=0,R=n;
	while(L<R){
		int mid=(L+R+1)>>1;
		if(ck(mid))L=mid;else R=mid-1;
	}
	int k=L;assert(k<n);
	ll ori=0;rep(i,1,n)ori+=max(s[i].b-s[i].a,0);
	rep(i,1,k)ori-=v[i];
	ans.a=1;ans.b=1;
	rep(i,1,n){
		ll tot=ori;
		if(i<=k)tot=tot+s[i].a-v[k+1];else tot-=max(s[i].b-s[i].a,0);
		upd(ans,(Frac){s[i].a-tot,s[i].b});
	//	printf("%d %lld %lld\n",i,s[i].a-tot,s[i].b);
	}
	ll x=ans.a,y=ans.b;
//	printf("%d %lld %lld\n",k,x,y);
	ans=(Frac){y-x+y*k,n*y};ans=Norm(ans);
	printf("%lld %lld\n",ans.a,ans.b);
	return 0;
}
