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<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX 1000

int n, L, P[MAX+1];

void compute(){
    vector<int> v;
    for ( int i = 0; i < n+1; i++ ){
	for ( int j = i; j < n+1; j++ ){
	    v.push_back(P[i] + P[j]);
	}
    }
    sort(v.begin(), v.end());
    int maxv = 0;

    for ( int i = 0; i < v.size(); i++ ){
	if ( v[i] > L ) break;
	int first = v[i];
	int target = L - v[i];
	
	int t = distance(v.begin(), upper_bound(v.begin(), v.end(), target));

	if ( v[t] + first <= L && maxv < v[t]+first ) maxv = v[t]+first;
	if ( t+1 < v.size() && v[t+1] + first <= L && maxv < v[t+1]+first ) maxv = v[t+1]+first;
	if ( t-1 >= 0 && v[t-1] + first <= L && maxv < v[t-1]+first ) maxv = v[t-1]+first;
    }

    cout << maxv << endl;
    

}

main(){
    while( cin >> n >> L && n ){
	P[0] = 0;
	for ( int i = 1; i <= n; i++ ) cin >> P[i];
	compute();
    }
}

C++: #include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <set>
#include <map>
#include <queue>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <cctype>
#include <cassert>
#include <cmath>
#include <limits>
#include <functional>

#define REP(i,n) for(int i=0;i<n;i++)
#define FOR(i,m,n) for(int i=m;i<n;i++)
#define FORR(i,m,n) for(int i=m;i>=n;i--)
#define pb(x) push_back(x) 
#define SORT(x) sort((x).begin(),(x).end())
#define INF 999999999

using namespace std;

#define int long long

signed main(){
	int n, m;
	while(1){
		cin >> n >> m;
		if(n==0) break;
		
		vector<int> p(n);
		REP(i, n){
			cin >> p[i];
		}
		p.push_back(0);
		sort(p.begin(), p.end());
		n++;
		
		vector<int> v;
		REP(i, n){
			FOR(j, i, n){
				if(p[i]+p[j]<=m) v.push_back(p[i]+p[j]);
			}
		}
		sort(v.begin(), v.end());
		
		int l=0, r=v.size()-1, ans=0;
		for(; l<=r; l++){
			while(v[l]+v[r]>m) r--;
			ans=max(ans, v[l]+v[r]);
		}
		
		cout << ans << endl;
	}
}

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

#define REP(i,a,b) for(i=a; i<b; ++i)
#define rep(i,n) REP(i,0,n)

