Problem:
Score : 400 points

Problem Statement

There are N islands lining up from west to east, connected by N-1 bridges.

The i-th bridge connects the i-th island from the west and the (i+1)-th island from the west.

One day, disputes took place between some islands, and there were M requests from the inhabitants of the islands:

Request i: A dispute took place between the a_i-th island from the west and the b_i-th island from the west. Please make traveling between these islands with bridges impossible.

You decided to remove some bridges to meet all these M requests.

Find the minimum number of bridges that must be removed.

Constraints

All values in input are integers.

2 \leq N \leq 10^5

1 \leq M \leq 10^5

1 \leq a_i < b_i \leq N

All pairs (a_i, b_i) are distinct.

Input

Input is given from Standard Input in the following format:

N M
a_1 b_1
a_2 b_2
:
a_M b_M

Output

Print the minimum number of bridges that must be removed.

Sample Input 1

5 2
1 4
2 5

Sample Output 1

1

The requests can be met by removing the bridge connecting the second and third islands from the west.

Sample Input 2

9 5
1 8
2 7
3 5
4 6
7 9

Sample Output 2

2

Sample Input 3

5 10
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5

Sample Output 3

4

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <algorithm>
#include <iostream>
#include <vector>
#include <utility>
#define rep(i,n) for(int (i)=0;(i)<(n);++(i))
#define all(x) (x).begin(),(x).end()
#define dump(x) cout << #x << " = " << (x) << endl

using namespace std;
using ll = long long;

struct UnionFind {
    int n;
    vector<int> parent;
    UnionFind(int _n=0): n(_n), parent(_n, -1) {}
    int root(int x) {
        if (parent[x] < 0) return x;
        return parent[x] = root(parent[x]);
    }
    bool connect(int x, int y) {
        x = root(x); y = root(y);
        if (x == y) return false;
        if (size(x) < size(y)) swap(x, y);
        parent[x] += parent[y];
        parent[y] = x;
        return true;
    }
    int group() {
        int res = 0;
        for (int i=0;i<n;++i) if (root(i) == i) res++;
        return res; 
    }
    bool same(int x, int y) { return root(x) == root(y); }
    int size(int x) { return -parent[root(x)]; }
};


int main() {
    int n, m; cin >> n >> m;
    UnionFind tree(n);

    vector<vector<int>> ab(n);
    rep(i, m) {
        int a, b; cin >> a >> b;
        a--;
        b--;
        ab[a].push_back(b);
        ab[b].push_back(a);
    }

    vector<int> bad_num;
    for (int i = 0; i < n - 1; ++i) {
        bool broken = false;
        for (int e: ab[i]) {
            bad_num.push_back(e);
        }
        for (auto e: bad_num) {
            if ((i + 1) == e) {
                broken = true;
                break;
            }
        }
        if (broken) {
            bad_num = {};
            continue;
        }
        tree.connect(i, i + 1);
    }

    cout << (tree.group() - 1) << endl;
}