Go: ///
// File:  0529.go
// Author: ymiyamoto
//
// Created on Wed Feb 28 20:39:28 2018
//
package main

import (
	"fmt"
	"sort"
)

func max(n, m int) int {
	if n < m {
		return m
	} else {
		return n
	}
}

func main() {
	for {
		var N, M int
		fmt.Scan(&N, &M)
		if N == 0 && M == 0 {
			break
		}

		arr := make([]int, N+1)
		for i := 1; i <= N; i++ {
			fmt.Scan(&arr[i])
		}
		sort.Ints(arr)

		sums := make([]int, len(arr)*len(arr))
		for i := 0; i < len(arr); i++ {
			for j := 0; j < len(arr); j++ {
				sums[i+j] = arr[i] + arr[j]
			}
		}
		sort.Ints(sums)

		m := 0
		for i := 0; i < len(sums); i++ {
			rem := M - sums[i]
			if rem >= 0 {
				index := sort.Search(len(sums), func(i int) bool { return sums[i] > rem }) - 1
				if index >= 0 {
					m = max(m, sums[i]+sums[index])
				}
			}
		}
		fmt.Println(m)
	}
}

C++: 
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int main()
{
	int ans[4];
	int temp;
	double energy,energy_min,energy_now;
	int M, N;
	int* p;
	int i, j;
	double T=100;
	int ret;
	while (1) {
		scanf("%d%d", &N, &M);
		p = (int*)malloc((N+1) * sizeof(int));
		for (i = 0; i < N; i++) {
			scanf("%d", &p[i]);
		}
		p[N] = 0;
		if (N == M && N == 0) {
			break;
		}
		energy_min = pow(10, 300);
		for (j = 0; j < 4; j++) {
			ans[j] = p[(int)((double)(rand() + 1) / (RAND_MAX + 2)*(N+1))];
		}
		
		for (T = 1000000; T > 10000; T--) {
			for (j = 0; j < 4; j++) {
				temp = p[(int)((double)(rand() + 1) / (RAND_MAX + 2)*(N+1))];
				for (j = 0; j < 4; j++) {
					ret = ans[0] + ans[1] + ans[2] + ans[3];
					ret += temp - ans[j];
					energy = M - ret;
					if (M < ret)energy += 100000000;

					if (energy < energy_min) {
						energy_min = energy;
						ans[j] = temp;
					}
					else if ((double)(rand() + 1) / (RAND_MAX + 2) < exp((energy_min - energy) / T*10)) {
						energy_min = energy;
						ans[j] = temp;
					}
				}

			}
		}
		ret=ans[0]+ +ans[1] + ans[2] + ans[3];
		printf("%d\n", ret);
	}
    return 0;
}

C++: #include<iostream>
#include<set>
using namespace std;

int main(int argc, char *argv[]){
  int n, m;
  while(cin >> n >> m, n){
    int point[n + 1];
    point[0] = 0;
    set<int> a, b;
    for (int i = 1; i <= n; i++) {
      cin >> point[i];
    }
    for (int i = 0; i <= n; i++) {
      for (int j = 0; j <= n; j++) {
        a.insert(point[i] + point[j]);
      }
    }
    int ans = 0;
    for (int i: a) {
      if(--a.upper_bound(m - i) != a.end()){
        ans = max(ans, i + *(--a.upper_bound(m - i)));
      }
    }
    std::cout << ans << std::endl;
  }
  return 0;
}

C++: #include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
long long n,m;
long long a,x;
long long i,j;
vector <long long> p,t;
int main ()
{
	while(1)
	{
		cin >> n >> m;
		if(n==0 && m==0) break;
		p.clear();
		t.clear();
		p.push_back(0);
		for(i=0;i<n;i++)
		{
			cin >> a;
			p.push_back(a);
		}
		sort(p.begin(),p.end());
		for(i=0;i<=n;i++)
		{
			j=i;
			while(p[i]+p[j]<=m)
			{
				t.push_back(p[i]+p[j]);
				if(j==n) break;
				j++;
			}
		}
		sort(t.begin(),t.end());
		x=0;
		j=t.size()-1;
		//for(i=0;i<p.size();i++) cout << "PP" << p[i];
		//for(i=0;i<t.size();i++) cout << "TT" << t[i];
		for(i=0;i<=j;i++)
		{
			while(t[i]+t[j]>m) j--;
			if(x<t[i]+t[j])
			{
				x=t[i]+t[j];
				//cout <<"AA"<< t[i] << " " << t[j];
			}
		}
		cout << x << endl;
	}
}

