Buggy python submission (verdict: Time Limit Exceeded):
#!/usr/bin/env python3

import numpy as np

def solve(N, M, A, B):
    # print('A', A)
    # print('B', B)
    ans = 0
    # 日付順にソートする
    dtype = [('a', np.uint32), ('b', np.uint32)]
    ab = np.array(list(zip(A, B)), dtype=dtype)
    ab = np.sort(ab, order='a')

    works = np.empty(ab.size, dtype=dtype)
    # print('ab=', ab)
    ans = 0
    ab_idx = 0
    works_n = 0
    for d in range(1, M+1):
        # print('d=', d)
        if ab_idx < ab.size and ab[ab_idx]['a'] == d:
            while ab_idx < ab.size and ab[ab_idx]['a'] == d:
                works[works_n] = ab[ab_idx]
                works_n += 1
                ab_idx += 1
            works[0:works_n] = np.sort(works[0:works_n], order='b')
        if works_n > 0:
            ans += works[works_n-1]['b']
            works_n -= 1

    return ans


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)


Fixed submission:
#!/usr/bin/env python3

from collections import deque


class PriorityQueue:
    def __init__(self, size):
        self.tree = [None] * size
        self.bottom = 0

    def add(self, data):
        n = self.bottom
        self.bottom += 1
        self.tree[n] = data
        while n != 0:
            parent = (n - 1) // 2
            if self.tree[parent][1] < self.tree[n][1]:
                self.tree[parent], self.tree[n] = (
                    self.tree[n],
                    self.tree[parent],
                )
                n = parent
            else:
                return

    def top(self):
        return self.tree[0]

    def size(self):
        return self.bottom

    def pop_top(self):
        rv = self.tree[0]
        self.tree[0] = self.tree[self.bottom - 1]
        self.bottom -= 1
        n = 0
        while True:
            child1 = 2 * n + 1
            if child1 >= self.bottom:
                return rv
            child2 = 2 * n + 2
            if child2 >= self.bottom:
                child2 = child1

            if (
                self.tree[n][1] > self.tree[child1][1]
                and self.tree[n][1] > self.tree[child2][1]
            ):
                return rv
            elif self.tree[child1][1] > self.tree[child2][1]:
                self.tree[n], self.tree[child1] = (
                    self.tree[child1],
                    self.tree[n],
                )
                n = child1
            else:
                self.tree[n], self.tree[child2] = (
                    self.tree[child2],
                    self.tree[n],
                )
                n = child2
        return rv


def solve(N, M, A, B):
    ans = 0
    # 日付順にソートする
    all_works = deque(sorted(zip(A, B), key=lambda x: x[0]))
    pq = PriorityQueue(N)

    for d in range(1, M+1):
        # print('d=', d)
        # 今日が期限の仕事があれば追加
        while all_works and all_works[0][0] == d:
            work = all_works.popleft()
            pq.add(work)
        # print('all_works', all_works)
        # print('pq=', pq.tree)
        # 優先キューから最優先の仕事をする
        if pq.size():
            work = pq.pop_top()
            ans += work[1]

    return ans


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
#!/usr/bin/env python3

import numpy as np

def solve(N, M, A, B):
    # print('A', A)
    # print('B', B)
    ans = 0
    # 日付順にソートする
    dtype = [('a', np.int), ('b', np.int)]
    ab = np.array(list(zip(A, B)), dtype=dtype)
    ab = np.sort(ab, order='a')

    works = np.zeros(ab.size, dtype=dtype)
    # print('ab=', ab)
    ans = 0
    ab_idx = 0
    works_n = 0
    for d in range(1, M+1):
        # print('d=', d)
        if ab_idx < ab.size and ab[ab_idx]['a'] == d:
            while ab_idx < ab.size and ab[ab_idx]['a'] == d:
                works[works_n] = ab[ab_idx]
                works_n += 1
                ab_idx += 1
            works[0:works_n] = np.sort(works[0:works_n], order='b')
        if works_n > 0:
            ans += works[works_n-1]['b']
            works_n -= 1

    return ans


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)


Fixed submission:
#!/usr/bin/env python3

from collections import deque


