#include <bits/stdc++.h>
using namespace std;
template <typename T>
T mabs(const T &a) {
  return a < 0 ? -a : a;
}
struct event {
  int t;
  int x;
  pair<int, int> other;
  int ind;
  event() {}
  event(int t0, int x0, pair<int, int> other0, int ind0 = -1) {
    t = t0;
    x = x0;
    other = other0;
    ind = ind0;
  }
  bool operator<(const event &b) const {
    if (x != b.x) return x < b.x;
    return t < b.t;
  }
};
int Fen[400400];
void addFen(int pos, int val, int sz) {
  pos += 2;
  for (int i = pos; i < sz; i += i & -i) Fen[i] += val;
}
int getFen(int pos) {
  pos += 2;
  int res = 0;
  for (int i = pos; i > 0; i -= i & -i) res += Fen[i];
  return res;
}
long long getRes(const vector<pair<int, int> > &S,
                 const vector<pair<int, int> > &F) {
  vector<event> E;
  vector<int> all;
  int n = (int)S.size();
  long long sumlen = 0;
  for (int i = (0), ei = (n); i < ei; i++) {
    int x0, y0, x1, y1;
    x0 = S[i].first;
    y0 = S[i].second;
    x1 = F[i].first;
    y1 = F[i].second;
    sumlen += abs(x1 - x0) + abs(y1 - y0);
    all.push_back(y0);
    all.push_back(y1 + 1);
    if (x0 == x1) {
      E.push_back(event(0, x0, pair<int, int>(y0, y1 + 1)));
    } else {
      E.push_back(event(1, x1, pair<int, int>(y0, 1), i));
      E.push_back(event(1, x0 - 1, pair<int, int>(y0, -1), i));
    }
  }
  sort((all).begin(), (all).end());
  int fenSize = (int)all.size() + 2;
  for (int i = (0), ei = (fenSize); i < ei; i++) Fen[i] = 0;
  sort((E).begin(), (E).end());
  for (int i = (0), ei = (E.size()); i < ei; i++) {
    E[i].other.first =
        (int)(lower_bound((all).begin(), (all).end(), E[i].other.first) -
              all.begin());
    if (E[i].t == 0)
      E[i].other.second =
          (int)(lower_bound((all).begin(), (all).end(), E[i].other.second) -
                all.begin());
  }
  static vector<int> Res;
  Res.assign(n, 0);
  for (int i = (0), ei = ((int)E.size()); i < ei; i++) {
    if (E[i].t == 0) {
      addFen(E[i].other.first, 1, fenSize);
      addFen(E[i].other.second, -1, fenSize);
    } else {
      Res[E[i].ind] += E[i].other.second * getFen(E[i].other.first);
    }
  }
  long long per = 0;
  for (int i = (0), ei = (n); i < ei; i++) per += Res[i];
  return sumlen + n - per - 1;
}
struct node {
  int t;
  int y;
  int x0, x1;
  int ind;
  node(int t0, int y0, int _x0, int _x1, int ind0) {
    t = t0;
    y = y0;
    x0 = _x0;
    x1 = _x1;
    ind = ind0;
  }
  bool operator<(const node &b) const {
    if (y != b.y) return y < b.y;
    return t < b.t;
  }
};
struct setElem {
  int x0, x1;
  int gInd;
  setElem() {}
  setElem(int _x0, int _x1, int gInd0) {
    x0 = _x0;
    x1 = _x1;
    gInd = gInd0;
  }
  bool operator<(const setElem &b) const { return x0 < b.x0; }
};
struct vert {
  vector<int> inc;
  int id;
  bool was = 0;
} g[300200];
vector<int> verts;
void dfs(int k) {
  g[k].was = 1;
  verts.push_back(g[k].id);
  for (int i = (0), ei = (g[k].inc.size()); i < ei; i++) {
    int to = g[k].inc[i];
    if (!g[to].was) dfs(to);
  }
}
void run() {
  int n;
  cin >> n;
  vector<pair<int, int> > A, B;
  vector<node> vec;
  for (int i = (0), ei = (n); i < ei; i++) {
    int x0, y0, x1, y1;
    scanf("%d%d%d%d", &x0, &y0, &x1, &y1);
    A.push_back(pair<int, int>(x0, y0));
    B.push_back(pair<int, int>(x1, y1));
    if (x0 == x1) {
      vec.push_back(node(0, y0, x0, x1, i));
      vec.push_back(node(2, y1, x0, x1, i));
    } else
      vec.push_back(node(1, y0, x0, x1, i));
  }
  sort((vec).begin(), (vec).end());
  int lastVertId = 0;
  set<setElem> stOtr;
  set<int> stX;
  for (int i = (0), ei = (vec.size()); i < ei; i++) {
    if (vec[i].t == 0 || vec[i].t == 2) {
      int currV;
      if (vec[i].t == 0) {
        currV = lastVertId++;
        g[currV].id = vec[i].ind;
      } else
        stX.erase(vec[i].x0);
      auto iter = stOtr.upper_bound(setElem(vec[i].x0, 0, 0));
      if (iter != stOtr.begin()) --iter;
      if (iter != stOtr.end() && iter->x0 <= vec[i].x0 &&
          vec[i].x0 <= iter->x1) {
        auto nxt = stX.upper_bound(vec[i].x0);
        auto prv = stX.lower_bound(vec[i].x0);
        if (prv != stX.begin()) --prv;
        int x0 = iter->x0;
        int x1 = iter->x1;
        int v = iter->gInd;
        stOtr.erase(*iter);
        if (prv != stX.end() && x0 <= *prv && *prv < vec[i].x0)
          stOtr.insert(setElem(x0, *prv, v));
        if (nxt != stX.end() && vec[i].x0 < *nxt && *nxt <= x1)
          stOtr.insert(setElem(*nxt, x1, v));
      }
      if (vec[i].t == 0) {
        stX.insert(vec[i].x0);
        stOtr.insert(setElem(vec[i].x0, vec[i].x0, currV));
      }
    } else if (vec[i].t == 1) {
      int currV = lastVertId++;
      g[currV].id = vec[i].ind;
      auto iter2 = stX.lower_bound(vec[i].x0);
      if (iter2 != stX.end() && *iter2 <= vec[i].x1) {
        vector<setElem> toDel;
        auto st = stOtr.lower_bound(setElem(vec[i].x0, 0, 0));
        if (st != stOtr.begin()) --st;
        int mn = 2e9;
        int mx = -2e9;
        auto fin = stOtr.upper_bound(setElem(vec[i].x1, 0, 0));
        for (auto it = st; it != fin; ++it) {
          if (it->x1 < vec[i].x0 || it->x0 > vec[i].x1) continue;
          int to = it->gInd;
          g[currV].inc.push_back(to);
          g[to].inc.push_back(currV);
          mn = min(mn, it->x0);
          mx = max(mx, it->x1);
          toDel.push_back(*it);
        }
        for (int i = (0), ei = (toDel.size()); i < ei; i++)
          stOtr.erase(toDel[i]);
        if (mn <= mx) stOtr.insert(setElem(mn, mx, currV));
      }
    }
  }
  long long res = 0;
  vector<pair<int, int> > L, R;
  for (int i = (0), ei = (lastVertId); i < ei; i++)
    if (!g[i].was) {
      verts.clear();
      dfs(i);
      L.clear();
      R.clear();
      for (int j = (0), ej = (verts.size()); j < ej; j++) {
        L.push_back(A[verts[j]]);
        R.push_back(B[verts[j]]);
      }
      long long here = getRes(L, R);
      res = max(res, here);
    }
  cout << res << endl;
}
int main() {
  run();
  return 0;
}
