#include <bits/stdc++.h>
using namespace std;
const int N = 4e5 + 10;
int m, tot, pw[35];
struct atom {
  int x, y;
  atom(int X = 0, int Y = 0) { x = X, y = Y; }
  friend bool operator<(atom a, atom b) {
    return a.x == b.x ? a.y < b.y : a.x < b.x;
  }
  friend bool operator==(atom a, atom b) { return a.x == b.x && a.y == b.y; }
} a[N][2], p[N << 1];
map<atom, int> mp;
map<int, atom> to;
map<int, int> pre;
int chk(atom a, int x, int y, int b) {
  if (a.x < x + pw[b] && a.y < y + pw[b]) return 0;
  if (a.x >= x + pw[b]) return 1;
  return 2;
}
bool cmp(atom a, atom b) {
  int x = 0, y = 0;
  for (int i = 30; i >= 0; i--) {
    int t1 = chk(a, x, y, i), t2 = chk(b, x, y, i);
    if (t1 == t2) {
      if (t1 == 1) x += pw[i];
      if (t1 == 2) y += pw[i];
    } else {
      if (!t1) {
        if (t2 == 1) return 1;
        if (t2 == 2) return a.x == x;
      }
      if (!t2) {
        if (t1 == 1) return 0;
        if (t1 == 2) return b.x != x;
      }
      return t1 > t2;
    }
  }
  return 0;
}
atom LCA(atom a, atom b) {
  int x = 0, y = 0;
  for (int i = 30; i >= 0; i--) {
    int t1 = chk(a, x, y, i), t2 = chk(b, x, y, i);
    if (t1 == t2) {
      if (t1 == 1) x += pw[i];
      if (t1 == 2) y += pw[i];
    } else {
      if (t1 + t2 == 3) return (atom){x, y};
      if (!t2) swap(t1, t2), swap(a, b);
      if (t2 == 1) b = (atom){x + pw[i] - 1, y};
      if (t2 == 2) b = (atom){x, y + pw[i] - 1};
    }
  }
  return a;
}
atom stk[N];
int top, idx, B[N], W[N], fa[N];
vector<int> g[N];
int ord(atom x) {
  if (mp.find(x) == mp.end()) mp[x] = ++idx, to[idx] = x;
  return mp[x];
}
void adde(int x, int y) { g[x].push_back(y), fa[y] = x; }
void build() {
  stk[top = 1] = (atom){0, 0};
  for (int i = 1; i <= tot; i++) {
    atom x = p[i];
    if (x == stk[top]) continue;
    atom lca = LCA(x, stk[top]);
    if (lca == stk[top])
      stk[++top] = x;
    else {
      while (top > 1 && cmp(lca, stk[top - 1])) {
        adde(ord(stk[top - 1]), ord(stk[top])), --top;
      }
      if (lca == stk[top - 1]) {
        adde(ord(lca), ord(stk[top])), stk[top] = x;
      } else {
        adde(ord(lca), ord(stk[top])), stk[top] = lca, stk[++top] = x;
      }
    }
  }
  while (top > 1) adde(ord(stk[top - 1]), ord(stk[top])), --top;
}
void rev(int l, int r) { pre[l] ^= 1, pre[r + 1] ^= 1; }
void dfs(int x) {
  for (int i = 0; i < g[x].size(); i++) {
    int y = g[x][i];
    dfs(y), B[x] += B[y];
  }
  if (B[x]) rev(to[x].x + to[x].y, to[x].x + to[x].y);
  B[x] += W[x];
  if (B[x] && fa[x]) rev(to[fa[x]].x + to[fa[x]].y + 1, to[x].x + to[x].y - 1);
}
int main() {
  pw[0] = 1;
  for (int i = 1; i <= 31; i++) pw[i] = pw[i - 1] * 2;
  cin >> m;
  for (int i = 1; i <= m; i++) {
    scanf("%d%d%d%d", &a[i][0].x, &a[i][0].y, &a[i][1].x, &a[i][1].y);
    p[++tot] = a[i][0], p[++tot] = a[i][1];
  }
  sort(p + 1, p + tot + 1, cmp);
  build();
  for (int i = 1; i <= m; i++) {
    int x = ord(a[i][0]), y = ord(a[i][1]);
    B[x]++, B[y]++, W[ord(LCA(a[i][0], a[i][1]))] -= 2;
  }
  dfs(ord(stk[1]));
  int ans = 0;
  for (map<int, int>::iterator it = pre.begin(); it != pre.end(); it++)
    ans += it->second;
  ans -= pre[0];
  printf("%d\n", ans);
  return 0;
}
