#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:64000000")
const int maxn = 18;
const int maxm = 110;
const int maxmask = (1 << maxn) - 1;
const int infi = 1e9 + 7;
const long long infl = 1e18;
const long double eps = 1e-8;
const long long mod1 = 1e9 + 7;
const long long mod2 = 1e9 + 9;
struct sob {
  int a, x, y, b;
};
sob ar[1100500];
int snm[1100500];
int sz[1100500];
long long dist[1100500];
void build(int a) {
  sz[a] = 1;
  snm[a] = a;
  return;
}
int find(int a) {
  if (snm[a] == a) {
    return a;
  }
  return snm[a] = find(snm[a]);
}
void union1(int a, int b) {
  a = find(a), b = find(b);
  if (sz[a] > sz[b]) {
    sz[a] += sz[b];
    snm[b] = a;
    dist[a] += dist[b];
  } else {
    sz[b] += sz[a];
    snm[a] = b;
    dist[b] += dist[a];
  }
  return;
}
struct block {
  int i, top, bot;
  block() {}
  block(int j, int q) {
    top = bot = q;
    i = j;
  }
};
bool operator<(block a, block b) { return a.top < b.top; }
bool operator<(sob a, sob b) { return a.x < b.x || a.x == b.x && a.a < b.a; }
int h[1100500];
int bintop(int l, int r, int d) {
  int ans = -1;
  while (l <= r) {
    int m = (l + r) >> 1;
    if (h[m] <= d) {
      ans = m;
      l = m + 1;
    } else {
      r = m - 1;
    }
  }
  return ans;
}
int binbot(int l, int r, int d) {
  int ans = -1;
  while (l <= r) {
    int m = (l + r) >> 1;
    if (h[m] >= d) {
      r = m - 1;
    } else {
      ans = m;
      l = m + 1;
    }
  }
  ++ans;
  return ans;
}
int sum[1100000];
int getsum(int i, int l, int r, int tl, int tr) {
  if (l > r) {
    return 0;
  }
  if (tl == l && tr == r) {
    return sum[i];
  }
  return getsum(i * 2, l, min(r, (tl + tr) >> 1), tl, (tl + tr) >> 1) +
         getsum(i * 2 + 1, max(l, ((tl + tr) >> 1) + 1), r,
                ((tl + tr) >> 1) + 1, tr);
}
void upd1(int i, int tl, int tr, int t, int d) {
  if (tl == tr) {
    sum[i] += d;
    return;
  }
  if (t <= (tl + tr) >> 1) {
    upd1(i * 2, tl, (tl + tr) >> 1, t, d);
  } else {
    upd1(i * 2 + 1, ((tl + tr) >> 1) + 1, tr, t, d);
  }
  sum[i] += d;
  return;
}
int bot[1100000];
int top[1100000];
void buildtop(int i, int l, int r) {
  top[i] = infi;
  if (l == r) {
    return;
  }
  buildtop(i * 2, l, (l + r) >> 1);
  buildtop(i * 2 + 1, ((l + r) >> 1) + 1, r);
  return;
}
int getbot(int i, int tl, int tr, int t) {
  if (t < tl) {
    return -infi;
  }
  if (tr <= t) {
    return bot[i];
  }
  return max(getbot(i * 2, tl, (tl + tr) >> 1, t),
             getbot(i * 2 + 1, ((tl + tr) >> 1) + 1, tr, t));
}
void updtop(int i, int tl, int tr, int t, bool d) {
  if (tl == tr) {
    if (!d) {
      top[i] = infi;
    } else {
      top[i] = tl;
    }
    return;
  }
  if (t <= (tl + tr) >> 1) {
    updtop(i * 2, tl, (tl + tr) >> 1, t, d);
  } else {
    updtop(i * 2 + 1, ((tl + tr) >> 1) + 1, tr, t, d);
  }
  top[i] = min(top[i * 2], top[i * 2 + 1]);
  return;
}
void buildbot(int i, int tl, int tr) {
  if (tl == tr) {
    bot[i] = -infi;
    return;
  }
  buildbot(i * 2, tl, (tl + tr) >> 1);
  buildbot(i * 2 + 1, ((tl + tr) >> 1) + 1, tr);
  bot[i] = -infi;
  return;
}
int gettop(int i, int tl, int tr, int t) {
  if (t > tr) {
    return infi;
  }
  if (t <= tl) {
    return top[i];
  }
  return min(gettop(i * 2, tl, (tl + tr) >> 1, t),
             gettop(i * 2 + 1, ((tl + tr) >> 1) + 1, tr, t));
}
void updbot(int i, int tl, int tr, int t, int d) {
  if (tl == tr) {
    if (d) {
      bot[i] = tl;
    } else {
      bot[i] = -infi;
    }
    return;
  }
  if (t <= (tl + tr) >> 1) {
    updbot(i * 2, tl, (tl + tr) >> 1, t, d);
  } else {
    updbot(i * 2 + 1, ((tl + tr) >> 1) + 1, tr, t, d);
  }
  bot[i] = max(bot[i * 2], bot[i * 2 + 1]);
  return;
}
int main() {
  int n;
  cin >> n;
  int q = 0;
  for (int i = 0; i < n; ++i) {
    int x1, y1, x2, y2;
    scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
    if (x1 == x2) {
      ar[q].a = 1;
      ar[q].x = x1;
      ar[q].y = max(y1, y2);
      ar[q].b = min(y1, y2);
      ++q;
    } else {
      ar[q].a = 0;
      ar[q].x = min(x1, x2);
      ar[q].y = y1;
      ar[q].b = max(x1, x2);
      ++q;
      ar[q].a = 2;
      ar[q].x = max(x1, x2);
      ar[q].y = y1;
      ++q;
    }
    h[i * 2] = y1, h[i * 2 + 1] = y2;
  }
  sort(h, h + n * 2);
  sort(ar, ar + q);
  vector<block> arz;
  set<block> w;
  int z = 0;
  buildtop(1, 0, n * 2 - 1);
  buildbot(1, 0, n * 2 - 1);
  long long ans = 0;
  for (int i = 0; i < q; ++i) {
    if (ar[i].a == 0) {
      if (w.size()) {
        set<block>::iterator e = w.upper_bound(block(-1, ar[i].y));
        if (e != w.end() && e->bot <= ar[i].y) {
          int a = bintop(0, n * 2 - 1, ar[i].y);
          block x = *e;
          int top1 = e->top, bot1 = e->bot;
          w.erase(e);
          x.bot = h[gettop(1, 0, n * 2 - 1, a)];
          w.insert(x);
          x.bot = bot1;
          x.top = h[getbot(1, 0, n * 2 - 1, a)];
          w.insert(x);
        }
      }
      block a;
      int b = bintop(0, n * 2 - 1, ar[i].y);
      a.bot = a.top = ar[i].y;
      build(z);
      a.i = snm[z];
      dist[z] = ar[i].b - ar[i].x;
      w.insert(a);
      ++z;
      upd1(1, 0, n * 2 - 1, b, 1);
      updbot(1, 0, n * 2 - 1, b, 1);
      updtop(1, 0, n * 2 - 1, b, 1);
    }
    if (ar[i].a == 1) {
      ans = max(ans, (long long)(ar[i].y - ar[i].b));
      int t = bintop(0, n * 2 - 1, ar[i].y);
      int b = binbot(0, n * 2 - 1, ar[i].b);
      int s = getsum(1, b, t, 0, n * 2 - 1);
      if (!s) {
        continue;
      }
      set<block>::iterator r = w.lower_bound(block(-1, ar[i].b)), l;
      l = r;
      block c;
      int a = -1;
      while (r != w.end() && ar[i].y >= r->bot) {
        if (a == -1) {
          c = *r;
          a = 1;
        } else {
          if (find(r->i) != find(c.i)) {
            ++a;
            union1(r->i, c.i);
          }
          c.bot = min(c.bot, r->bot), c.top = max(c.top, r->top);
        }
        ++r;
      }
      w.erase(l, r);
      w.insert(c);
      dist[find(c.i)] += max(
          (long long)ar[i].y - (long long)ar[i].b - (long long)s + (long long)a,
          0LL);
    }
    if (ar[i].a == 2) {
      set<block>::iterator e = w.lower_bound(block(-1, ar[i].y));
      int l = binbot(0, n * 2 - 1, e->bot);
      int r = bintop(0, n * 2 - 1, e->top);
      int a = bintop(0, n * 2 - 1, ar[i].y);
      upd1(1, 0, n * 2 - 1, a, -1);
      updbot(1, 0, n * 2 - 1, a, 0);
      updtop(1, 0, n * 2 - 1, a, 0);
      if (h[l] == h[r]) {
        w.erase(e);
        continue;
      }
      if (h[l] != ar[i].y && h[r] != ar[i].y) {
        continue;
      }
      if (h[l] == h[a]) {
        block b = *e;
        b.bot = h[gettop(1, 0, n * 2 - 1, a)];
        w.erase(e);
        w.insert(b);
        continue;
      }
      if (h[r] == h[a]) {
        block b = *e;
        b.top = h[getbot(1, 0, n * 2 - 1, a)];
        w.erase(e);
        w.insert(b);
        continue;
      }
    }
  }
  for (int i = 0; i < n * 4; ++i) {
    ans = max(ans, (long long)(dist[find(i)]));
  }
  cout << ans;
  return 0;
}
