#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
typedef struct MCMF {
  int n, m;
  vector<int> ghead, gnxt, gto, gcap;
  vector<int> gcost;
  vector<int> d;
  vector<int> bck;
  vector<int> pot;
  vector<int> flow;
  void init(int _n) {
    n = _n, m = 0;
    ghead = vector<int>(n, -1);
    gnxt.clear(), gto.clear(), gcap.clear(), gcost.clear();
    d = vector<int>(n);
    bck = vector<int>(n);
    pot = vector<int>(n, 0);
    flow = vector<int>(n);
  }
  void addedge(int a, int b, int c, int d) {
    gnxt.push_back(ghead[a]);
    ghead[a] = m;
    gto.push_back(b);
    gcap.push_back(c);
    gcost.push_back(+d);
    ++m;
    gnxt.push_back(ghead[b]);
    ghead[b] = m;
    gto.push_back(a);
    gcap.push_back(0);
    gcost.push_back(-d);
    ++m;
  }
  pair<int, int> solve(int s, int t) {
    for (int i = (0); i < (n); ++i) pot[i] = 0;
    pair<int, int> ret = make_pair(0, 0);
    while (true) {
      for (int i = (0); i < (n); ++i) d[i] = INT_MAX, bck[i] = -1, flow[i] = 0;
      d[s] = 0, bck[s] = -2, flow[s] = INT_MAX;
      vector<vector<int>> q(1);
      q[0].push_back(s);
      for (int i = (0); i < (((int)(q).size())); ++i)
        for (int j = (0); j < (((int)(q[i]).size())); ++j) {
          int cost = i, at = q[i][j];
          for (int x = ghead[at]; x != -1; x = gnxt[x])
            if (gcap[x] > 0) {
              int to = gto[x];
              int rcost = gcost[x] + pot[at] - pot[to];
              if (d[at] + rcost >= d[to]) continue;
              d[to] = d[at] + rcost;
              bck[to] = x ^ 1;
              flow[to] = min(flow[at], gcap[x]);
              if (d[to] >= ((int)(q).size())) q.resize(d[to] + 1);
              q[d[to]].push_back(to);
            }
        }
      if (d[t] == INT_MAX) break;
      assert(flow[t] > 0);
      for (int i = (0); i < (n); ++i)
        if (d[i] != INT_MAX) pot[i] += d[i];
      ret.first += flow[t], ret.second += pot[t] * flow[t];
      for (int at = t; at != s; at = gto[bck[at]]) {
        gcap[bck[at]] += flow[t];
        gcap[bck[at] ^ 1] -= flow[t];
      }
    }
    return ret;
  }
} MCMF;
const int MAXN = 2 * 2200;
const int MAXVAL = 1000000000;
struct Stock {
  int a, b;
  long long eval(int t) { return (long long)a * t + b; }
};
int n;
Stock stock[MAXN];
pair<long long, int> opt[MAXN];
int nopt;
long long have[MAXN / 2], need[MAXN / 2];
int nid, sid, tid, lid[MAXN], zcid[MAXN], rid[MAXN], tcid[MAXN];
int zval[MAXN];
long long tval[MAXN];
int nzval, ntval;
MCMF g;
bool can(int t) {
  for (int i = (0); i < (n); ++i)
    opt[i] = make_pair(-stock[i].eval(t), stock[i].b);
  sort(opt, opt + n);
  for (int i = (0); i < (n); ++i) opt[i].first = -opt[i].first;
  nopt = 0;
  for (int i = (0); i < (n); ++i)
    if (i == 0 || opt[i].second < opt[nopt - 1].second) opt[nopt++] = opt[i];
  for (int i = (0); i < (n / 2); ++i) {
    int l = -1, h = nopt - 1;
    assert(stock[i].b >= opt[h].second);
    while (l + 1 < h) {
      int m = l + (h - l) / 2;
      if (stock[i].b >= opt[m].second)
        h = m;
      else
        l = m;
    }
    have[i] = opt[h].first;
  }
  for (int i = (0); i < (n / 2); ++i) need[i] = stock[n / 2 + i].eval(t);
  sort(have, have + n / 2);
  sort(need, need + n / 2);
  for (int i = (0); i < (n / 2); ++i)
    if (have[i] < need[i]) return false;
  return true;
}
pair<int, int> solve() {
  int l = -1, h = MAXVAL;
  if (!can(h)) return make_pair(-1, -1);
  while (l + 1 < h) {
    int m = l + (h - l) / 2;
    if (can(m))
      h = m;
    else
      l = m;
  }
  int t = h;
  nzval = 0;
  for (int i = (0); i < (n); ++i) zval[nzval++] = stock[i].b;
  sort(zval, zval + nzval);
  nzval = unique(zval, zval + nzval) - zval;
  ntval = 0;
  for (int i = (0); i < (n); ++i) tval[ntval++] = stock[i].eval(t);
  sort(tval, tval + ntval);
  ntval = unique(tval, tval + ntval) - tval;
  nid = 0;
  sid = nid++;
  tid = nid++;
  for (int i = (0); i < (n); ++i) lid[i] = nid++;
  for (int i = (0); i < (nzval); ++i) zcid[i] = nid++;
  for (int i = (0); i < (n); ++i) rid[i] = nid++;
  for (int i = (0); i < (ntval); ++i) tcid[i] = nid++;
  g.init(nid);
  for (int i = (0); i < (n / 2); ++i) g.addedge(sid, lid[i], 1, 0);
  for (int i = (0); i < (n); ++i) {
    int zidx = lower_bound(zval, zval + nzval, stock[i].b) - zval;
    g.addedge(lid[i], zcid[zidx], n, 1);
    g.addedge(zcid[zidx], lid[i], n, 0);
  }
  for (int i = (0); i < (nzval - 1); ++i) g.addedge(zcid[i + 1], zcid[i], n, 0);
  for (int i = (0); i < (n); ++i) g.addedge(lid[i], rid[i], n, 0);
  for (int i = (0); i < (n); ++i) {
    int tidx = lower_bound(tval, tval + ntval, stock[i].eval(t)) - tval;
    g.addedge(rid[i], tcid[tidx], n, 1);
    g.addedge(tcid[tidx], rid[i], n, 0);
  }
  for (int i = (0); i < (ntval - 1); ++i) g.addedge(tcid[i + 1], tcid[i], n, 0);
  for (int i = (0); i < (n / 2); ++i) g.addedge(rid[n / 2 + i], tid, 1, 0);
  pair<int, long long> res = g.solve(sid, tid);
  assert(res.first == n / 2);
  return make_pair(t, (int)res.second);
}
void run() {
  scanf("%d", &n);
  n *= 2;
  for (int i = (0); i < (n); ++i) scanf("%d%d", &stock[i].a, &stock[i].b);
  pair<int, int> ans = solve();
  if (ans.first == -1)
    printf("%d\n", -1);
  else
    printf("%d %d\n", ans.first, ans.second);
}
int main() {
  run();
  return 0;
}
