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 static System.Console;
using static System.Math;
using System.IO;
using System.Collections.Generic;
namespace I_am_the_green_coder{
    class ComparableArray2 : IComparable<ComparableArray2>{
        public long[] arr = new long[2];

        public ComparableArray2(long a, long b){
            arr[0] = a; arr[1] = b;
        }

        public int CompareTo(ComparableArray2 other){
            if(this.arr[0]>other.arr[0]){
                return 1;
            }else if(this.arr[0]<other.arr[0]){
                return -1;
            }else{
                if(this.arr[1]<other.arr[1]){
                    return 1;
                }else if(this.arr[1]>other.arr[1]){
                    return -1;
                }else{
                    return 0;
                }
            }
        }
    }
    class Inonoa{
        static void Main(){
            long[] nm = ILongs();
            long[][] ab = ILongLongs(nm[0]);

            PriorityQueue<ComparableArray2> q = new PriorityQueue<ComparableArray2>();
            List<ComparableArray2> list = new List<ComparableArray2>();

            for(long i=0;i<nm[0];i++){
                q.Enqueue(new ComparableArray2(ab[i][1],ab[i][0]));
            }

            long ans = 0;
            long nissuu = 1;

            while(true){
                if(nissuu>nm[1]){
                    break;
                }
                if(q.Count==0){
                    nissuu ++;
                    if(nissuu>nm[1]){
                        break;
                    }
                    foreach(ComparableArray2 ca in list){
                        q.Enqueue(ca);
                    }
                    list = new List<ComparableArray2>();
                    continue;
                }
                ComparableArray2 ima = q.Dequeue();
                if(ima.arr[1]<=nissuu){
                    ans += ima.arr[0];
                    nissuu ++;
                    foreach(ComparableArray2 ca in list){
                        q.Enqueue(ca);
                    }
                    list = new List<ComparableArray2>();
                }else{
                    list.Add(ima);
                }
            }

            Console.WriteLine(ans);
        }

        static readonly long MOD = 1000000007;

        ///<summary>a_1, a_2, a_3, ...みたいなの</summary>
        static long[] ILongs(){
            string[] s = ReadLine().Split();
            long[] re = new long[s.Length];
            for(long i=0;i<s.Length;i++){
                re[i] = long.Parse(s[i]);
            }
            return re;
        }

        ///<summary>xooxoxoxxoxo...みたいなの</summary>
        static char[] IChars(){
            return ReadLine().ToCharArray();
        }

        ///<summary>n m とかをちょっとはやくかくだけ</summary>
        static string[] IStrings(){
            return ReadLine().Split();
        }

        ///<summary>n行の入力を取ったり</summary>
        static long[][] ILongLongs(long n){
            long[][] re = new long[n][];
            for(long i=0;i<n;i++){
                string[] s = ReadLine().Split();
                re[i] = new long[s.Length];
                for(long j=0;j<s.Length;j++){
                    re[i][j] = long.Parse(s[j]);
                }
            }
            return re;
        }

        ///<summary>n行の文字列を取ったり</summary>
        static char[][] ICharsChars(long n){
            char[][] re = new char[n][];
            for(long i=0;i<n;i++){
                re[i] = ReadLine().ToCharArray();
            }
            return re;
        }
    }
    class PriorityQueue<T> where T : IComparable<T>{
        private List<T> list = new List<T>();

        public long Count{
            get{
                return list.Count;
            }
        }

        public void Enqueue(T elem){
            int c = list.Count;
            list.Add(elem);

            while(c!=0){
                int i = (c-1) /2;

                if(list[c].CompareTo(list[i])>0){
                    T tmp = list[c];
                    list[c] = list[i];
                    list[i] = tmp;
                }
                
                c = i;
            }
        }

        public T Dequeue(){
            int c = list.Count - 1;
            T pop = list[0];
            list[0] = list[c];
            list.RemoveAt(c);

            for(int i=0, j=1; j<c; ){
                if((j != c-1) && (list[j].CompareTo(list[j+1]) < 0)){
                    j ++;
                }

                if(list[i].CompareTo(list[j])<0){
                    T tmp = list[j];
                    list[j] = list[i];
                    list[i] = tmp;
                }

                i = j;
                j = 2*i + 1;
            }

            return pop;
        }
    }
}