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 OCaml (4.02.3) (judge verdict: Accepted)

open Scanf
open Printf

let (n,m) = sscanf (read_line ()) "%d %d" (fun a b -> (a,b));;
(*
let array = Array.make n (0,0);;
for i = 0 to (n-1) do
  let (x,y) = sscanf (read_line ()) "%d %d" (fun a b -> (a,b)) in
  array.(i) <- (x,y)
done;;
*)

let rec input_list = function
  | 0 -> []
  | x -> sscanf (read_line ()) "%d %d" (fun a b -> (a,b)) :: (input_list (x-1));;

let list = input_list n;;
let sort_list = List.sort (fun a b -> compare (fst a) (fst b)) list;;

module PrioQueue =
struct
  type priority = int
  type 'a queue = Empty | Node of priority * 'a * 'a queue * 'a queue
  let empty = Empty
  let rec insert queue prio elt =
    match queue with
      Empty -> Node(prio, elt, Empty, Empty)
    | Node(p, e, left, right) ->
      (* prio <= p なら小さいほうが優先 prio >= p なら大きい方が優先 *)
      if prio = p then (* prio = p なら eltが小さい方を優先 *)
        if e >= elt
          then Node(prio, elt, insert right p e, left)
          else Node(p, e, insert right prio elt, left)
      else 
      if prio > p
        then Node(prio, elt, insert right p e, left)
        else Node(p, e, insert right prio elt, left)
  exception Queue_is_empty
  let rec remove_top = function
      Empty -> raise Queue_is_empty
    | Node(prio, elt, left, Empty) -> left
    | Node(prio, elt, Empty, right) -> right
    | Node(prio, elt, (Node(lprio, lelt, _, _) as left), (Node(rprio, relt, _, _) as right)) ->
      if lprio = rprio then (* prio <= p なら小さいほうが優先 prio >= p なら大きい方が優先 *)
        if relt >= lelt
      then Node(lprio, lelt, remove_top left, right)
      else Node(rprio, relt, left, remove_top right)
      else if lprio > rprio 
      then Node(lprio, lelt, remove_top left, right)
      else Node(rprio, relt, left, remove_top right)
  let rec print_queue = function
      Empty -> Printf.printf "Empty\n"
    | Node(prio, elt, left, right) -> 
      let _ = Printf.printf "prio = %d, elt = %d \n" prio elt in
      let _ = Printf.printf "left = " in
      let _ = print_queue left in
      let _ = Printf.printf "right = " in
      let _ = print_queue right in ()
  let extract = function
      Empty -> raise Queue_is_empty
    | Node(prio, elt, _, _) as queue -> (prio, elt, remove_top queue)
end;;

open PrioQueue;;

let rec solve_aux list m pq =
  match list with
  | [] -> ([], pq)
  | (x,y) :: rest ->
    if x <= m then 
      let new_pq = PrioQueue.insert pq y x in
      solve_aux rest m new_pq
    else
      (list,pq);;

let solve () =
let rec loop rest_day ans candi pq =
  (*let _ = printf "candi = " in
  let _ = List.iter (fun a -> printf "%d / " (fst a))  candi in*)
  if rest_day = m+1 then ans
  else
   (* let _ = printf "rest_day = %d, ans = %d, \n pq = " rest_day ans in*)
    let (rest, new_pq) = solve_aux candi rest_day pq in
    (*let _ = PrioQueue.print_queue new_pq in*)
    match new_pq with
    | Empty -> 
      loop (rest_day + 1) ans rest Empty
    | Node(prio, elt, _, _) as queue -> 
      loop (rest_day + 1) (ans + prio) rest (PrioQueue.remove_top queue)
in loop 1 0 sort_list Empty;;

let _ = printf "%d\n" (solve ());;