#include <bits/stdc++.h>
using namespace std;
namespace IO {
template <typename T>
inline void read(T &x) {
  x = 0;
  long long f = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = -f;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = x * 10 + ch - 48;
    ch = getchar();
  }
  x = x * f;
}
}  // namespace IO
using namespace IO;
long long N, S = 0;
vector<pair<long long, long long> > T;
bool mp(pair<long long, long long> A, pair<long long, long long> B) {
  return (A.first * B.second < A.second * B.first);
}
long long gcd(long long x, long long y) { return y == 0 ? x : gcd(y, x % y); }
int main() {
  read(N);
  for (int i = 1; i <= N; i++) {
    long long x, y;
    read(x), read(y);
    S += x;
    T.push_back(make_pair(std::max(x, y), y));
  }
  sort(T.begin(), T.end(), greater<pair<long long, long long> >());
  long long pos = 0;
  long long point = 0;
  int ca = 0;
  for (auto it = T.begin(); it != T.end(); it++) {
    if ((pos + it->first) > S) break;
    pos += it->first;
    point = it - T.begin();
    ca++;
  }
  if (point == T.size() - 1) {
    cout << "0 1";
    return 0;
  }
  pair<long long, long long> ans(0, 1);
  for (int i = 0; i < T.size(); ++i) {
    if (i > point) {
      if (pos + T[i].second >= S) {
        pair<long long, long long> res(pos + T[i].second - S, T[i].second);
        ans = (mp(ans, res)) ? res : ans;
      }
    } else {
      if (pos - T[i].first + T[point + 1].first + T[i].second >= S) {
        pair<long long, long long> res(
            pos - T[i].first + T[point + 1].first + T[i].second - S,
            T[i].second);
        ans = (mp(ans, res)) ? res : ans;
      }
    }
  }
  ans.first += ans.second * (N - ca - 1);
  ans.second *= N;
  long long _f = gcd(ans.first, ans.second);
  cout << ans.first / _f << " " << ans.second / _f << endl;
  return 0;
}
