Arkady has got an infinite plane painted in color 0. Then he draws n rectangles filled with paint with sides parallel to the Cartesian coordinate axes, one after another. The color of the i-th rectangle is i (rectangles are enumerated from 1 to n in the order he draws them). It is possible that new rectangles cover some of the previous ones completely or partially.

Count the number of different colors on the plane after Arkady draws all the rectangles.

Input

The first line contains a single integer n (1 ≤ n ≤ 100 000) — the number of rectangles.

The i-th of the next n lines contains 4 integers x_1, y_1, x_2 and y_2 (-10^9 ≤ x_1 < x_2 ≤ 10^9, -10^9 ≤ y_1 < y_2 ≤ 10^9) — the coordinates of corners of the i-th rectangle.

Output

In the single line print the number of different colors in the plane, including color 0.

Examples

Input

5
-1 -1 1 1
-4 0 0 4
0 0 4 4
-4 -4 0 0
0 -4 4 0


Output

5

Input

4
0 0 4 4
-4 -4 0 0
0 -4 4 0
-2 -4 2 4


Output

5

Note

<image> That's how the plane looks in the first sample

<image> That's how the plane looks in the second sample

0 = white, 1 = cyan, 2 = blue, 3 = purple, 4 = yellow, 5 = red. 
#include <bits/stdc++.h>
using namespace std;
const int MAX = 210000;
const int INF = 1000000000;
const int MOD = 1000000007;
const int MX = 700;
unsigned long long mod(unsigned long long a, unsigned long long b,
                       unsigned long long m) {
  unsigned long long ret = 1;
  a %= m;
  while (b) {
    if (b & 1) ret = ret * a % m;
    b >>= 1;
    a = a * a % m;
  }
  return ret;
}
unsigned long long inv(unsigned long long a) { return mod(a, MOD - 2, MOD); }
unsigned long long vabs(unsigned long long x) { return x > 0 ? x : -x; }
unsigned long long gcd(unsigned long long a, unsigned long long b) {
  return a % b ? gcd(b, a % b) : b;
}
int cross(pair<int, int> a, pair<int, int> b) {
  return a.first * b.second - a.second * b.first;
}
int dir[4][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
int dblcmp(double x) {
  if (fabs(x) < 1e-8) return 0;
  return x < 0 ? -1 : 1;
}
struct Event {
  int x, l, r, id;
  Event() {}
  Event(int x_, int l_, int r_, int id_) {
    x = x_;
    l = l_;
    r = r_;
    id = id_;
  }
} e[MAX];
int dcre[MAX];
bool cmp(Event a, Event b) { return a.x < b.x; }
struct Tree {
  int l, r;
  int max, min;
  set<int> c;
  int mid() { return l + r >> 1; }
} node[MAX << 2];
void build(int l, int r, int tag) {
  node[tag].c.clear();
  node[tag].l = l;
  node[tag].r = r;
  node[tag].max = -1;
  node[tag].min = -1;
  int mid = node[tag].mid();
  if (l + 1 == r) return;
  build(l, mid, (tag << 1));
  build(mid, r, ((tag << 1) | 1));
}
bool vis[MAX];
void update(int tag) {
  int c;
  if (node[tag].l + 1 == node[tag].r) {
    if (node[tag].c.empty()) {
      node[tag].max = node[tag].min = -1;
    } else {
      c = -*(node[tag].c.begin());
      node[tag].min = c;
      if (vis[c]) {
        node[tag].max = -1;
      } else {
        node[tag].max = c;
      }
    }
    return;
  }
  if (node[tag].c.empty()) {
    node[tag].max = max(node[(tag << 1)].max, node[((tag << 1) | 1)].max);
    node[tag].min = min(node[(tag << 1)].min, node[((tag << 1) | 1)].min);
  } else {
    c = -*(node[tag].c.begin());
    if (c > max(node[(tag << 1)].max, node[((tag << 1) | 1)].max)) {
      if (c < min(node[(tag << 1)].min, node[((tag << 1) | 1)].min)) {
        node[tag].max = -1;
      } else {
        if (!vis[c]) {
          node[tag].max = c;
        } else {
          node[tag].max = -1;
        }
      }
    } else {
      node[tag].max = max(node[(tag << 1)].max, node[((tag << 1) | 1)].max);
    }
    node[tag].min =
        max(c, min(node[(tag << 1)].min, node[((tag << 1) | 1)].min));
  }
}
void ins(int l, int r, int id, int tag) {
  if (l <= node[tag].l && node[tag].r <= r) {
    if (id > 0) {
      node[tag].c.insert(-id);
    } else {
      node[tag].c.erase(id);
    }
    update(tag);
    return;
  }
  int mid = node[tag].mid();
  if (r <= mid)
    ins(l, r, id, (tag << 1));
  else if (l >= mid)
    ins(l, r, id, ((tag << 1) | 1));
  else {
    ins(l, mid, id, (tag << 1));
    ins(mid, r, id, ((tag << 1) | 1));
  }
  update(tag);
}
int L[MAX], R[MAX];
void makeTag(int l, int r, int id, int tag) {
  if (l <= node[tag].l && node[tag].r <= r) {
    update(tag);
    return;
  }
  int mid = node[tag].mid();
  if (r <= mid)
    makeTag(l, r, id, (tag << 1));
  else if (l >= mid)
    makeTag(l, r, id, ((tag << 1) | 1));
  else {
    makeTag(l, mid, id, (tag << 1));
    makeTag(mid, r, id, ((tag << 1) | 1));
  }
  update(tag);
}
int main() {
  int i, j;
  int T = 0;
  int n = 1, m;
  cin >> n;
  int c = 2 * n;
  for (i = 0; i < n; i++) {
    int x1, y1, x2, y2;
    scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
    dcre[i] = y1;
    dcre[i + n] = y2;
    e[i] = Event(x1, y1, y2, i + 1);
    e[i + n] = Event(x2, y1, y2, -i - 1);
    vis[i] = false;
  }
  vis[i] = false;
  sort(dcre, dcre + c);
  c = unique(dcre, dcre + c) - dcre;
  sort(e, e + 2 * n, cmp);
  j = 0;
  build(0, c, 1);
  for (i = 0; i < 2 * n; i++) {
  }
  for (i = 0; i < c; i++) {
  }
  for (i = 0; i < 2 * n; i++) {
    j = i;
    while (j < 2 * n && e[j].x == e[i].x) {
      int idx = e[j].id;
      if (idx < 0) idx = -idx;
      ins(L[idx] = lower_bound(dcre, dcre + c, e[j].l) - dcre,
          R[idx] = lower_bound(dcre, dcre + c, e[j].r) - dcre, e[j].id, 1);
      j++;
    }
    i = j - 1;
    while (node[1].max != -1) {
      vis[node[1].max] = true;
      int idx = node[1].max;
      makeTag(L[idx], R[idx], idx, 1);
    }
  }
  int ans = 0;
  for (i = 0; i <= n; i++) {
    ans += vis[i];
  }
  cout << ans + 1 << endl;
  return 0;
}
