#include <bits/stdc++.h>
using namespace std;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
int len(pair<int, int> xy) { return xy.first + xy.second; }
pair<int, int> jump(pair<int, int> xy, int len) {
  if (len == 0) return xy;
  auto [x, y] = xy;
  if (len > x + y) return {0, 0};
  int bit = 31 - __builtin_clz(len);
  int cur = x ^ y;
  int take = cur & ((1 << bit) - 1);
  assert(take <= len);
  x &= ~take;
  y &= ~take;
  len -= take;
  while (len > 0) {
    int bit = __builtin_ctz(x ^ y);
    int take = min(1 << bit, len);
    if ((x >> bit) & 1)
      x -= take;
    else
      y -= take;
    len -= take;
  }
  return {x, y};
}
pair<int, int> lca(pair<int, int> u, pair<int, int> v) {
  int lu = len(u), lv = len(v);
  if (lu > lv) {
    swap(lu, lv);
    swap(u, v);
  }
  v = jump(v, lv - lu);
  if (u == v) return u;
  for (int bit = 29; bit >= 0; bit--) {
    auto nu = jump(u, 1 << bit), nv = jump(v, 1 << bit);
    if (nu != nv) tie(u, v) = {nu, nv};
  }
  return jump(u, 1);
}
bool cmp(pair<int, int> u, pair<int, int> v) {
  if (u == v) return false;
  bool swp = false;
  int lu = len(u), lv = len(v);
  if (lu > lv) {
    swap(lu, lv);
    swap(u, v);
    swp = true;
  }
  v = jump(v, lv - lu);
  if (u == v) return true ^ swp;
  return (u > v) ^ swp;
}
using event = pair<pair<int, int>, int>;
vector<event> evt;
struct node {
  int val, depth;
  node *left, *right;
};
node *build(int from, int to) {
  if (from >= to) return nullptr;
  int val = 0;
  auto w = lca(evt[from].first, evt[to - 1].first);
  while (from < to && evt[from].first == w) {
    val += evt[from].second;
    ++from;
  }
  auto [wx, wy] = w;
  if ((wx + 1) & wy) return new node({val, len(w), nullptr, build(from, to)});
  if (wx & (wy + 1)) return new node({val, len(w), build(from, to), nullptr});
  pair<int, int> rchild(wx, wy + 1);
  int lo = from - 1, hi = to;
  while (lo + 1 < hi) {
    auto mi = (lo + hi) / 2;
    if (cmp(evt[mi].first, rchild))
      lo = mi;
    else
      hi = mi;
  }
  return new node({val, len(w), build(from, hi), build(hi, to)});
}
vector<int> change;
void add(int l, int r) {
  change.push_back(l);
  change.push_back(r);
}
void simplify() {
  sort((change).begin(), (change).end());
  vector<int> st;
  for (auto x : change) {
    if (!st.empty() && st.back() == x)
      st.pop_back();
    else
      st.push_back(x);
  }
  change = st;
}
int dfs(node *u) {
  int ans = 0;
  if (u->left) {
    auto s = dfs(u->left);
    if (s > 0) add(u->depth + 1, u->left->depth);
    ans += s;
  }
  if (u->right) {
    auto s = dfs(u->right);
    if (s > 0) add(u->depth + 1, u->right->depth);
    ans += s;
  }
  ans += u->val;
  if (ans > 0) add(u->depth, u->depth + 1);
  return ans;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int m;
  cin >> m;
  while (m--) {
    int x1, y1, x2, y2;
    cin >> x1 >> y1 >> x2 >> y2;
    pair<int, int> u(x1, y1), v(x2, y2);
    pair<int, int> w = lca(u, v);
    evt.emplace_back(u, +1);
    evt.emplace_back(v, +1);
    evt.emplace_back(w, -1);
    if (len(w)) {
      w = jump(w, 1);
      evt.emplace_back(w, -1);
    }
  }
  sort((evt).begin(), (evt).end(),
       [](const event &a, const event &b) { return cmp(a.first, b.first); });
  auto tree = build(0, ((int)(evt).size()));
  dfs(tree);
  simplify();
  int ans = ((int)(change).size());
  if (ans > 0 && change[0] == 0) --ans;
  cout << ans << endl;
  return 0;
}
