#include <bits/stdc++.h>
using namespace std;
struct data {
  int sj, type, id;
};
bool cmp(data a, data b) { return a.sj < b.sj; }
int x[2][500000], y[2][500000], tx[500000], ty[500000], tot_x, tot_y,
    tl[500000], tr[500000], mx[1000000], mn[1000000];
int res[500000], ans;
set<int> color[1000000];
data A[500000];
int read() {
  int tmp = 0, fh = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') fh = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    tmp = tmp * 10 + c - '0';
    c = getchar();
  }
  return tmp * fh;
}
void update(int now, int l, int r) {
  set<int>::iterator it = color[now].end();
  if (color[now].size()) it--;
  if (l == r) {
    if (color[now].empty()) {
      mn[now] = 0;
      mx[now] = -1;
    } else {
      if (res[*it] == 0)
        mx[now] = *it;
      else
        mx[now] = -1;
      mn[now] = *it;
    }
    return;
  }
  if (color[now].empty() || *it <= max(mx[now * 2], mx[now * 2 + 1]))
    mx[now] = max(mx[now * 2], mx[now * 2 + 1]);
  else if (res[*it] || min(mn[now * 2], mn[now * 2 + 1]) > *it)
    mx[now] = -1;
  else
    mx[now] = *it;
  if (color[now].empty())
    mn[now] = min(mn[now * 2], mn[now * 2 + 1]);
  else
    mn[now] = max(min(mn[now * 2], mn[now * 2 + 1]), *it);
}
void rebuild(int now, int l, int r, int left, int right) {
  if (l == left && r == right) {
    update(now, l, r);
    return;
  }
  int mid = (l + r) / 2;
  if (left <= mid) rebuild(now * 2, l, mid, left, min(right, mid));
  if (right >= mid + 1)
    rebuild(now * 2 + 1, mid + 1, r, max(left, mid + 1), right);
  update(now, l, r);
}
void solve() {
  while (mx[1] != -1) {
    res[mx[1]] = 1;
    ans++;
    rebuild(1, 1, tot_y, tl[mx[1]], tr[mx[1]]);
  }
}
void modify(int now, int l, int r, int left, int right, int id, int type) {
  if (l == left && r == right) {
    if (type == 1)
      color[now].insert(id);
    else
      color[now].erase(id);
    update(now, l, r);
    return;
  }
  int mid = (l + r) / 2;
  if (left <= mid) modify(now * 2, l, mid, left, min(right, mid), id, type);
  if (right >= mid + 1)
    modify(now * 2 + 1, mid + 1, r, max(left, mid + 1), right, id, type);
  update(now, l, r);
}
void build(int now, int l, int r) {
  mx[now] = -1;
  if (l == r) return;
  int mid = (l + r) / 2;
  build(now * 2, l, mid);
  build(now * 2 + 1, mid + 1, r);
}
int main() {
  int n = read(), tot = 0;
  for (int i = 1; i <= n; i++)
    for (int j = 0; j <= 1; j++) {
      x[j][i] = read();
      y[j][i] = read();
      tx[++tot_x] = x[j][i];
      ty[++tot_y] = y[j][i];
    }
  sort(tx + 1, tx + tot_x + 1);
  sort(ty + 1, ty + tot_y + 1);
  tot_x = unique(tx + 1, tx + tot_x + 1) - tx - 1;
  tot_y = unique(ty + 1, ty + tot_y + 1) - ty - 1;
  build(1, 1, tot_y);
  for (int i = 1; i <= n; i++) {
    tl[i] = lower_bound(ty + 1, ty + tot_y + 1, y[0][i]) - ty;
    tr[i] = lower_bound(ty + 1, ty + tot_y + 1, y[1][i]) - ty - 1;
    for (int j = 0; j <= 1; j++) {
      int tmp;
      tmp = lower_bound(tx + 1, tx + tot_x + 1, x[j][i]) - tx;
      A[++tot] = (data){tmp, j, i};
    }
  }
  sort(A + 1, A + tot + 1, cmp);
  for (int i = 1; i <= tot; i++) {
    data tmp = A[i];
    if (tmp.type == 0)
      modify(1, 1, tot_y, tl[tmp.id], tr[tmp.id], tmp.id, 1);
    else
      modify(1, 1, tot_y, tl[tmp.id], tr[tmp.id], tmp.id, -1);
    if (i == tot || A[i].sj != A[i + 1].sj) solve();
  }
  printf("%d\n", ans + 1);
  return 0;
}
