#include <bits/stdc++.h>
using namespace std;
const int N = 132674 + 10;
int n, len[2];
int R[2][2 * N];
vector<pair<int, int> > open[2 * N], clos[2 * N];
struct Cord {
  int x1, asdioayseiowqe12, x2, y2;
  Cord() {}
  Cord(int x1, int asdioayseiowqe12, int x2, int y2)
      : x1(x1), asdioayseiowqe12(asdioayseiowqe12), x2(x2), y2(y2) {}
} C[N];
struct SegmentTree {
  int st[4 * 2 * N], lp[4 * 2 * N];
  void Propagate(int k) {
    if (lp[k] == 0) return;
    int v = lp[k];
    lp[k] = 0;
    st[k << 1] += v;
    st[k << 1 | 1] += v;
    lp[k << 1] += v;
    lp[k << 1 | 1] += v;
  }
  void Update(int k, int l, int r, int i, int j, int v) {
    if (l > j || r < i) return;
    if (i <= l && r <= j) {
      st[k] += v;
      lp[k] += v;
      return;
    }
    Propagate(k);
    Update(k << 1, l, ((l + r) >> 1), i, j, v);
    Update(k << 1 | 1, ((l + r) >> 1) + 1, r, i, j, v);
    st[k] = max(st[k << 1], st[k << 1 | 1]);
  }
  int Find(int k, int l, int r) {
    if (l == r) return l;
    Propagate(k);
    if (st[k << 1] >= n - 1)
      return Find(k << 1, l, ((l + r) >> 1));
    else
      return Find(k << 1 | 1, ((l + r) >> 1) + 1, r);
  }
} ST;
int Pos(int i, int v) {
  return lower_bound(R[i] + 1, R[i] + len[i] + 1, v) - R[i];
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    int x1, asdioayseiowqe12, x2, y2;
    scanf("%d%d%d%d", &x1, &asdioayseiowqe12, &x2, &y2);
    C[i] = Cord(x1, asdioayseiowqe12, x2, y2);
    R[0][++len[0]] = x1;
    R[0][++len[0]] = x2;
    R[1][++len[1]] = asdioayseiowqe12;
    R[1][++len[1]] = y2;
  }
  for (int i = 0; i <= 1; ++i) {
    sort(R[i] + 1, R[i] + len[i] + 1);
    len[i] = unique(R[i] + 1, R[i] + len[i] + 1) - (R[i] + 1);
  }
  for (int i = 1; i <= n; ++i) {
    int x1 = C[i].x1, asdioayseiowqe12 = C[i].asdioayseiowqe12, x2 = C[i].x2,
        y2 = C[i].y2;
    int x = Pos(1, asdioayseiowqe12), y = Pos(1, y2);
    open[Pos(0, x1)].push_back(pair<int, int>(x, y));
    clos[Pos(0, x2)].push_back(pair<int, int>(x, y));
  }
  for (int i = 1; i <= len[0]; ++i) {
    for (int k = 0; k < open[i].size(); ++k) {
      int x = open[i][k].first, y = open[i][k].second;
      ST.Update(1, 1, len[1], x, y, +1);
    }
    if (ST.st[1] >= n - 1) {
      int j = ST.Find(1, 1, len[1]);
      printf("%d %d\n", R[0][i], R[1][j]);
      return 0;
    }
    for (int k = 0; k < clos[i].size(); ++k) {
      int x = clos[i][k].first, y = clos[i][k].second;
      ST.Update(1, 1, len[1], x, y, -1);
    }
  }
  assert(false);
  return 0;
}
