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 Java8 (OpenJDK 1.8.0) (judge verdict: Accepted)

/*
Stay innocent, be naive. 
But still dream big. 
Dream big to the point that it is beyond your ability and endeavour to achieve it. 
So dream big and don’t lose your innocence.
*/
import java.util.*;
import java.io.*;

   public class Main
   {
      public static void main(String args[]) throws Exception
      {
         BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));  
         StringTokenizer st = new StringTokenizer(infile.readLine());
         int N = Integer.parseInt(st.nextToken());
         int M = Integer.parseInt(st.nextToken());
         Unit[] arr = new Unit[N];
         for(int i=0; i < N; i++)
         {
            st = new StringTokenizer(infile.readLine());
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());
            arr[i] = new Unit(x, y);
         }
         //days increase, reward decrease
         Arrays.sort(arr);
         int maxday = 1;
         PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
         int i=0;
         for(; i < N; i++)
         {
            if(arr[i].a == maxday)
               pq.add(-1*arr[i].b);
            else
               break;
         }
         int res = 0;
         for(; maxday <= M; maxday++)
         {
            for(; i < N; i++)
            {
               if(arr[i].a <= maxday)
                  pq.add(-1*arr[i].b);
               else
                  break;
            }
            if(pq.size() == 0)
               continue;
            int max = -1*pq.poll();
            res += max;
         }
         System.out.println(res);
      }
   }
   class Unit implements Comparable<Unit>
   {
      public int a;
      public int b;
      
      public Unit(int x, int b)
      {
         a = x;
         this.b = b;
      }
      public int compareTo(Unit oth)
      {
         if(a != oth.a)
            return a-oth.a;
         return oth.b-b;
      }
   }