#include <bits/stdc++.h>
#pragma warning(disable : 4996)
using namespace std;
int n;
set<int> yset;
map<int, int> ymap;
int yi;
int a[300000][4];
int hv[300000];
int u[1000000];
int ui;
struct EVENT {
  int x;
  int type;
  int tar;
  bool operator()(EVENT p, EVENT q) {
    if (p.x != q.x)
      return p.x < q.x;
    else
      return p.type < q.type;
  }
} ev[1000000];
int evi;
struct CHUNK {
  int s, e;
  int u;
  CHUNK() {}
  CHUNK(int S, int E, int U) { s = S, e = E, u = U; }
  bool operator<(const CHUNK &p) const { return e < p.e; }
  bool operator==(const CHUNK &p) const { return e == p.e; }
  bool operator>(const CHUNK &p) const { return e > p.e; }
};
set<CHUNK> s;
set<pair<int, int> > nowh;
int S = 524288;
int itree[2000000];
long long length[300000];
void update(int x) {
  x /= 2;
  while (x > 0) {
    itree[x] = itree[x * 2] + itree[x * 2 + 1];
    x /= 2;
  }
}
int getsum(int x, int y) {
  int sum = 0;
  while (x <= y) {
    if (x % 2 == 1) sum += itree[x++];
    if (y % 2 == 0) sum += itree[y--];
    x /= 2, y /= 2;
  }
  return sum;
}
int find(int x) {
  if (u[x] == x) return x;
  return u[x] = find(u[x]);
}
int main() {
  int i, j, k;
  scanf("%d", &n);
  for (i = 0; i < n; i++) {
    for (j = 0; j < 4; j++) scanf("%d", &a[i][j]);
    yset.insert(a[i][1]);
    yset.insert(a[i][3]);
    if (a[i][0] == a[i][2]) {
      hv[i] = 1;
      if (a[i][1] > a[i][3]) swap(a[i][1], a[i][3]);
    } else {
      hv[i] = 0;
      if (a[i][0] > a[i][2]) swap(a[i][0], a[i][2]);
    }
    u[i] = i;
    length[i] = a[i][2] - a[i][0] + a[i][3] - a[i][1];
  }
  for (auto y : yset) ymap[y] = yi++;
  for (i = 0; i < n; i++) {
    a[i][1] = ymap[a[i][1]];
    a[i][3] = ymap[a[i][3]];
  }
  for (i = 0; i < n; i++) {
    if (!hv[i]) {
      ev[evi].x = a[i][0];
      ev[evi].type = 0;
      ev[evi].tar = i;
      evi++;
      ev[evi].x = a[i][2];
      ev[evi].type = 2;
      ev[evi].tar = i;
      evi++;
    } else {
      ev[evi].x = a[i][0];
      ev[evi].type = 1;
      ev[evi].tar = i;
      evi++;
    }
  }
  sort(ev, ev + evi, EVENT());
  for (i = 0; i < evi; i++) {
    int now = ev[i].tar;
    if (ev[i].type == 0) {
      auto it = s.lower_bound(CHUNK(-1, a[now][1], -1));
      if (it != s.end() && it->s <= a[now][1]) {
        CHUNK oldc1 = CHUNK(
            nowh.upper_bound(pair<int, int>(a[now][1], ((1 << 30) - 1)))->first,
            it->e, it->u);
        CHUNK oldc2 = CHUNK(
            it->s,
            (--nowh.lower_bound(pair<int, int>(a[now][1], -((1 << 30) - 1))))
                ->first,
            it->u);
        s.erase(it);
        s.insert(oldc1), s.insert(oldc2);
      }
      nowh.insert(pair<int, int>(a[now][1], now));
      itree[S + a[now][1]]++;
      update(S + a[now][1]);
      CHUNK nc = CHUNK(a[now][1], a[now][1], now);
      s.insert(nc);
    } else if (ev[i].type == 1) {
      auto it1 = s.lower_bound(CHUNK(-1, a[now][1], -1));
      auto it2 = s.lower_bound(CHUNK(-1, a[now][3], -1));
      int bad1 = 0, bad2 = 0;
      if (it1 == s.end() || it1->s > a[now][3])
        bad1 = 1;
      else if (it2 == s.end() || it2->s > a[now][3]) {
        if (it2 == s.begin())
          bad2 = 1;
        else {
          it2--;
          if (it2->e < a[now][1]) bad2 = 1;
        }
      }
      if (bad1 || bad2) continue;
      int dint = getsum(S + a[now][1], S + a[now][3]);
      if (!dint) continue;
      set<int> dset;
      auto it = it1;
      int x = find(it->u);
      int ns = it1->s, ne = it2->e;
      while (1) {
        int y = find(it->u);
        dset.insert(y);
        if (x != y) {
          length[x] += length[y];
          u[y] = x;
        }
        auto tit = it;
        if (it == it2) {
          s.erase(tit);
          break;
        }
        it++;
        s.erase(tit);
      }
      s.insert(CHUNK(ns, ne, x));
      length[x] += length[now] - dint + dset.size();
    } else {
      auto it = s.lower_bound(CHUNK(-1, a[now][1], -1));
      if (it->s == it->e) {
        s.erase(it);
      } else if (it->s == a[now][1]) {
        CHUNK nc = CHUNK(
            nowh.upper_bound(pair<int, int>(a[now][1], ((1 << 30) - 1)))->first,
            it->e, it->u);
        s.erase(it);
        s.insert(nc);
      } else if (it->e == a[now][1]) {
        CHUNK nc = CHUNK(
            it->s, (--nowh.find(pair<int, int>(a[now][1], now)))->first, it->u);
        s.erase(it);
        s.insert(nc);
      }
      nowh.erase(pair<int, int>(a[now][1], now));
      itree[S + a[now][1]]--;
      update(S + a[now][1]);
    }
  }
  long long ma = 0;
  for (i = 0; i < n; i++) ma = max(ma, length[i]);
  printf("%I64d", ma);
  return 0;
}