class PriorityQueue:
    def __init__(self, size):
        self.tree = [None] * size
        self.bottom = 0

    def add(self, data):
        n = self.bottom
        self.bottom += 1
        self.tree[n] = data
        while n != 0:
            parent = (n - 1) // 2
            if self.tree[parent][1] < self.tree[n][1]:
                self.tree[parent], self.tree[n] = (
                    self.tree[n],
                    self.tree[parent],
                )
                n = parent
            else:
                return

    def top(self):
        return self.tree[0]

    def size(self):
        return self.bottom

    def pop_top(self):
        rv = self.tree[0]
        self.tree[0] = self.tree[self.bottom - 1]
        self.bottom -= 1
        n = 0
        while True:
            child1 = 2 * n + 1
            if child1 >= self.bottom:
                return rv
            child2 = 2 * n + 2
            if child2 >= self.bottom:
                child2 = child1

            if (
                self.tree[n][1] > self.tree[child1][1]
                and self.tree[n][1] > self.tree[child2][1]
            ):
                return rv
            elif self.tree[child1][1] > self.tree[child2][1]:
                self.tree[n], self.tree[child1] = (
                    self.tree[child1],
                    self.tree[n],
                )
                n = child1
            else:
                self.tree[n], self.tree[child2] = (
                    self.tree[child2],
                    self.tree[n],
                )
                n = child2
        return rv


def solve(N, M, A, B):
    ans = 0
    # 日付順にソートする
    all_works = deque(sorted(zip(A, B), key=lambda x: x[0]))
    pq = PriorityQueue(N)

    for d in range(1, M+1):
        # print('d=', d)
        # 今日が期限の仕事があれば追加
        while all_works and all_works[0][0] == d:
            work = all_works.popleft()
            pq.add(work)
        # print('all_works', all_works)
        # print('pq=', pq.tree)
        # 優先キューから最優先の仕事をする
        if pq.size():
            work = pq.pop_top()
            ans += work[1]

    return ans


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
#!/usr/bin/env python3

from collections import deque
from bisect import insort_left


# 仕事を仕事リストに追加する
# 仕事リストはポイントが大きい順、同じ仕事なら日付が多い順に並んでいる
# これを実現するため -b, -a としている
def add_work(works, ab):
    ba = (-ab[1], -ab[0])
    insort_left(works, ba)


def solve(N, M, A, B):
    ans = 0
    # 下準備 A,B をまとめ、日付順にソートする
    ab_que = deque(list(sorted(zip(A, B))))
    # 仕事リスト
    works = []
    for i in range(1, M+1):
        # 丁度間に合う仕事があれば追加する
        while ab_que and ab_que[0][0] == i:
            ab = ab_que.popleft()
            add_work(works, ab)
        # 仕事を一つする
        if works:
            ans -= works[0][0]
            works = works[1:]

    return ans


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)


Fixed submission:
#!/usr/bin/env python3

from collections import deque


class PriorityQueue:
    def __init__(self, size):
        self.tree = [None] * size
        self.bottom = 0

    def add(self, data):
        n = self.bottom
        self.bottom += 1
        self.tree[n] = data
        while n != 0:
            parent = (n - 1) // 2
            if self.tree[parent][1] < self.tree[n][1]:
                self.tree[parent], self.tree[n] = (
                    self.tree[n],
                    self.tree[parent],
                )
                n = parent
            else:
                return

    def top(self):
        return self.tree[0]

    def size(self):
        return self.bottom

    def pop_top(self):
        rv = self.tree[0]
        self.tree[0] = self.tree[self.bottom - 1]
        self.bottom -= 1
        n = 0
        while True:
            child1 = 2 * n + 1
            if child1 >= self.bottom:
                return rv
            child2 = 2 * n + 2
            if child2 >= self.bottom:
                child2 = child1

            if (
                self.tree[n][1] > self.tree[child1][1]
                and self.tree[n][1] > self.tree[child2][1]
            ):
                return rv
            elif self.tree[child1][1] > self.tree[child2][1]:
                self.tree[n], self.tree[child1] = (
                    self.tree[child1],
                    self.tree[n],
                )
                n = child1
            else:
                self.tree[n], self.tree[child2] = (
                    self.tree[child2],
                    self.tree[n],
                )
                n = child2
        return rv


