#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
template <class T>
using pq = priority_queue<T>;
template <class T>
using pqg = priority_queue<T, vector<T>, greater<T>>;
int scan() { return getchar(); }
void scan(int &a) { cin >> a; }
void scan(long long &a) { cin >> a; }
void scan(char &a) { cin >> a; }
void scan(double &a) { cin >> a; }
void scan(long double &a) { cin >> a; }
void scan(char a[]) { scanf("%s", a); }
void scan(string &a) { cin >> a; }
template <class T>
void scan(vector<T> &);
template <class T, size_t size>
void scan(array<T, size> &);
template <class T, class L>
void scan(pair<T, L> &);
template <class T, size_t size>
void scan(T (&)[size]);
template <class T>
void scan(vector<T> &a) {
  for (auto &i : a) scan(i);
}
template <class T>
void scan(deque<T> &a) {
  for (auto &i : a) scan(i);
}
template <class T, size_t size>
void scan(array<T, size> &a) {
  for (auto &i : a) scan(i);
}
template <class T, class L>
void scan(pair<T, L> &p) {
  scan(p.first);
  scan(p.second);
}
template <class T, size_t size>
void scan(T (&a)[size]) {
  for (auto &i : a) scan(i);
}
template <class T>
void scan(T &a) {
  cin >> a;
}
void IN() {}
template <class Head, class... Tail>
void IN(Head &head, Tail &...tail) {
  scan(head);
  IN(tail...);
}
string stin() {
  string s;
  cin >> s;
  return s;
}
template <class T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
vector<int> iota(int n) {
  vector<int> a(n);
  iota(begin(a), end(a), 0);
  return a;
}
template <class T>
void UNIQUE(vector<T> &x) {
  sort(begin(x), end(x));
  x.erase(unique(begin(x), end(x)), x.end());
}
int in() {
  int x;
  cin >> x;
  return x;
}
long long lin() {
  unsigned long long x;
  cin >> x;
  return x;
}
void print() { putchar(' '); }
void print(bool a) { cout << a; }
void print(int a) { cout << a; }
void print(long long a) { cout << a; }
void print(char a) { cout << a; }
void print(string &a) { cout << a; }
void print(double a) { cout << a; }
template <class T>
void print(const vector<T> &);
template <class T, size_t size>
void print(const array<T, size> &);
template <class T, class L>
void print(const pair<T, L> &p);
template <class T, size_t size>
void print(const T (&)[size]);
template <class T>
void print(const vector<T> &a) {
  if (a.empty()) return;
  print(a[0]);
  for (auto i = a.begin(); ++i != a.end();) {
    cout << " ";
    print(*i);
  }
  cout << endl;
}
template <class T>
void print(const deque<T> &a) {
  if (a.empty()) return;
  print(a[0]);
  for (auto i = a.begin(); ++i != a.end();) {
    cout << " ";
    print(*i);
  }
}
template <class T, size_t size>
void print(const array<T, size> &a) {
  print(a[0]);
  for (auto i = a.begin(); ++i != a.end();) {
    cout << " ";
    print(*i);
  }
}
template <class T, class L>
void print(const pair<T, L> &p) {
  cout << '(';
  print(p.first);
  cout << ",";
  print(p.second);
  cout << ')';
}
template <class T>
void print(set<T> &x) {
  for (auto e : x) print(e), cout << " ";
  cout << endl;
}
template <class T, size_t size>
void print(const T (&a)[size]) {
  print(a[0]);
  for (auto i = a; ++i != end(a);) {
    cout << " ";
    print(*i);
  }
}
template <class T>
void print(const T &a) {
  cout << a;
}
int out() {
  putchar('\n');
  return 0;
}
template <class T>
int out(const T &t) {
  print(t);
  putchar('\n');
  return 0;
}
template <class Head, class... Tail>
int out(const Head &head, const Tail &...tail) {
  print(head);
  putchar(' ');
  out(tail...);
  return 0;
}
long long gcd(long long a, long long b) {
  while (b) {
    long long c = b;
    b = a % b;
    a = c;
  }
  return a;
}
long long lcm(long long a, long long b) {
  if (!a || !b) return 0;
  return a * b / gcd(a, b);
}
vector<pair<long long, long long>> factor(long long x) {
  vector<pair<long long, long long>> ans;
  for (long long i = 2; i * i <= x; i++)
    if (x % i == 0) {
      ans.push_back({i, 1});
      while ((x /= i) % i == 0) ans.back().second++;
    }
  if (x != 1) ans.push_back({x, 1});
  return ans;
}
vector<int> divisor(int x) {
  vector<int> ans;
  for (int i = 1; i * i <= x; i++)
    if (x % i == 0) {
      ans.push_back(i);
      if (i * i != x) ans.push_back(x / i);
    }
  return ans;
}
int popcount(long long x) { return __builtin_popcountll(x); }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int n) { return uniform_int_distribution<int>(0, n - 1)(rng); }
template <class... T>
void err(const T &...) {}
template <class Monoid, class OperatorMonoid = Monoid>
struct RandomizedBinarySearchTree {
  using F = function<Monoid(Monoid, Monoid)>;
  using G = function<Monoid(Monoid, OperatorMonoid)>;
  using H = function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;
  using P = function<OperatorMonoid(OperatorMonoid, int)>;
  inline int xor128() {
    static int x = 123456789;
    static int y = 362436069;
    static int z = 521288629;
    static int w = 88675123;
    int t;
    t = x ^ (x << 11);
    x = y;
    y = z;
    z = w;
    return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
  }
  struct Node {
    Node *l, *r;
    int cnt;
    Monoid key, sum;
    OperatorMonoid lazy;
    Node() = default;
    Node(const Monoid &k, const OperatorMonoid &p)
        : cnt(1), key(k), sum(k), lazy(p), l(nullptr), r(nullptr) {}
  };
  vector<Node> pool;
  int ptr;
  const Monoid M1;
  const OperatorMonoid OM0;
  const F f;
  const G g;
  const H h;
  const P p;
  RandomizedBinarySearchTree(int sz, const F &f, const Monoid &M1)
      : pool(sz),
        ptr(0),
        f(f),
        g(G()),
        h(H()),
        p(P()),
        M1(M1),
        OM0(OperatorMonoid()) {}
  RandomizedBinarySearchTree(int sz, const F &f, const G &g, const H &h,
                             const P &p, const Monoid &M1,
                             const OperatorMonoid &OM0)
      : pool(sz), ptr(0), f(f), g(g), h(h), p(p), M1(M1), OM0(OM0) {}
  inline Node *alloc(const Monoid &key) {
    return &(pool[ptr++] = Node(key, OM0));
  }
  virtual Node *clone(Node *t) { return t; }
  inline int count(const Node *t) { return t ? t->cnt : 0; }
  inline Monoid sum(const Node *t) { return t ? t->sum : M1; }
  inline Node *update(Node *t) {
    t->cnt = count(t->l) + count(t->r) + 1;
    t->sum = f(f(sum(t->l), t->key), sum(t->r));
    return t;
  }
  Node *propagate(Node *t) {
    t = clone(t);
    if (t->lazy != OM0) {
      t->key = g(t->key, p(t->lazy, 1));
      if (t->l) {
        t->l = clone(t->l);
        t->l->lazy = h(t->l->lazy, t->lazy);
        t->l->sum = g(t->l->sum, p(t->lazy, count(t->l)));
      }
      if (t->r) {
        t->r = clone(t->r);
        t->r->lazy = h(t->r->lazy, t->lazy);
        t->r->sum = g(t->r->sum, p(t->lazy, count(t->r)));
      }
      t->lazy = OM0;
    }
    return update(t);
  }
  Node *merge(Node *l, Node *r) {
    if (!l || !r) return l ? l : r;
    if (xor128() % (l->cnt + r->cnt) < l->cnt) {
      l = propagate(l);
      l->r = merge(l->r, r);
      return update(l);
    } else {
      r = propagate(r);
      r->l = merge(l, r->l);
      return update(r);
    }
  }
  pair<Node *, Node *> split(Node *t, int k) {
    if (!t) return {t, t};
    t = propagate(t);
    if (k <= count(t->l)) {
      auto s = split(t->l, k);
      t->l = s.second;
      return {s.first, update(t)};
    } else {
      auto s = split(t->r, k - count(t->l) - 1);
      t->r = s.first;
      return {update(t), s.second};
    }
  }
  Node *build(int l, int r, const vector<Monoid> &v) {
    if (l + 1 >= r) return alloc(v[l]);
    return merge(build(l, (l + r) >> 1, v), build((l + r) >> 1, r, v));
  }
  Node *build(const vector<Monoid> &v) {
    ptr = 0;
    return build(0, (int)v.size(), v);
  }
  void dump(Node *r, typename vector<Monoid>::iterator &it) {
    if (!r) return;
    r = propagate(r);
    dump(r->l, it);
    *it = r->key;
    dump(r->r, ++it);
  }
  vector<Monoid> dump(Node *r) {
    vector<Monoid> v((size_t)count(r));
    auto it = begin(v);
    dump(r, it);
    return v;
  }
  string to_string(Node *r) {
    auto s = dump(r);
    string ret;
    for (int i = 0; i < s.size(); i++) ret += ", ";
    return (ret);
  }
  void insert(Node *&t, int k, const Monoid &v) {
    auto x = split(t, k);
    t = merge(merge(x.first, alloc(v)), x.second);
  }
  void erase(Node *&t, int k) {
    auto x = split(t, k);
    t = merge(x.first, split(x.second, 1).second);
  }
  Monoid query(Node *&t, int a, int b) {
    auto x = split(t, a);
    auto y = split(x.second, b - a);
    auto ret = sum(y.first);
    t = merge(x.first, merge(y.first, y.second));
    return ret;
  }
  void set_propagate(Node *&t, int a, int b, const OperatorMonoid &p) {
    if (b <= a) return;
    auto x = split(t, a);
    auto y = split(x.second, b - a);
    y.first->lazy = h(y.first->lazy, p);
    t = merge(x.first, merge(propagate(y.first), y.second));
  }
  void set_element(Node *&t, int k, const Monoid &x) {
    t = propagate(t);
    if (k < count(t->l))
      set_element(t->l, k, x);
    else if (k == count(t->l))
      t->key = t->sum = x;
    else
      set_element(t->r, k - count(t->l) - 1, x);
    t = update(t);
  }
  int size(Node *t) { return count(t); }
  bool empty(Node *t) { return !t; }
  Node *makeset() { return nullptr; }
  int lower_bound(Node *t, const Monoid &x) {
    if (!t) return 0;
    t = propagate(t);
    if (x <= t->key) return lower_bound(t->l, x);
    return lower_bound(t->r, x) + count(t->l) + 1;
  }
  pair<int, Monoid> lower_bound_with_value(Node *t, const Monoid &x) {
    if (!t) return {0, M1};
    t = propagate(t);
    if (x <= t->key) {
      auto res = lower_bound_with_value(t->l, x);
      if (t->key <= x) return {res.first, f(res.second, t->key)};
      return res;
    }
    auto res = lower_bound_with_value(t->r, x);
    res.first += count(t->l) + 1;
    return {res.first, f(res.second, t->key)};
  }
  Monoid kth(Node *t, int n) {
    t = propagate(t);
    if (!t) return M1;
    if (n <= count(t->l)) return kth(t->l, n);
    if (n == count(t->l) + 1) return t->key;
    return kth(t->r, n - count(t->l) - 1);
  }
};
signed main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cout << fixed << setprecision(15);
  int n;
  IN(n);
  auto f = [](int x, int y) { return max(x, y); };
  auto p = [](int x, int y) { return x; };
  const int N = 1e6;
  RandomizedBinarySearchTree<int> tree(N, f, plus<int>(), plus<int>(), p, 0, 0);
  RandomizedBinarySearchTree<int>::Node *root = nullptr;
  tree.insert(root, 0, 0);
  for (long long i = 0; i < n; ++i) {
    int l = in(), r = in();
    int a = tree.lower_bound(root, l), b = tree.lower_bound(root, r);
    tree.set_propagate(root, a, b, 1);
    tree.erase(root, b);
    tree.insert(root, a, l);
  }
  cout << tree.count(root) - 1 << '\n';
}

