#include <bits/stdc++.h>
#pragma warning(disable : 4244 4267 4018 4996 4800)
using namespace std;
istream& in = cin;
ostream& out = cout;
vector<int> indices, cnt, parent, rnk;
vector<long long> length;
int get_set(int idx) {
  if (parent[idx] == -1 || parent[idx] == idx) return idx;
  return parent[idx] = get_set(parent[idx]);
}
void join_sets(int a, int b) {
  int c = get_set(a), d = get_set(b);
  if (c == d) return;
  if (rnk[c] <= rnk[d]) {
    parent[c] = d;
    rnk[d] += rnk[c];
    length[d] += length[c];
  } else {
    parent[d] = c;
    rnk[c] += rnk[d];
    length[c] += length[d];
  }
}
void set_set(int idx, int to) {
  parent[idx] = to;
  rnk[to] += 1;
}
void get_set(int idx, long long& res, int& last) {
  if (idx >= indices.size()) return;
  int curset = indices[idx];
  for (int i = idx; i > 0; i >>= 1) {
    if (indices[i] != -1) curset = indices[i];
  }
  if (curset != -1) {
    if (cnt[idx]) {
      res -= cnt[idx] - 1;
      if (last != -1) {
        if (get_set(last) == get_set(curset))
          --res;
        else
          join_sets(last, curset);
      }
      last = get_set(curset);
    }
    return;
  }
  get_set(idx << 1, res, last);
  get_set((idx << 1) + 1, res, last);
}
int count(int left, int right, long long& res) {
  left += indices.size() / 2, right += indices.size() / 2;
  int last = -1;
  while (left <= right) {
    if (left & 1) get_set(left, res, last);
    if ((right & 1) == 0) get_set(right, res, last);
    left = (left + 1) >> 1;
    right = (right - 1) >> 1;
  }
  return last;
}
vector<int> st;
void push(int idx, int set, int count) {
  cnt[idx] = count;
  st.clear();
  for (int i = idx; i > 1;) {
    i >>= 1;
    st.push_back(i);
    cnt[i] = cnt[i * 2] + cnt[i * 2 + 1];
  }
  for (int i = st.size() - 1; i >= 0; --i) {
    int j = st[i];
    if (indices[j] != -1) {
      indices[2 * j] = indices[j];
      indices[2 * j + 1] = indices[j];
      indices[j] = -1;
    }
  }
  indices[idx] = set;
}
void update_sets(int left, int right, int set) {
  left += indices.size() / 2, right += indices.size() / 2;
  while (left <= right) {
    if (left & 1) push(left, set, cnt[left]);
    if ((right & 1) == 0) push(right, set, cnt[right]);
    left = (left + 1) >> 1;
    right = (right - 1) >> 1;
  }
}
int main() {
  int n;
  vector<int> x1, y1, x2, y2, xs, ys;
  vector<pair<int, pair<int, int>>> events;
  in >> n;
  x1 = y1 = x2 = y2 = vector<int>(n);
  for (int i = 0; i < n; ++i) {
    in >> x1[i] >> y1[i] >> x2[i] >> y2[i];
    if (y1[i] > y2[i]) swap(y1[i], y2[i]);
    if (x1[i] > x2[i]) swap(x1[i], x2[i]);
    if (x2[i] != x1[i]) {
      ys.push_back(y1[i]);
      events.push_back(make_pair(x1[i], make_pair(0, i)));
      events.push_back(make_pair(x2[i], make_pair(2, i)));
    } else {
      events.push_back(make_pair(x1[i], make_pair(1, i)));
    }
  }
  sort((events).begin(), (events).end());
  sort((ys).begin(), (ys).end());
  ys.erase(unique((ys).begin(), (ys).end()), ys.end());
  int size = 1;
  while (size < ys.size()) size <<= 1;
  indices = vector<int>(size << 1, -1);
  cnt = vector<int>(indices.size(), 0);
  for (int i = indices.size() / 2; i < indices.size(); ++i)
    indices[i] = i - indices.size() / 2;
  parent = vector<int>(ys.size() + 2 * n, -1);
  rnk = vector<int>(parent.size());
  length = vector<long long>(parent.size());
  int current_set = ys.size();
  long long res = 0;
  for (auto e : events) {
    int type = e.second.first;
    int idx = e.second.second;
    int y1idx = lower_bound((ys).begin(), (ys).end(), y1[idx]) - ys.begin();
    if (type == 0) {
      int newset = current_set++;
      set_set(y1idx, newset);
      push(y1idx + indices.size() / 2, newset, 1);
    } else if (type == 2) {
      length[get_set(y1idx)] += abs(x2[idx] - x1[idx]);
      int newset = current_set++;
      set_set(y1idx, newset);
      push(y1idx + indices.size() / 2, newset, 0);
    } else {
      int left = y1idx, right = upper_bound((ys).begin(), (ys).end(), y2[idx]) -
                                ys.begin() - 1;
      long long curlen = y2[idx] - y1[idx];
      if (left > right) {
        res = max(res, curlen);
        continue;
      }
      int lastset = ::count(left, right, curlen);
      if (lastset != -1) {
        length[lastset] += curlen;
        update_sets(left, right, lastset);
      } else
        res = max(res, curlen);
    }
  }
  res = max(res, *max_element((length).begin(), (length).end()));
  out << res;
  return 0;
}