def solve(N, M, A, B):
    ans = 0
    # 日付順にソートする
    all_works = deque(sorted(zip(A, B), key=lambda x: x[0]))
    pq = PriorityQueue(N)

    for d in range(1, M+1):
        # print('d=', d)
        # 今日が期限の仕事があれば追加
        while all_works and all_works[0][0] == d:
            work = all_works.popleft()
            pq.add(work)
        # print('all_works', all_works)
        # print('pq=', pq.tree)
        # 優先キューから最優先の仕事をする
        if pq.size():
            work = pq.pop_top()
            ans += work[1]

    return ans


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
from bisect import bisect_right
 
 
def solve(N, M, A, B):
    ab = dict()
    for a, b in zip(A, B):
        if a in ab:
            ab[a].append(b)
        else:
            ab[a] = [b]
 
    keys = []
    for a in ab:
        ab[a] = sorted(ab[a], reverse=True)
        keys.append(a)
    keys = sorted(keys)
 
    # print('ab=', ab)
    # print('keys=', keys)
 
    total = 0
    for i in range(1, M+1):
        if i < keys[0]:
            continue
        # print('i=', i)
        mx = 0
        pos = -1
        for j in range(bisect_right(keys, i)):
            # print('  j=', j)
            key = keys[j]
            if ab[key][0] > mx:
                mx = ab[key][0]
                pos = j
        if pos >= 0:
            total += mx
            key = keys[pos]
            ab[key] = ab[key][1:]
            if len(ab[key]) == 0:
                keys = keys[0:pos] + keys[pos+1:]
                if len(keys) == 0:
                    break
            # print(' ab=', ab)
            # print(' keys=', keys)
 
    return total
 
 
if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())
 
    ans = solve(N, M, A, B)
 
    print(ans)

Fixed submission:
#!/usr/bin/env python3

from collections import deque


class PriorityQueue:
    def __init__(self, size):
        self.tree = [None] * size
        self.bottom = 0

    def add(self, data):
        n = self.bottom
        self.bottom += 1
        self.tree[n] = data
        while n != 0:
            parent = (n - 1) // 2
            if self.tree[parent][1] < self.tree[n][1]:
                self.tree[parent], self.tree[n] = (
                    self.tree[n],
                    self.tree[parent],
                )
                n = parent
            else:
                return

    def top(self):
        return self.tree[0]

    def size(self):
        return self.bottom

    def pop_top(self):
        rv = self.tree[0]
        self.tree[0] = self.tree[self.bottom - 1]
        self.bottom -= 1
        n = 0
        while True:
            child1 = 2 * n + 1
            if child1 >= self.bottom:
                return rv
            child2 = 2 * n + 2
            if child2 >= self.bottom:
                child2 = child1

            if (
                self.tree[n][1] > self.tree[child1][1]
                and self.tree[n][1] > self.tree[child2][1]
            ):
                return rv
            elif self.tree[child1][1] > self.tree[child2][1]:
                self.tree[n], self.tree[child1] = (
                    self.tree[child1],
                    self.tree[n],
                )
                n = child1
            else:
                self.tree[n], self.tree[child2] = (
                    self.tree[child2],
                    self.tree[n],
                )
                n = child2
        return rv


def solve(N, M, A, B):
    ans = 0
    # 日付順にソートする
    all_works = deque(sorted(zip(A, B), key=lambda x: x[0]))
    pq = PriorityQueue(N)

    for d in range(1, M+1):
        # print('d=', d)
        # 今日が期限の仕事があれば追加
        while all_works and all_works[0][0] == d:
            work = all_works.popleft()
            pq.add(work)
        # print('all_works', all_works)
        # print('pq=', pq.tree)
        # 優先キューから最優先の仕事をする
        if pq.size():
            work = pq.pop_top()
            ans += work[1]

    return ans


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
#!/usr/bin/env python3

# from operator import neg
from bisect import bisect_right
from itertools import accumulate


def solve(N, M, A, B):
    ab = dict()
    for a, b in zip(A, B):
        if a in ab:
            ab[a].append(b)
        else:
            ab[a] = [b]

    keys = []
    for a in ab:
        ab[a] = sorted(ab[a], reverse=True)
        keys.append(a)
    keys = sorted(keys)

    mxs = list(accumulate([ab[key][0] for key in keys], max))

    total = 0
    for i in range(1, M+1):
        if i < keys[0]:
            continue
        # print('i=', i)
        mx = 0
        pos = -1
        for j in range(bisect_right(keys, i)):
            # print('  j=', j)
            key = keys[j]
            if ab[key][0] > mx:
                mx = ab[key][0]
                pos = j
            if mxs[j] == mx:
                break
        if pos >= 0:
            total += mx
            key = keys[pos]
            ab[key] = ab[key][1:]
            if len(ab[key]) == 0:
                keys = keys[0:pos] + keys[pos+1:]
                if len(keys) == 0:
                    break
            # print(' ab=', ab)
            # print(' keys=', keys)

    return total


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)


Fixed submission:
#!/usr/bin/env python3

from collections import deque


