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

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

    que%i = que%i+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
        p=self/2

        do
            if (p < 1) exit
            if (que%n(p) > que%n(self)) exit
            call swap(que%n(p), que%n(self))
            self = p
            p = self/2
        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 
            if (c1 > que%i) then
                exit
            else if (c2 > que%i) then
                if (que%n(c1) > que%n(self)) call swap(que%n(c1), que%n(self))
                exit
            end if

            if (que%n(self) > max(que%n(c1), que%n(c2))) exit
            if (que%n(c1) > que%n(c2)) then
                call swap(que%n(c1), que%n(self))
                self = c1
                c1 = self*2
                c2 = self*2+1
            else
                call swap(que%n(c2), que%n(self))
                self = c2
                c1 = self*2
                c2 = self*2+1
            end if
        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))
    allocate(que%n(1))
    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, n
    !     call append(que, i)
    !     ! print*, que%n(:)
    ! end do
    ! print*, 'a'
    ! do i=1, n
    !     j = pop(que)
    !     ! print*, j, que%n(:)
    ! end do



    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

Measured memory_bytes: 2020