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: Time Limit Exceeded)

use std::io::*;
use std::str::FromStr;
// use std::collections::HashMap;

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char) 
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

fn main() {
    let n: u32 = read();
    let m: u32 = read();
    let ab: Vec<(u32, u32)> = (0..n).map(|_| (read(), read())).collect();

    // let mut a_map: HashMap<u32, Vec<u32>> = HashMap::new();
    // let mut b_map: HashMap<u32, Vec<u32>> = HashMap::new();
    // for i in 0..n {
    //     let a: u32 = ab[i as usize].0;
    //     let b: u32 = ab[i as usize].1;
    //     if a_map.contains_key(&a) {
    //         if let Some(x) = a_map.get_mut(&a) {
    //             x.push(i);
    //         }
    //     } else {
    //         a_map.insert(a, vec![i]);
    //     }
    //     if b_map.contains_key(&b) {
    //         if let Some(x) = b_map.get_mut(&b) {
    //             x.push(i);
    //         }
    //     } else {
    //         b_map.insert(b, vec![i]);
    //     }
    // }

    // let mut keys: Vec<u32> = b_map.keys().map(|i| *i).collect();
    // keys.sort();
    // keys.reverse();
    // for key in keys {
    //     println!("{}", key);
    // }

    let mut reward_indexes: Vec<u32> = (0..n).collect();
    reward_indexes.sort_by(|a, b| ab[*a as usize].1.partial_cmp(&ab[*b as usize].1).unwrap());
    reward_indexes.reverse();

    let mut work_days: Vec<i32> = vec![-1; m as usize];
    let mut wd_cnt = 0;
    let mut ans = 0;
    for i in reward_indexes {
        // println!("{}", i);
        let a: u32 = ab[i as usize].0;
        let b: u32 = ab[i as usize].1;
        // println!("{} {}", a, b);

        
        let res = work_days.iter().skip((a - 1) as usize).position(|&x| x == -1);
        // println!("{:?}", res);
        if res.is_some() {
            let j: u32 = (res.unwrap() + a as usize - 1) as u32;
            work_days[j as usize] = i as i32;
            ans += b;
            wd_cnt += 1;
        }
        // for j in a..(m + 1) {
        //     // println!("j: {}", j);
        //     if work_days[(j - 1) as usize] == -1 {
        //         work_days[(j - 1) as usize] = i as i32;
        //         ans += b;
        //         wd_cnt += 1;
        //         break;
        //     }   
        // }
        // println!("{:?}", work_days);
        // println!("{}", ans);
        if wd_cnt >= m {
            break;
        }

    }

    println!("{}", ans);
}