/* ========================================================================
   $File: $
   $Date: $
   $Revision: $
   $Creator: Creative GP $
   $Notice: (C) Copyright 2018 by Creative GP. All Rights Reserved. $
   ======================================================================== */

#pragma warning(disable:4786)
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>

#include <cstdlib>
#include <cmath>

#include <iterator>
#include <algorithm>
#include <utility>
#include <set>
#include <unordered_set>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#include <numeric>
#include <climits>
using namespace std;

template<class X, class Y> bool operator==(pair<X,Y>& lhs, pair<X,Y>& rhs) {
    return lhs.first == rhs.first && lhs.second == rhs.second;
}

template<class X, class Y> ostream& operator<<(ostream& os, pair<X,Y>& val) {
    os << "(" << val.first << ", " << val.second << ")";
    return os;
}

template<class X> ostream& operator<<(ostream& os, vector<X>& val) {
    os << "{";
    for (X e : val)
        os << e << " ";
    os << "}" << endl;
    return os;
}

template<class T> void SetPrint(set<T> rseti) {
    for (typename set<T>::iterator iti = rseti.begin(); iti != rseti.end(); iti++)
    { printf("%3d ", *iti); }
    printf("\n");
}

template<class T> void VectorPrint(vector<T>& vi) {
    cout << "{";
    for (T e : vi)
        cout << e << " ";
    cout << "}" << endl;
}

#define v__print VectorPrint 
#define s__print SetPrint

template<class T> bool contains(const vector<T>& vec, const T& val) {
    return find(vec.begin(), vec.end(), val) != vec.end();
}

// 和集合の計算
template<class T> set<T> Union(set<T>& rsettA, set<T>&rsettB) {
    set<T> settUnion(rsettA);
    for (auto itt : rsettB) {
        settUnion.insert(itt);
    }
    return settUnion;
}
// 積集合の計算
template<class T> set<T> Product(set<T>& rsettA, set<T>&rsettB) {
    set<T> settProduct;
    for (auto itt : rsettB) {
        if (rsettA.find(itt) != rsettA.end()) {
            settProduct.insert(itt);
        }
    }
    return settProduct;
}
// 補集合の計算
template<class T> set<T> Complement(set<T>& rsettA, set<T>&rsettB) {
    set<T> settComplement(rsettA);
    for (auto itt : rsettB) {
        settComplement.erase(itt);
    }
    return settComplement;
}

#define ll long
#define ull unsigned long long

#define gt(a, b) (((a)>(b))?(a):(b))
#define ls(a, b) (((a)<(b))?(a):(b))


#define rep(i, n) for(ll i = 0; i < (ll)(n); i++)

#define val(a) (a).begin(), (a).end()
#define uniq(a) sort(val(a)); a.erase(unique(val(a)), a.end() );
#define rm_byval(a, b) a.erase(remove(a.begin(), a.end(), b), a.end());

vector<vector<ll>> dupp(ll len, ll mag) {
    vector<ll> idx(len, 1);
    vector<vector<ll>> ans;
    ll maxi = pow(mag, len);
    ll counti = 0;
    while (count(idx.begin(), idx.end(), mag) != len) {
        ans.push_back(idx);

        if (idx.back() == mag) {
            for (ll i = len-1; len >= 0; --i) {
                if (idx[i] == mag) {
                    idx[i] = i==len-1 ? 0 : 1;
                } else {
                    ++idx[i];
                    break;
                }
            }
        }

        ++idx[idx.size()-1];
        ++counti;
    }
    ans.push_back(idx);
    return ans;


}

// #define DEBUG

#define LL(x) ll x = 0
#define STR(x) string x = ""

int main () {
    ll n; cin >> n;
    vector<ll> l;
    rep(i,n) {
        ll tmp; cin >> tmp;
        l.push_back(tmp);
    }

    sort(l.begin(), l.end());

    ll ans = 0;

    for (ll a = 0; a < n; ++a) {
        for (ll b = a+1; b < n; ++b) {
            for (ll c = b+1; c < n; ++c) {
                if (l[c] >= l[a] + l[b]) break;
                ans++;
            }
        }
    }

    cout << ans;

    
    return 0;
}



Measured memory_bytes: 256