#include <bits/stdc++.h>
using namespace std;
int n;
struct point {
  int x, y;
  point(int _x = 0, int _y = 0) { x = _x, y = _y; }
  friend bool operator==(point a, point b) { return a.x == b.x && a.y == b.y; }
  friend bool operator!=(point a, point b) { return a.x != b.x || a.y != b.y; }
};
vector<point> getanc(point A) {
  int x = A.x, y = A.y;
  vector<point> res;
  int flag = -1;
  for (int i = 0; i < 30; i++) {
    if ((x >> i) & 1) {
      if (flag != 0) res.push_back(point(x, y));
      flag = 0, x ^= (1 << i);
    }
    if ((y >> i) & 1) {
      if (flag != 1) res.push_back(point(x, y));
      flag = 1, y ^= (1 << i);
    }
  }
  res.push_back(point(0, 0));
  reverse(res.begin(), res.end());
  return res;
}
inline int lowbit(int x) { return x & (-x); }
inline bool dir(point a) {
  int x = a.x, y = a.y;
  if (!x || !y) return x < y;
  return lowbit(x) > lowbit(y);
}
inline int dis(point a, point b) { return b.x - a.x + b.y - a.y; }
const int maxn = 100005;
point fr[maxn], ed[maxn];
namespace tree {
map<pair<int, int>, int> Map;
vector<point> A[maxn << 2];
vector<int> son[maxn << 2];
int fa[maxn << 2], dep[maxn << 2], rt, tot;
inline int getid(point a) {
  pair<int, int> tmp = make_pair(a.x, a.y);
  if (!Map.count(tmp)) {
    Map[tmp] = ++tot;
    dep[tot] = a.x + a.y;
    A[tot] = getanc(a);
  }
  return Map[tmp];
}
bool cmp(int x, int y) {
  if (x == y) return 0;
  for (int i = 1; i < (int)A[x].size() && i < (int)A[y].size(); i++) {
    if (A[x][i] != A[y][i]) {
      if (dir(A[x][i]) != dir(A[y][i])) return dir(A[x][i]) < dir(A[y][i]);
      int lenA = dis(A[x][i - 1], A[x][i]), lenB = dis(A[y][i - 1], A[y][i]);
      if (lenA > lenB) {
        if (i + 1 == (int)A[y].size()) return 0;
        return dir(A[x][i]) < dir(A[y][i + 1]);
      } else {
        if (i + 1 == (int)A[x].size()) return 1;
        return dir(A[x][i + 1]) < dir(A[y][i]);
      }
    }
  }
  return A[x].size() < A[y].size();
}
point getlca(int x, int y) {
  point now;
  for (int i = 1; i < (int)A[x].size() && i < (int)A[y].size(); i++) {
    if (A[x][i] != A[y][i]) {
      if (dir(A[x][i]) != dir(A[y][i])) return now;
      int lenA = dis(A[x][i - 1], A[x][i]), lenB = dis(A[y][i - 1], A[y][i]);
      return lenA < lenB ? A[x][i] : A[y][i];
    }
    now = A[x][i];
  }
  return now;
}
inline void add(int x, int y) {
  fa[y] = x;
  son[x].push_back(y);
}
int st[maxn], top;
void insert(int x) {
  if (!top) {
    st[++top] = x;
    return;
  }
  int lca = getid(getlca(x, st[top]));
  if (st[top] != lca) {
    while (top > 1 && !cmp(st[top - 1], lca)) add(st[top - 1], st[top]), top--;
    if (st[top] != lca) add(lca, st[top]), st[top] = lca;
  }
  st[++top] = x;
}
void build(vector<point> &p) {
  vector<int> P;
  for (auto x : p) P.push_back(getid(x));
  sort(P.begin(), P.end(), cmp);
  P.resize(unique(P.begin(), P.end()) - P.begin());
  for (auto x : P) insert(x);
  while (--top) add(st[top], st[top + 1]);
  rt = st[1];
}
int f[maxn << 2], g[maxn << 2];
inline void addtag(int x, int y) {
  if (dep[x] > dep[y]) swap(x, y);
  int lca = getid(getlca(x, y));
  f[x]++, f[y]++, f[lca]--, f[fa[lca]]--;
  g[x]++, g[y]++, g[lca] -= 2;
}
int ans;
map<int, int> mp;
inline void addseg(int l, int r) {
  if (l >= 1) {
    int tmp = mp[--l];
    ans += (tmp ^ 1) - tmp;
    mp[l] = tmp ^ 1;
  }
  int tmp = mp[r];
  ans += (tmp ^ 1) - tmp;
  mp[r] = tmp ^ 1;
}
void dfs(int x) {
  for (auto v : son[x]) {
    dfs(v);
    f[x] += f[v];
    g[x] += g[v];
    if (g[v]) addseg(dep[x] + 1, dep[v] - 1);
  }
  if (f[x]) addseg(dep[x], dep[x]);
}
void solve() {
  dfs(rt);
  cout << ans << endl;
}
}  // namespace tree
using tree::getid;
int main() {
  scanf("%d", &n);
  vector<point> p;
  for (int i = 1, x, y; i <= n; i++) {
    scanf("%d%d", &x, &y), fr[i] = point(x, y);
    scanf("%d%d", &x, &y), ed[i] = point(x, y);
    p.push_back(fr[i]), p.push_back(ed[i]);
  }
  tree::build(p);
  for (int i = 1; i <= n; i++) {
    int x = getid(fr[i]), y = getid(ed[i]);
    tree::addtag(x, y);
  }
  tree::solve();
  return 0;
}
