#include <bits/stdc++.h>
using namespace std;
inline int qr() {
  int ret = 0, f = 0, c = getchar();
  while (!isdigit(c)) f |= c == 45, c = getchar();
  while (isdigit(c)) ret = ret * 10 + c - 48, c = getchar();
  return f ? -ret : ret;
}
const int maxn = 2333;
struct E {
  int a, b, id;
  long long F(long long x) { return a * x + b; }
} data[maxn * 3];
int n, S, T;
struct ED {
  int to, nx, w, c;
} e[maxn * 30];
int head[maxn * 7], last[maxn * 7], d[maxn * 7], fl[maxn * 7];
int cnt = 1;
void add(int fr, int to, int w, int c) {
  e[++cnt] = (ED){to, head[fr], w, c};
  head[fr] = cnt;
  e[++cnt] = (ED){fr, head[to], 0, -c};
  head[to] = cnt;
}
int GetCost(long long Time) {
  static deque<int> q;
  int ret = 0, F = 0;
  S = 0;
  T = 7 * n + 1;
  cerr << "t/n=" << (double)T / n << endl;
  for (int t = 1; t <= 2 * n; ++t)
    if (data[t].id <= n)
      add(S, data[t].id + 6 * n, 1, 0),
          add(data[t].id + 6 * n, data[t].id, 1, 0);
    else
      add(data[t].id, T, 1, 0);
  sort(data + 1, data + n * 2 + 1, [&](E A, E B) { return A.b < B.b; });
  for (int t = 1; t <= 2 * n; ++t) {
    if (t > 1) add(data[t].id + 2 * n, data[t - 1].id + 2 * n, 1e9, 0);
    add(data[t].id + 2 * n, data[t].id, 1e9, 0);
    int p = upper_bound(data + 1, data + n + n + 1, data[t],
                        [&](E A, E B) { return A.b < B.b; }) -
            data - 1;
    if (data[t].id <= n) add(data[t].id + 6 * n, data[p].id + 2 * n, 1, 1);
  }
  sort(data + 1, data + n + n + 1,
       [&](E A, E B) { return A.a * Time + A.b < B.a * Time + B.b; });
  for (int t = 1; t <= 2 * n; ++t) {
    if (t > 1) add(data[t].id + 4 * n, data[t - 1].id + 4 * n, 1e9, 0);
    add(data[t].id + 4 * n, data[t].id, 1e9, 0);
    int p = upper_bound(
                data + 1, data + n + n + 1, data[t],
                [&](E A, E B) { return A.a * Time + A.b < B.a * Time + B.b; }) -
            data - 1;
    add(data[t].id, data[p].id + 4 * n, 1e9, 1);
  }
  while (1) {
    memset(last, 0, sizeof last);
    memset(d, 0x3f, sizeof d);
    memset(fl, 0, sizeof fl);
    q.push_back(S);
    d[S] = 0;
    fl[S] = 1e9;
    while (q.size()) {
      int now = q.front();
      q.pop_front();
      for (int t = head[now]; t; t = e[t].nx)
        if (d[e[t].to] > d[now] + e[t].c && e[t].w)
          fl[e[t].to] = min(e[t].w, fl[now]), d[e[t].to] = d[now] + e[t].c,
          last[e[t].to] = t,
          (e[t].c > 0 ? q.push_back(e[t].to) : q.push_front(e[t].to));
    }
    if (!fl[T]) break;
    F += fl[T];
    ret += fl[T] * d[T];
    for (int t = T; t != S; t = e[last[t] ^ 1].to)
      e[last[t]].w -= fl[T], e[last[t] ^ 1].w += fl[T];
  }
  return ret;
}
vector<long long> ve, nd;
bool chek(long long T) {
  ve.clear();
  nd.clear();
  long long Max = 0;
  for (int t = 1; t <= n + n; ++t)
    if (data[t].id > n) nd.push_back(data[t].F(T));
  sort(nd.begin(), nd.end());
  auto sav = nd;
  stable_sort(data + 1, data + n + n + 1, [&](E A, E B) { return A.b < B.b; });
  for (int t = 1, r = 1; t <= n + n; t = ++r) {
    if (r < n + n && data[r + 1].b == data[t].b)
      Max = max(Max, data[r + 1].F(T)), ++r;
    Max = max(Max, data[t].F(T));
    for (int i = t; i <= r; ++i)
      if (data[i].id <= n) ve.push_back(Max);
  }
  sort(ve.begin(), ve.end());
  sort(nd.begin(), nd.end());
  int siz = 0;
  while (nd.size()) {
    while (ve.size() && ve.back() >= nd.back()) ++siz, ve.pop_back();
    if (!siz) return 0;
    --siz, nd.pop_back();
  }
  return 1;
}
signed main() {
  n = qr();
  for (int t = 1; t <= n + n; ++t)
    data[t].a = qr(), data[t].b = qr(), data[t].id = t;
  int l = 0, r = 2e9, mid;
  do {
    mid = (0ll + l + r) >> 1;
    if (chek(mid))
      r = mid - 1;
    else
      l = mid + 1;
  } while (l <= r);
  if (l == -1 || l > 2e9)
    return puts("-1"), 0;
  else {
    int g = GetCost(l);
    cout << l << ' ' << g << endl;
    cerr << l << ' ' << (double)cnt / n << endl;
  }
  return 0;
}
