#include <bits/stdc++.h>
using namespace std;
int m, i, j, k, tot, cnt;
struct Node {
  int x, y;
  Node(int _x = 0, int _y = 0) { x = _x, y = _y; }
} a[400005][2], p[400005];
int operator<(Node a, Node b) { return a.x < b.x || a.x == b.x && a.y < b.y; }
int operator==(Node a, Node b) { return a.x == b.x && a.y == b.y; }
map<Node, int> num;
Node P[400005];
map<int, int> sum;
map<int, int>::iterator it;
int nm(Node a) {
  if (num.find(a) == num.end()) num[a] = ++tot, P[tot] = a;
  return num[a];
}
int mul[31];
int getb(Node a, int x, int y, int k) {
  if (a.x < x + mul[k] && a.y < y + mul[k]) return 0;
  if (a.x >= x + mul[k]) return 1;
  return 2;
}
int cmp(Node a, Node b) {
  int x = 0, y = 0;
  for (int k = 30; k >= 0; k--) {
    int t1 = getb(a, x, y, k), t2 = getb(b, x, y, k);
    if (t1 == t2) {
      if (t1 == 1) x += mul[k];
      if (t1 == 2) y += mul[k];
    } else {
      if (t1 == 0) {
        if (t2 == 1) return 1;
        if (t2 == 2) return a.x == x;
      }
      if (t2 == 0) {
        if (t1 == 1) return 0;
        if (t1 == 2) return b.x != x;
      }
      return t1 > t2;
    }
  }
  return 0;
}
Node Lca(Node a, Node b) {
  int x = 0, y = 0;
  for (int k = 30; k >= 0; k--) {
    int t1 = getb(a, x, y, k), t2 = getb(b, x, y, k);
    if (t1 == t2) {
      if (t1 == 1) x += mul[k];
      if (t1 == 2) y += mul[k];
    } else {
      if (t1 + t2 == 3) return Node(x, y);
      if (t2 == 0) swap(t1, t2), swap(a, b);
      if (t2 == 1) b = Node(x + mul[k] - 1, y);
      if (t2 == 2) b = Node(x, y + mul[k] - 1);
    }
  }
  return a;
}
int tar[400005], nex[400005], fir[400005], egd;
int w, fat[400005], c0[400005], c1[400005];
Node d[400005];
void Add(int x, int y) {
  egd++;
  tar[egd] = y;
  nex[egd] = fir[x];
  fir[x] = egd;
  fat[y] = x;
}
void Build() {
  d[w = 1] = Node(0, 0);
  for (int i = 1; i <= cnt; i++) {
    Node x = p[i];
    if (x == d[w]) continue;
    Node y = Lca(d[w], x);
    if (y == d[w])
      d[++w] = x;
    else {
      while (cmp(y, d[w - 1])) Add(nm(d[w - 1]), nm(d[w])), w--;
      if (y == d[w - 1]) {
        Add(nm(d[w - 1]), nm(d[w]));
        d[w] = x;
      } else {
        Add(nm(y), nm(d[w]));
        d[w] = y, d[++w] = x;
      }
    }
  }
  while (w > 1) Add(nm(d[w - 1]), nm(d[w])), w--;
}
void Change(int l, int r) { sum[l] ^= 1, sum[r + 1] ^= 1; }
void dfs(int x) {
  for (int i = fir[x]; i; i = nex[i]) dfs(tar[i]), c0[x] += c0[tar[i]];
  if (c0[x]) Change(P[x].x + P[x].y, P[x].x + P[x].y);
  c0[x] += c1[x];
  if (c0[x] && fat[x])
    Change(P[fat[x]].x + P[fat[x]].y + 1, P[x].x + P[x].y - 1);
}
int main() {
  for (i = 0; i <= 30; i++) mul[i] = 1 << i;
  scanf("%d", &m);
  for (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[++cnt] = a[i][0], p[++cnt] = a[i][1];
  }
  sort(p + 1, p + 1 + cnt, cmp);
  Build();
  for (i = 1; i <= m; i++) {
    c0[nm(a[i][0])]++, c0[nm(a[i][1])]++;
    c1[nm(Lca(a[i][0], a[i][1]))] -= 2;
  }
  dfs(nm(Node(0, 0)));
  int ans = 0;
  for (it = sum.begin(); it != sum.end(); it++) ans += (*it).second;
  ans = ans - sum[0];
  printf("%d\n", ans);
}
