CodeEff/ECCO huggingface dataset:
# Original solution
N, M = list(map(int, input().split()))
AB = [list(map(int, input().split())) for _ in range(N)]
AB = sorted(sorted(AB, key=lambda x: x[0], reverse=False), key=lambda x: x[1], reverse=True)
x = [0] * M
p = [x for x in range(M)]

cnt = 0
cntIN = M
for a, b in AB:
    i = M-a

    s = []
    while i >= 0 and p[i] != i:
        s.append(i)
        i = p[i]
    for j in s:
        p[j] = i - 1

    if i >= 0:
        x[i] = b
        p[i] = i - 1
        cntIN -= 1            
        if cntIN <= 0:
            break

print((sum(x)))


# Optimized solution
N, M = list(map(int, input().split()))
AB = [(a, b) for _ in range(N) for a, b in [list(map(int, input().split()))] if M - a >= 0]

AB = sorted(sorted(AB, key=lambda x: x[0], reverse=False), key=lambda x: x[1], reverse=True)
x = [0] * M
p = [x for x in range(M)]

cnt = 0
cntIN = M
for a, b in AB:
    i = M-a

    s = []
    while i >= 0 and p[i] != i:
        s.append(i)
        i = p[i]
    for j in s:
        p[j] = i - 1

    if i >= 0:
        x[i] = b
        p[i] = i - 1
        cntIN -= 1            
        if cntIN <= 0:
            break

print((sum(x)))
# Original solution
from heapq import *
from collections import defaultdict

n, m = list(map(int, input().split()))
jobs = defaultdict(list)
for _ in range(n):
    a, b = list(map(int, input().split()))
    jobs[a].append(-b)

result = 0
pool = []
for i in range(1, m+1):
    for j in jobs[i]:
        heappush(pool, j)
    if 0 < len(pool):
        result += -heappop(pool)

print(result)

# Optimized solution
import sys
from collections import defaultdict
from heapq import *
sys.setrecursionlimit(10**8)

input = sys.stdin.readline

def main():
    """ main """
    N,M = list(map(int, input().split()))
    job_list = defaultdict(list)
    for _ in range(N):
        a, b = list(map(int, input().split()))
        job_list[a].append(-b)

    pool = []
    ans = 0
    for i in range(1, M+1):
        for reward in job_list[i]:
            heappush(pool, reward)
        if 0 < len(pool):
            ans -= heappop(pool)
    print(ans)

if __name__ == '__main__':
    main()
# Original solution
from heapq import heappop, heappush
import sys
input = sys.stdin.readline

N, M = list(map(int, input().split()))
X = sorted([list(map(int, input().split())) for _ in range(N)], key = lambda x: x[0])

hq = []
ans, j = 0, 0

for i in range(1, M + 1):  # M - i 日後にするバイトを考える
    while (j < N) and (X[j][0] <= i):
        heappush(hq, -X[j][1])  # 候補の追加
        j += 1
    if len(hq):
        ans += -heappop(hq)  # 候補があるとき、候補から最大値を取り出す

print(ans)

# Optimized solution
from heapq import heappop, heappush
N, M = list(map(int, input().split()))
X = sorted([list(map(int, input().split())) for _ in range(N)], key = lambda x: x[0])

hq = []
ans, j = 0, 0

for i in range(1, M + 1):  # M - i 日後にするバイトを考える
    while (j < N) and (X[j][0] <= i):
        heappush(hq, -X[j][1])  # 候補の追加
        j += 1
    if len(hq):
        ans += -heappop(hq)  # 候補があるとき、候補から最大値を取り出す

print(ans)
# Original solution
import heapq


def main():
    n, m = [int(e) for e in input().split()]
    AB = [[int(e) for e in input().split()] for i in range(n)]

    AB.sort(key=lambda x: x[0])
    H = []
    ans = 0
    mi = 1
    for a, b in AB:
        while a > mi:
            if len(H) > 0:
                heapq.heapify(H)
                ans += -heapq.heappop(H)

            mi += 1
            if mi > m:
                break

        if a > m:
            break

        H.append(-b)

    while mi <= m and len(H) > 0:
        heapq.heapify(H)
        ans += -heapq.heappop(H)
        mi += 1

    print(ans)


if __name__ == '__main__':
    main()


# Optimized solution
import heapq


