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 Fortran (gfortran v4.8.4) (judge verdict: Accepted)

module mod_priority_queue
    private swap
    type pq
        integer(4):: i=0
        integer(4),pointer:: n(:) => null()
    end type

contains
subroutine append(que,x)
    type(pq):: que
    integer(4):: x

    que%i = que%i+1
    if ( .not. associated(que%n)) allocate(que%n(1))
    if (que%i >= size(que%n(:))) then
        block; integer(4), pointer:: tmp(:)
            allocate(tmp(que%i))
            tmp(:) = que%n(:)
            deallocate(que%n)
            allocate(que%n(que%i*2))
            que%n(:que%i) = tmp(:)
            deallocate(tmp)
        end block
    end if
    que%n(que%i) = x

    block
        integer(4):: self, p
        self = que%i

        do while(self >= 2)
            p = self/2
            if (que%n(p) > que%n(self)) exit
            call swap(que%n(p), que%n(self))
            self = p
        end do
    end block

end subroutine


function pop(que) result(ret)
    type(pq):: que
    integer(4):: ret
    integer(4),pointer:: tmp(:)
    ret = que%n(1)
    que%n(1) = que%n(que%i)
    que%i=que%i-1

    block
        integer:: self, c1, c2
        self = 1
        c1=self*2
        c2=self*2+1

        do while(c1 <= que%i)

            if (c2 <= que%i .and. que%n(c2) > que%n(c1)) c1 = c2
            if (que%n(c1) < que%n(self)) exit
            call swap(que%n(c1), que%n(self))
            self = c1
            c1 = self*2
            c2 = self*2+1
        end do
    end block
end function

subroutine swap(a,b)
    integer(4):: a, b, tmp
    tmp =  a
    a = b
    b = tmp
end subroutine
end module


program summer_vacation
    use mod_priority_queue
    implicit none
    integer(4):: n,m
    integer(4):: i,j,k
    integer(4),allocatable:: a(:), b(:)
    integer(8):: ans=0
    type(pq):: que

    read*,n,m
    allocate(a(n),b(n))
    do i=1,n
        read*,a(i),b(i)
    end do
    call merge_sort(a(:),b(:),1,n)
    j=1


    do i=1, m
        do while (a(j) == i)
            call append(que,b(j))
            j=j+1
        end do
        if (que%i > 0) ans = ans + pop(que)
    end do

    print*, ans
        

contains
recursive subroutine merge_sort(a,b,fst,lst)
    integer(4):: a(:),b(:),fst,lst,mdl

    if (lst-fst < 2) then
        if(a(lst) < a(fst)) then
            call swap(a(:), fst,lst)
            call swap(b(:), fst,lst)
        end if
        return
    end if

    mdl = (fst+lst)/2
    call merge_sort(a(:),b(:),fst,mdl)
    call merge_sort(a(:),b(:),mdl+1,lst)
    call merge_(a(:),b(:),fst,mdl,lst)
end subroutine

subroutine merge_(a,b,fst,mdl,lst)
    integer(4):: a(:),b(:),fst,mdl,lst
    integer(4),pointer:: ta(:),tb(:)
    integer(4):: it,il,ir

    allocate(ta(lst-fst+1), tb(lst-fst+1))
    it=1; il=fst; ir=mdl+1

    do while(il <= mdl .and. ir <= lst)
        if (a(il) <= a(ir)) then
            ta(it) = a(il)
            tb(it) = b(il)
            il=il+1
        else
            ta(it) = a(ir)
            tb(it) = b(ir)
            ir=ir+1
        end if
        it=it+1        
    end do

    if (ir > lst) then
        ta(it:) = a(il:mdl)
        tb(it:) = b(il:mdl)
    else
        ta(it:) = a(ir:lst)
        tb(it:) = b(ir:lst)
    end if
    a(fst:lst) = ta(:)
    b(fst:lst) = tb(:)
    deallocate(ta,tb)
end subroutine

subroutine swap(ar,x,y)
    integer(4):: ar(:), x, y, tmp
    tmp = ar(x)
    ar(x) = ar(y)
    ar(y) = tmp
end subroutine

end program summer_vacation