program triangles
    implicit none
    integer(4):: n
    integer(4), allocatable:: a(:)
    integer(4):: i,j
    integer(8):: ans=0

    read*,n
    allocate(a(n))  
    read*, a(:)
    
    call merge_sort(a(:),1,n)
    
    do i=1,n-2
        do j=i+1,n-1
            block;integer(4):: l,r,m,tp
                l = j
                r = n+1
                tp = a(i)+a(j)
                do while(r-l > 1)
                    m = (l+r)/2
                    if (a(m) < tp) then
                        l = m
                    else
                        r = m
                    end if
                end do
                ans = ans + max(0,l-j)
            end block
        end do
    end do
    print*,ans
contains
recursive subroutine merge_sort(ar,fst,lst)
    integer(4):: ar(:), fst, lst
    integer(4):: tmp, mdl

    if (lst-fst < 2) then
        if (ar(fst) > ar(lst)) then
            tmp = ar(fst)
            ar(fst) = ar(lst)
            ar(lst) = tmp
        end if
        return
    end if

    mdl = (fst+lst)/2
    call merge_sort(ar(:), fst, mdl)
    call merge_sort(ar(:), mdl+1,lst)
    call merge(ar(:), fst, mdl, lst)
end subroutine

subroutine merge(ar,fst,mdl,lst)
    integer(4):: ar(:),fst,mdl,lst
    integer(4),pointer::tmp(:)
    integer(4):: l,r,t

    allocate(tmp(lst-fst+1))
    l=fst; r=mdl+1; t=1

    do while(l <= mdl .and. r <= lst)
        if (ar(l) <= ar(r)) then
            tmp(t) = ar(l)
            l=l+1
        else
            tmp(t) = ar(r)
            r=r+1
        end if
        t=t+1
    end do

    if (r > lst) then
        tmp(t:) = ar(l:mdl)
    else
        tmp(t:) = ar(r:lst)
    end if

    ar(fst:lst) = tmp(:)
end subroutine
end program triangles