Buggy python submission (verdict: Time Limit Exceeded):
import heapq
import os
import sys

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(2147483647)
INF = float("inf")
IINF = 10 ** 18
MOD = 10 ** 9 + 7


class PrimalDual:
    """
    最小費用流 ダイクストラ版
    """

    def __init__(self, graph=None, residual=None):
        """
        :param list of (list of (int, int, int)) graph: (to, cap, cost) の隣接リスト
        :param list of (list of (list of (int|list))) residual: (to, cap, cost, rev) の残余グラフ
        """
        assert (graph and not residual) or (not graph and residual)
        if graph:
            self.graph = self.residual_graph(graph)
        else:
            self.graph = residual

    @staticmethod
    def residual_graph(graph):
        """
        残余グラフ構築
        :param list of (list of (int, int, int)) graph: (to, cap, cost) の隣接リスト
        :rtype: list of (list of (list of (int|list)))
        :return: (to, cap, cost, rev) の残余グラフ
        """
        ret = [[] for _ in range(len(graph))]
        for v in range(len(graph)):
            for u, cap, cost in graph[v]:
                rev = [v, 0, -cost]
                edge = [u, cap, cost, rev]
                rev.append(edge)
                ret[v].append(edge)
                ret[u].append(rev)
        return ret

    def solve(self, from_v, to_v, flow):
        """
        :param int from_v:
        :param int to_v:
        :param int flow:
        :rtype: int
        """
        total_cost = 0
        prevv = [-1] * len(self.graph)
        preve = [-1] * len(self.graph)
        # ポテンシャル
        h = [0] * len(self.graph)
        remains = flow
        while remains > 0:
            dist = [float('inf')] * len(self.graph)
            dist[from_v] = 0
            heap = [(0, from_v)]

            # Dijkstra
            while heap:
                d, v = heapq.heappop(heap)
                if d > dist[v]:
                    continue
                for edge in self.graph[v]:
                    u, cap, cost, rev = edge
                    if cap > 0 and dist[v] + cost + h[v] - h[u] < dist[u]:
                        dist[u] = dist[v] + cost + h[v] - h[u]
                        prevv[u] = v
                        preve[u] = edge
                        heapq.heappush(heap, (dist[u], u))

            if dist[to_v] == float('inf'):
                # これ以上流せない
                break

            for i, d in enumerate(dist):
                h[i] += d

            # 最短路に流せる量
            flow = remains
            v = to_v
            while v != from_v:
                cap = preve[v][1]
                flow = min(cap, flow)
                v = prevv[v]

            # 最短路に flow だけ流す
            v = to_v
            while v != from_v:
                preve[v][1] -= flow
                preve[v][3][1] += flow
                v = prevv[v]

            remains -= flow
            total_cost += flow * h[to_v]
        return total_cost


N, M = list(map(int, sys.stdin.readline().split()))
AB = [list(map(int, sys.stdin.readline().split())) for _ in range(N)]

S = M
T = M + 1
graph = [[] for _ in range(M + 2)]
for i in range(M):
    graph[i].append((T, 1, 0))
for i in range(M - 1):
    graph[i + 1].append((i, IINF, 0))
for a, b in AB:
    if M - a >= 0:
        graph[S].append((M - a, 1, -b))

ans = -PrimalDual(graph).solve(S, T, IINF)
print(ans)


Fixed submission:
import heapq
import os
import sys

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(2147483647)
INF = float("inf")
IINF = 10 ** 18
MOD = 10 ** 9 + 7

N, M = list(map(int, sys.stdin.readline().split()))
AB = [list(map(int, sys.stdin.readline().split())) for _ in range(N)]

AB.sort(key=lambda ab: (ab[0], -ab[1]))

heap = []
abi = 0
ans = 0
for i in range(1, M + 1):
    # i までのやつは入れられる
    while abi < N and AB[abi][0] <= i:
        a, b = AB[abi]
        heapq.heappush(heap, (-b, a))
        abi += 1
    if heap:
        b, a = heapq.heappop(heap)
        ans += -b
print(ans)