#include <bits/stdc++.h>
int M;
int bit_len(int x) {
  if (x == 0) return 0;
  int L = 0;
  for (int i = 16; i; i >>= 1)
    if (x >> L >> i) L += i;
  return ++L;
}
struct point {
  int x, y;
  point fa() const {
    if (x == 0 || y != 0 && (x & -x) > (y & -y))
      return {x, y - 1};
    else
      return {x - 1, y};
  }
  point last_node() const {
    if (x == 0 || y != 0 && (x & -x) > (y & -y))
      return {x, y & y - 1};
    else
      return {x & x - 1, y};
  }
  int dep() const { return x + y; }
  inline bool operator==(const point &b) const { return x == b.x && y == b.y; }
  inline bool operator!=(const point &b) const { return x != b.x || y != b.y; }
  friend point LCA(point a, point b) {
    if (a == b) return a;
    int B = std::max(bit_len(a.x ^ b.x), bit_len(a.y ^ b.y));
    point ma = {a.x & (1 << B) - 1, a.y & (1 << B) - 1};
    point mb = {b.x & (1 << B) - 1, b.y & (1 << B) - 1};
    point prefix = {a.x - ma.x, a.y - ma.y};
    if ((ma.x < ma.y) != (mb.x < mb.y) || ma.x == 0 && ma.y == 0 ||
        mb.x == 0 && mb.y == 0)
      return prefix;
    if (ma.x < ma.y && mb.x < mb.y) {
      point m = ma.y < mb.y ? ma : mb;
      int L = (1 << bit_len(m.x)) - 1;
      return {prefix.x, prefix.y | m.y & ~L};
    } else {
      point m = ma.x < mb.x ? ma : mb;
      int L = (1 << bit_len(m.y)) - 1;
      return {prefix.x | m.x & ~L, prefix.y};
    }
  }
  inline bool operator<(const point &b) const {
    if (*this == b) return false;
    int B = std::max(bit_len(x ^ b.x), bit_len(y ^ b.y)) - 1;
    if (x >> B & 1) return (b.y & (2 << B) - 1) != 0;
    if (y >> B & 1) return false;
    if (b.x >> B & 1) return (y & (2 << B) - 1) == 0;
    return true;
  }
};
point u[100001], v[100001];
point p[200002], vt[400002];
int fa[400002], q[400002];
int N, D, root, n;
std::vector<int> V[400002];
std::map<std::pair<int, int>, int> ref;
int LOG, J[19][400002], dep[400002], cover[400002], single_cover[400002];
int LCA(int u, int v) {
  for (int i = LOG; i >= 0; i--) {
    if (dep[u] - dep[v] >= 1 << i) u = J[i][u];
    if (dep[v] - dep[u] >= 1 << i) v = J[i][v];
  }
  if (u == v) return u;
  for (int i = LOG; i >= 0; i--)
    if (J[i][u] != J[i][v]) {
      u = J[i][u];
      v = J[i][v];
    }
  return fa[u];
}
void BFS() {
  q[1] = root;
  dep[root] = 0;
  int H = 0, T = 1;
  while (H < T) {
    int u = q[++H];
    for (int v : V[u]) dep[q[++T] = v] = dep[u] + 1;
  }
}
int main() {
  scanf("%d", &M);
  for (int i = 1; i <= M; i++) {
    scanf("%d%d%d%d", &u[i].x, &u[i].y, &v[i].x, &v[i].y);
    p[++N] = u[i];
    p[++N] = v[i];
  }
  std::sort(p + 1, p + N + 1);
  N = std::unique(p + 1, p + N + 1) - p - 1;
  for (int i = 1; i <= N; i++) {
    if (D) {
      point lca = LCA(vt[q[D]], p[i]);
      while (D > 1 && vt[q[D - 1]].dep() >= lca.dep()) D--;
      if (lca == vt[q[D]]) {
        vt[++n] = p[i];
        fa[n] = q[D];
        q[++D] = n;
      } else {
        vt[++n] = lca;
        vt[++n] = p[i];
        fa[n - 1] = fa[q[D]];
        fa[q[D]] = fa[n] = n - 1;
        q[D] = n - 1;
        q[++D] = n;
      }
    } else {
      vt[++n] = p[i];
      fa[n] = 0;
      q[++D] = n;
    }
  }
  root = q[1];
  for (int i = 1; i <= n; i++) {
    if (i != root) V[fa[i]].push_back(i);
    J[0][i] = fa[i];
    ref[{vt[i].x, vt[i].y}] = i;
  }
  BFS();
  while (2 << LOG < n) LOG++;
  for (int i = 1; i <= LOG; i++)
    for (int j = 1; j <= n; j++) J[i][j] = J[i - 1][J[i - 1][j]];
  for (int i = 1; i <= M; i++) {
    int tu = ref[{u[i].x, u[i].y}], tv = ref[{v[i].x, v[i].y}],
        lca = LCA(tu, tv);
    cover[tu]++;
    cover[tv]++;
    cover[lca] -= 2;
    single_cover[lca]++;
  }
  for (int i = n; i > 1; i--) cover[fa[q[i]]] += cover[q[i]];
  std::map<int, int> ans_segs;
  for (int i = 1; i <= n; i++)
    if (cover[i]) {
      ans_segs[vt[i].dep()] ^= 1;
      ans_segs[vt[fa[i]].dep()] ^= 1;
    } else if (single_cover[i]) {
      ans_segs[vt[i].dep()] ^= 1;
      ans_segs[vt[i].dep() - 1] ^= 1;
    }
  int ans = 0;
  for (auto &i : ans_segs)
    if (i.first != -1) ans += i.second;
  printf("%d\n", ans);
  return 0;
}
