#include <bits/stdc++.h>
using namespace std;
int n, m;
struct DOT {
  int x, y;
  int dep() { return x + y; }
  DOT fa() {
    if (x == 0 && y == 0) return (DOT){0, -1};
    if (x == 0) return (DOT){x, y - 1};
    if (y == 0) return (DOT){x - 1, y};
    return ((x) & -(x)) < ((y) & -(y)) ? (DOT){x - 1, y} : (DOT){x, y - 1};
  }
  DOT top() {
    if (x == 0 || y == 0) return (DOT){0, 0};
    if (((x) & -(x)) > ((y) & -(y)))
      return (DOT){x, y - (y & ((x) & -(x)) - 1)};
    return (DOT){x - (x & ((y) & -(y)) - 1), y};
  }
} d[400005];
bool operator<(DOT a, DOT b) { return a.x < b.x || a.x == b.x && a.y < b.y; }
map<DOT, int> id;
bool operator==(DOT a, DOT b) { return a.x == b.x && a.y == b.y; }
bool same_line(DOT a, DOT b) {
  return a.top() == b.top() && (a.x == b.x || a.y == b.y);
}
DOT LCA(DOT a, DOT b) {
  while (!same_line(a, b))
    if (a.top().dep() > b.top().dep())
      a = a.top();
    else
      b = b.top();
  return a.dep() < b.dep() ? a : b;
}
bool cmpd(DOT a, DOT b) {
  DOT A = a, B = b;
  while (!same_line(a, b))
    if (a.top().dep() > b.top().dep())
      a = a.top();
    else
      b = b.top();
  DOT lca = a.dep() < b.dep() ? a : b;
  if (B == lca) return 0;
  if (A == lca) return 1;
  return a.y == b.y ? a.x < b.x : a.y > b.y;
}
struct edge {
  DOT u, v;
} ed[400005];
struct EDGE {
  int to;
  EDGE *las;
} e[400005];
int ne;
EDGE *last[400005];
void link(int u, int v) {
  e[ne] = {v, last[u]};
  last[u] = e + ne++;
}
int build() {
  static int st[400005];
  int tp = 1;
  st[1] = 1;
  int _m = m;
  for (int i = 2; i <= m; ++i) {
    DOT _lca = LCA(d[i], d[st[tp]]);
    if (!id[_lca]) {
      d[++_m] = _lca;
      id[_lca] = _m;
    }
    int lca = id[_lca];
    while (tp > 1 && d[lca].dep() < d[st[tp - 1]].dep()) {
      link(st[tp - 1], st[tp]);
      --tp;
    }
    if (tp && d[lca].dep() < d[st[tp]].dep()) {
      link(lca, st[tp]);
      --tp;
      if (!(lca == st[tp])) st[++tp] = lca;
    }
    st[++tp] = i;
  }
  while (tp > 1) {
    link(st[tp - 1], st[tp]);
    --tp;
  }
  m = _m;
  return st[1];
}
int c[400005], b[400005];
int q[400005 * 2], nq;
int dep[400005];
int ans[400005];
void dfs(int x, int fa = 0) {
  dep[x] = d[x].dep();
  for (EDGE *ei = last[x]; ei; ei = ei->las) dfs(ei->to, x), c[x] += c[ei->to];
  if (c[x]) {
    q[++nq] = dep[fa] + 1, q[++nq] = dep[x] + 1;
  } else if (b[x]) {
    q[++nq] = dep[x], q[++nq] = dep[x] + 1;
  }
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    int x1, y1, x2, y2;
    scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
    d[++m] = {x1, y1};
    d[++m] = {x2, y2};
    ed[i] = {d[m - 1], d[m]};
  }
  sort(d + 1, d + m + 1, cmpd);
  m = unique(d + 1, d + m + 1) - d - 1;
  for (int i = 1; i <= m; ++i) id[d[i]] = i;
  int rt = build();
  for (int i = 1; i <= n; ++i) {
    int u = id[ed[i].u], v = id[ed[i].v];
    int lca = id[LCA(d[u], d[v])];
    c[u]++, c[v]++, c[lca] -= 2;
    b[lca] = 1;
  }
  dfs(rt);
  sort(q + 1, q + nq + 1);
  int cnt = 0, s = 0, last[2] = {-2, -2};
  for (int i = 1; i <= nq; ++i) {
    s ^= 1;
    if (i == nq || q[i] != q[i + 1]) {
      if (last[s] <= last[s ^ 1]) cnt++;
      last[s] = q[i];
    }
  }
  if (last[0] > last[1]) cnt--;
  printf("%d\n", cnt);
  return 0;
}
