#include <bits/stdc++.h>
#include <complex>
#include <time.h>
#include <stdlib.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pb push_back
#define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
#define ull unsigned long long
#define gcd(a,b) __gcd((a),(b))
#define lcm(a,b) ((a)*(b))/__gcd((a),(b))
#define clr(x) x.clear()
#define vi vector<int>
#define vll vector<long long>
#define vvi vector<vi>
#define mp make_pair
#define hell 1000000007
#define pii pair<int,int>
#define pll pair<ll,ll>
#define vpii vector<pii>
#define vpll vector<pll>
#define all(a) a.begin(),a.end()
#define ign cin.ignore();

#define o_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define o_setll tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
//member functions :
//1. order_of_key(k) : number of elements strictly lesser than k
//2. find_by_order(k) : k-th element in the set

using namespace std;
using namespace __gnu_pbds;

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

typedef vector<ll> VI;
double PI = acos(0) * 2;

class cmplx
{
public:
	double a, b;
	cmplx() {a = 0.0; b = 0.0;}
	cmplx(double na, double nb) {a = na; b = nb;}
	const cmplx operator+(const cmplx &c) const
		{return cmplx(a + c.a, b + c.b);}
	const cmplx operator-(const cmplx &c) const
		{return cmplx(a - c.a, b - c.b);}
	const cmplx operator*(const cmplx &c) const
		{return cmplx(a*c.a - b*c.b, a*c.b + b*c.a);}
	double magnitude() {return sqrt(a*a+b*b);}
	void print() {printf("(%.3f %.3f)\n", a, b);}
};

class FFT
{
public:
	vector<cmplx> data;
	vector<cmplx> roots;
	VI rev;
	ll s, n;

	void setSize(ll ns)
	{
		s = ns;
		n = (1 << s);
		ll i, j;
		rev = VI(n);
		data = vector<cmplx> (n);
		roots = vector<cmplx> (n+1);
		for (i = 0; i < n; i++)
			for (j = 0; j < s; j++)
				if ((i & (1 << j)) != 0)
					rev[i] += (1 << (s-j-1));
		roots[0] = cmplx(1, 0);
		cmplx mult = cmplx(cos(2*PI/n), sin(2*PI/n));
		for (i = 1; i <= n; i++)
			roots[i] = roots[i-1] * mult;
	}

	void bitReverse(vector<cmplx> &arr)
	{
		vector<cmplx> temp(n);
		ll i;
		for (i = 0; i < n; i++)
			temp[i] = arr[rev[i]];
		for (i = 0; i < n; i++)
			arr[i] = temp[i];
	}

	void trnsfrm(bool inverse = false)
	{
		bitReverse(data);
		ll i, j, k;
		for (i = 1; i <= s; i++) {
			ll m = (1 << i), md2 = m / 2;
			ll start = 0, increment = (1 << (s-i));
			if (inverse) {
				start = n;
				increment *= -1;
			}
			cmplx t, u;
			for (k = 0; k < n; k += m) {
				ll index = start;
				for (j = k; j < md2+k; j++) {
					t = roots[index] * data[j+md2];
					index += increment;
					data[j+md2] = data[j] - t;
					data[j] = data[j] + t;
				}
			}
		}
		if (inverse)
			for (i = 0; i < n; i++) {
				data[i].a /= n;
				data[i].b /= n;
			}
	}

	static VI convolution(VI &a, VI &b)
	{
		ll alen = a.size(), blen = b.size();
		ll resn = alen + blen - 1;	// size of the resulting arr
		ll s = 0, i;
		while ((1 << s) < resn) s++;	// n = 2^s
		ll n = 1 << s;	// round up the the nearest power of two

		FFT pga, pgb;
		pga.setSize(s);	// fill and trnsfrm first arr
		for (i = 0; i < alen; i++) pga.data[i] = cmplx(a[i], 0);
		for (i = alen; i < n; i++)	pga.data[i] = cmplx(0, 0);
		pga.trnsfrm();

		pgb.setSize(s);	// fill and trnsfrm second arr
		for (i = 0; i < blen; i++)	pgb.data[i] = cmplx(b[i], 0);
		for (i = blen; i < n; i++)	pgb.data[i] = cmplx(0, 0);
		pgb.trnsfrm();

		for (i = 0; i < n; i++)	pga.data[i] = pga.data[i] * pgb.data[i];
		pga.trnsfrm(true);	// inverse trnsfrm
		VI result = VI (resn);	// round to nearest integer
		for (i = 0; i < resn; i++)	result[i] = (ll) (pga.data[i].a + 0.5);

		ll actualSize = resn - 1;	// find proper size of arr
		while (result[actualSize] == 0)
			actualSize--;
		if (actualSize < 0) actualSize = 0;
		result.resize(actualSize+1);
		return result;
	}
};

VI a,b;

#define MAXI 200010

int main()
{
    IOS
    a.resize(MAXI);
    ll n,m;
    cin>>n>>m;
    int temp;
	for (int i = 0; i < n; i++){
		cin>>temp;
		a[temp]++;
	}
	b = FFT::convolution(a, a);
	/* 1 8 34 104 259 560 1092 1968 3333
	5368 8052 11120 14259 17104 19234 20168 19361 16200 10000*/
	/*for (ll i = (ll)b.size(); i >=0; i++)
		printf("%d ", b[i]);*/
    ll val=(ll)b.size()-1;
    ll res=0;
    while(m){
        ll pres=b[val];
        ll mini=min(pres,m);
        res=res+mini*val;
        val--;
        m-=mini;
    }
    cout<<res;
	return 0;
}


Measured memory_bytes: 51068