#include <bits/stdc++.h>
// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <cmath>
#include <iomanip>
#include <time.h>
#define dibs reserve
#define OVER9000 1234567890
#define ALL_THE(CAKE,LIE) for(auto LIE =CAKE.begin(); LIE != CAKE.end(); LIE++)
#define tisic 47
#define soclose 1e-8
#define chocolate win
// so much chocolate
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
#define uint unsigned int
#define dbl long double
#define pi 3.14159265358979323846
using namespace std;
// mylittledoge

using cat = long long;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

cat gcd(cat x, cat y) {
	if(x > y) swap(x, y);
	return (x == 0) ? y : gcd(y%x, x);
}

int main() {
	cin.sync_with_stdio(0);
	cin.tie(0);
	cout << fixed << setprecision(10);
	int N;
	cin >> N;
	vector< pair<int, int> > near, far;
	cat BA_dif = 0;
	for(int i = 0; i < N; i++) {
		int a, b;
		cin >> a >> b;
		if(a <= b) {
			near.push_back({b, a});
			BA_dif += b-a;
		}
		else far.push_back({a, b});
	}
	sort(begin(near), end(near));
	vector<cat> B_sum_near(near.size()+1, 0);
	for(int i = 0; i < (int)near.size(); i++) B_sum_near[i+1] = B_sum_near[i] + near[i].ff;
	sort(begin(far), end(far));
	vector<cat> A_sum_far(far.size()+1, 0);
	for(int i = 0; i < (int)far.size(); i++) A_sum_far[i+1] = A_sum_far[i] + far[i].ff;
	cat ans_num = 0, ans_denom = 1;

	for(int f = 0, n = 0; n < (int)near.size(); n++) {
		cat dif = BA_dif - B_sum_near[n];
		if(dif < 0) continue;
		static cat cur_A_sum_far = 0;
		while(f < (int)far.size() && dif >= cur_A_sum_far + far[f].ff) {
			cur_A_sum_far += far[f].ff;
			f++;
		}
		while(f > 0 && dif < cur_A_sum_far) {
			f--;
			cur_A_sum_far -= far[f].ff;
		}
		dif -= cur_A_sum_far;
		if(dif < 0 || dif > near[n].ff) continue;
		cat P_num = 1LL * near[n].ff * (n + f) + dif;
		cat P_denom = near[n].ff;

		cat P = P_num / P_denom, ans = ans_num / ans_denom;
		if(P > ans)
			ans_num = P_num, ans_denom = P_denom;
		else if(P == ans && (P_num%P_denom) * ans_denom > (ans_num%ans_denom) * P_denom)
			ans_num = P_num, ans_denom = P_denom;
	}

	for(int f = 0; f < (int)far.size(); f++) {
		int n = upper_bound(begin(near), end(near), pair<int, int>(far[f].ss, -1)) - begin(near);
		cat dif = BA_dif - B_sum_near[n] + far[f].ss - far[f].ff;
		if(dif < 0) continue;
		int cnt_far = upper_bound(begin(A_sum_far), end(A_sum_far), dif) - 1 - begin(A_sum_far);
		cat cur_A_sum_far = A_sum_far[cnt_far];
		if(f < cnt_far) {
			cur_A_sum_far -= far[f].ff;
			if(cnt_far < (int)far.size() && far[cnt_far].ff+cur_A_sum_far <= dif) {
				cur_A_sum_far += far[cnt_far].ff;
				cnt_far++;
			}
		}
		if(cnt_far > f) cnt_far--;
		dif -= cur_A_sum_far;
		if(dif < 0 || dif > far[f].ss) continue;
		cat P_num = 1LL * far[f].ss * (n + cnt_far) + dif;
		cat P_denom = far[f].ss;

		cat P = P_num / P_denom, ans = ans_num / ans_denom;
		if(P > ans)
			ans_num = P_num, ans_denom = P_denom;
		else if(P == ans && (P_num%P_denom) * ans_denom > (ans_num%ans_denom) * P_denom)
			ans_num = P_num, ans_denom = P_denom;
	}

	cat g = gcd(ans_num, ans_denom*N);
	cout << ans_num/g << " " << ans_denom*N/g << "\n";
	return 0;
}

// look at my code
// my code is amazing


Measured memory_bytes: 2036