#include <bits/stdc++.h>
using namespace std;
namespace solution {
const int MAXN = 100005;
const int SZ = 1501000;
int n;
int x1[MAXN], x2[MAXN], y1[MAXN], y2[MAXN];
vector<int> cx, cy;
vector<pair<int, int> > events[2 * MAXN];
int mx[SZ];
int mn[SZ];
bool seen[MAXN];
bool erased[MAXN];
priority_queue<int> colors[SZ];
enum { ACTION_ADD, ACTION_ERASE, ACTION_VOID };
void calc(int idx) {
  int max_in_child = max(mx[idx * 2], mx[idx * 2 + 1]);
  while (!colors[idx].empty() && erased[colors[idx].top()]) {
    colors[idx].pop();
  }
  int max_in_node = colors[idx].empty() ? -1 : colors[idx].top();
  int min_in_child = min(mn[idx * 2], mn[idx * 2 + 1]);
  if (max_in_node > max_in_child) {
    if (seen[max_in_node] || max_in_node < min_in_child) {
      mx[idx] = -1;
    } else {
      mx[idx] = max_in_node;
    }
  } else {
    mx[idx] = max_in_child;
  }
  mn[idx] = max(min_in_child, max_in_node);
}
void update(int x, int y, int val, int action, int idx, int s, int e) {
  if (x > e || y < s) return;
  if (x <= s && e <= y) {
    if (action == ACTION_ADD) {
      colors[idx].push(val);
    }
    calc(idx);
    return;
  }
  int m = (s + e) / 2;
  update(x, y, val, action, idx * 2, s, m);
  update(x, y, val, action, idx * 2 + 1, m + 1, e);
  calc(idx);
}
int run() {
  scanf("%d", &n);
  for (int i = 0; i < n; ++i) {
    scanf("%d%d%d%d", &x1[i], &y1[i], &x2[i], &y2[i]);
    cx.push_back(x1[i]);
    cx.push_back(x2[i]);
    cy.push_back(y1[i]);
    cy.push_back(y2[i]);
  }
  sort((cx).begin(), (cx).end());
  cx.resize(unique((cx).begin(), (cx).end()) - cx.begin());
  sort((cy).begin(), (cy).end());
  cy.resize(unique((cy).begin(), (cy).end()) - cy.begin());
  for (int i = 0; i < n; ++i) {
    x1[i] = lower_bound((cx).begin(), (cx).end(), x1[i]) - cx.begin();
    x2[i] = lower_bound((cx).begin(), (cx).end(), x2[i]) - cx.begin();
    y1[i] = lower_bound((cy).begin(), (cy).end(), y1[i]) - cy.begin();
    y2[i] = lower_bound((cy).begin(), (cy).end(), y2[i]) - cy.begin();
    events[x1[i]].push_back({i, ACTION_ADD});
    events[x2[i]].push_back({i, ACTION_ERASE});
  }
  memset(seen, 0, sizeof seen);
  memset(erased, 0, sizeof erased);
  memset(mx, -1, sizeof mx);
  for (int i = 0; i < cx.size(); ++i) {
    for (auto e : events[i]) {
      if (e.second == ACTION_ERASE) erased[e.first] = true;
      update(y1[e.first], y2[e.first] - 1, e.first, e.second, 1, 0, 2 * n - 1);
    }
    while (mx[1] >= mn[1]) {
      int id = mx[1];
      seen[id] = true;
      update(y1[id], y2[id] - 1, id, ACTION_VOID, 1, 0, 2 * n - 1);
    }
  }
  int ans = 1;
  for (int i = 0; i < n; ++i) {
    if (seen[i]) ++ans;
  }
  printf("%d\n", ans);
  return 0;
}
}  // namespace solution
int main() { solution::run(); }
