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 (GCC 5.4.1) (judge verdict: Accepted)

#include <stdio.h>
#define SIZE 100006
typedef struct mk{
    int b;
    struct mk *next;
}data;
data *input[SIZE],node[SIZE];
int id = 0;
data *New(int b){
    data *tm = &node[id++];
    tm->b = b;
    tm->next = NULL;
    return tm;
}
data *insert(data *root, int b){
    if(root==NULL) return New(b);
    data *tm = New(b);
    tm->next = root;
    return tm;
}
int len = 0,heap[SIZE];
void swap(int *x,int *y){
    int t = *x;
    *x = *y;
    *y = t;
}
int minChild(int *ar,int len,int r,int lf,int rt){
    if(lf<len && ar[r]<ar[lf]) r = lf;
    if(rt<len && ar[r]<ar[rt]) r = rt;
    return r;
}
void heapify(int *ar, int len,int r){
    int c = minChild(ar,len,r,r*2+1,r*2+2);
    if(c!=r){
        swap(&ar[r],&ar[c]);
        heapify(ar,len,c);
    }
}
int getTop(int len){
    int ret = heap[0];
    heap[0] = heap[len];
    heapify(heap,len, 0);
    return ret;
}
void Insert(int v,int len){
    heap[len]=v;
    while(len>0 && heap[(len-1)/2]<heap[len]){
        swap(&heap[len],&heap[(len-1)/2]);
        len = (len-1)/2;
    }
}
void MRoy(){
    int n,m,a,b,length = 0;
    for(int i = 0;i<SIZE;i++) input[i] = NULL;
    scanf("%d%d",&n,&m);
    for(int i = 0;i<n;i++){
        scanf("%d %d",&a,&b);
        input[a] = insert(input[a],b);
    }
    int Ans = 0;
    for(int i = 0;i<m;i++){
        data *tm = input[i+1];
        while(tm!=NULL){
            // printf("%d ",tm->b);
            Insert(tm->b,length);
            length++;
            tm=tm->next;
        }
        if(length){
            Ans += getTop(--length);
        }
            // printf("%d\n",Ans);
    }
    printf("%d\n",Ans);
    return;
}
int main(){
    MRoy();
    return 0;
}