class PriorityQueue:
    def __init__(self, size):
        self.tree = [None] * size
        self.bottom = 0

    def add(self, data):
        n = self.bottom
        self.bottom += 1
        self.tree[n] = data
        while n != 0:
            parent = (n - 1) // 2
            if self.tree[parent][1] < self.tree[n][1]:
                self.tree[parent], self.tree[n] = (
                    self.tree[n],
                    self.tree[parent],
                )
                n = parent
            else:
                return

    def top(self):
        return self.tree[0]

    def size(self):
        return self.bottom

    def pop_top(self):
        rv = self.tree[0]
        self.tree[0] = self.tree[self.bottom - 1]
        self.bottom -= 1
        n = 0
        while True:
            child1 = 2 * n + 1
            if child1 >= self.bottom:
                return rv
            child2 = 2 * n + 2
            if child2 >= self.bottom:
                child2 = child1

            if (
                self.tree[n][1] > self.tree[child1][1]
                and self.tree[n][1] > self.tree[child2][1]
            ):
                return rv
            elif self.tree[child1][1] > self.tree[child2][1]:
                self.tree[n], self.tree[child1] = (
                    self.tree[child1],
                    self.tree[n],
                )
                n = child1
            else:
                self.tree[n], self.tree[child2] = (
                    self.tree[child2],
                    self.tree[n],
                )
                n = child2
        return rv


def solve(N, M, A, B):
    ans = 0
    # 日付順にソートする
    all_works = deque(sorted(zip(A, B), key=lambda x: x[0]))
    pq = PriorityQueue(N)

    for d in range(1, M+1):
        # print('d=', d)
        # 今日が期限の仕事があれば追加
        while all_works and all_works[0][0] == d:
            work = all_works.popleft()
            pq.add(work)
        # print('all_works', all_works)
        # print('pq=', pq.tree)
        # 優先キューから最優先の仕事をする
        if pq.size():
            work = pq.pop_top()
            ans += work[1]

    return ans


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
#!/usr/bin/env python3

# from operator import neg
from bisect import bisect_right


def solve(N, M, A, B):
    ab = dict()
    for a, b in zip(A, B):
        if a in ab:
            ab[a].append(b)
        else:
            ab[a] = [b]

    keys = []
    for a in ab:
        ab[a] = sorted(ab[a], reverse=True)
        keys.append(a)
    keys = sorted(keys)

    # print('ab=', ab)
    # print('keys=', keys)

    total = 0
    for i in range(1, M+1):
        if i < keys[0]:
            continue
        # print('i=', i)
        mx = 0
        pos = -1
        for j in range(bisect_right(keys, i)):
            # print('  j=', j)
            key = keys[j]
            if ab[key][0] > mx:
                mx = ab[key][0]
                pos = j
        if pos >= 0:
            total += mx
            key = keys[pos]
            ab[key] = ab[key][1:]
            if len(ab[key]) == 0:
                keys = keys[0:pos] + keys[pos+1:]
                if len(keys) == 0:
                    break
            # print(' ab=', ab)
            # print(' keys=', keys)

    return total


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)


Fixed submission:
#!/usr/bin/env python3

from collections import deque


class PriorityQueue:
    def __init__(self, size):
        self.tree = [None] * size
        self.bottom = 0

    def add(self, data):
        n = self.bottom
        self.bottom += 1
        self.tree[n] = data
        while n != 0:
            parent = (n - 1) // 2
            if self.tree[parent][1] < self.tree[n][1]:
                self.tree[parent], self.tree[n] = (
                    self.tree[n],
                    self.tree[parent],
                )
                n = parent
            else:
                return

    def top(self):
        return self.tree[0]

    def size(self):
        return self.bottom

    def pop_top(self):
        rv = self.tree[0]
        self.tree[0] = self.tree[self.bottom - 1]
        self.bottom -= 1
        n = 0
        while True:
            child1 = 2 * n + 1
            if child1 >= self.bottom:
                return rv
            child2 = 2 * n + 2
            if child2 >= self.bottom:
                child2 = child1

            if (
                self.tree[n][1] > self.tree[child1][1]
                and self.tree[n][1] > self.tree[child2][1]
            ):
                return rv
            elif self.tree[child1][1] > self.tree[child2][1]:
                self.tree[n], self.tree[child1] = (
                    self.tree[child1],
                    self.tree[n],
                )
                n = child1
            else:
                self.tree[n], self.tree[child2] = (
                    self.tree[child2],
                    self.tree[n],
                )
                n = child2
        return rv


