#[allow(unused_imports)]
use std::cmp::{min,max};
#[allow(unused_imports)]
use std::collections::BTreeMap;
#[allow(unused_imports)]
use std::ops::*;
#[allow(unused_imports)]
use std::collections::BinaryHeap;

struct DoubleBinaryHeap<T,U> {
    first:      BinaryHeap<(T,U)>,
    first_del:  BinaryHeap<(T,U)>,
    second:     BinaryHeap<(U,T)>,
    second_del: BinaryHeap<(U,T)>,
}

impl<T:Ord+Copy,U:Ord+Copy> DoubleBinaryHeap<T,U> {
    fn new() -> DoubleBinaryHeap<T,U> {
        DoubleBinaryHeap {
            first: BinaryHeap::new(),
            first_del: BinaryHeap::new(),
            second: BinaryHeap::new(),
            second_del: BinaryHeap::new(),
        }
    }
    fn push(&mut self, x: T, y: U) {
        self.first.push((x,y));
        self.second.push((y,x));
    }
    fn normalize_first(&mut self) {
        while ! self.first.is_empty() && ! self.first_del.is_empty() && self.first.peek().unwrap() == self.first_del.peek().unwrap() {
            self.first.pop();
            self.first_del.pop();
        }
    }
    fn normalize_second(&mut self) {
        while ! self.second.is_empty() && ! self.second_del.is_empty() && self.second.peek().unwrap() == self.second_del.peek().unwrap() {
            self.second.pop();
            self.second_del.pop();
        }
    }
    fn peek_first(&mut self) -> Option<&(T,U)> {
        self.normalize_first();
        self.first.peek()
    }
    fn peek_second(&mut self) -> Option<&(U,T)> {
        self.normalize_second();
        self.second.peek()
    }
    fn pop_first(&mut self) -> Option<(T,U)> {
        self.normalize_first();
        match self.first.pop() {
            Some((a,b)) => {
                self.second_del.push((b,a));
                Some((a,b))
            }
            None => {
                None
            }
        }
    }
    fn pop_second(&mut self) -> Option<(U,T)> {
        self.normalize_second();
        match self.second.pop() {
            Some((b,a)) => {
                self.first_del.push((a,b));
                Some((b,a))
            }
            None => {
                None
            }
        }
    }
}

fn main() {
    let (_,m) = {
        let xs = read_vec_i64();
        (xs[0] as usize, xs[1] as usize)
    };
    let mut dheap = DoubleBinaryHeap::<i64,i64>::new();
    let mut xs = vec![];
    for _ in 0..m {
        let ts = read_vec_i64();
        let (a,b) = (ts[0], ts[1]);
        xs.push((a,b));
        dheap.push(-a,-b);
    }
    let mut res = 0;
    loop {
        if let Some((nb1,_)) = dheap.pop_second() {
            res += 1;
            loop {
                let mut flag = false;
                if let Some(&(na2,_)) = dheap.peek_first() {
                    if -na2 < -nb1 {
                        flag = true;
                    }
                }
                if flag {
                    dheap.pop_first();
                }
                else {
                    break;
                }
            }
        }
        else {
            break;
        }
    }
    println!("{}", res);
}

#[allow(dead_code)]
fn read_line() -> String {
    let mut ret = String::new();
    std::io::stdin().read_line(&mut ret).ok();
    ret.pop();
    return ret;
}

#[allow(dead_code)]
fn read_i64() -> i64 {
    let ss = read_line();
    return ss.parse::<i64>().unwrap();
}

#[allow(dead_code)]
fn read_vec_i64() -> Vec<i64> {
    let mut res = vec![];
    let ss = read_line();
    for ts in ss.split_whitespace() {
        let x = ts.parse::<i64>().unwrap();
        res.push(x);
    }
    return res;
}

use std::fmt::Display;
#[allow(dead_code)]
fn write_vec<T: Display>(xs: &Vec<T>) {
    if xs.len() == 0 {
        println!("");
        return;
    }
    print!("{}", xs[0]);
    for i in 1..xs.len() {
        print!(" {}", xs[i]);
    }
    println!("");
}


Measured memory_bytes: 12468