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 (GCC 5.4.1) (judge verdict: Accepted)

#include <stdio.h>
#include <stdlib.h>

struct kugyu {
	int pos;
	int isOn;
	int idx;
};

int mareitaso(const void* x, const void* y) {
	struct kugyu a = *(const struct kugyu*)x, b = *(const struct kugyu*)y;
	if (a.pos != b.pos) return a.pos < b.pos ? -1 : 1;
	/* OFF → ON の順で並べる */
	if (a.isOn && !b.isOn) return 1;
	if (!a.isOn && b.isOn) return -1;
	return 0;
}

int N, M;
int a[114514], b[114514];

struct kugyu tomatu[271828];

int activeCount = 0;
int activeIndice[114514];
int isActive[114514];

int main(void) {
	int i;
	int count = 0;
	if (scanf("%d%d", &N, &M) != 2) return 1;
	for (i = 0; i < M; i++) {
		if (scanf("%d%d", &a[i], &b[i]) != 2) return 1;
	}
	for (i = 0; i < M; i++) {
		tomatu[i * 2].pos = a[i];
		tomatu[i * 2].isOn = 1;
		tomatu[i * 2].idx = i;
		tomatu[i * 2 + 1].pos = b[i];
		tomatu[i * 2 + 1].isOn = 0;
		tomatu[i * 2 + 1].idx = i;
	}
	qsort(tomatu, M * 2, sizeof(*tomatu), mareitaso);
	for (i = 0; i < M * 2; i++) {
		if (tomatu[i].isOn) {
			activeIndice[activeCount++] = tomatu[i].idx;
			isActive[tomatu[i].idx] = 1;
		} else {
			if (isActive[tomatu[i].idx]) {
				int j;
				count++;
				for (j = 0; j < activeCount; j++) {
					isActive[activeIndice[j]] = 0;
				}
				activeCount = 0;
			}
		}
	}
	printf("%d\n", count);
	return 0;
}

/*

溜めといて区間の右端で一気に落とす

*/