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++: // AOJ 0529 (http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0529)
#include<cstdio>
#include<algorithm>
#define rep(i,a) for(int i=0;i<(a);++i)

const int MAX_N = 1001;

int N, M;
int P[MAX_N], S[MAX_N*MAX_N];

int main()
{
	while( scanf( "%d%d", &N, &M ), N|M )
	{
		rep( i, N )
			scanf( "%d", P+i+1 );
		++N;

		rep( i, N ) rep( j, N )
			S[i*N+j] = P[i]+P[j];

		std::sort( S, S+N*N );

		int ans = 0;
		rep( i, N*N )
		{
			int t = S[i]+*(std::upper_bound( S, S+N*N, M-S[i] )-1);

			if( t <= M )
				ans = std::max( ans, t );
		}

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

	return 0;
}

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

using namespace std;

void darts();

int main()
{
  darts();
}


void darts()
{
  while (true)
  {
    int n, m;
    cin >> n >> m;

    // stop cond
    if (n == 0) break;

    vector<int> p(n);
    for (int i = 0; i < n; ++i) cin >> p[i];

    // 2 darts combination
    // p = q, 0, p + q
    vector<int> q = p;
    q.push_back(0);
    for (int i = 0; i < n; ++i)
    {
      for (int j = 0; j <= i; ++j)
      {
        q.push_back(p[i] + p[j]);
      }
    }

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

    // q's size = 1 + n + n(n + 1) / 2
    //cout << q.size() << "\n";
    //for (auto x : q) cout << x << " ";

    int ret = 0;
    int j = q.size() - 1;
    //i:q linear scan
    for (int i = 0; i < q.size(); ++i)
    {
      if (q[i] > m) break;
      while (q[i] + q[j] > m) --j;
      ret = max(ret, q[i] + q[j]);
    }

    cout << ret << "\n";
  }
}

C++: #include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;

ll n, m, p[1000], d[600000];

int main() {
  while (scanf("%lld%lld", &n, &m), n) {
    for (ll i = 0; i < n; i++) scanf("%lld", &p[i]);
    ll counter = 0;
    for (ll i = 0; i < n; i++) for (ll j = 0; j <= i; j++) d[counter++] = p[i] + p[j];
    for (ll i = 0; i < n; i++) d[counter++] = p[i];
    sort(d, d + counter);
    ll ans = 0;
    for (ll i = 0, j = counter - 1; i < counter; i++) {
      while (d[i] + d[j] > m) j--;
      if (i > j) break;
      if (ans < d[i] + d[j]) ans = d[i] + d[j];
    }
    printf("%lld\n", ans);
  }
}

C++: #include <iostream>
#include <string>
#include <queue>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <utility>
#include <iomanip>

#define ll long long int
#define pb push_back
#define mk make_pair
#define pq priority_queue

using namespace std;
typedef pair<int, int> P;
typedef pair<ll, int> Pl;
const int inf = 1e9;
const ll linf = 1LL << 50;

int n, m;
int p[1001];
int arr[1000001];

int main(int argc, char const* argv[])
{
	while(true){
			cin >> n >> m;
			if(n == 0)break;
			for(int i = 0; i < n; i++){
					cin >> p[i];
			}
			vector<int> vec;
			vec.pb(0);
			for(int i = 0; i < n - 1; i++){
					if(p[i] <= m)vec.pb(p[i]);
					else continue;
					for(int j = i; j < n; j++){
							if(p[i] + p[j] <= m)vec.pb(p[i] + p[j]);
					}
			}
			sort(vec.begin(), vec.end());
			int ind = 1;
			for(auto itr = vec.begin(); itr != vec.end(); ++itr){
					arr[vec.size() - ind] = *itr;
					ind++;
			}
			int res = 0;
			for(auto itr = vec.begin(); itr != vec.end(); ++itr){
					int index = lower_bound(arr, arr+vec.size(), m-*itr, greater<int>()) - arr;
					if(index >= 0 && index < vec.size()){
							res = max(res, arr[index] + *itr);
					}
			}
			cout << res << endl;
	}
	return 0;
}

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

int main(){
  long n,m,p[1001];
  while(cin>>n>>m,n||m){
    for(int i=1;i<=n;++i) cin>>p[i];
    p[0]=0;
    vector<long> s(0);
    for(int i=0;i<=n;++i){
      for(int j=0;j<=n;++j) s.push_back(p[i]+p[j]);
    }
    sort(s.begin(),s.end());
    long a=0;
    for(vector<long>::iterator it=s.begin();it!=s.end();++it){
      if(*it>m/2) break;
      a=max(a,*it+*(upper_bound(s.begin(),s.end(),m-*it)-1));
    }
    cout<<a<<endl;
  }
  return 0;
}

C++: #include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main(){
	while(1){
	int n,m,p,q=0,r=0,l=0,s=0,e=0,ans=0;
	cin>>n>>m;
		if(n==0 && m==0)
			break;
	vector<int> a,x;
	a.push_back(0);
	for(int i=0;i<n;i++){
		cin>>p;
		a.push_back(p);
	}
	q=n+1;
	//cout<<q<<endl;
	for(int i=0;i<q;i++){
		for(int j=0;j<q;j++){
			x.push_back(a[i]+a[j]);
		}
	}
	sort(x.begin(),x.end());
	//for(int i=0;i<q*q;i++)
	//cout<<x[i]<<' ';
	//cout<<endl;
	for(int i=0;i<q*q;i++){
		r=m-x[i];
		//cout<<r<<"を探します"<<endl;
		s=0;
		e=q*q;
		while(1){
			l=(s+e)/2;
			//cout<<"l="<<l<<endl;
			if(x[l]>r){
				e=l-1;
			}else if(x[l]<r){
				s=l+1;
			}
			if(s>=e || x[l]==r || l==0){
				if(x[i]+x[l]<=m)
				ans=max(ans,x[i]+x[l]);
				break;
			}
		}
		while(1){
			if(l+1>q*q)break;
			if(x[l+1]<=r){
				l++;
				ans=max(ans,x[i]+x[l]);
			}
			else break;
		}
	}
		cout<<ans<<endl;
	}
	return 0;
}