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: Time Limit Exceeded)

import sys,collections as cl,bisect as bs
sys.setrecursionlimit(100000)
mod = 10**9+7
Max = sys.maxsize

def cmb(n, r):
    if n - r < r: r = n - r
    if r == 0: return 1
    if r == 1: return n

    numerator = [n - r + k + 1 for k in range(r)]
    denominator = [k + 1 for k in range(r)]

    for p in range(2,r+1):
        pivot = denominator[p - 1]
        if pivot > 1:
            offset = (n - r) % p
            for k in range(p-1,r,p):
                numerator[k - offset] /= pivot
                denominator[k] /= pivot

    result = 1
    for k in range(r):
        if numerator[k] > 1:
            result *= int(numerator[k])

    return result
def l(): #intのlist
    return list(map(int,input().split()))
def m(): #複数文字
    return map(int,input().split())
def onem(): #Nとかの取得
    return int(input())
def s(x): #圧縮
    a = []
    aa = x[0][0]
    su = [x[0]]
    for i in range(len(x)-1):
        if aa != x[i+1][0]:
            a.append(su)
            aa = x[i+1][0]
            su = [x[i+1]]
        else:
            su.append(x[i+1])
    a.append(su)
    return a
def jo(x): #listをスペースごとに分ける
    return " ".join(map(str,x))
def max2(x): #他のときもどうように作成可能
    return max(map(max,x))

def binary_search_recursion(a,b):

    arry = a
    target = b
    arry_len = len(arry) 

    def recursion(left=0,right=arry_len-1):

        if left > right:
            return print("not found")

        mid = (left+right) // 2
        if arry[mid] > target:
            return recursion(left,mid-1)
        elif arry[mid] < target:
            return recursion(mid+1,right)
        else:
            return print("found: " + str(mid+1) + " 番目にありました")

    recursion()

n,m = l()

a = []

for i in range(n):
    z,x = l()
    a.append([z,x])

a.sort(key = lambda x:(x[0],-x[1]))
kkk = s(a)
co = 0
p = 0
al = []
for i in range(m):
    k = i + 1
    if p <= len(kkk)-1:
        if k >= kkk[p][0][0]:
            for ppp in kkk[p]:
                al.append(ppp[1])
            p += 1
    al.sort(reverse = True)
    if len(al) != 0:
        an = al.pop(0)
        co += an 
print(co)