C++: #include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void solve()
{
	int N, M;
	while (cin >> N >> M, N || M)
	{
		vector<int> point(N);
		for (int i = 0; i < N; ++i)
		{
			cin >> point[i];
		}
		point.push_back(0);
		vector<int> sum;
		for (int i = 0; i <= N; ++i)
		{
			for (int j = 0; j <= N; ++j)
			{
				sum.push_back(point[i] + point[j]);
			}
		}
		int ans = 0;
		sort(sum.begin(), sum.end());
		for (int i = 0; i < sum.size(); ++i)
		{
			if (M - sum[i] < 0)
			{
				continue;
			}
			int left = 0;
			int right = sum.size();
			while (left < right)
			{
				int middle = (left + right) / 2;
				if (sum[i] + sum[middle] > M)
				{
					right = middle;
				}
				else if (sum[i] + sum[middle] < M)
				{
					left = middle + 1;
				}
				else
				{
					break;
				}
			}
			ans = max(ans, sum[i] + sum[right - 1]);
		}
		cout << ans << endl;
	}
}

int main()
{
	solve();
	return(0);
}

C++: #include<stdio.h>
#include<iostream>
int main(){
int i,j,n,m,s=0,o;
static int ,p[1001],v[1001*1001]={0};
scanf("%d%d",&n,&m);
if(n==0&&m==0)return 0;
o=n+1;
for(i=1;i<=n;i++){
scanf("%d",&p[i]);
v[i]=p[i];
}
for(i=0;i<=n;i++){
for(j=i;j<=n;j++){
v[o]=p[i]+p[j];
o++;
}
}
for(i=0;i<o;i++){
for(j=i;j<o;j++){
if(v[i]+v[j]>s&&v[i]+v[j]<=m)s=v[i]+v[j];
}
}
printf("%d\n",s);
}
return 0;
}

C++: #include <iostream>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;

using ll = long long;
ll n,m;
ll p[1001];

void solve(){
    set<ll> st; 
    for(int i=0;i<n;i++){
        scanf("%lld",&p[i]);
    }
    sort(p,p+n);

    for(int i=0;i<n;i++){
        if(p[i]>m) break;
        st.insert(p[i]);
    }
    for(int i=0;i<n;i++){
        if(p[i] > m) break;
        for(int j=i+1;j<n;j++){
            if(p[i] + p[j]> m) break;
            st.insert(p[i]+p[j]);
        }
    }

    ll ans = 0;
    if(st.empty() == false){
        ans = *st.rbegin();
    }

    for(auto& s : st){
        if(s > m/2){
            break;
        }
        auto iter = st.upper_bound(m-s);
        if(iter == st.begin()){
            break;
        }
        iter--;
        ll v = *iter;
        ans = max(ans, s + v);
    }

    printf("%lld\n",ans);
}

int main(){
    while(1){
        scanf("%lld %lld",&n,&m);
        if(!n && !m) break;
        solve();
    }
}

C++: #include <math.h>
#include <utility>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;

int main(){
	int n;
	int M;
	vector<int> p;
	vector<int> q;
	while(true) {
		cin >> n >> M;
		if ( n == 0 ) break;
		p.clear();
		int k;
		for ( int i = 0; i < n; i++ ) {
			cin >> k;
			p.push_back(k);
		}
		p.push_back(0);
		n++;
		sort(p.begin(),p.end());
		q.clear();
		int u = 0;
		for ( int i = 0; i < n; i++ ) {
			for ( int j = i; j < n; j++ ) {
				q.push_back( p[i]+p[j] );
				u++;
			}
		}
		sort(q.begin(),q.end());
		int s = 0;
		for ( int i = 0; i < n; i++ ) {
			for ( int j = i; j < n; j++ ) {
				int c = p[i] + p[j];
				if ( c > M ) continue;
				if ( c == M ) {
					s = M;
					break;
				}
				if ( M - c < q[0] ) {
					s = max( s, c );
					continue;
				}
				if ( q[u-1] <= M - c ) {
					s = max( s, c + q[u-1] );
					continue;
				}
				s = max( s, c );
				int x = 0;
				int y = u - 1;
				while(true) {
					int k = ( x + y ) / 2;
					if ( q[k] < M - c ) {
						s = max( s, c + q[k] );
						if ( k == y ) break;
						x = k + 1;
						continue;
					}else if ( q[k] == M - c ) {
						s = M;
						break;
					}else {
						if ( x == k ) break;
						y = k - 1;
						continue;
					}
				}
			}
		}
		cout << s << endl;
	}
	return 0;
}