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

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>

enum Color {red, black};
typedef struct RBT_Node{
	int key;
	enum Color color;
	struct RBT_Node *left, *right, *parent;
} Node;
Node *nil, *T;
Node* tree_minimum(Node *x){
	Node *res = x;
	while((*res).left != nil)res = (*res).left;
	return res;
}
Node* tree_maximum(Node *x){
	Node *res = x;
	while((*res).right != nil)res = (*res).right;
	return res;
}
void left_lotate(Node *x){
	Node *y = (*x).right;
	(*x).right = (*y).left;
	if((*y).left != nil){
		(*(*y).left).parent = x;
	}
	(*y).parent = (*x).parent;
	if((*x).parent == nil){
		T = y;
	}else if(x == (*(*x).parent).left){
		(*(*x).parent).left = y;
	}else {
		(*(*x).parent).right = y;
	}
	(*y).left = x;
	(*x).parent = y;
	return;
}
void right_lotate(Node *x){
	Node *y = (*x).left;
	(*x).left = (*y).right;
	if((*y).right != nil){
		(*(*y).right).parent = x;
	}
	(*y).parent = (*x).parent;
	if((*x).parent == nil){
		T = y;
	}else if(x == (*(*x).parent).right){
		(*(*x).parent).right = y;
	}else {
		(*(*x).parent).left = y;
	}
	(*y).right = x;
	(*x).parent = y;
	return;
}
void insert_fixup(Node *z){
	while((*(*z).parent).color == red){
		if((*z).parent == (*(*(*z).parent).parent).left){
			Node *y = (*(*(*z).parent).parent).right;
			if((*y).color == red){
				(*(*z).parent).color = black;
				(*y).color = black;
				(*(*(*z).parent).parent).color = red;
				z = (*(*z).parent).parent;
			}else {
				if(z == (*(*z).parent).right){
					z = (*z).parent;
					left_lotate(z);
				}
				(*(*z).parent).color = black;
				(*(*(*z).parent).parent).color = red;
				right_lotate((*(*z).parent).parent);
			}
		}else{
			Node *y = (*(*(*z).parent).parent).left;
			if((*y).color == red){
				(*(*z).parent).color = black;
				(*y).color = black;
				(*(*(*z).parent).parent).color = red;
				z = (*(*z).parent).parent;
			}else {
				if(z == (*(*z).parent).left){
					z = (*z).parent;
					right_lotate(z);
				}
				(*(*z).parent).color = black;
				(*(*(*z).parent).parent).color = red;
				left_lotate((*(*z).parent).parent);
			}
		}
	}
	(*T).color = black;
	return;
}
void insert(Node *z){
	Node *y = nil;
	Node *x = T;
	while(x != nil){
		y = x;
		if((*z).key < (*x).key){
			x = (*x).left;
		}else {
			x = (*x).right;
		}
	}
	(*z).parent = y;
	if(y == nil){
		T = z;
	}else if((*z).key < (*y).key){
		(*y).left = z;
	}else {
		(*y).right = z;
	}
	insert_fixup(z);
	return;
}
void push(int x){
	Node *z = (Node*)malloc(sizeof(Node));
	(*z).key = x;
	(*z).parent = (*z).left = (*z).right = nil;
	(*z).color = red;
	insert(z);
	return;
}
void transplant(Node *u, Node *v){
	if((*u).parent == nil){
		T = v;
	}else if(u == (*(*u).parent).left){
		(*(*u).parent).left = v;
	}else {
		(*(*u).parent).right = v;
	}
	(*v).parent = (*u).parent;
	return;
}
void delete_fixup(Node *x){
	while(x != T && (*x).color == black){
		if(x == (*(*x).parent).left){
			Node *w = (*(*x).parent).right;
			if((*w).color == red){
				(*w).color = black;
				(*(*x).parent).color = red;
				left_lotate((*x).parent);
				w = (*(*x).parent).right;
			}
			if((*(*w).left).color == black && (*(*w).right).color == black){
				(*w).color = red;
				x = (*x).parent;
			}else {
				if((*(*w).right).color == black){
					(*(*w).left).color = black;
					(*w).color = red;
					right_lotate(w);
					w = (*(*x).parent).right;
				}
				(*w).color = (*(*x).parent).color;
				(*(*x).parent).color = black;
				(*(*w).right).color = black;
				left_lotate((*x).parent);
				x = T;
			}
		}else{
			Node *w = (*(*x).parent).left;
			if((*w).color == red){
				(*w).color = black;
				(*(*x).parent).color = red;
				right_lotate((*x).parent);
				w = (*(*x).parent).left;
			}
			if((*(*w).right).color == black && (*(*w).left).color == black){
				(*w).color = red;
				x = (*x).parent;
			}else {
				if((*(*w).left).color == black){
					(*(*w).right).color = black;
					(*w).color = red;
					left_lotate(w);
					w = (*(*x).parent).left;
				}
				(*w).color = (*(*x).parent).color;
				(*(*x).parent).color = black;
				(*(*w).left).color = black;
				right_lotate((*x).parent);
				x = T;
			}
		}
	}
	(*x).color = black;
	return;
}
bool delete(int t){
	Node *z = T;
	while((*z).key != t && z != nil){
		if((*z).key > t){
			z = (*z).left;
		}else {
			z = (*z).right;
		}
	}
	if(z == nil) return false;
	Node *x;
	Node *y = z;
	enum Color y_original_color = (*y).color;
	if((*z).left == nil){
		x = (*z).right;
		transplant(z, (*z).right);
	}else if((*z).right == nil){
		x = (*z).left;
		transplant(z, (*z).left);
	}else {
		y = tree_minimum((*z).right);
		y_original_color = (*y).color;
		x = (*y).right;
		if((*y).parent == z){
			(*x).parent = y;
		}else {
			transplant(y, (*y).right);
			(*y).right = (*z).right;
			(*(*y).right).parent = y;
		}
		transplant(z, y);
		(*y).left = (*z).left;
		(*(*y).left).parent = y;
		(*y).color = (*z).color;
	}
		free(z);
	if(y_original_color == black){
		delete_fixup(x);
	}
	return true;
}
void nil_init(){
	nil = (Node*)malloc(sizeof(Node));
	(*nil).color = black;
	(*nil).key = -1;
	(*nil).left = (*nil).right = (*nil).parent = nil;
	return;
}
int N, M, A[1<<17], B[1<<17], idx[1<<17], ans = 0;
int cmp(const void *a, const void *b){
	return A[*(int*)a] - A[*(int*)b];
}
int main(){
	nil_init(); T = nil;
	scanf("%d%d", &N, &M);
	for(int i=0; i<N; i++){
		scanf("%d%d", A+i, B+i);
		idx[i] = i;
	}
	qsort(idx, N, 4, cmp);
	int j = 0;
	for(int i=1; i<=M; i++){
		for(;A[idx[j]] <= i && j < N; j++){
			push(B[idx[j]]);
		}
		if(T != nil){
			Node *t = tree_maximum(T);
			ans += (*t).key;
			delete((*t).key);
		}
	}
	printf("%ld\n", ans);
	return 0;
}