#include <bits/stdc++.h> 

using namespace std;


typedef pair<int, int> pii;

#define REP(i,n) for(int(i)=0;(i)<(int)(n);(i)++)

using namespace std;

int n;
typedef __int128_t ll;

struct bar {
	int diff;
	int s, r;
};

ll gcd(ll a, ll b) {
	if (b == 0) return a;
	return gcd(b, a%b);
}

bar bars[110000];
vector<bar> negs;
vector<bar> pos;

struct frac {
	ll a, b;
	frac(ll _a, ll _b) {
		a = _a; b = _b;
		simplify();
	}

	void simplify() {
		ll g = gcd(a,b);
		a /= g; b /= g;
	}

	frac operator+(frac ot) {
		frac ret(1,1);
		ret.b = b/gcd(b,ot.b) * ot.b;
		ret.a = a*(ret.b/b) + ot.a*(ret.b/ot.b);
		ret.simplify();
		return ret;
	}

	bool operator<(frac ot) {
		return a*ot.b < b*ot.a;
	}
};

int main() {
	scanf("%d", &n);

	REP(i,n) {
		int a,b;
		scanf("%d %d", &a, &b);
		bars[i].diff = a-b;
		bars[i].s = a;
		bars[i].r = b;
	
		if (bars[i].s < bars[i].r) {
			negs.push_back(bars[i]);
		}
		else {
			pos.push_back(bars[i]);
		}
	}

	sort(negs.begin(), negs.end(), [](bar a, bar b) {return a.r > b.r;});
	sort(pos.begin(), pos.end(), [](bar a, bar b){return a.s < b.s;});

	multiset<int> rs;

	ll cur = 0;
	for (int i = 0; i < negs.size(); i++) {
		cur += negs[i].s;
	}

	int atneg = 0;
	while (cur > 0 && atneg < negs.size()) {
		cur -= negs[atneg++].r;
	}

	frac ans(0,1);
	for (int atp = 0; atp <= pos.size(); atp++) {
		if (cur > 0) break;

		int has = (int)negs.size() - atneg;
		has += atp;

		frac r(has, 1);
		//printf("has = %d cur = %lld\n", has, cur);
		if (atneg != 0) {
			frac r1 = r + frac(-cur,negs[atneg-1].r);
			frac r2(0,1);
			if (atp != 0) r2 = r + frac(-(cur - pos[atp-1].s + negs[atneg-1].r), pos[atp-1].s); 
		}
		if (ans < r1) ans = r1;
		if (ans < r2) ans = r2;
		//printf("%lld %lld", ans.a, ans.b);

		if (atp != pos.size()) {
			cur += pos[atp].s;
			while (cur > 0 && atneg < negs.size()) {
				cur -= negs[atneg++].r;
			}
		}
	}

	long long num = ans.a;
	long long den = ans.b;
	ll g = gcd(num, n);
	num /= g; n /= g;
	den *= n;

	printf("%lld %lld\n", num, den);
}