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 C# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

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

class Program {
  static void Main() {
    string[] input = Console.ReadLine().Trim().Split(' ');
    int N = int.Parse(input[0]);
    int term = int.Parse(input[1]);
    int days, reward;
    int maxIndex = 0;
    int maxValue = 0;
    int answer = 0;
    
    var dict = new Dictionary<int, List<int>>();
    
    for(var i = 0; i < N; i++) {
      input = Console.ReadLine().Trim().Split(' ');
      days = int.Parse(input[0]);
      reward = int.Parse(input[1]);
      if(days <= term) {
        if(dict.ContainsKey(days)) {
          dict[days].Add(reward);
          dict[days].Sort();
        } else {
          dict.Add(days, new List<int>());
          dict[days].Add(reward);
          dict[days].Sort();
        }       
      }
    }        
    
    for(var i = 1; i <= term; i++) {
      maxValue = 0;
      maxIndex = 0;
      for(var j = i; j >= 1; j--) {
        if(dict.ContainsKey(j)) {
          if(dict[j].Last() > maxValue) {
            maxValue = dict[j].Last();
            maxIndex = j;
          }
        }
      }
      if(maxIndex != 0) {
        answer += maxValue;
        if(dict[maxIndex].Count() == 1) {
          dict.Remove(maxIndex);
        } else {                 
          dict[maxIndex].Remove(maxValue);
        }
      }      
    }
    Console.WriteLine(answer);
  }  
}