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

import (
	"fmt"
	"sort"
)

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

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

		arr := make([]int64, N+1)
		for i := 1; i <= N; i++ {
			fmt.Scan(&arr[i])
		}
		sort.Slice(arr, func(i, j int) bool { return arr[i] < arr[j] })

		sums := make([]int64, 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.Slice(sums, func(i, j int) bool { return sums[i] < sums[j] })

		var m int64 = 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　ダーツの問題

	矢を四本投げるので、2本投げたときの

*******************************************************************/

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <fstream>
#include <queue>

#pragma warning( disable: 4996 )

using namespace std;

typedef long long ll;
typedef pair<int, int> P;

#define INF 1000000000
#define EPS 1e-10

#define MAX_N 1001

int N, M;
int po[MAX_N];

vector<int> ans_list;

int main(){

	while (true){
		cin >> N >> M;
		if (N == 0 && M == 0)
			break;
		for (int i = 0; i < N; i++){
			cin >> po[i];
		}
		po[N] = 0;
		N++;
		vector<int> A;

		for (int i = 0; i < N; i++){
			for (int j = 0; j < N; j++){
				A.push_back(po[i] + po[j]);
			}
		}

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

		int ans = 0;
		for (int i = 0; i < A.size(); i++){
			int tmp = A[i];
			int max_tmp = M - tmp;
			if (max_tmp < 0)
				break;
			int lb = 0, ub = A.size();
			while (ub - lb > 1){
				int mid = (ub + lb) / 2;
				if (max_tmp < A[mid])
					ub = mid;
				else
					lb = mid;
			}
			ans = max(ans, M - (max_tmp - A[lb]));
		}

		ans_list.push_back(ans);

	}

	for (int i = 0; i < ans_list.size(); i++){
		cout << ans_list[i] << endl;
	}

}

C++: #include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <string>
#define SIZE 1005
#define LSIZE 1000005
#define INF 1000000005LL

using namespace std;
typedef long long int ll;
typedef pair <int,int> P;

int n;
ll M;
ll T[SIZE];
set<ll> S;
ll K;


ll solve()
{
	scanf("%d %lld",&n,&M);
	if(n+M ==0)return -1;
	for(int i=1;i<=n;i++)scanf("%lld",&T[i]);
	T[0]=0;
	S.clear();
	for(int i=0;i<=n;i++){
		for(int j=i;j<=n;j++){
			S.insert(T[i]+T[j]);
		}
	}
	for(ll i=M;i>=0;i--){
		for(set<ll>::iterator it=S.begin();it!=S.end();it++){
			if(S.find(i-(*it))!=S.end()){
				return i;
			}
		}
	}
	return 0;
}

int main()
{
	while(1){
		ll ans = solve();
		if(ans==-1)break;
		else printf("%lld\n",ans);
	}
	return 0;
}

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

#define MAX_N 1000
int P[MAX_N + 1];
int N, M;
int table[(MAX_N + 1) * (MAX_N + 1)];

int main(){
	while(1){		
		scanf("%d%d", &N, &M);
		
		if(N == 0 && M == 0) return 0;
		
		P[0] = 0;
		for(int i = 1; i <= N; i++) scanf("%d", &P[i]);
	
		for(int i = 0; i < N + 1; i++){
			for(int j = 0; j < N + 1; j++){
				table[(N + 1) * i + j] = P[i] + P[j];
			}
		}
		sort(table, table + (N + 1) * (N + 1));
		
		int right = (N + 1) * (N + 1) - 1;
		int res = 0;
		for(int i = 0; i < (N + 1) * (N + 1); i++){
			while(right >= 0){
				if(table[i] + table[right] <= M){
					res = max(res, table[i] + table[right]);
					break;
				}
				if(table[i] == table[right]) goto OUT;
				right--;
			}
		}
		OUT:
		
		printf("%d\n", res);
	}
}

C++: #include <algorithm>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define rep(i, n) for(int(i) = 0; (i) < (n); (i)++)
#define FOR(i, m, n) for(int(i) = (m); (i) < (n); (i)++)
#define All(v) (v).begin(), (v).end()
#define pb push_back
#define MP(a, b) make_pair((a), (b))
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
const int INF = 1 << 30;
const ll LINF = 1LL << 60;
const int MOD = 1e9 + 7;

int main() {
    int N, M;
    while(cin >> N >> M, N | M) {
        vector<ll> P(N);
        rep(i, N) { cin >> P[i]; }
        P.pb(0);
        vector<ll> P2;
        rep(i, N + 1) {
            FOR(j, i, N + 1) { P2.pb(P[i] + P[j]); }
        }
        sort(All(P2));
        ll res = 0;
        for(int i = 0; i < P2.size(); i++) {
            if(P2[i] > M)
                continue;
            auto it = lower_bound(All(P2), M - P2[i]);
            if(it != P2.begin())
                it--;
            res = max(res, P2[i] + *it);
        }
        cout << res << endl;
    }
    return 0;
}

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

int main()
{
	int n,m,in,MAX;
	vector<int> P;
	vector<int>::iterator it;
	
	while(scanf("%d%d",&n,&m)&&(n!=0||m!=0)){
		P.clear();
		
		for(int i = 0; i < n; i++){
			scanf("%d",&in);
			P.push_back(in);
		}
		for(int i = 0; i < n; i++){
			for(int j = i; j < n; j++){
				P.push_back(P[i]+P[j]);
			}
		}
	
		P.push_back(0);
		sort( P.begin(),P.end() );
		MAX = 0;
	
		for(int i = 0; i < P.size(); i++){
			if(P[i] > m){
				break;
			}
			it = upper_bound(P.begin(),P.end(),m-P[i]);
			it--;
			MAX = max(MAX,P[i] + *it);
		}
	
		printf("%d\n",MAX);
	}
	
	return 0;
}

C++: #include <bits/stdc++.h>
#define rep(i,l,n) for(int i=l;i<n;i++)
#define rer(i,l,n) for(int i=l;i<=n;i++)
#define all(a) a.begin(),a.end()
#define o(a) cout<<a<<endl
#define pb(a) push_back(a)
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> pii;

int main(){
	while(1){
		int n,m,ans=0,MAX=0;
		cin>>n>>m;
		vi d(n+1),w;
		if(n==0 && m==0) break;
		d[0]=0;
		rep(i,1,n+1) cin>>d[i];
		rep(i,0,n+1){
			rep(j,0,n+1){
				w.pb(d[i]+d[j]);
			}
		}
		sort(all(w));
		rep(i,0,w.size()){
			//vector<int>::iteratar it=upper_bound(all(w),m-w[i]);
			int p=upper_bound(all(w),m-w[i])-w.begin();
			if(p==0) continue;
			MAX=max(MAX,w[i]+w[p-1]);
		}
		o(MAX);
	}
}

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

int A[2000];
int KK[1000];

int N,M;

int k;
void getK()
{
	k = 0;
	for(int i =0; i<=N; i++)
		for(int j = i; j<=N; j++)
			KK[k++] = A[i]+A[j];	
	
	sort(KK,KK+k);		

}


int binarySearch(int a)
{
	int left = 0;
	int right = k;
	int mid;
	while(left+1<right)
	{
		mid = (left+right)/2;
		if(KK[mid] <= a) left = mid;
		else right = mid;
	}

	return KK[left];
}


void solve()
{
	
	int maxS = 0;
	for(int i =0; i<=N;i++)
		for(int j = 0; j <=N; j++)
		{
			int temp = binarySearch(M-A[i]-A[j])+A[i]+A[j];	
			if(temp > maxS && temp <= M)
				maxS = temp;
		}
	cout << maxS << endl;
}

int main()
{
	A[0] = 0;
	while(cin >>N>>M && N||M)
	{
		
		for(int i = 1; i<=N;i++)
			cin >> A[i];
		
		sort(A,A+N+1);
		getK();
		
		solve();
	}
}