def main():
    n, m = [int(e) for e in input().split()]
    AB = [[int(e) for e in input().split()] for i in range(n)]

    AB.sort(key=lambda x: x[0])
    H = []
    ans = 0
    mi = 1
    for a, b in AB:
        while a > mi:
            if len(H) > 0:
                ans += -heapq.heappop(H)

            mi += 1
            if mi > m:
                break

        if a > m:
            break

        heapq.heappush(H, -b)

    while mi <= m and len(H) > 0:
        ans += -heapq.heappop(H)
        mi += 1

    print(ans)


if __name__ == '__main__':
    main()
# Original solution
def main():
    N,M=list(map(int,input().split()))
    job=[[0,0] for i in range(0,N)]
    for i in range(0,N):
        job[i][0],job[i][1]=list(map(int,input().split()))
    s=0
    job=sorted(job,reverse=True)
    for i in range(0,M):
        for j in range(0,N):
            if job[j][0]>M-i:
                job[j][1]=0
        jobsub=[job[k][1] for k in range(0,N)]
        s+=max(jobsub)
        job[jobsub.index(max(jobsub))][1]=0

    print(s)


if __name__ == '__main__':
    main()

# Optimized solution
import sys
import heapq

input=sys.stdin.readline

N,M=list(map(int,input().split()))
job={i:[] for i in range(1,M+1)}
for i in range(0,N):
    a,b=list(map(int,input().split()))
    if M>=a:
        job[a].append(b)

ans=0
ablejob=[]
heapq.heapify(ablejob)
for i in range(1,M+1):
    for j in job[i]:
        heapq.heappush(ablejob,-j)
    if ablejob:
        m=-heapq.heappop(ablejob)
        ans+=m

print(ans)
# Original solution
#template
def inputlist(): return [int(k) for k in input().split()]
#template

N,M = inputlist()
li = [[] for _ in range(M+1)]
for i in range(N):
    A,B = inputlist()
    B *= -1
    if A > M:
        continue
    li[A].append(B)
ans = 0
import heapq
for i in range(1,M+1):
    if i >= 2:
        li[i] += li[i-1]
    heapq.heapify(li[i])
    if len(li[i]) == 0:
        continue
    k = heapq.heappop(li[i])
    ans += k*(-1)

print(ans)

# Optimized solution
#template
def inputlist(): return [int(k) for k in input().split()]
#template

N,M = inputlist()
li = []
for i in range(N):
    A,B = inputlist()
    B *= -1
    li.append([A,B])
ans = 0
from heapq import *
li.sort()
k = []
heapify(k)
flag = 0
for i in range(1,M+1):
    if flag == N:
        for i in range(M+1-i):
            ans -= heappop(k)
        break
    while li[flag][0] <= i:
        heappush(k,li[flag][1])
        flag = flag + 1
        if flag == N:
            break
    if len(k)>=1:
        ans -= heappop(k)
print(ans)
# Original solution
#最終日から見る，残り日数条件を満たす中で最大収入のものを選ぶ

import heapq

N,M=list(map(int,input().split()))
AB=[[0,0] for _ in range(N)]

for i in range(N):
    AB[i][0],AB[i][1] = list(map(int,input().split()))
AB.sort()

ans=0
q=[]
heapq.heapify(q)
ne=0
#dは残り日数
for d in range(1,M+1):
    for i in range(ne,N):
        if AB[i][0]<=d:
            heapq.heappush(q,AB[i][1]*-1)
            ne=i+1
    if len(q)!=0:
        a=heapq.heappop(q)
        ans-=a
    
print(ans)

# Optimized solution
#最終日から見る，残り日数条件を満たす中で最大収入のものを選ぶ

import heapq

N,M=list(map(int,input().split()))
AB=[[0,0] for _ in range(N)]

for i in range(N):
    AB[i][0],AB[i][1] = list(map(int,input().split()))

AB.sort()

ans=0
q=[]
heapq.heapify(q)
ne=0
#dは残り日数
for d in range(1,M+1):
    for i in range(ne,N):
        if AB[i][0]<=d:
            heapq.heappush(q,AB[i][1]*-1)
            ne=i+1
        else:
            break
    if len(q)!=0:
        a=heapq.heappop(q)
        ans-=a
    
print(ans)
# Original solution
from collections import defaultdict
import heapq
 
 
 
