#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using D = double;
using uint = unsigned int;
template <typename T>
using pair2 = pair<T, T>;
using pii = pair<int, int>;
using pli = pair<ll, int>;
using pll = pair<ll, ll>;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
__int128 abs(__int128 a) { return a > 0 ? a : -a; }
__int128 gcd(__int128 a, __int128 b) { return a == 0 ? b : gcd(b % a, a); }
struct frac {
  __int128 up, down;
  frac() {}
  frac(__int128 up_, __int128 down_) {
    up = up_;
    down = down_;
    __int128 g = gcd(abs(up), abs(down));
    up /= g;
    down /= g;
    if (down < 0) {
      up *= -1;
      down *= -1;
    }
  }
};
inline frac operator+(const frac &a, const frac &b) {
  return frac(a.up * b.down + a.down * b.up, a.down * b.down);
}
inline bool operator<(const frac &a, const frac &b) {
  return a.up * b.down < b.up * a.down;
}
const int maxn = 100005;
const ll inf = 1e18;
vector<pair2<int>> fast, slow;
ll sumbfast[maxn];
int n;
ll totald;
frac solvefast(ll tA) {
  int pos = lower_bound(sumbfast, sumbfast + (int)fast.size(), -totald - tA) -
            sumbfast;
  if (pos != 0) {
    ll tB2 = sumbfast[pos - 1];
    ll up = -totald - tA - tB2;
    ll down = fast[pos - 1].second;
    up = min(up, down);
    assert(up >= 0);
    return frac(pos - 1, n) + frac(up, n * down);
  }
  return frac(0, 1);
}
int main() {
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    if (x <= y)
      fast.push_back({x, y});
    else
      slow.push_back({x, y});
  }
  sort((fast).begin(), (fast).end(),
       [&](pair2<int> &a, pair2<int> &b) { return a.second < b.second; });
  sumbfast[0] = 0;
  for (int i = 0; i < (int)fast.size(); i++)
    sumbfast[i + 1] = sumbfast[i] + fast[i].second;
  sort((slow).begin(), (slow).end(), [&](pair2<int> &a, pair2<int> &b) {
    return a.first - a.second < b.first - b.second;
  });
  totald = 0;
  for (auto t : fast) totald += t.first - t.second;
  ll totaldslow = 0;
  ll minB = inf;
  ll tB = 0;
  ll tA = 0;
  frac answer = solvefast(0);
  for (int i = 0; i < (int)slow.size(); i++) {
    totaldslow += slow[i].first - slow[i].second;
    tB += slow[i].second;
    minB = min(minB, (ll)slow[i].second);
    if (tB > -(totald + totaldslow)) break;
    ll up = -(totald + totaldslow) - tB;
    up = min(up, (ll)minB);
    frac curans = frac(i, n) + frac(up, n * minB);
    tA += slow[i].first;
    curans = curans + solvefast(tA);
    if (answer < curans) answer = curans;
  }
  printf("%lld %lld\n", (ll)answer.up, (ll)answer.down);
  return 0;
}