int main() {
  int i,j,k,n,m;
  while(scanf("%d %d", &n, &m), n|m) {
    vector<int> p(n);
    rep(i,n) {
      scanf("%d", &p[i]);
    }

    vector<int> f2;
    rep(i,n) {
      REP(j,i,n) {
	f2.push_back(p[i]+p[j]);
      }
      f2.push_back(p[i]);
    }
    f2.push_back(0);
    f2.push_back(0);

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

    int ans = 0;
    vector<int>::iterator it;
    rep(i,f2.size()) {
      if(f2[i] > m) break;
      if(f2[i] == m) ans = m;
      it = upper_bound(f2.begin(), f2.end(), m-f2[i]);
      ans = max(ans, *(it-1)+f2[i]);
    }

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

C++: #include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;i++)
using namespace std;
int n,m,a[1001];
int s[500501],stop;
int main(){
	while(true){
	cin>>n>>m;
	if(!n&&!m)break;
	stop=1,a[0]=0,s[0]=0;
	rep(i,n){
		cin>>a[i+1];
		rep(j,i+2)if(s[i+1]+s[j]<=m)s[stop]=a[i+1]+a[j],stop++;
	}
	sort(s,s+stop);
	int ans=0;
	rep(i,stop){
		int left=0,right=stop,mid,key=m-s[i];
		if(key>=0){
		while(left<right){
			mid=(left+right)/2;
			if(s[mid]<key)left=mid+1;
			else right=mid;
		}
		if(s[mid]>key)mid--;
		if(mid+1)ans=max(ans,s[mid]+s[i]);
		}
	}
	cout<<ans<<endl;
	}
	return 0;
}

C++: #include <iostream>
using namespace std;
 
int main() {
	for(;;){
		/*入力*/
		int N,M,count=0;
		cin >> N >> M;
		if(N==0 && M==0)exit(0);
		int P[N+1],array[M+1]={0};
		P[0]=0;
		for(int i=1;i<=N;i++)cin >> P[i];
		for(int i=0;i<=N;i++)array[P[i]]=1;
 
		/*２投(０投１投を含む)で1からMまでが可能か判定*/
		for(int i=0;i<=N;i++){
			for(int j=0;j<=N;j++){
				if(P[i]+P[j] <= M)array[P[i]+P[j]]=1;
			}
		}
 
		/*４投に拡張*/
		for(int i=0;i<=M;i++){
			if(array[i]==1)count++;
		}
		int k=0,p[count];
		for(int i=0;i<=M;i++){
			if(array[i]==1){
				p[k]=i;
				k++;
			}
		}
		for(int i=0;i<count;i++){
			for(int j=0;j<count;j++){
				if(p[i]+p[j] <= M)array[p[i]+p[j]]=1;
			}
		}
 
		/*判定出力*/
		for(int i=M;i>0;i--){
			if(array[i]==1){
				cout << i << endl;
				break;
			}
		}
	}
	return 0;
}

C++: #include <stdio.h>
#include <algorithm>
#include <iostream>
#include <stack>
#include <vector>
#include <math.h>

using namespace std;


void func(int N,int M){
    vector<int> First,Second;

    First.push_back(0);
    int tmp,max = 0;

    for(int i = 0; i < N; i++){
        scanf("%d",&tmp);
        if(tmp <= M){
        	First.push_back(tmp);
        }
    }

    for(int i = 0; i < N;i++){
    	for(int k = i; k < N;k++){
    		if(First[i]+First[k] <= M){
    			Second.push_back(First[i]+First[k]);
    		}else{ //????????\??????First[i]+First[k]???M????????§????????????????????§break;
    			break;
    		}
    	}
    }

    for(int i = Second.size()-1; i >= 0;i--){
    	for(int k = i; k >= 0;k--){
    		if(Second[i]+Second[k] <= M){
    			if(Second[i]+Second[k] > max){
    				max = Second[i]+Second[k];
    			}else{ //????????\????????????max???????°?????????????????????§break;
    				break;
    			}
    		}
    	}
    }

    printf("%d\n",max);

}

int main(){

    int N,M;

    while(true){
        scanf("%d %d",&N,&M);
        if(N == 0 && M == 0)break;

        func(N,M);
    }

    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),t(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*2>m) break;
      a=max(a,*it+*(upper_bound(s.begin(),s.end(),m-*it)-1));
    }
    cout<<a<<endl;
  }
  return 0;
}

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

using namespace std;

int main()
{
	int N, M, D;

	while (true)
	{
		scanf("%d", &N);
		scanf("%d", &M);

		if (N == 0 && M == 0) { break; }

		vector<int> C;

		for (int i = 0; i < N; i++)
		{
			scanf("%d", &D);

			if (D <= M)
			{
				C.push_back(D);
			}
		}

		vector<int> r;

		for (int i = 0; i < C.size(); i++)
		{
			for (int j = 0; j < C.size(); j++)
			{
				if (C[i] + C[j] <= M)
				{
					r.push_back(C[i] + C[j]);
				}
			}
		}

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

		int ret = 0;

		for (int i = 0; i < r.size(); i++)
		{
			ret = max(ret, *(upper_bound(r.begin(), r.end(), M - r[i]) - 1));
		}

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

	return 0;
}