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 <sstream>
#include <vector>
#include <list>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
using namespace std;

typedef long long INT;
typedef vector <INT> VI;
typedef set <INT> SI;

INT P[1001];
INT Q[1002001];

INT solve( int N, INT M ) {
    INT answer = 0;
    for ( int i = 0; i < N; ++ i ) {
        int q = Q[i];
        int L = 0;
        int R = N;
        INT m = M - q;
        while ( L < R ) {
            int p = ( R - L ) / 2 + L;
            INT t = q + Q[p];
            if ( t <= M ) answer = max( answer, t );
            if ( Q[p] > m ) {
                R = p - 1;
            } else {
                L = p + 1;
            }
        }
    }
    return answer;
}

int main() {
    int n, m;
    while ( cin >> n >> m ) {
        if ( n == 0 && m == 0 ) break;
        for ( int i = 0; i < n; ++ i ) {
            INT p;
            cin >> p;
            P[i] = p;
        }
        P[n] = 0;
        for ( int i = 0; i < n + 1; ++ i ) {
            for ( int j = 0; j < n + 1; ++ j ) {
                Q[i * ( n + 1 ) + j] = P[i] + P[j];
            }
        }
        int length = ( n + 1 ) * ( n + 1 );
        sort( Q, Q + length );
        cout << solve( length, m ) << endl;
    }
    return 0;
}

C++: //http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2676345#1
//http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2676345#1
#include <iostream>
#include<cstdlib>
#include<queue>
#include<set>
#include<vector>
#include<string>
#include<algorithm>
#include<stack>
#include<map>
#include<cstdio>
#include<fstream>
#include<cstring>
using namespace std;
#define rep(i,a) for(int i=0;i<a;i++)
#define mp make_pair
#define P pair<int,int>
#define ll __int64

ll n,m;
ll t[10000];
const int MA=1000000;
ll s1[MA],s2[MA];


int main(){

while(cin>>n>>m,n||m){
rep(i,MA)s1[i]=s2[i]=0;
rep(i,10000)t[i]=0;

for(int i=1;i<=n;i++)cin>>t[i];
int g=0;

for(int i=0;i<=n;i++){
	for(int j=0;j<=n;j++){
		s1[i*(n+1)+j]=t[i]+t[j];
		g++;
	}
}


sort(s1,s1+g);
rep(i,g)s2[i]=s1[i];

int ans=0;

for(int i=0;i<g;i++){
	int now=s1[i];

	int l=0;
	int r=g-1;
	int mid=(l+r)/2;
	int x=s2[mid];

	for(int i=0;i<70;i++){
		if(x+now==m)break;
		if(l>r)break;
		if(x+now>m){
			r=mid;
			mid=(r+l)/2;
			x=s2[mid];
		}
		else{
			l=mid;
			mid=(r+l)/2;
			x=s2[mid];
		}
	}

	//cout<<" "<<x<<" "<<now<<" "<<x+now<<endl;
	if(x+now<=m)
	ans=max(ans,x+now);
}
cout<<ans<<endl;
}
	return 0;
}

C++: //dpではとけなかった(なんでかは分からん)

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

//long dp[6][1100];
/*
long rec(int a, int b){ //a本目，最後に当てた位置b
	if(dp[a][b]>=0) return dp[a][b];
	
	long ret=0;
	long tmp=0;
	
	if(a==4) ret=0;
	else{
		for(int i=b; i<=n; ++i){
			tmp=rec(a+1, i)+p[i];
			if(tmp>m) tmp=0;	
			
			ret=max(ret, tmp);
			
		}		
	}
	
	return dp[a][b]=ret;
}
*/

int n;
long m, p[1001], q[1100000];

int main(){
	while(1){
		
		scanf(" %d %ld", &n, &m);
		if(n==0) break;
		p[0]=0; //投げない選択肢
		for(int i=1; i<=n; ++i) scanf(" %ld", &p[i]);
		sort(p, p+n);
		
		//半分全列挙(?)
		long now=0;
		for(int i=0; i<=n; ++i)
		for(int j=i; j<=n; ++j)
		q[now++]=p[i]+p[j];
		sort(q, q+now);
		
		//for(long i=0; i<now; ++i) printf("q[%ld]=%ld\n", i, q[i]);
		
		/*
		memset(dp, -1, sizeof(dp));
		printf("%ld\n", rec(0,0));
		*/
		
		long ans=0;
		for(long i=0; i<now; ++i){
			for(long j=i; j<now; ++j){
				long c=q[i]+q[j];
				if(ans<c && c<=m) ans=c;
			}
		}
		
		printf("%ld\n", ans);
	}
}

C++: #include <cstdio>
#include <algorithm>

using namespace std;


int a[1000*1001];

int main(){
	int n,m;
	int i,j,k;
	int *p;
	int r,rr;

	while(true){

		//memset(a,0,sizeof(a));
		scanf("%d%d",&n,&m);
		if(n==0&&m==0) break;

		for(i=0;i<n;i++){
			scanf("%d",&a[i]);
		}

		k=n;
		for(i=0;i<n;i++){
			for(j=i;j<n;j++){
				a[k++]=a[i]+a[j];
				}
		}
		sort(a,a+n*(n+1)/2+n);

	
		for(i=0;i<n*(n+1)/2+n;i++){
			printf("%d\n",a[i]);
		}

		rr=0;
		for(i=0;i<n*(n+1)/2+n;i++){
			p=lower_bound(a+i,a+n*(n+1)/2+n,m-a[i]);
			r=*(p-1)+a[i];
			if((*(p-1)<=m-a[i])&&(r>rr)) rr=r;
			}

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

		}

	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) {
      ans = max(ans, i + *(--a.upper_bound(m - i)));
    }
    std::cout << ans << std::endl;
  }
  return 0;
}

C++: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)n; ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cout<<*i<<" "; cout<<endl; }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;

int main(){
	int n,m;
	while(cin>>n>>m,n){
		vector<int> c(n+1);
		REP(i,n)cin>>c[i+1];
		vector<int> a;
		REP(i,n+1)REP(j,n+1)a.push_back(c[i]+c[j]);
		sort(a.begin(), a.end());
		a.erase(unique(a.begin(),a.end()), a.end());
		int ans = 0;
		REP(i,a.size()){
			if(a[i] <= m){
				int t = m - a[i];
				vector<int>::iterator it = upper_bound(a.begin(), a.end(), t);
				it--;
				ans = max(ans, a[i] + *it);
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

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

using namespace std;

typedef unsigned long long int ULLI;

int main() {
    int n;
    ULLI m;
    ULLI p[1000];
    while (true) {
        ULLI max_point;
        vector<ULLI> half_points, points;
        cin >> n >> m;
        if (n == 0) {
            return 0;
        }
        for (int i=0; i<n; i++) {
            cin >> p[i];
        }
        p[n] = 0;
        for (int i=0; i<=n; i++) {
            for (int j=i; j<=n; j++) {
                ULLI point = p[i]+p[j];
                if (point <= m) {
                    half_points.push_back(point);
                }
            }
        }
        for (int i=0; i<(int)half_points.size(); i++) {
            for (int j=i; j<(int)half_points.size(); j++) {
                ULLI point = half_points[i]+half_points[j];
                if (point <= m) {
                    points.push_back(point);
                }
            }
        }
        max_point = points[0];
        for (int i=1; i<(int)points.size(); i++) {
            max_point = max(max_point, points[i]);
        }
        cout << max_point << endl;
    }
}