/*{{{*/
//#define HOME
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
using namespace std;

#define MP make_pair
#define MT make_tuple
#define PB push_back
#define EB emplace_back
#define F first
#define S second

template<class T> void _R(T &_x) { cin >> _x; }
void _R(int &_x) { scanf("%d", &_x); }
void _R(int64_t &_x) { scanf("%" SCNd64, &_x); }
void _R(double &_x) { scanf("%lf", &_x); }
void _R(char &_x) { scanf(" %c", &_x); }
void _R(char *_x) { scanf("%s", _x); }
template<class T, class U> void _R(pair<T, U> &_x) {_R(_x.F); _R(_x.S);}
void R() {}
template<class T, class... U> void R(T &_head, U &... _tail) { _R(_head); R(_tail...); }

template<class T> void _W(const T &_x) { cout << _x; }
void _W(const int &_x) { printf("%d", _x); }
void _W(const int64_t &_x) { printf("%" PRId64, _x); }
void _W(const double &_x) { printf("%.16f", _x); }
void _W(const char &_x) { putchar(_x); }
void _W(const char *_x) { printf("%s", _x); }
template<class T, class U> void _W(const pair<T, U> &_x) {_W(_x.F); putchar(' '); _W(_x.S);}
template<class T> void _W(const vector<T> &_x) { for (auto i = _x.begin(); i != _x.end(); _W(*i++)) if (i != _x.cbegin()) putchar(' '); }
void W() {}
template<class T, class... U> void W(const T &_head, const U &... _tail) { _W(_head); putchar(sizeof...(_tail) ? ' ' : '\n'); W(_tail...); }
template<class T, class... U> void DB(const T &_head, const U &... _tail) {
#ifdef HOME
    W('#', _head, _tail...);
#endif
}

#define SZ(x) (int)((x).size())
#define ALL(x) (x).begin(), (x).end()
#define RAN(x,n) (x).begin(), (x).begin()+(n)
#define UNIQUE(x) {sort(ALL(x)); (x).erase(unique(ALL(x)), (x).end());}

#define REP(i,a,b) for (int i = (a); i <= (b); ++i)
#define REPD(i,a,b) for (int i = (a); i >= (b); --i)
#define FORI(i,n) REP(i,1,n)
#define FOR(i,n) REP(i,0,int(n)-1)
//#define ITER(i,t) for (auto i = t.begin(); i != t.end(); ++i)
#define IT3(i,st,ed) for (auto i = st; i != ed; ++i)
#define IT2(i,range) IT3(i,range)

#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define MS(X, v) memset((X), (v), sizeof((X)))

template<class T> using MaxHeap = priority_queue<T>;
template<class T> using MinHeap = priority_queue<T, vector<T>, greater<T>>;

typedef int64_t ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;

inline int LG (const unsigned int &_x) { return 31-__builtin_clz(_x); }  // floor: LG(x), ceil: LG(x-1)+1
/*}}}*/

int n;
vector<pii> vs;

int main(){
    R(n);
    vs.assign(n, pii());
    FOR(i, n) R(vs[i].F, vs[i].S);

    sort(ALL(vs));

    DB(vs);

    vector<pii> pos, neg;
    ll neg_sum = 0;
    FOR(i, n){
        if(vs[i].F - vs[i].S > 0) pos.EB(vs[i]);
        else neg.EB(vs[i]), neg_sum += vs[i].S - vs[i].F;
    }

    int offset = SZ(pos);
    FOR(i, SZ(pos)){
        if(neg_sum - pos[i].F < 0){
            offset = i;
            break;
        }
        neg_sum -= pos[i].F;
    }

    sort(ALL(neg), [](pii a, pii b){ return a.S < b.S; });

    int offset2 = 0;
    FOR(i, SZ(neg)){
        if(neg_sum - neg[i].S < 0){
            offset2 = i;
            break;
        }
        neg_sum -= neg[i].S;
    }

    //reverse(neg.begin()+offset2, neg.end());
    sort(neg.begin()+offset2, neg.end(), [](pii a, pii b){ return a.S-a.F < b.S-b.F; });

    REP(i, 0, offset-1) vs[i] = pos[i];
    REP(i, offset, offset+SZ(neg)-1) vs[i] = neg[i-offset];
    REP(i, offset+SZ(neg), n-1) vs[i] = pos[i-SZ(neg)];

    //sort(vs.begin(), vs.begin()+offset, [](pii a, pii b){ return a.S < b.S; });

    DB(vs);

    int le = 0, ri = n, ed = 0;
    while(le + 1 < ri){
        DB(le, ri, ed);
        int mi = (le + ri) / 2;
        bool win = false;
        ll sum = 0;
        FOR(i, mi) sum += vs[i].F;
        REP(i, mi, n-1){
            sum += vs[i].F - vs[i].S;
            if(sum <= 0){
                win = true;
                ed = i;
                break;
            }
        }
        if(win) le = mi;
        else ri = mi;
    }

    DB(le, ri, ed);

    if(le == 0 && vs[0].F > vs[0].S){
        W(0, 1);
        return 0;
    }

    ll sum = 0;
    REP(i, 0, ed) sum += vs[i].F;
    REP(i, ri, ed) sum -= vs[i].S;
    // ans = (le + (vs[le].S - sum) / vs[le].S) / n;
    ll num = (ll)le * vs[le].S + (vs[le].S - sum);
    ll den = (ll)n * vs[le].S;
    ll d = __gcd(num, den);

    W(num / d, den / d);

    return 0;
}