n, m = list(map(int, input().split()))
m_dict = defaultdict(list)
for i in range(n):
    a, b = list(map(int, input().split()))
    m_dict[a] = m_dict[a] + [b]


job_que = []
    
    
total = 0
for j in range(1, m+1):
    for k in m_dict[j]:
        heapq.heappush(job_que, -k)
 
 
    if job_que:
        total -= heapq.heappop(job_que)
        
    
            
print(total)

# Optimized solution
import heapq

n, m = list(map(int, input().split()))
t_r_list = []
for i in range(n):
    t_r_list.append(list(map(int, input().split())))

t_r_list.sort()
que = []
total = 0
l = 0
for j in range(1, m + 1):
    while True:
        if l == n:
            break
        if t_r_list[l][0] != j:
            break
        heapq.heappush(que, -t_r_list[l][1])
        l += 1

    if que:
        total -= heapq.heappop(que)


print(total)
# Original solution
N,M = list(map(int, input().split()))
L = [[int(a) for a in input().split()] for _ in range(N)]

import heapq

L.sort()
h = []
ans = [0]*(M)
i = 0
j = 0
d = 0
while i < M and d < M:
    i += 1
    while j < N and L[j][0] <= i:
        heapq.heappush(h, [-L[j][1], L[j][0]])
        j += 1
    if h:
        temp = heapq.heappop(h)
        ans[i-1] = -temp[0]
    
if N < M:
    ans.sort(reverse=True)
    c = 0
    for i in range(N):
        c += ans[i]
    print(c)
else:
    print((sum(ans)))

# Optimized solution
N,M = list(map(int, input().split()))
L = [[int(l) for l in input().split()] for _ in range(N)]

import heapq
h = []
ans = 0
L.sort()
m = 1
i = 0
while i < N and L[i][0] <= M:
    if L[i][0] == m:
        heapq.heappush(h, -L[i][1])
        i += 1
    else:
        m += 1
        if h:
            ans -= heapq.heappop(h)
while m <= M and h:
    ans -= heapq.heappop(h)
    m += 1
print(ans)
# Original solution
import heapq

n,m=list(map(int,input().split()))
arr=[list(map(int,input().split())) for _ in range(n)]
arr2=[[i,0] for i in range(1,m+2)] #すべてのAi=1 to Mについて報酬0の仕事を追加する
arr.extend(arr2)
arr=sorted(arr,key=lambda x:x[0]) #Aiの小さい順にソート
q=[]
ans=0
pos=0
while 1:
 a,b=arr[pos]
 if a>m: #AiがMより大きければその仕事を請ける意味はない
   break
 if a==arr[pos+1][0]: #Aiの値が等しいとき、その仕事を優先度付きキューに追加する
   heapq.heappush(q,-b)
 else:
   heapq.heappush(q,-b)
   ans-=heapq.heappop(q) #Aiの値が変化したとき、そのAiまででの仕事の報酬の最大値を答えに加える
 pos+=1
print(ans)

# Optimized solution
'''tanon  優先度付きキュー
t(=0 to M-1)日目に仕事を請けることを考えると、Ai>M-tなるiについては、
その仕事を請けるかどうかを考えなくて良い(∵この仕事を請けても、
Ai>M-t⇔Ai+t>Mより報酬はM日目より後にしかもらえません)。
したがって、tを大きい順に見ていくと、
M-1日目にはAi<=1なるiについて、報酬が最大となる仕事iを請けるべき、
M-2日目にはAi<=2なるiについて、まだ請けていない仕事の中で
報酬が最大となる仕事iを請けるべき、
…0日目にはAi<=Mなるiについて、まだ請けていない仕事の中で報酬が
最大となる仕事iを請けるべきであるといえます。
したがって、元の配列をAiの小さい順にソートしておき、
Ai=1の仕事について優先度付きキューに報酬Biを追加し、
優先度付きキューから取ってきた最大値を答えに加え、
次にAi=2の仕事について優先度付きキューに報酬Biを追加し、
優先度付きキューから取ってきた最大値を答えに加え、
…最後にAi=Mの仕事について優先度付きキューに報酬Biを追加し、
優先度付きキューから取ってきた最大値を答えに加えることで、
求める答えが得られます。
'''
import heapq
n,m=list(map(int,input().split()))
arr=[list(map(int,input().split())) for _ in range(n)]
arr2=[[i,0] for i in range(1,m+2)] 
#すべてのAi=1 to Mについて報酬0の仕事を追加する
#こうすることで、必ずAiに対し、報酬0でも仕事がある⇒空振りがなくなる
arr.extend(arr2)
arr=sorted(arr,key=lambda x:x[0]) #Aiの小さい順にソート
q=[]
ans=0
pos=0
while 1:
 a,b=arr[pos]
 if a>m: #AiがMより大きければその仕事を請ける意味はない
   break
 if a==arr[pos+1][0]: 
  #Aiの値が等しいとき、その仕事を優先度付きキューに追加する
   heapq.heappush(q,-b)#マイナスを付けて、ヒープキューに入れている
 else:
   heapq.heappush(q,-b)
   ans-=heapq.heappop(q)#ヒープキューから最大値を持ってくるのでマイナス
  #Aiの値が変化したとき、そのAiまででの仕事の報酬の最大値を答えに加える
 pos+=1
