module mod_priority_queue
    type pq
        integer(4):: i
        integer(4),pointer:: n(:)
    end type

contains
subroutine append(que,x)
    type(pq):: que
    integer(4):: x
    integer(4),pointer:: tmp(:)
    allocate(tmp(que%i))
    tmp(:) = que%n(:)
    deallocate(que%n)
    que%i = que%i+1

    allocate(que%n(que%i))
    que%n(:que%i-1) = tmp(:)
    que%n(que%i) = x

    deallocate(tmp)
    call adjust_heap(que)
end subroutine

subroutine adjust_heap(que)
    type(pq):: que
    if (que%i==1) return
    do i=que%i/2, 1
        call adjust_child(que,i)
    end do
end subroutine

recursive subroutine adjust_child(que,self)
    type(pq):: que
    integer(4):: self, c1,c2, tmp

    c1 = self*2
    c2 = c1+1
    if (c1 > que%i) return
    if (c2 > que%i) then
        if (que%n(c1) > que%n(self)) then
            tmp = que%n(self)
            que%n(self) = que%n(c1)
            que%n(c1) = tmp
        end if
        return
    end if

    if (que%n(self) >= max(que%n(c1), que%n(c2))) return

    if (que%n(c1) >= que%n(c2)) then
        tmp = que%n(c1)
        que%n(c1) = que%n(self)
        que%n(self) = tmp
        call adjust_child(que,c1)
    else
        tmp = que%n(c2)
        que%n(c2) = que%n(self)
        que%n(self) = tmp
        call adjust_child(que,c2)
    end if
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)

    allocate(tmp(que%i))
    tmp(:) = que%n(:)
    deallocate(que%n)
    que%i=que%i-1
    allocate(que%n(que%i))
    que%n(:) = tmp(:que%i)
    deallocate(tmp)

    call adjust_heap(que)
end function

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))
    allocate(que%n(0))
    que%i=0
    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