def solve(N, M, A, B):
    ans = 0
    # 日付順にソートする
    all_works = deque(sorted(zip(A, B), key=lambda x: x[0]))
    pq = PriorityQueue(N)

    for d in range(1, M+1):
        # print('d=', d)
        # 今日が期限の仕事があれば追加
        while all_works and all_works[0][0] == d:
            work = all_works.popleft()
            pq.add(work)
        # print('all_works', all_works)
        # print('pq=', pq.tree)
        # 優先キューから最優先の仕事をする
        if pq.size():
            work = pq.pop_top()
            ans += work[1]

    return ans


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
#!/usr/bin/env python3

from operator import neg
from bisect import bisect_left


MIN = -10**5-1


def solve(N, M, A, B):
    ab = list(sorted(zip(A, map(neg, B))))
    len_ab = len(ab)
    mx = 0
    for i in range(len_ab):
        if mx > ab[i][1]:
            mx = ab[i][1]
        ab[i] = tuple(list(ab[i]) + [mx])

    total = 0
    for i in range(1, M+1):
        right = bisect_left(ab, (i, MIN))
        if right >= len(ab):
            right -= 1
        if ab[right][0] > i:
            right -= 1

        pos = -1
        bmax = -1
        for j in range(right, -1, -1):
            if -ab[j][1] > bmax:
                bmax = -ab[j][1]
                pos = j
            if ab[j][1] == ab[j][2]:
                break
        if pos >= 0:
            ab = ab[0:pos] + ab[pos+1:]
            total += bmax
    return total


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)


Fixed submission:
#!/usr/bin/env python3

from collections import deque


class PriorityQueue:
    def __init__(self, size):
        self.tree = [None] * size
        self.bottom = 0

    def add(self, data):
        n = self.bottom
        self.bottom += 1
        self.tree[n] = data
        while n != 0:
            parent = (n - 1) // 2
            if self.tree[parent][1] < self.tree[n][1]:
                self.tree[parent], self.tree[n] = (
                    self.tree[n],
                    self.tree[parent],
                )
                n = parent
            else:
                return

    def top(self):
        return self.tree[0]

    def size(self):
        return self.bottom

    def pop_top(self):
        rv = self.tree[0]
        self.tree[0] = self.tree[self.bottom - 1]
        self.bottom -= 1
        n = 0
        while True:
            child1 = 2 * n + 1
            if child1 >= self.bottom:
                return rv
            child2 = 2 * n + 2
            if child2 >= self.bottom:
                child2 = child1

            if (
                self.tree[n][1] > self.tree[child1][1]
                and self.tree[n][1] > self.tree[child2][1]
            ):
                return rv
            elif self.tree[child1][1] > self.tree[child2][1]:
                self.tree[n], self.tree[child1] = (
                    self.tree[child1],
                    self.tree[n],
                )
                n = child1
            else:
                self.tree[n], self.tree[child2] = (
                    self.tree[child2],
                    self.tree[n],
                )
                n = child2
        return rv


def solve(N, M, A, B):
    ans = 0
    # 日付順にソートする
    all_works = deque(sorted(zip(A, B), key=lambda x: x[0]))
    pq = PriorityQueue(N)

    for d in range(1, M+1):
        # print('d=', d)
        # 今日が期限の仕事があれば追加
        while all_works and all_works[0][0] == d:
            work = all_works.popleft()
            pq.add(work)
        # print('all_works', all_works)
        # print('pq=', pq.tree)
        # 優先キューから最優先の仕事をする
        if pq.size():
            work = pq.pop_top()
            ans += work[1]

    return ans


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
#!/usr/bin/env python3

from operator import neg
from bisect import bisect_left


MIN = -10**5-1


def solve(N, M, A, B):
    ab = list(sorted(zip(A, map(neg, B))))
    total = 0
    for i in range(1, M+1):
        right = bisect_left(ab, (i, MIN))
        if right >= len(ab):
            right -= 1
        if ab[right][0] > i:
            right -= 1

        pos = -1
        bmax = -1
        for j in range(right, -1, -1):
            if -ab[j][1] > bmax:
                bmax = -ab[j][1]
                pos = j
        if pos >= 0:
            ab = ab[0:pos] + ab[pos+1:]
            total += bmax
    return total


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)


Fixed submission:
#!/usr/bin/env python3

from collections import deque