print(ans)
# Original solution
#### import ####
import sys
import math
from collections import defaultdict

#### 設定 ####
sys.setrecursionlimit(10**7)

#### 定数 ####
mod = 10**9 + 7

#### 読み込み ####
def I(): return int(eval(input()))
def II(): return list(map(int, input().split()))
def III(): return list(map(int, input().split()))
def Line(N):
  read_all = [tuple(map(int, input().split())) for _ in range(N)]
  return list(map(list,list(zip(*read_all))))

#################

N,M = II()
A,B = Line(N)
a = []
for i in range(N):
  a.append([A[i],B[i]])
a.sort(key = lambda x:(-x[1]))

from bisect import bisect_left
s = [i for i in range(1,M+1)]
ans = 0
for i in range(N):
  if a[i][0]<=M:
    place = bisect_left(s,a[i][0])
    if place <= len(s)-1:
      s.pop(place)
      ans += a[i][1]
print(ans)

# Optimized solution
#### import ####
import sys
import math
from collections import defaultdict

#### 設定 ####
sys.setrecursionlimit(10**7)

#### 定数 ####
mod = 10**9 + 7

#### 読み込み ####
def I(): return int(eval(input()))
def II(): return list(map(int, input().split()))
def III(): return list(map(int, input().split()))
def Line(N):
  read_all = [tuple(map(int, input().split())) for _ in range(N)]
  return list(map(list,list(zip(*read_all))))

#################

N,M = II()
A,B = Line(N)
a = []
for i in range(N):
  a.append([A[i],B[i]])
a.sort(key = lambda x:(x[0],x[1]))

b = []
for i in range(N):
  b.append([-a[i][1], a[i][0]])

from bisect import bisect_left, bisect_right
import heapq

ans = 0
h = []

for i in range(1,M+1):
  left = bisect_left(a,[i,0])
  right = bisect_right(a,[i,float('inf')])-1
  if right-left>=0:
    for i in range(left,right+1):
      heapq.heappush(h,b[i])
    x = heapq.heappop(h)
    ans += -x[0]
  else:
    if h:
      x = heapq.heappop(h)
      ans += -x[0]

print(ans)
# Original solution
from bisect import bisect_left
import sys
input = sys.stdin.readline

N, M = list(map(int, input().split()))
AB = [[int(i) for i in input().split()] for _ in range(N)]

AB.sort(key=lambda x: x[1], reverse=True)

s = [i for i in range(1, M + 1)]
ret = 0
for a, b in AB :
    if a > s[-1] :
        continue
    
    a = bisect_left(s, a)
    s.pop(a)
    ret += b
    if not s :
        break
print(ret)


# Optimized solution
from heapq import heappush, heappop

N, M = list(map(int, input().split()))
AB = [[] for _ in range(M+1)]

for _ in range(N) :
    a, b = list(map(int, input().split()))
    if a <= M :
        AB[M-a].append(b)
    
q = []
for a in range(M+1) :
    for b in AB[a] :
        heappush(q, b)
        if len(q) > a + 1 :
            heappop(q)
            
print((sum(q)))
# Original solution
import sys
import math
import itertools
import bisect
from copy import copy
from collections import deque,Counter
from decimal import Decimal
def s(): return eval(input())
def i(): return int(eval(input()))
def S(): return input().split()
def I(): return list(map(int,input().split()))
def L(): return list(input().split())
def l(): return list(map(int,input().split()))
def lcm(a,b): return a*b//math.gcd(a,b)
sys.setrecursionlimit(10**9)
INF = 10**9
mod = 10**9+7
import heapq

