#include <iostream>
#include <algorithm>
#include <chrono>
#include <random>
#include <vector>
#include <string>
#include <cmath>
#include <bitset>
#include <list>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cassert>

#define sq(x) ((x) * (x))
#define err(x) cerr << "["#x"]  " << (x) << "\n";
#define errv(x) {cerr << "["#x"]  [";for(const auto& ___ : (x)) cerr << ___ << ", "; cerr << "]\n";}
#define errvn(x, n) {cerr << "["#x"]  [";for(auto ___ = 0; ___ < (n); ++___) cerr << (x)[___] << ", "; cerr << "]\n";}
#define errf() cerr << "\n\n";

//#pragma GCC optimize("Ofast, unroll-loops", "omit-frame-pointer","inline")
//#pragma GCC option("arch=native","tune=native","no-zero-upper")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native,avx2")

using namespace std;

using ll = long long;
using ull = unsigned long long;
using ld = long double;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int getrnd(int l, int r) {
    return uniform_int_distribution<int>(l, r)(rng);
}

template <typename T1, typename T2>
bool relax(T1& a, const T2& b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}

template <typename T1, typename T2>
bool strain(T1& a, const T2& b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}

// :::::::::::::::::::::::::::::::

void solve() {
    ll n, m;
    cin >> n >> m;
    
    vector<ll> a(n);
    for (int i = 0; i < n; ++i)
        cin >> a[i];
    sort(a.rbegin(), a.rend());
    
    vector<ll> pref(n + 1, 0);
    for (int i = 1; i <= n; ++i)
        pref[i] = pref[i - 1] + a[i - 1];
    
    ll l = 0, r = 3e5, mid;
    while(r - l > 1) {
        mid = (r + l) / 2;
        
        ll elems = 0;
        // pick every one : a[i] + a[j] >= mid
        for (int i = 0; i < n; ++i) {
            auto pos = lower_bound(a.rbegin(), a.rend(), mid - a[i]);
            ll ind = n - (pos - a.rbegin()) - 1;
            if (ind >= i)
                elems += 2 * (ind - i) + 1;
        }
        
        if (elems >= m)
            l = mid;
        else
            r = mid;
    }
    
    ll sum = 0;
    for (int i = 0; i < n; ++i) {
        auto pos = lower_bound(a.rbegin(), a.rend(), r - a[i]);
        ll ind = n - (pos - a.rbegin()) - 1;
        if (ind >= i) {
            m -= 2 * (ind - i) + 1;
            sum += 2 * a[i] + 2 * ((ind - i) * a[i] + pref[ind + 1] - pref[i + 1]);
        }
    }
//    errv(a);
//    err(r);
//    err(sum);
    
    // take exact l cost handshake to perform m ops
    for (int i = 0; i < n; ++i) {
        if (m == 0) break;
        auto pos = lower_bound(a.rbegin(), a.rend(), l - a[i]);
        auto pos2 = upper_bound(a.rbegin(), a.rend(), l - a[i]);
        
        ll ind1 = n - (pos - a.rbegin()) - 1;
        ll ind2 = n - (pos2 - a.rbegin()) - 1;
        strain(ind2, i);
        
        ll range = ind1 - ind2;
        if (ind1 >= i && range >= 0) {
            ll rn = 2 * range + 1;
            relax(rn, m);
            m -= rn;
            sum += rn * l;
        }
    }
    
    cout << sum << '\n';
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(nullptr); cout.tie(nullptr);
    srand(time(0));
    
    int t = 1;
//    cin >> t;
    while (t--)
        solve();
    
    return 0;
}


Measured memory_bytes: 1792