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