### Prompt

Construct a cpp code solution to the problem outlined:

Leha and Noora decided to go on a trip in the Baltic States. As you know from the previous problem, Leha has lost his car on the parking of the restaurant. Unfortunately, requests to the watchman didn't helped hacker find the car, so friends decided to go hitchhiking.

In total, they intended to visit n towns. However it turned out that sights in i-th town are open for visitors only on days from li to ri.

What to do? Leha proposed to choose for each town i a day, when they will visit this town, i.e any integer xi in interval [li, ri]. After that Noora choses some subsequence of towns id1, id2, ..., idk, which friends are going to visit, that at first they are strictly increasing, i.e idi < idi + 1 is for all integers i from 1 to k - 1, but also the dates of the friends visits are strictly increasing, i.e xidi < xidi + 1 is true for all integers i from 1 to k - 1.

Please help Leha and Noora in choosing such xi for each town i, and such subsequence of towns id1, id2, ..., idk, so that friends can visit maximal number of towns.

You may assume, that Leha and Noora can start the trip any day.

Input

The first line contains a single integer n (1 ≤ n ≤ 3·105) denoting the number of towns Leha and Noora intended to visit.

Each line i of the n subsequent lines contains two integers li, ri (1 ≤ li ≤ ri ≤ 109), denoting that sights in i-th town are open for visitors on any day <image>.

