// Dmitry _kun_ Sayutin (2019)

#include <bits/stdc++.h>

using std::cin;
using std::cout;
using std::cerr;

using std::vector;
using std::map;
using std::array;
using std::set;
using std::string;
using std::queue;

using std::pair;
using std::make_pair;

using std::tuple;
using std::make_tuple;
using std::get;

using std::min;
using std::abs;
using std::max;
using std::swap;

using std::unique;
using std::sort;
using std::generate;
using std::reverse;
using std::min_element;
using std::max_element;

#ifdef LOCAL
#define LASSERT(X) assert(X)
#else
#define LASSERT(X) {}
#endif

template <typename T>
T input() {
    T res;
    cin >> res;
    LASSERT(cin);
    return res;
}

template <typename IT>
void input_seq(IT b, IT e) {
    std::generate(b, e, input<typename std::remove_reference<decltype(*b)>::type>);
}

#define SZ(vec)         int((vec).size())
#define ALL(data)       data.begin(),data.end()
#define RALL(data)      data.rbegin(),data.rend()
#define TYPEMAX(type)   std::numeric_limits<type>::max()
#define TYPEMIN(type)   std::numeric_limits<type>::min()

struct ratio {
    int64_t p;
    int64_t q;
};

bool operator<(ratio a, ratio b) {
    // a.p / a.q < b.p / b.q
    // a.p * b.q < b.p * a.q

    return __int128_t(a.p) * b.q < __int128_t(b.p) * a.q;
}

int main() {
    std::iostream::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    // code here
    int n = input<int32_t>();

    vector<pair<int, int>> seg(n);
    for (int i = 0; i < n; ++i)
        cin >> seg[i].first >> seg[i].second;

    vector<int> gavno;
    vector<int> by_delta;
    int64_t base = 0;

    for (int i = 0; i < n; ++i)
        if (seg[i].second > seg[i].first)
            by_delta.push_back(-seg[i].second), base += seg[i].second - seg[i].first;
        else
            gavno.push_back(-seg[i].first);

    sort(RALL(gavno));
    sort(RALL(by_delta));
        
    int ptr_delta = 0;
    int64_t sum_delta = 0;
    while (ptr_delta != SZ(by_delta) and sum_delta + by_delta[ptr_delta] + base >= 0) {
        sum_delta += by_delta[ptr_delta++];
    }

    ratio ans;

    if (ptr_delta == SZ(by_delta))
        ans = {SZ(by_delta), 1};
    else {
        // (base + sum_delta) + a/b * by_delta[ptr_delta] = 0
        // b (base + sum_delta) = a * (-by_delta[ptr_delta])
        int64_t a = (base + sum_delta);
        int64_t b = -by_delta[ptr_delta];

        auto g = std::__gcd(a, b);
        a /= g;
        b /= g;
        ans = {a + b * int64_t(ptr_delta), b};
    }

    int counter = 0;
    for (int x: gavno) {
        base += x;
        ++counter;
        if (base < 0)
            break;

        while (sum_delta + base < 0) {
            sum_delta -= by_delta[--ptr_delta];
        }

        ratio new_ans;
        if (ptr_delta == SZ(by_delta))
            new_ans = {SZ(by_delta) + counter, 1};
        else {
            int64_t a = (base + sum_delta);
            int64_t b = -by_delta[ptr_delta];

            auto g = std::__gcd(a, b);
            a /= g;
            b /= g;
            new_ans = {a + b * int64_t(ptr_delta+counter), b};
        }

        if (ans < new_ans)
            ans = new_ans;
    }

    ans.q *= n;
    auto g = std::__gcd(ans.p, ans.q);
    ans.p /= g;
    ans.q /= g;

    cout << ans.p << " " << ans.q << "\n";
        
    
    // int64_t mx = 0;
    // int64_t cur = 0;
    // for (int i = 0; i < n; ++i) {
    //     cur += seg[i].second;
    //     cur -= seg[i].first;

    //     mx = max(mx, cur);
    // }

    // for (int i = 0; i < n; ++i)
    //     if (mx >= seg[i].second)
    //         mx -= seg[i].second;
    //     else {
    //         cout << "Prob is " << (i + double(mx) / seg[i].second) / n << "\n";
    //         return 0;
    //     }

    // assert(false);
    
    return 0;
}