N,M = I()
L = [l() for _ in range(N)]
A = []
B = []
L.sort()
ans = 0
for a,b in L:
    A.append(a)
    B.append(b)
q = []
heapq.heapify(q)
for i in range(1,M+1):
    for j in range(len(A)):
        if A[0] > i:
            break
        else:
            A.pop(0)
            heapq.heappush(q,B.pop(0)*-1)
    if q:
        ans += heapq.heappop(q)*-1
print(ans)

# Optimized solution
import sys
import math
import itertools
import bisect
from copy import copy
from collections import deque,Counter
from decimal import Decimal
def s(): return eval(input())
def i(): return int(eval(input()))
def S(): return input().split()
def I(): return list(map(int,input().split()))
def L(): return list(input().split())
def l(): return list(map(int,input().split()))
def lcm(a,b): return a*b//math.gcd(a,b)
sys.setrecursionlimit(10**9)
INF = 10**9
mod = 10**9+7
import heapq

N,M = I()
L = [l() for _ in range(N)]
A = deque([])
B = deque([])
L.sort()
ans = 0
for a,b in L:
    A.append(a)
    B.append(b)
q = []
heapq.heapify(q)
for i in range(1,M+1):
    for j in range(len(A)):
        if A[0] > i:
            break
        else:
            A.popleft()
            heapq.heappush(q,B.popleft()*-1)
    if q:
        ans += heapq.heappop(q)*-1
print(ans)
# Original solution
N, M = list(map(int, input().split()))
AB = [list(map(int, input().split())) for _ in range(N)]

AB.sort()
B = [[] for _ in range(100005)]
tmp = 0
for ab in AB:
  if ab[0] != tmp:
    B[ab[0]] = B[tmp].copy()
  B[ab[0]].append(ab[1])
  tmp = ab[0]

for i in range(1, M + 1):
  if len(B[i]) == 0:
    B[i] = B[i - 1].copy()

ans = 0
for i in range(1, M + 1):
  if len(B[i]) > 0:
    m = max(B[i])
    ans += m
    for j in range(i, M + 1):
      if len(B[j]) > 0:
        B[j].remove(m)

print(ans)

# Optimized solution
N, M = list(map(int, input().split()))
AB = []

for i in range(N):
  ab = list(map(int, input().split()))
  if ab[0] <= M:
    AB.append(ab)

AB.sort(reverse = True, key = lambda x:x[1])
ans = 0
for i in range(1, M + 1):
  for j in range(len(AB)):
    if AB[j][0] <= i:
      ans += AB.pop(j)[1]
      break

print(ans)
# Original solution
from heapq import heappush, heappop

N, M = list(map(int, input().split()))
AB = []

for i in range(N):
  ab = list(map(int, input().split()))
  #Ai > M の仕事はいらない
  if ab[0] <= M:
    AB.append(ab)

#最終日はAi=1の仕事のみ選べる。その前の日はAi<=2, ...
#終わりから考えればよさそう
AB.sort()
hq = []
ans = 0
for i in range(1, M + 1):
  while len(AB) > 0 and AB[0][0] <= i:
    heappush(hq, -1 * AB.pop(0)[1])
  if len(hq) > 0:
    m = -1 * heappop(hq)
    ans += m

print(ans)

# Optimized solution
from heapq import heappush, heappop

N, M = list(map(int, input().split()))
jobs = [[] for _ in range(M)]

for i in range(N):
  ab = list(map(int, input().split()))
  #Ai > M の仕事はいらない
  if ab[0] <= M:
    jobs[ab[0] - 1].append(ab[1])

#最終日はAi=1の仕事のみ選べる。その前の日はAi<=2, ...
#終わりから考えればよさそう
hq = []
ans = 0
for i in range(M):
  for b in jobs[i]:
    heappush(hq, -1 * b)
  if len(hq) > 0:
    m = -1 * heappop(hq)
    ans += m

print(ans)
# Original solution
import heapq
import bisect
N, M = list(map(int, input().split()))
ABs = [list(map(int, input().split())) for _ in range(N)]

lists = [[] for _ in range(10**5 + 1)]
availables = []
for A, B in ABs:
    bisect.insort(lists[A], B)

