#include <bits/stdc++.h>
using namespace std;
const int MAXN = 4e5 + 5;
const long long inf = 1e9 + 5;
struct fenwickTree {
  int tree[MAXN];
  fenwickTree() { memset(this->tree, 0, sizeof(this->tree)); }
  void update(int ind, int val) {
    ind++;
    while (ind < MAXN) {
      this->tree[ind] += val;
      ind += ind & (-ind);
    }
  }
  int query(int ind) {
    int sum = 0;
    ind++;
    while (ind > 0) {
      sum += tree[ind];
      ind -= ind & (-ind);
    }
    return sum;
  }
  int query(int l, int r) { return query(r) - query(l - 1); }
};
struct segment {
  int x1, x2, y1, y2;
};
int n;
fenwickTree *treeMark = new fenwickTree(), *treeCnt = new fenwickTree();
map<int, vector<pair<int, int>>> row2Segments;
map<int, vector<pair<int, int>>> row2Downwards;
map<int, vector<int>> toEnd;
map<int, vector<pair<int, int>>> horizontal, vertical;
set<int> allRows;
int codeNum = 1;
map<int, int> num2Code;
int compress(int x) {
  if (num2Code.count(x) == false) {
    num2Code[x] = codeNum;
    codeNum++;
    return codeNum - 1;
  }
  return num2Code[x];
}
void readAndInit() {
  set<int> s;
  vector<segment> v;
  cin >> n;
  for (int i = 0; i < n; i++) {
    int x1, x2, y1, y2;
    cin >> x1 >> y1 >> x2 >> y2;
    if (x1 > x2) swap(x1, x2);
    if (y1 > y2) swap(y1, y2);
    v.push_back({x1, x2, y1, y2});
    s.insert(x1);
    s.insert(x2);
    allRows.insert(y1);
    allRows.insert(y2);
    if (y1 == y2)
      horizontal[y1].push_back({x1, x2});
    else if (x1 == x2) {
      vertical[x1].push_back({y1, y2});
    }
  }
  for (auto it = s.begin(); it != s.end(); it++) {
    compress(*it);
  }
  for (int i = 0; i < n; i++) {
    v[i].x1 = compress(v[i].x1);
    v[i].x2 = compress(v[i].x2);
  }
  for (int i = 0; i < n; i++) {
    int x1 = v[i].x1, x2 = v[i].x2;
    int y1 = v[i].y1, y2 = v[i].y2;
    if (y1 == y2) {
      row2Segments[y1].push_back({x1, x2});
    } else {
      row2Downwards[y1].push_back({x1, y2});
    }
  }
}
long long addLine(vector<pair<int, int>> segments) {
  vector<pair<long long, bool>> v;
  for (pair<int, int> x : segments) {
    v.push_back({x.first, false});
    v.push_back({x.second, true});
  }
  int cnt = 0;
  long long ans = 0, last = -inf;
  sort(v.begin(), v.end());
  for (int i = 0; i < v.size(); i++) {
    if (cnt == 0) {
      if (last != -inf) {
        ans += v[i - 1].first - last + 1;
      }
      last = v[i].first;
    }
    if (v[i].second == false)
      cnt++;
    else
      cnt--;
  }
  ans += v.back().first - last + 1;
  return ans;
}
long long doRow(int row, vector<pair<int, int>> segments) {
  long long ans = 0;
  for (pair<int, int> x : row2Downwards[row]) {
    treeCnt->update(x.first, +1);
    if (treeCnt->query(x.first, x.first) == 1) {
      treeMark->update(x.first, +1);
    }
    toEnd[x.second].push_back(x.first);
  }
  if (segments.empty() == false) {
    vector<pair<int, bool>> v;
    for (pair<int, int> x : segments) {
      v.push_back({x.first, false});
      v.push_back({x.second, true});
    }
    sort(v.begin(), v.end());
    int cnt = 0;
    int last = -1;
    for (int i = 0; i < v.size(); i++) {
      if (cnt == 0) {
        if (last != -1) {
          ans += treeMark->query(last, v[i - 1].first);
        }
        last = v[i].first;
      }
      if (v[i].second == false)
        cnt++;
      else
        cnt--;
    }
    ans += treeMark->query(last, v.back().first);
  }
  for (int x : toEnd[row]) {
    treeCnt->update(x, -1);
    if (treeCnt->query(x, x) == 0) treeMark->update(x, -1);
  }
  return ans;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  readAndInit();
  long long exclude = 0, include = 0;
  for (auto it = allRows.begin(); it != allRows.end(); it++) {
    exclude += doRow(*it, row2Segments[*it]);
  }
  for (auto it = vertical.begin(); it != vertical.end(); it++)
    include += addLine(it->second);
  for (auto it = horizontal.begin(); it != horizontal.end(); it++)
    include += addLine(it->second);
  cout << include - exclude << '\n';
}
