#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline T read(register T& t) {
  register T f = 1;
  register char ch = getchar();
  t = 0;
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -f;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') t = t * 10 + ch - '0', ch = getchar();
  t *= f;
  return t;
}
template <typename T, typename... Args>
inline void read(T& t, Args&... args) {
  read(t);
  read(args...);
}
const long long p = 1e9 + 7;
inline long long power(register long long x, register long long k = p - 2) {
  register long long re = 1;
  for (; k; k >>= 1, x = x * x % p)
    if (k & 1) re = re * x % p;
  return re;
}
int n;
struct point {
  unsigned int x, y;
  inline void print() { printf("(%d,%d)\n", x, y); }
};
bool operator!=(point a, point b) { return a.x != b.x || a.y != b.y; }
bool operator==(point a, point b) { return a.x == b.x && a.y == b.y; }
bool operator<(point a, point b) {
  if (a.x != b.x) return a.x < b.x;
  return a.y < b.y;
}
point a[100005], b[100005], c[200005];
point lca(point a, point b) {
  unsigned int x = 0, y = 0;
  for (int i = 31; i >= 0; i--) {
    if ((a.x >> i & 1) == (b.x >> i & 1) && (a.y >> i & 1) == (b.y >> i & 1)) {
      if (a.x >> i & 1) x |= 1 << i;
      if (a.y >> i & 1) y |= 1 << i;
      continue;
    }
    if (a.x >> i & 1) {
      for (int j = i; j >= 0; j--) {
        if (b.y >> j & 1) break;
        if (b.x >> j & 1) x |= 1 << j;
      }
      return (point){x, y};
    }
    if (a.y >> i & 1) {
      for (int j = i; j >= 0; j--) {
        if (b.x >> j & 1) break;
        if (b.y >> j & 1) y |= 1 << j;
      }
      return (point){x, y};
    }
    if (b.x >> i & 1) {
      for (int j = i; j >= 0; j--) {
        if (a.y >> j & 1) break;
        if (a.x >> j & 1) x |= 1 << j;
      }
      return (point){x, y};
    }
    if (b.y >> i & 1) {
      for (int j = i; j >= 0; j--) {
        if (a.x >> j & 1) break;
        if (a.y >> j & 1) y |= 1 << j;
      }
      return (point){x, y};
    }
  }
  return (point){x, y};
}
bool cmp(point a, point b) {
  if (a == b) return 0;
  point c = lca(a, b);
  if (c == a) return 1;
  if (c == b) return 0;
  unsigned int x = 0, y = 0;
  for (int i = 31; i >= 0; i--) {
    if ((a.x >> i & 1) == (b.x >> i & 1) && (a.y >> i & 1) == (b.y >> i & 1)) {
      if (a.x >> i & 1) x |= 1 << i;
      if (a.y >> i & 1) y |= 1 << i;
      continue;
    }
    if (a.x >> i & 1) return 1;
    if (a.y >> i & 1) return 0;
    if (b.x >> i & 1) return 0;
    if (b.y >> i & 1) return 1;
  }
  return 0;
}
int c_top;
point st[300005];
int st_top;
vector<pair<int, int> > opt;
vector<int> num;
bool as[4000005];
map<point, point> fa;
map<point, int> vis;
map<point, vector<point> > to;
inline void Add(point a, point b) {
  fa[a] = b;
  to[b].push_back(a);
}
void dfs(point now) {
  for (auto i : to[now]) dfs(i), vis[now] += vis[i];
}
map<point, bool> used;
int main() {
  read(n);
  for (int i = 1; i <= n; i++)
    read(a[i].x, a[i].y, b[i].x, b[i].y), c[i] = a[i], c[i + n] = b[i];
  sort(c + 1, c + n * 2 + 1, cmp);
  c_top = unique(c + 1, c + n * 2 + 1) - c - 1;
  st[st_top = 1] = (point){0, 0};
  for (int i = c[1] != st[1] ? 1 : 2; i <= c_top; i++) {
    point y = lca(st[st_top], c[i]);
    while (st_top > 1 && !cmp(st[st_top - 1], y))
      Add(st[st_top], st[st_top - 1]), st_top--;
    if (st[st_top] != y) Add(st[st_top], y), st[st_top] = y;
    st[++st_top] = c[i];
  }
  while (st_top > 1) Add(st[st_top], st[st_top - 1]), st_top--;
  for (int i = 1; i <= n; i++) {
    point lc = lca(a[i], b[i]);
    point A = a[i], B = b[i];
    vis[A]++;
    vis[B]++;
    vis[lc] -= 2;
    used[lc] = used[A] = used[B] = 1;
  }
  dfs((point){0, 0});
  for (auto i : vis)
    if (i.second > 0)
      used[i.first] = 0, opt.push_back({fa[i.first].x + fa[i.first].y + 1,
                                        i.first.x + i.first.y + 1});
  for (auto i : used)
    if (i.second)
      opt.push_back({i.first.x + i.first.y, i.first.x + i.first.y + 1});
  for (auto i : opt) num.push_back(i.first), num.push_back(i.second);
  sort(num.begin(), num.end());
  num.erase(unique(num.begin(), num.end()), num.end());
  for (auto& i : opt)
    i.first = lower_bound(num.begin(), num.end(), i.first) - num.begin() + 1,
    i.second = lower_bound(num.begin(), num.end(), i.second) - num.begin() + 1;
  for (auto i : opt) as[i.first] ^= 1, as[i.second] ^= 1;
  for (int i = 1; i <= num.size() + 1; i++) as[i] ^= as[i - 1];
  assert(num.size() <= 4000005);
  int ans = 0;
  for (int i = 1; i <= num.size(); i++)
    if (as[i] == 1 && as[i + 1] == 0) ans += 2;
  if (num[0] == 0 && as[1] == 1) ans--;
  printf("%d\n", ans);
}