ans = 0
for i in range(1, M + 1):
    availables = list(heapq.merge(availables, lists[i]))
    if availables:
        ans += availables.pop()

print(ans)

# Optimized solution
import heapq
N, M = list(map(int, input().split()))
ABs = [list(map(int, input().split())) for _ in range(N)]

heapq.heapify(ABs)
availables = []
ans = 0
for i in range(1, M + 1):
    while ABs:
        a = heapq.heappop(ABs)
        if a[0] == i:
            heapq.heappush(availables, -a[1])
        else:
            heapq.heappush(ABs, a)
            break
    if availables:
        ans -= heapq.heappop(availables)

print(ans)
# Original solution
from heapq import heappush, heappop
N, M = list(map(int, input().split()))
Data = [list(map(int, input().split())) for _ in range(N)]

heap = [0] * M
ans = 0
for i in range(1, M+1):
    N = len(Data)
    for j in range(N-1, -1, -1):
        if (Data[j][0] <= i):
            heappush(heap, -(Data.pop(j)[1]))

    ans += -(heappop(heap))

print(ans)


# Optimized solution
from heapq import heappush, heappop
N, M = list(map(int, input().split()))

Data = [list(map(int, input().split())) for _ in range(N)]
Data.sort(reverse = True)

heap = [0] * M
ans = 0
for i in range(1, M+1):
    N = len(Data)
    for j in range(N-1, -1, -1):
        if Data[j][0] > i:
            break
        if (Data[j][0] <= i):
            heappush(heap, -(Data.pop(j)[1]))

    ans += -(heappop(heap))

print(ans)
# Original solution
import heapq

n, m = list(map(int, input().split()))

dic = {}
for i in range(n):
    a, b = list(map(int, input().split()))
    if a >= m+1:
        continue
    if a in list(dic.keys()):
        dic[a].append(b)
    else:
        dic[a] = [b]

ans = 0
l = []
heapq.heapify(l)
for j in range(1, m+1):
    if j in list(dic.keys()):
        for x in dic[j]:
            heapq.heappush(l, -x)
    if l:
        ans += -l[0]
        heapq.heappop(l)

print(ans)

# Optimized solution
import heapq

n, m = list(map(int, input().split()))
memo = [[] for _ in range(m+1)]

for _ in range(n):
    a, b = list(map(int ,input().split()))
    if a <= m:
        memo[a].append(-b)

ans = 0
HQ = []
heapq.heapify(HQ)
for i in range(1, m+1):
    for j in memo[i]:
        heapq.heappush(HQ, j)
    if HQ:
        ans += heapq.heappop(HQ)

print((-ans))
# Original solution
import heapq
#listから複数index削除するやつ
dellist = lambda items, indexes: [item for index, item in enumerate(items) if index not in indexes]

[N,M]=[int(x) for x in input().split()]
work=[[int(x) for x in input().split()] for _ in range(N)]

work.sort() #日付の短い順にsortしておく　これいる？いる！！！！
tank=[] #候補を入れる
res=0 #回答
indexlist=[] #バイトは重複不可なので決定済の労働をindexで管理

for i in range(M+1): #日付を後ろから見ていく
  for n,item in enumerate(work): #（日付的に働けるかをみて）候補たりうるものを探しheapqに突っ込む
    if item[0]<=i:
      heapq.heappush(tank,-item[1])
      indexlist.append(n)
      
    work=dellist(work,indexlist)
    indexlist=[]
    
  #print("tank1:",tank)
  
  if len(tank)==0: #候補がなければ次の日へ
    #print("continue.")
    continue

  else: #候補があればもっとも良いのを回答に足す
    res -= heapq.heappop(tank)
    #print("res=",res)
    
  #print("tank2:",tank)
    
print(res)

# Optimized solution
import heapq
#listから複数index削除するやつ
dellist = lambda items, indexes: [item for index, item in enumerate(items) if index not in indexes]

[N,M]=[int(x) for x in input().split()]
work=[[int(x) for x in input().split()] for _ in range(N)]

work.sort() #日付の短い順にsortしておく　これいる？いる！！！！
tank=[] #候補を入れる
res=0 #回答
j=0

