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# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Practice
{
    class Program
    {
        private static int ReadAndParseInt()
        {
            return int.Parse(Console.ReadLine());
        }
        private static int[] ReadAndParseIntArr()
        {
            return Array.ConvertAll(Console.ReadLine().Split(' '), int.Parse);
        }
        private static long ReadAndParseLong()
        {
            return long.Parse(Console.ReadLine());
        }
        private static long[] ReadAndParseLongArr()
        {
            return Array.ConvertAll(Console.ReadLine().Split(' '), long.Parse);
        }
        static void Main(string[] args)
        {
            //SolveA(args);
            //SolveB(args);
            //SolveC(args);
            SolveD(args);


        }
        private static void SolveA(string[] args)
        {
            int[] a = ReadAndParseIntArr();
            List<int> cost = new List<int>();
            cost.Add(CalcCost(a[0], a[1], a[2]));
            cost.Add(CalcCost(a[0], a[2], a[1]));
            cost.Add(CalcCost(a[1], a[0], a[2]));
            cost.Add(CalcCost(a[1], a[2], a[0]));
            cost.Add(CalcCost(a[2], a[0], a[1]));
            cost.Add(CalcCost(a[2], a[1], a[0]));

            Console.WriteLine(cost.Min());
        }
        private static int CalcCost(int a, int b, int c)
        {
            int cost = Math.Abs(b - a);
            cost += Math.Abs(c - b);
            return cost;
        }

        private static void SolveB(string[] args)
        {
            string s = Console.ReadLine();
            string t = Console.ReadLine();

            for(int i=0;i<s.Length;++i)
            {
                bool match = true;
                for(int j=0;j<s.Length;++j)
                {
                    int idx = (i + j) % s.Length;
                    if( s[j] != t[idx])
                    {
                        match = false;
                        break;
                    }
                }
                if(match)
                {
                    Console.WriteLine("Yes");
                    return;
                }
            }
            Console.WriteLine("No");
        }
        private static void SolveC(string[] args)
        {
            int n = ReadAndParseInt();
            int[] a = ReadAndParseIntArr();

            int val = a.Sum() - a.Length;
            Console.WriteLine(val);
        }
        private static int Func(int [] a, int m)
        {
            int val = 0;
            for(int i=0;i<a.Length;++i)
            {
                val += m % a[i];
            }
            return val;
        }
        private struct Pair
        {
            public int a;
            public int b;
        }
        private static void SolveD(string[] args)
        {
            int[] nm = ReadAndParseIntArr();
            int n = nm[0];
            int m = nm[1];
            List<Pair> ab = new List<Practice.Program.Pair>();
            for(int i=0;i<m;++i)
            {
                int[] tmp = ReadAndParseIntArr();
                ab.Add( new Pair() { a = tmp[0], b = tmp[1] });
            }

            ab.Sort((a, b) => a.b.CompareTo(b.b));
            int brokenBridgeTotal = 0;
            int lastBrokenBridge = 0;
            for(int i=0;i<ab.Count;++i)
            {
                if (ab[i].a <= lastBrokenBridge && lastBrokenBridge < ab[i].b)
                {

                }
                else
                {
                    lastBrokenBridge = ab[i].b - 1;
                    brokenBridgeTotal++;
                }
            }

            Console.WriteLine(brokenBridgeTotal);
        }
#if false
        public struct Node
        {
            public int loc;
            public int l;
            public int r;
        }
        public struct Point
        {
            public int v;
            public int x;
            public int y;
        }
        static int s_np;
        static List<Point> s_P = new List<Point>();
        static List<Node> s_T = new List<Node>();
        static void SolveB(string[] args)
        {
            int n = ReadAndParseInt();
            //int[][] xy = new int[n][];
            for (int i = 0; i < n; ++i)
            {
                int[] xy = ReadAndParseIntArr();
                s_P.Add(new Point() { v = i, x = xy[0], y = xy[1] });
                s_T.Add(new Node() { l = -1, r = -1});// dummy
            }
            int root = Make2DTree(0, n, 0);


            int q = ReadAndParseInt();
            //int[][] st = new int[q][];
            List<int> ans = new List<int>();
            for (int i = 0; i < q; ++i)
            {
                int[] st = ReadAndParseIntArr();
                ans.Clear();
                    Find(root, st[0], st[1], st[2], st[3], 0, ans);
                ans.Sort();
                for(int j =0;j<ans.Count;++j)
                {
                    Console.WriteLine(ans[j]);
                }
                Console.WriteLine();
            }

        }
        static List<Point> s_tmpList = new List<Point>();
        private static int Make2DTree(int l, int r, int depth)
        {
            if (!(l < r))
            {
                return -1;
            }
            int mid = (l + r) / 2;
            int t = s_np;
            s_np++;

            s_tmpList.Clear();
            for (int i = l; i < l - r; ++i)
            {
                s_tmpList.Add(s_P[i]);
            }
            if (depth % 2 == 0)
            {
                s_tmpList.Sort(SortFuncByX);
            }
            else
            {
                s_tmpList.Sort(SortFuncByY);
            }
            for (int i = l; i < l - r; ++i)
            {
                s_P[i] = s_tmpList[i - l];
            }
            var node = new Node();
            node.loc = mid;
            node.l = Make2DTree(l, mid, depth + 1);
            node.r = Make2DTree(mid + 1, r, depth + 1);
            s_T[t] = node;
            return t;
        }
        static int SortFuncByX(Point a, Point b)
        {
            return a.x.CompareTo(b.x);
        }
        static int SortFuncByY(Point a, Point b)
        {
            return a.y.CompareTo(b.y);
        }
        private static void Find(int v, int sx, int tx, int sy, int ty, int depth, List<int> ans)
        {
            int x = s_P[s_T[v].loc].x;
            int y = s_P[s_T[v].loc].y;
            if (sx <= x && x <= tx && sy <= y && y <= ty)
            {
                ans.Add((s_P[s_T[v].loc].v));
         
            }
            if (depth % 2 == 0)
            {
                if (s_T[v].l != -1 && sx <= x)
                {
                    Find(s_T[v].l, sx, tx, sy, ty, depth + 1, ans);
                }
                if (s_T[v].r != -1 && x <= tx)
                {
                    Find(s_T[v].r, sx, tx, sy, ty, depth + 1, ans);

                }
            }
            else
            {
                if (s_T[v].l != -1 && sy <= y)
                {
                    Find(s_T[v].l, sx, tx, sy, ty, depth + 1, ans);
                }
                if (s_T[v].r != -1 && y <= ty)
                {
                    Find(s_T[v].r, sx, tx, sy, ty, depth + 1, ans);

                }
            }
        }
#endif
    }
}