#include <bits/stdc++.h>
int n;
struct Data {
  int x1, y1, x2, y2;
} a[100010];
namespace Steaunk {
std::vector<int> I[200010], O[200010];
bool cmp(const int *i, const int *j) { return *i < *j; }
bool cmp1(const Data &i, const Data &j) { return i.x1 < j.x1; }
int *s[200010], cnt, Ans;
bool vis[100010];
struct pair {
  int p;
  bool v;
  bool operator<(const pair &i) const { return p > i.p; }
  bool operator>(const pair &i) const { return p < i.p; }
  bool operator<=(const pair &i) const { return p >= i.p; }
  bool operator==(const pair &i) const { return p == i.p; }
};
std::multiset<pair> S[1 << 19];
pair v[1 << 19];
int d[1 << 19];
void PU(int u, int Ls, int Rs) {
  v[u] = *S[u].begin();
  if (Ls < Rs) {
    if (v[u] < v[u << 1] && v[u] < v[u << 1 | 1])
      ;
    else if (v[u << 1] < v[u] && v[u << 1 | 1] < v[u]) {
      if (v[u << 1].v != v[u << 1 | 1].v)
        v[u] = v[u << 1].v ? v[u << 1] : v[u << 1 | 1];
      else if (v[u << 1].v)
        v[u] = (v[u << 1] < v[u << 1 | 1] ? v[u << 1] : v[u << 1 | 1]);
      else
        v[u] = (v[u << 1] > v[u << 1 | 1] ? v[u << 1] : v[u << 1 | 1]);
    } else if (v[u << 1] < v[u] && v[u] <= v[u << 1 | 1] && (v[u << 1].v))
      v[u] = v[u << 1];
    else if (v[u << 1 | 1] < v[u] && v[u] <= v[u << 1] && (v[u << 1 | 1].v))
      v[u] = v[u << 1 | 1];
  }
}
void Add(int u, int Ls, int Rs, int l, int r, int p) {
  if (l <= Ls && Rs <= r) {
    S[u].insert((pair){p, 1});
    PU(u, Ls, Rs);
    return;
  }
  int Mid = Ls + Rs >> 1;
  if (l <= Mid) Add(u << 1, Ls, Mid, l, r, p);
  if (r > Mid) Add(u << 1 | 1, Mid + 1, Rs, l, r, p);
  PU(u, Ls, Rs);
}
void Del(int u, int Ls, int Rs, int l, int r, int p) {
  if (l <= Ls && Rs <= r) {
    assert(S[u].find((pair){p, 0}) != S[u].end());
    S[u].erase(S[u].find((pair){p, 0}));
    PU(u, Ls, Rs);
    return;
  }
  int Mid = Ls + Rs >> 1;
  if (l <= Mid) Del(u << 1, Ls, Mid, l, r, p);
  if (r > Mid) Del(u << 1 | 1, Mid + 1, Rs, l, r, p);
  PU(u, Ls, Rs);
}
int Query(int u, int Ls, int Rs) {
  if (!v[u].v || !v[u].p) return 0;
  if (v[u] == *S[u].begin()) {
    assert(S[u].size());
    pair t = *S[u].begin();
    S[u].erase(S[u].begin());
    t.v = 0;
    S[u].insert(t);
    PU(u, Ls, Rs);
    return t.p;
  }
  int Mid = Ls + Rs >> 1, p = 0;
  if (v[u] == v[u << 1] && v[u << 1].v)
    p = Query(u << 1, Ls, Mid);
  else
    p = Query(u << 1 | 1, Mid + 1, Rs);
  PU(u, Ls, Rs);
  return p;
}
int m = 0;
void Build(int u, int Ls, int Rs) {
  m = (u > m ? u : m);
  S[u].insert((pair){0, 1});
  v[u] = (pair){0, 1};
  if (Ls == Rs) return;
  int Mid = Ls + Rs >> 1;
  Build(u << 1, Ls, Mid);
  Build(u << 1 | 1, Mid + 1, Rs);
}
void main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i)
    scanf("%d %d %d %d", &a[i].x1, &a[i].y1, &a[i].x2, &a[i].y2);
  cnt = 0;
  for (Data *i = a + 1; i <= a + n; ++i) {
    s[++cnt] = &i->x1;
    s[++cnt] = &i->x2;
  }
  std::sort(s + 1, s + 1 + cnt, cmp);
  int last = *s[1] - 1, tot = 0;
  for (int i = 1; i <= cnt; ++i) {
    if (*s[i] != last) {
      last = *s[i];
      ++tot;
    }
    *s[i] = tot;
  }
  tot = cnt = 0;
  for (Data *i = a + 1; i <= a + n; ++i) {
    s[++cnt] = &i->y1;
    s[++cnt] = &i->y2;
  }
  std::sort(s + 1, s + 1 + cnt, cmp);
  last = *s[1] - 1;
  for (int i = 1; i <= cnt; ++i) {
    if (*s[i] != last) {
      last = *s[i];
      ++tot;
    }
    *s[i] = tot;
  }
  for (Data *i = a + 1; i <= a + n; ++i) --i->y2;
  for (Data *i = a + 1; i <= a + n; ++i) {
    I[i->x1].push_back(i - a);
    O[i->x2].push_back(i - a);
  }
  Build(1, 1, cnt);
  for (int i = 1; i <= cnt; ++i) {
    for (std::vector<int>::iterator j = O[i].begin(); j != O[i].end(); ++j)
      Del(1, 1, cnt, a[*j].y1, a[*j].y2, *j);
    for (std::vector<int>::iterator j = I[i].begin(); j != I[i].end(); ++j)
      Add(1, 1, cnt, a[*j].y1, a[*j].y2, *j);
    int p;
    while (p = Query(1, 1, cnt))
      if (!vis[p]) {
        ++Ans;
        vis[p] = 1;
      }
  }
  ++Ans;
  printf("%d\n", Ans);
}
}  // namespace Steaunk
int main() {
  Steaunk::main();
  return 0;
}
