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

#!/usr/bin/env python3
import sys
import collections
from operator import itemgetter
import heapq


def solve(N: int, M: int, A: "List[int]", B: "List[int]"):

    jobs_time = collections.defaultdict(list)
    for a,b in zip(A,B):
        jobs_time[b].append(a)

    jobs_time = sorted(jobs_time.items(),reverse=True)
    job_list = [0] * M

    for k,v in jobs_time: 
        v.sort()
        st = -1
        for vv in v:
            if vv <= M:
                for i in range(max(st,vv-1),len(job_list)):
                    if job_list[i] < k:
                        job_list[i] = k
                        st = min(i+1,len(job_list))
                        break
            else:
                break

        if all(j>0 for j in job_list):
            break

    print(sum(job_list))

    return

def solve2(N: int, M: int, A: "List[int]", B: "List[int]"):
    jobs_time = []
    for a,b in zip(A,B):
        jobs_time.append((b,a))

    jobs_time = sorted(jobs_time,key=itemgetter(0,1),reverse=True)
    #jobs_time = sorted(jobs_time,key=lambda x: -x[0]*10**6+x[1])
    job_list = [0] * M
    job_cnt = 0
    res = 0
    end = len(job_list)
    for b,a in jobs_time: 
        if a <= M:
            for i in range(a-1,end):
                if job_list[i] < b:
                    if job_list[i] == 0:
                        job_cnt += 1
                    else:
                        res -= job_list[i]
                    job_list[i] = b
                    res += b
                    break
            if job_cnt >= len(job_list):
                break

            for i in range(end-1,-1,-1):
                if job_list[i] == 0:
                    end = i + 1
                    break

    print(res)

def solve3(N: int, M: int, A: "List[int]", B: "List[int]"):
    jobs_time = []
    for a,b in zip(A,B):
        jobs_time.append((a,b))
    jobs_time = sorted(jobs_time,key=itemgetter(0))

    job_list = []
    res = 0
    js = 0
    #print(jobs_time)
    for i in range(M):
        for j in range(js,N):
            if jobs_time[j][0] == (i+1):
                heapq.heappush(job_list,(- jobs_time[j][1], jobs_time[j][1]))
            elif jobs_time[j][0] > (i+1):
                js = j
                break

        if len(job_list) > 0:
            _,b = heapq.heappop(job_list)
            res += b

    print(res)



# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    M = int(next(tokens))  # type: int
    A = [int()] * (N)  # type: "List[int]" 
    B = [int()] * (N)  # type: "List[int]" 
    for i in range(N):
        A[i] = int(next(tokens))
        B[i] = int(next(tokens))
    solve3(N, M, A, B)

if __name__ == '__main__':
    main()