Output

Print a single integer denoting the maximal number of towns, that Leha and Noora can visit.

Example

Input

5
6 6
1 2
3 4
2 2
1 4


Output

3

Note

Consider the first example.

Let's take this plan: let's visit the sight in the second town on the first day, in the third town on the third day and in the fifth town on the fourth. That's would be the optimal answer.

### Response

```cpp
#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
template <class T>
using pq = priority_queue<T>;
template <class T>
using pqg = priority_queue<T, vector<T>, greater<T>>;
int scan() { return getchar(); }
void scan(int &a) { cin >> a; }
void scan(long long &a) { cin >> a; }
void scan(char &a) { cin >> a; }
void scan(double &a) { cin >> a; }
void scan(long double &a) { cin >> a; }
void scan(char a[]) { scanf("%s", a); }
void scan(string &a) { cin >> a; }
template <class T>
void scan(vector<T> &);
template <class T, size_t size>
void scan(array<T, size> &);
template <class T, class L>
void scan(pair<T, L> &);
template <class T, size_t size>
void scan(T (&)[size]);
template <class T>
void scan(vector<T> &a) {
  for (auto &i : a) scan(i);
}
template <class T>
void scan(deque<T> &a) {
  for (auto &i : a) scan(i);
}
template <class T, size_t size>
void scan(array<T, size> &a) {
  for (auto &i : a) scan(i);
}
template <class T, class L>
void scan(pair<T, L> &p) {
  scan(p.first);
  scan(p.second);
}
template <class T, size_t size>
void scan(T (&a)[size]) {
  for (auto &i : a) scan(i);
}
template <class T>
void scan(T &a) {
  cin >> a;
}
void IN() {}
template <class Head, class... Tail>
void IN(Head &head, Tail &...tail) {
  scan(head);
  IN(tail...);
}
string stin() {
  string s;
  cin >> s;
  return s;
}
template <class T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
vector<int> iota(int n) {
  vector<int> a(n);
  iota(begin(a), end(a), 0);
  return a;
}
template <class T>
void UNIQUE(vector<T> &x) {
  sort(begin(x), end(x));
  x.erase(unique(begin(x), end(x)), x.end());
}
int in() {
  int x;
  cin >> x;
  return x;
}
long long lin() {
  unsigned long long x;
  cin >> x;
  return x;
}
void print() { putchar(' '); }
void print(bool a) { cout << a; }
void print(int a) { cout << a; }
void print(long long a) { cout << a; }
void print(char a) { cout << a; }
void print(string &a) { cout << a; }
void print(double a) { cout << a; }
template <class T>
void print(const vector<T> &);
template <class T, size_t size>
void print(const array<T, size> &);
template <class T, class L>
void print(const pair<T, L> &p);
template <class T, size_t size>
void print(const T (&)[size]);
template <class T>
void print(const vector<T> &a) {
  if (a.empty()) return;
  print(a[0]);
  for (auto i = a.begin(); ++i != a.end();) {
    cout << " ";
    print(*i);
  }
  cout << endl;
}
template <class T>
void print(const deque<T> &a) {
  if (a.empty()) return;
  print(a[0]);
  for (auto i = a.begin(); ++i != a.end();) {
    cout << " ";
    print(*i);
  }
}
template <class T, size_t size>
void print(const array<T, size> &a) {
  print(a[0]);
  for (auto i = a.begin(); ++i != a.end();) {
    cout << " ";
    print(*i);
  }
}
template <class T, class L>
void print(const pair<T, L> &p) {
  cout << '(';
  print(p.first);
  cout << ",";
  print(p.second);
  cout << ')';
}
template <class T>
void print(set<T> &x) {
  for (auto e : x) print(e), cout << " ";
  cout << endl;
}
template <class T, size_t size>
void print(const T (&a)[size]) {
  print(a[0]);
  for (auto i = a; ++i != end(a);) {
    cout << " ";
    print(*i);
  }
}
template <class T>
void print(const T &a) {
  cout << a;
}
int out() {
  putchar('\n');
  return 0;
}
template <class T>
int out(const T &t) {
  print(t);
  putchar('\n');
  return 0;
}
template <class Head, class... Tail>
int out(const Head &head, const Tail &...tail) {
  print(head);
  putchar(' ');
  out(tail...);
  return 0;
}
long long gcd(long long a, long long b) {
  while (b) {
    long long c = b;
    b = a % b;
    a = c;
  }
  return a;
}
long long lcm(long long a, long long b) {
  if (!a || !b) return 0;
  return a * b / gcd(a, b);
}
vector<pair<long long, long long>> factor(long long x) {
  vector<pair<long long, long long>> ans;
  for (long long i = 2; i * i <= x; i++)
    if (x % i == 0) {
      ans.push_back({i, 1});
      while ((x /= i) % i == 0) ans.back().second++;
    }
  if (x != 1) ans.push_back({x, 1});
  return ans;
}
vector<int> divisor(int x) {
  vector<int> ans;
  for (int i = 1; i * i <= x; i++)
    if (x % i == 0) {
      ans.push_back(i);
      if (i * i != x) ans.push_back(x / i);
    }
  return ans;
}
int popcount(long long x) { return __builtin_popcountll(x); }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int n) { return uniform_int_distribution<int>(0, n - 1)(rng); }
template <class... T>
void err(const T &...) {}
template <class Monoid, class OperatorMonoid = Monoid>
struct RandomizedBinarySearchTree {
  using F = function<Monoid(Monoid, Monoid)>;
  using G = function<Monoid(Monoid, OperatorMonoid)>;
  using H = function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;
  using P = function<OperatorMonoid(OperatorMonoid, int)>;
  inline int xor128() {
    static int x = 123456789;
    static int y = 362436069;
    static int z = 521288629;
    static int w = 88675123;
    int t;
    t = x ^ (x << 11);
    x = y;
    y = z;
    z = w;
    return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
  }
  struct Node {
    Node *l, *r;
    int cnt;
    Monoid key, sum;
    OperatorMonoid lazy;
    Node() = default;
    Node(const Monoid &k, const OperatorMonoid &p)
        : cnt(1), key(k), sum(k), lazy(p), l(nullptr), r(nullptr) {}
  };
  vector<Node> pool;
  int ptr;
  const Monoid M1;
  const OperatorMonoid OM0;
  const F f;
  const G g;
  const H h;
  const P p;
  RandomizedBinarySearchTree(int sz, const F &f, const Monoid &M1)
      : pool(sz),
        ptr(0),
        f(f),
        g(G()),
        h(H()),
        p(P()),
        M1(M1),
        OM0(OperatorMonoid()) {}
  RandomizedBinarySearchTree(int sz, const F &f, const G &g, const H &h,
                             const P &p, const Monoid &M1,
                             const OperatorMonoid &OM0)
      : pool(sz), ptr(0), f(f), g(g), h(h), p(p), M1(M1), OM0(OM0) {}
  inline Node *alloc(const Monoid &key) {
    return &(pool[ptr++] = Node(key, OM0));
  }
  virtual Node *clone(Node *t) { return t; }
  inline int count(const Node *t) { return t ? t->cnt : 0; }
  inline Monoid sum(const Node *t) { return t ? t->sum : M1; }
  inline Node *update(Node *t) {
    t->cnt = count(t->l) + count(t->r) + 1;
    t->sum = f(f(sum(t->l), t->key), sum(t->r));
    return t;
  }
  Node *propagate(Node *t) {
    t = clone(t);
    if (t->lazy != OM0) {
      t->key = g(t->key, p(t->lazy, 1));
      if (t->l) {
        t->l = clone(t->l);
        t->l->lazy = h(t->l->lazy, t->lazy);
        t->l->sum = g(t->l->sum, p(t->lazy, count(t->l)));
      }
      if (t->r) {
        t->r = clone(t->r);
        t->r->lazy = h(t->r->lazy, t->lazy);
        t->r->sum = g(t->r->sum, p(t->lazy, count(t->r)));
      }
      t->lazy = OM0;
    }
    return update(t);
  }
  Node *merge(Node *l, Node *r) {
    if (!l || !r) return l ? l : r;
    if (xor128() % (l->cnt + r->cnt) < l->cnt) {
      l = propagate(l);
      l->r = merge(l->r, r);
      return update(l);
    } else {
      r = propagate(r);
      r->l = merge(l, r->l);
      return update(r);
    }
  }
  pair<Node *, Node *> split(Node *t, int k) {
    if (!t) return {t, t};
    t = propagate(t);
    if (k <= count(t->l)) {
      auto s = split(t->l, k);
      t->l = s.second;
      return {s.first, update(t)};
    } else {
      auto s = split(t->r, k - count(t->l) - 1);
      t->r = s.first;
      return {update(t), s.second};
    }
  }
  Node *build(int l, int r, const vector<Monoid> &v) {
    if (l + 1 >= r) return alloc(v[l]);
    return merge(build(l, (l + r) >> 1, v), build((l + r) >> 1, r, v));
  }
  Node *build(const vector<Monoid> &v) {
    ptr = 0;
    return build(0, (int)v.size(), v);
  }
  void dump(Node *r, typename vector<Monoid>::iterator &it) {
    if (!r) return;
    r = propagate(r);
    dump(r->l, it);
    *it = r->key;
    dump(r->r, ++it);
  }
  vector<Monoid> dump(Node *r) {
    vector<Monoid> v((size_t)count(r));
    auto it = begin(v);
    dump(r, it);
    return v;
  }
  string to_string(Node *r) {
    auto s = dump(r);
    string ret;
    for (int i = 0; i < s.size(); i++) ret += ", ";
    return (ret);
  }
  void insert(Node *&t, int k, const Monoid &v) {
    auto x = split(t, k);
    t = merge(merge(x.first, alloc(v)), x.second);
  }
  void erase(Node *&t, int k) {
    auto x = split(t, k);
    t = merge(x.first, split(x.second, 1).second);
  }
  Monoid query(Node *&t, int a, int b) {
    auto x = split(t, a);
    auto y = split(x.second, b - a);
    auto ret = sum(y.first);
    t = merge(x.first, merge(y.first, y.second));
    return ret;
  }
  void set_propagate(Node *&t, int a, int b, const OperatorMonoid &p) {
    if (b <= a) return;
    auto x = split(t, a);
    auto y = split(x.second, b - a);
    y.first->lazy = h(y.first->lazy, p);
    t = merge(x.first, merge(propagate(y.first), y.second));
  }
  void set_element(Node *&t, int k, const Monoid &x) {
    t = propagate(t);
    if (k < count(t->l))
      set_element(t->l, k, x);
    else if (k == count(t->l))
      t->key = t->sum = x;
    else
      set_element(t->r, k - count(t->l) - 1, x);
    t = update(t);
  }
  int size(Node *t) { return count(t); }
  bool empty(Node *t) { return !t; }
  Node *makeset() { return nullptr; }
  int lower_bound(Node *t, const Monoid &x) {
    if (!t) return 0;
    t = propagate(t);
    if (x <= t->key) return lower_bound(t->l, x);
    return lower_bound(t->r, x) + count(t->l) + 1;
  }
  pair<int, Monoid> lower_bound_with_value(Node *t, const Monoid &x) {
    if (!t) return {0, M1};
    t = propagate(t);
    if (x <= t->key) {
      auto res = lower_bound_with_value(t->l, x);
      if (t->key <= x) return {res.first, f(res.second, t->key)};
      return res;
    }
    auto res = lower_bound_with_value(t->r, x);
    res.first += count(t->l) + 1;
    return {res.first, f(res.second, t->key)};
  }
  Monoid kth(Node *t, int n) {
    t = propagate(t);
    if (!t) return M1;
    if (n <= count(t->l)) return kth(t->l, n);
    if (n == count(t->l) + 1) return t->key;
    return kth(t->r, n - count(t->l) - 1);
  }
};
signed main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cout << fixed << setprecision(15);
  int n;
  IN(n);
  auto f = [](int x, int y) { return max(x, y); };
  auto p = [](int x, int y) { return x; };
  const int N = 1e6;
  RandomizedBinarySearchTree<int> tree(N, f, plus<int>(), plus<int>(), p, 0, 0);
  RandomizedBinarySearchTree<int>::Node *root = nullptr;
  tree.insert(root, 0, 0);
  for (long long i = 0; i < n; ++i) {
    int l = in(), r = in();
    int a = tree.lower_bound(root, l), b = tree.lower_bound(root, r);
    tree.set_propagate(root, a, b, 1);
    tree.erase(root, b);
    tree.insert(root, a, l);
  }
  cout << tree.count(root) - 1 << '\n';
}

```