class PriorityQueue:
    def __init__(self, size):
        self.tree = [None] * size
        self.bottom = 0

    def add(self, data):
        n = self.bottom
        self.bottom += 1
        self.tree[n] = data
        while n != 0:
            parent = (n - 1) // 2
            if self.tree[parent][1] < self.tree[n][1]:
                self.tree[parent], self.tree[n] = (
                    self.tree[n],
                    self.tree[parent],
                )
                n = parent
            else:
                return

    def top(self):
        return self.tree[0]

    def size(self):
        return self.bottom

    def pop_top(self):
        rv = self.tree[0]
        self.tree[0] = self.tree[self.bottom - 1]
        self.bottom -= 1
        n = 0
        while True:
            child1 = 2 * n + 1
            if child1 >= self.bottom:
                return rv
            child2 = 2 * n + 2
            if child2 >= self.bottom:
                child2 = child1

            if (
                self.tree[n][1] > self.tree[child1][1]
                and self.tree[n][1] > self.tree[child2][1]
            ):
                return rv
            elif self.tree[child1][1] > self.tree[child2][1]:
                self.tree[n], self.tree[child1] = (
                    self.tree[child1],
                    self.tree[n],
                )
                n = child1
            else:
                self.tree[n], self.tree[child2] = (
                    self.tree[child2],
                    self.tree[n],
                )
                n = child2
        return rv


def solve(N, M, A, B):
    ans = 0
    # 日付順にソートする
    all_works = deque(sorted(zip(A, B), key=lambda x: x[0]))
    pq = PriorityQueue(N)

    for d in range(1, M+1):
        # print('d=', d)
        # 今日が期限の仕事があれば追加
        while all_works and all_works[0][0] == d:
            work = all_works.popleft()
            pq.add(work)
        # print('all_works', all_works)
        # print('pq=', pq.tree)
        # 優先キューから最優先の仕事をする
        if pq.size():
            work = pq.pop_top()
            ans += work[1]

    return ans


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)

Buggy python submission (verdict: Runtime Error):
#!/usr/bin/env python3

def total_money(bs, m, m_max):
    m = min(m, m_max)
    if m == 1:
        mx = 0
        for i in reversed(range(m)):
            if len(bs[i]) > 0:
                if bs[i][0] > mx:
                    mx = bs[i][0]
        return mx

    mx = 0
    max_tmp  = 0
    for i in reversed(range(m)):
        if len(bs[i]) > 0:
            tmp = bs[i][0]
            if tmp > max_tmp:
                max_tmp = tmp
                bs[i] = bs[i][1:]
                subtotal = total_money(bs, m-1, i+1)
                if tmp+subtotal > mx:
                    mx = tmp+subtotal
            bs[i].insert(0, tmp)
    return mx


def solve(N, M, A, B):
    # 下準備
    bs = [[]] * M
    for a,b in zip(A, B):
        if a <= M:
            bs[a-1] = sorted(bs[a-1] + [b], reverse=True)

    return total_money(bs, M, M)


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)


Fixed submission:
#!/usr/bin/env python3

from collections import deque


class PriorityQueue:
    def __init__(self, size):
        self.tree = [None] * size
        self.bottom = 0

    def add(self, data):
        n = self.bottom
        self.bottom += 1
        self.tree[n] = data
        while n != 0:
            parent = (n - 1) // 2
            if self.tree[parent][1] < self.tree[n][1]:
                self.tree[parent], self.tree[n] = (
                    self.tree[n],
                    self.tree[parent],
                )
                n = parent
            else:
                return

    def top(self):
        return self.tree[0]

    def size(self):
        return self.bottom

    def pop_top(self):
        rv = self.tree[0]
        self.tree[0] = self.tree[self.bottom - 1]
        self.bottom -= 1
        n = 0
        while True:
            child1 = 2 * n + 1
            if child1 >= self.bottom:
                return rv
            child2 = 2 * n + 2
            if child2 >= self.bottom:
                child2 = child1

            if (
                self.tree[n][1] > self.tree[child1][1]
                and self.tree[n][1] > self.tree[child2][1]
            ):
                return rv
            elif self.tree[child1][1] > self.tree[child2][1]:
                self.tree[n], self.tree[child1] = (
                    self.tree[child1],
                    self.tree[n],
                )
                n = child1
            else:
                self.tree[n], self.tree[child2] = (
                    self.tree[child2],
                    self.tree[n],
                )
                n = child2
        return rv


def solve(N, M, A, B):
    ans = 0
    # 日付順にソートする
    all_works = deque(sorted(zip(A, B), key=lambda x: x[0]))
    pq = PriorityQueue(N)

    for d in range(1, M+1):
        # print('d=', d)
        # 今日が期限の仕事があれば追加
        while all_works and all_works[0][0] == d:
            work = all_works.popleft()
            pq.add(work)
        # print('all_works', all_works)
        # print('pq=', pq.tree)
        # 優先キューから最優先の仕事をする
        if pq.size():
            work = pq.pop_top()
            ans += work[1]

    return ans


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)

