#include <bits/stdc++.h>
using namespace std;
const int N = 2 * 1e5 + 100;
int n;
struct node {
  int L, R, l, r;
  inline bool check() {
    if (L > R || l > r) return 0;
    return 1;
  }
  inline void Set() {
    L = -0x3f3f3f3f, R = 0x3f3f3f3f;
    l = -0x3f3f3f3f, r = 0x3f3f3f3f;
  }
} sh[N];
node pre[N], suc[N];
inline void ckmin(int &a, int b) { a = ((a < b) ? a : b); }
inline void ckmax(int &a, int b) { a = ((a > b) ? a : b); }
node merge(node a, node b) {
  ckmax(a.L, b.L);
  ckmin(a.R, b.R);
  ckmax(a.l, b.l);
  ckmin(a.r, b.r);
  return a;
}
inline int read() {
  int f = 1, x = 0;
  char s = getchar();
  while (s < '0' || s > '9') {
    if (s == '-') f = -1;
    s = getchar();
  }
  while (s >= '0' && s <= '9') {
    x = x * 10 + s - '0';
    s = getchar();
  }
  return x * f;
}
signed main() {
  n = read();
  for (int i = 1; i <= n; i++) {
    int L = read(), l = read(), R = read(), r = read();
    sh[i] = (node){L, R, l, r};
  }
  pre[0].Set();
  suc[n + 1].Set();
  for (int i = 1; i <= n; i++) pre[i] = merge(pre[i - 1], sh[i]);
  for (int i = n; i >= 1; i--) suc[i] = merge(suc[i + 1], sh[i]);
  for (int i = 1; i <= n; i++) {
    node now = merge(pre[i - 1], suc[i + 1]);
    if (now.check()) {
      printf("%d %d\n", now.L, now.l);
      return 0;
    }
  }
}
