#include<bits/stdc++.h>
#define XX first
#define YY second
#define pb emplace_back
#define FOR(i,a,b) for(int (i)=(a);i<(b);++(i))
#define EFOR(i,a,b) for(int (i)=(a);i<=(b);++(i))
#define rep(X,Y) for (int (X) = 0;(X) < (Y);++(X))
#define REP rep
#define rrep(X,Y) for (int (X) = (Y)-1;(X) >=0;--(X))
#define all(X) (X).begin(),(X).end()
#define eb emplace_back

using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef ll LL;
typedef pii PII;
typedef pll PLL;
const ll MOD=1e9+7;

#define rall(X) (X).rbegin(),(X).rend()
#define UNIQUE(X) (X).erase(unique(all(X)),(X).end())
#define reps(X,S,Y) for (int (X) = S;(X) < (Y);++(X))
#define rreps(X,S,Y) for (int (X) = (Y)-1;(X) >= (S);--(X))
template<class T> inline bool MX(T &l,const T &r){return l<r?l=r,1:0;}
template<class T> inline bool MN(T &l,const T &r){return l>r?l=r,1:0;}

int N;
LL A[114514];
LL B[114514];

bool check(int l) {
  LL cur = 0;
  multiset<pll> as, bs;
  rep(i, N) {
    LL d = B[i] - A[i];
    if (d >= 0) {
      cur += d;
      bs.insert(pll(B[i], A[i]));
    } else {
      as.insert(pll(A[i], B[i]));
    }
  }

  multiset<LL> cs;
  while (as.size() > l) {
    cs.insert(as.rbegin()->YY);
    as.erase(as.find(*as.rbegin()));
  }
  while (as.size() < l && bs.size()) {
    cur -= bs.begin()->XX - bs.begin()->YY;
    as.insert(pll(bs.begin()->YY, bs.begin()->XX));
    bs.erase(bs.begin());
  }
  if (as.size() < l) return false;
  for (auto &p : as) cur -= p.XX;

  while (!as.empty() && !bs.empty()) {
    if (bs.begin()->XX < as.rbegin()->XX) {
      cs.insert(as.rbegin()->YY);
      cur += as.rbegin()->XX-bs.begin()->XX;
      as.insert(pll(bs.begin()->YY, bs.begin()->XX));
      as.erase(as.find(*as.rbegin()));
      bs.erase(bs.begin());
    } else break;
  }
  return cur >= 0;
}

pll GetAns(int l) {
  if (l == N) return pll(1, 1);

  LL cur = 0;
  multiset<pll> as, bs;
  rep(i, N) {
    LL d = B[i] - A[i];
    if (d >= 0) {
      cur += d;
      bs.insert(pll(B[i], A[i]));
    } else {
      as.insert(pll(A[i], B[i]));
    }
  }

  multiset<LL> cs;
  while (as.size() > l) {
    cs.insert(as.rbegin()->YY);
    as.erase(as.find(*as.rbegin()));
  }
  while (as.size() < l && bs.size()) {
    cur -= bs.begin()->XX - bs.begin()->YY;
    as.insert(pll(bs.begin()->YY, bs.begin()->XX));
    bs.erase(bs.begin());
  }
  assert(as.size() >= l);
  for (auto &p : as) cur -= p.XX;

  while (!as.empty() && !bs.empty()) {
    if (bs.begin()->XX < as.rbegin()->XX) {
      cs.insert(as.rbegin()->YY);
      cur += as.rbegin()->XX-bs.begin()->XX;
      as.insert(pll(bs.begin()->YY, bs.begin()->XX));
      as.erase(as.find(*as.rbegin()));
      bs.erase(bs.begin());
    } else break;
  }

  if (cur > 0) assert(!bs.empty());
  if (!bs.empty()) {
    cs.clear();
    for (auto &p : bs) cs.insert(p.XX);
  }
  assert(!cs.empty());
  assert(cur < *cs.begin());
  LL q = *cs.begin();
  LL p = l*q+cur;
  q *= N;
  LL g = __gcd(p, q);
  return pll(p/g, q/g);
}

signed main(){
  ios_base::sync_with_stdio(false);
  cout<<fixed<<setprecision(0);

  cin >> N;
  rep(i, N) {
    cin >> A[i] >> B[i];
  }

  int low = 0;
  int high = N+1;
  while (high-low > 1) {
    int mid = (high+low)/2;
    if (check(mid)) low = mid;
    else high = mid;
  }
 
  //cout << low << endl;
  auto ans = GetAns(low);
  cout << ans.XX << " " << ans.YY << endl;
}