for i in range(M+1): #日付を後ろから見ていく
  while j<=N-1 and work[j][0]<=i: #forじゃないのはheapqに入れた分はずっと候補なのでもうみなくていいため
    heapq.heappush(tank,-work[j][1])
    j+=1
  #print("tank1:",tank)
  
  if len(tank)==0: #候補がなければ次の日へ
    #print("continue.")
    continue

  else: #候補があればもっとも良いのを回答に足す
    res -= heapq.heappop(tank)
    #print("res=",res)
    
  #print("tank2:",tank)
    
print(res)
# Original solution
from collections import deque


N, M = list(map(int, input().split()))
ab_list = [ list(map(int, input().split())) for i in range(N)]

score_list = [[] for i in range(M+1)]


for ab in ab_list:
    if ab[0] <= M:
        score_list[ab[0]].append(ab[1])

scores = [deque() for i in range(M+1)]
for i in range(len(score_list)):
    scores[i] = deque(sorted(score_list[i], reverse=True))

ans = 0
for i in range(0, M+1):

    max_idx = -1
    max_n = -1
    for j in range(i+1):
        if len(scores[j]) == 0:
          continue
        if max_n < scores[j][0]:
            max_n = scores[j][0]
            max_idx = j

    if max_idx > 0:
        ans += scores[max_idx].popleft()

print(ans)

# Optimized solution
import heapq


N, M = list(map(int, input().split()))
ab_list = [ list(map(int, input().split())) for i in range(N)]

score_list = [[] for i in range(M+1)]


for ab in ab_list:
    if ab[0] <= M:
        score_list[ab[0]].append(ab[1])


ans = 0
candidates = []

for i in range(0, M+1):

    for s in score_list[i]:
        heapq.heappush(candidates, -s)
    if len(candidates) == 0:
        continue
    ans -= heapq.heappop(candidates)


print(ans)
# Original solution
from collections import defaultdict as dd
from collections import deque

n,m=list(map(int,input().split()))
dic=dd(list)
for i in range(1,m+1):
    dic[i]=[0]*m

for i in range(n):
    a,b=list(map(int,input().split()))
    dic[a].append(b)


for k,v in list(dic.items()):
    dic[k]=deque(sorted(dic[k],reverse=True))

#print(dic)

ans=0
max2nd=[0]*m
for i in reversed(list(range(m))):
    d=m-i
    a=dic[d][0]
    max2nd=deque(sorted(max2nd,reverse=True))
    b=max2nd[0]
    if a>=b:
        ans+=dic[d].popleft()
    else:
        ans+=max2nd.popleft()
    max2nd+=dic[d]
        

print(ans)


# Optimized solution
from collections import defaultdict as dd
from collections import deque

n,m=list(map(int,input().split()))
dic=dd(list)
for i in range(1,m+1):
    dic[i]=[0]


for i in range(n):
    a,b=list(map(int,input().split()))
    dic[a].append(b)


for k,v in list(dic.items()):
    dic[k]=deque(sorted(dic[k],reverse=True))

#print(dic)

ans=0
max2nd=[0]
for i in reversed(list(range(m))):
    d=m-i
    a=dic[d][0]
    max2nd=deque(sorted(max2nd,reverse=True))
    b=max2nd[0]
    if a>=b:
        ans+=dic[d].popleft()
        if len(dic[d])==0: dic[d]=[0];
    else:
        ans+=max2nd.popleft()
        if len(max2nd)==0: max2nd=[0];
    max2nd+=dic[d]
        

print(ans)
# Original solution
import heapq
from collections import defaultdict
N,M = list(map(int,input().split()))
AB = defaultdict(list)
for i in range(N):
    a,b = list(map(int,input().split()))
    if a not in AB:
        AB[a] = [-b]
    else:
        AB[a] += [-b]
work = 0
AB2 = []
for i in range(1,M+1):
    AB2 += AB[i]
    heapq.heapify(AB2)
    if not AB2:
        continue
    b = heapq.heappop(AB2)
    work += -b
print(work)

# Optimized solution
import heapq
from collections import defaultdict
N,M = list(map(int,input().split()))
AB = defaultdict(list)
for i in range(N):
    a,b = list(map(int,input().split()))
    if a not in AB:
        AB[a] = [-b]
    else:
        AB[a] += [-b]
work = 0
AB2 = []
heapq.heapify(AB2)
for i in range(1,M+1):
    for j in AB[i]:
        heapq.heappush(AB2,j)
    if not AB2:
        continue
    b = heapq.heappop(AB2)
    work += -b
print(work)