Buggy python submission (verdict: Runtime Error):
#!/usr/bin/env python3

def total_money(bs, m):
    if m == 1:
        mx = 0
        for i in reversed(range(m)):
            if len(bs[i]) > 0:
                if bs[i][0] > mx:
                    mx = bs[i][0]
        return mx

    mx = 0
    max_tmp  = 0
    for i in reversed(range(m)):
        if len(bs[i]) > 0:
            tmp = bs[i][0]
            if tmp > max_tmp:
                max_tmp = tmp
                bs[i] = bs[i][1:]
                subtotal = total_money(bs, m-1)
                if tmp+subtotal > mx:
                    mx = tmp+subtotal
            bs[i].insert(0, tmp)
    return mx


def solve(N, M, A, B):
    # 下準備
    bs = [[]] * M
    for a,b in zip(A, B):
        if a <= M:
            bs[a-1] = sorted(bs[a-1] + [b], reverse=True)

    return total_money(bs, M)


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)


Fixed submission:
#!/usr/bin/env python3

from collections import deque


class PriorityQueue:
    def __init__(self, size):
        self.tree = [None] * size
        self.bottom = 0

    def add(self, data):
        n = self.bottom
        self.bottom += 1
        self.tree[n] = data
        while n != 0:
            parent = (n - 1) // 2
            if self.tree[parent][1] < self.tree[n][1]:
                self.tree[parent], self.tree[n] = (
                    self.tree[n],
                    self.tree[parent],
                )
                n = parent
            else:
                return

    def top(self):
        return self.tree[0]

    def size(self):
        return self.bottom

    def pop_top(self):
        rv = self.tree[0]
        self.tree[0] = self.tree[self.bottom - 1]
        self.bottom -= 1
        n = 0
        while True:
            child1 = 2 * n + 1
            if child1 >= self.bottom:
                return rv
            child2 = 2 * n + 2
            if child2 >= self.bottom:
                child2 = child1

            if (
                self.tree[n][1] > self.tree[child1][1]
                and self.tree[n][1] > self.tree[child2][1]
            ):
                return rv
            elif self.tree[child1][1] > self.tree[child2][1]:
                self.tree[n], self.tree[child1] = (
                    self.tree[child1],
                    self.tree[n],
                )
                n = child1
            else:
                self.tree[n], self.tree[child2] = (
                    self.tree[child2],
                    self.tree[n],
                )
                n = child2
        return rv


def solve(N, M, A, B):
    ans = 0
    # 日付順にソートする
    all_works = deque(sorted(zip(A, B), key=lambda x: x[0]))
    pq = PriorityQueue(N)

    for d in range(1, M+1):
        # print('d=', d)
        # 今日が期限の仕事があれば追加
        while all_works and all_works[0][0] == d:
            work = all_works.popleft()
            pq.add(work)
        # print('all_works', all_works)
        # print('pq=', pq.tree)
        # 優先キューから最優先の仕事をする
        if pq.size():
            work = pq.pop_top()
            ans += work[1]

    return ans


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)

Buggy python submission (verdict: Runtime Error):
#!/usr/bin/env python3

def total_money(bs, m):
    if m == 1:
        mx = 0
        for i in sorted(range(m)):
            if len(bs[i]) > 0:
                if bs[i][0] > mx:
                    mx = bs[i][0]
        return mx

    mx = 0
    for i in range(m):
        if len(bs[i]) > 0:
            tmp = bs[i][0]
            bs[i] = bs[i][1:]
            subtotal = total_money(bs, m-1)
            if tmp+subtotal > mx:
                mx = tmp+subtotal
            bs[i].insert(0, tmp)
    return mx


def solve(N, M, A, B):
    # 下準備
    bs = [[]] * M
    for a,b in zip(A, B):
        if a <= M:
            bs[a-1] = sorted(bs[a-1] + [b], reverse=True)

    return total_money(bs, M)


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)


Fixed submission:
#!/usr/bin/env python3

from collections import deque


