Problem:
Score : 400 points

Problem Statement

There are N one-off jobs available. If you take the i-th job and complete it, you will earn the reward of B_i after A_i days from the day you do it.

You can take and complete at most one of these jobs in a day.

However, you cannot retake a job that you have already done.

Find the maximum total reward that you can earn no later than M days from today.

You can already start working today.

Constraints

All values in input are integers.

1 \leq N \leq 10^5

1 \leq M \leq 10^5

1 \leq A_i \leq 10^5

1 \leq B_i \leq 10^4

Input

Input is given from Standard Input in the following format:

N M
A_1 B_1
A_2 B_2
\vdots
A_N B_N

Output

Print the maximum total reward that you can earn no later than M days from today.

Sample Input 1

3 4
4 3
4 1
2 2

Sample Output 1

5

You can earn the total reward of 5 by taking the jobs as follows:

Take and complete the first job today. You will earn the reward of 3 after four days from today.

Take and complete the third job tomorrow. You will earn the reward of 2 after two days from tomorrow, that is, after three days from today.

Sample Input 2

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

Sample Output 2

10

Sample Input 3

1 1
2 1

Sample Output 3

0

Solution in Rust (1.15.1) (judge verdict: Accepted)

fn solve(src: &str) -> String {
    let mut sc = Scanner::from_str(src);

    let n: usize = sc.read();
    let m: usize = sc.read();
    let mut ab: Vec<(usize,usize)> = (0..n).map(|_| (sc.read(), sc.read())).collect();
    ab.sort();

    use std::collections::BinaryHeap;
    let mut heap = BinaryHeap::new();
    let mut ans = 0;
    let mut i = 0;
    let mut j = 1;
    while j <= m {
        while i<n && ab[i].0 == j {
            heap.push(ab[i].1);
            i += 1;
        }
        if let Some(b) = heap.pop() {
            ans += b;
        }
        j += 1;
    }

    format!("{}\n", ans)
}
#[test]
fn test_solve() {
   assert_eq!(solve("3 4\n4 3\n4 1\n2 2\n"), "5\n");
   assert_eq!(solve("5 3\n1 2\n1 3\n1 4\n2 1\n2 3\n"), "10\n");
   assert_eq!(solve("1 1\n2 1\n"), "0\n");
}
fn main() {
    let mut buf = String::new();
    use std::io::Read;
    std::io::stdin().read_to_string(&mut buf).unwrap();
    use std::io::Write;
    std::io::stdout().write_all(solve(&buf).as_bytes()).unwrap();
}
struct Scanner<I> {
    src: I,
}
impl<'a> Scanner<std::str::SplitWhitespace<'a>> {
    fn from_str(src: &'a str) -> Self {
        Scanner {
            src: src.split_whitespace(),
        }
    }
}
#[allow(dead_code)]
impl<'a, I> Scanner<I>
where
    I: std::iter::Iterator<Item = &'a str>,
{
    fn read<T: std::str::FromStr>(&mut self) -> T {
        self.src.next().unwrap().parse().ok().expect("Parse error")
    }
    fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    fn chars(&mut self) -> Vec<char> {
        self.src.next().unwrap().chars().collect()
    }
}