class PriorityQueue:
    def __init__(self, size):
        self.tree = [None] * size
        self.bottom = 0

    def add(self, data):
        n = self.bottom
        self.bottom += 1
        self.tree[n] = data
        while n != 0:
            parent = (n - 1) // 2
            if self.tree[parent][1] < self.tree[n][1]:
                self.tree[parent], self.tree[n] = (
                    self.tree[n],
                    self.tree[parent],
                )
                n = parent
            else:
                return

    def top(self):
        return self.tree[0]

    def size(self):
        return self.bottom

    def pop_top(self):
        rv = self.tree[0]
        self.tree[0] = self.tree[self.bottom - 1]
        self.bottom -= 1
        n = 0
        while True:
            child1 = 2 * n + 1
            if child1 >= self.bottom:
                return rv
            child2 = 2 * n + 2
            if child2 >= self.bottom:
                child2 = child1

            if (
                self.tree[n][1] > self.tree[child1][1]
                and self.tree[n][1] > self.tree[child2][1]
            ):
                return rv
            elif self.tree[child1][1] > self.tree[child2][1]:
                self.tree[n], self.tree[child1] = (
                    self.tree[child1],
                    self.tree[n],
                )
                n = child1
            else:
                self.tree[n], self.tree[child2] = (
                    self.tree[child2],
                    self.tree[n],
                )
                n = child2
        return rv


def solve(N, M, A, B):
    ans = 0
    # 日付順にソートする
    all_works = deque(sorted(zip(A, B), key=lambda x: x[0]))
    pq = PriorityQueue(N)

    for d in range(1, M+1):
        # print('d=', d)
        # 今日が期限の仕事があれば追加
        while all_works and all_works[0][0] == d:
            work = all_works.popleft()
            pq.add(work)
        # print('all_works', all_works)
        # print('pq=', pq.tree)
        # 優先キューから最優先の仕事をする
        if pq.size():
            work = pq.pop_top()
            ans += work[1]

    return ans


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)

Buggy python submission (verdict: Runtime Error):
#!/usr/bin/env python3

def total_money(bs, m):
    if m == 1:
        mx = 0
        for i in range(m):
            if len(bs[i]) > 0:
                if bs[i][0] > mx:
                    mx = bs[i][0]
        return mx

    mx = 0
    for i in range(m):
        if len(bs[i]) > 0:
            tmp = bs[i][0]
            bs[i] = bs[i][1:]
            subtotal = total_money(bs, m-1)
            if tmp+subtotal > mx:
                mx = tmp+subtotal
            bs[i].insert(0, tmp)
    return mx


def solve(N, M, A, B):
    # 下準備
    bs = [[]] * M
    for a,b in zip(A, B):
        if a <= M:
            bs[a-1] = sorted(bs[a-1] + [b], reverse=True)

    return total_money(bs, M)


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)


Fixed submission:
#!/usr/bin/env python3

from collections import deque


class PriorityQueue:
    def __init__(self, size):
        self.tree = [None] * size
        self.bottom = 0

    def add(self, data):
        n = self.bottom
        self.bottom += 1
        self.tree[n] = data
        while n != 0:
            parent = (n - 1) // 2
            if self.tree[parent][1] < self.tree[n][1]:
                self.tree[parent], self.tree[n] = (
                    self.tree[n],
                    self.tree[parent],
                )
                n = parent
            else:
                return

    def top(self):
        return self.tree[0]

    def size(self):
        return self.bottom

    def pop_top(self):
        rv = self.tree[0]
        self.tree[0] = self.tree[self.bottom - 1]
        self.bottom -= 1
        n = 0
        while True:
            child1 = 2 * n + 1
            if child1 >= self.bottom:
                return rv
            child2 = 2 * n + 2
            if child2 >= self.bottom:
                child2 = child1

            if (
                self.tree[n][1] > self.tree[child1][1]
                and self.tree[n][1] > self.tree[child2][1]
            ):
                return rv
            elif self.tree[child1][1] > self.tree[child2][1]:
                self.tree[n], self.tree[child1] = (
                    self.tree[child1],
                    self.tree[n],
                )
                n = child1
            else:
                self.tree[n], self.tree[child2] = (
                    self.tree[child2],
                    self.tree[n],
                )
                n = child2
        return rv


def solve(N, M, A, B):
    ans = 0
    # 日付順にソートする
    all_works = deque(sorted(zip(A, B), key=lambda x: x[0]))
    pq = PriorityQueue(N)

    for d in range(1, M+1):
        # print('d=', d)
        # 今日が期限の仕事があれば追加
        while all_works and all_works[0][0] == d:
            work = all_works.popleft()
            pq.add(work)
        # print('all_works', all_works)
        # print('pq=', pq.tree)
        # 優先キューから最優先の仕事をする
        if pq.size():
            work = pq.pop_top()
            ans += work[1]

    return ans


if __name__ == '__main__':
    N, M = map(int, input().split())
    A = [0] * N
    B = [0] * N
    for idx in range(N):
        A[idx], B[idx] = map(int, input().split())

    ans = solve(N, M, A, B)

    print(ans)