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*len(arr)+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++: #include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <utility>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <map>
#include <set>
#include <stack>
#include <queue>
 
using namespace std;
 
#define pb(n)	push_back(n)
#define mp(n,m) make_pair(n,m)
#define fi 	first
#define se 	second
#define all(r) (r).begin(),(r).end()
 
#define REP(i,s,e)	for(int i=(s); i<(e); i++)
#define rep(i,n)	REP(i,0,n)
#define REPE(i,s,e)	for(int i=s; i>e; i--)
#define repe(i,n)	REPE(i,n,-1)


typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
 
typedef vector<vi> vvi;
 
const int IMAX=((1<<30)-1)*2+1;
const int INF=100000000;
const double EPS=1e-10;
//int mod=1000000007


int main(){
	int n,m;
	while(cin>>n>>m){
		if(n ==0 && m == 0) break;
		vi v(n + 1, 0);
		for(int i = 0; i < n ; i++) cin>>v[i];
		vi w;
		for(int i = 0; i <= n; i++){
			for(int j = 0; j <= n; j++){
				w.pb(v[i]+v[j]);
			}
		}
		sort(all(w));
		int ans=0;
		for(int i = 0; i < w.size(); i++){
			vi::iterator it = upper_bound(all(w),m-w[i]);
			if(it == w.begin()) continue;
			--it;
			ans = max(ans,w[i] + *it);
		}
		cout<<ans<<endl;
	}
}

C++: #include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <functional> //sort(A,A.end(),greater<int>());???????????????
#include <queue>
#include <stack>
#include <vector>

#define INF 10 << 10

long p[1001];
long dp[4][1001];

int main() {
	int n;
	long m;
	while (cin >> n >> m && n != 0 && m != 0) {
		for (int i = 1; i <= n; ++i) {
			cin >> p[i];
		}
		for (int i = 0; i < 4; ++i) { dp[i][0] = 0; }
		for (int i = 0; i < 4; ++i) {
			for (long i2 = 1; i2 <= n; ++i2) {
				if (i == 0) {
					if (p[i2] <= m) {
						dp[i][i2] = max(dp[i][i2 - 1], p[i2]);
					}
					else { dp[i][i2] = dp[i][i2 - 1]; }
				}
				else {
					for (long i3 = 0; i3 <= n; ++i3) {
						if (dp[i - 1][i3] + p[i2] <= m) {
							dp[i][i2] = max(dp[i][i2], dp[i - 1][i3] + p[i2]);
						}
					}
				}
			}
		}

		cout << dp[3][n] << endl;
	}
}

C++: #include<iostream>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<climits>

using namespace std;

int main() {
	long long   m[10], t[10][1000]{ 0 }, a[1000];
	int n[10], i = 0;
	while (1) {
		cin >> n[i] >> m[i];
		if (n[i] == 0)break;
		for (int j = 0; j < n[i]; j++)cin >> t[i][j];
		i++;
	}
	for (int k = 0; k < i; k++) {
		long long ans = 0;
		for (int j = 0; j < n[k]; j++)a[j] = t[k][j];
		sort(a, a + n[k]);
		for (int p = n[k] - 1; p >= 0; p--) {
			if (a[p] > m[k])continue;
			else if (a[p] == m[k]) {
				ans = m[k];
				goto ANS;
			}
			else if (ans > a[p] * 4)goto ANS;
			else {
				ans = max(ans, a[p]);
				for (int q = p; q >= 0; q--) {
					if (a[p] + a[q] > m[k])continue;
					else if (a[p] + a[q] == m[k]) {
						ans = m[k];
						goto ANS;
					}
					else if (ans > a[p] + a[q] * 3)goto ANS;
					else {
						ans = max(ans, a[p] + a[q]);
						for (int r = q; r >= 0; r--) {
							if (a[p] + a[q] + a[r] > m[k])continue;
							else if (a[p] + a[q] + a[r] == m[k]) {
								ans = m[k];
								goto ANS;
							}
							else if (ans > a[p] + a[q] + a[r] * 2)goto ANS;
							else {
								ans = max(ans, a[p] + a[q] + a[r]);
								for (int s = r; s >= 0; s--) {
									if (a[p] + a[q] + a[r] + a[s] > m[k])continue;
									else if (a[p] + a[q] + a[r] + a[s] == m[k]) {
										ans = m[k];
										goto ANS;
									}
									else if (ans > a[p] + a[q] + a[r] + a[s])break;
									else ans = max(ans, a[p] + a[q] + a[r] + a[s]);
								}
							}
						}
					}
				}
			}
		}
	ANS:
		cout << ans << endl;
	}
	return 0;
}

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

int main() {
	int N, M;

	while(cin >> N >> M, N || M) {
		vector<int> P;
		vector<int> v;
		for(int i = 0; i < N; i++) {
			int tmp;
			cin >> tmp;
			P.push_back(tmp);
		}
		P.push_back(0);

		for(int i = 0; i < P.size(); i++) {
			for(int j = 0; j < P.size(); j++) {
				v.push_back(P[i]+P[j]);
			}
		}
		sort(v.begin(), v.end());
		int j = v.size() - 1;
		int res = 0;
		for(int i = 0; i < v.size(); i++) {
			while(v[i]+v[j] > M && j >= 0)
				j--;
			if(j >= 0)
				res = max(res, v[i] + v[j]);
		}
		cout << res << endl;
	}
}

C++: #include<stdio.h>
#include<algorithm>

#define rep(i,j) for(int i=0;i<(j);i++)
#define reps(i,j,k) for(int i=j;i<=k;i++)

using namespace std;
int main(){
	int n,m,ans,p[1001];
	int dp[1001][4];
	for(;;){
		scanf("%d%d",&n,&m);
		if(n==0&&m==0)break;
		rep(i,1001)rep(j,4)dp[i][j]=0;
		rep(i,n)scanf("%d",p+i);
		sort(p,p+n);
		ans = 0;
		rep(i,n)rep(j,4){
			if(j==0 && p[i] <= m){
				dp[i][j]=p[i];
				continue;
			}
			rep(k,i+1)rep(l,j){
				int t=dp[i][l] + p[k];
				if(t<=m)dp[i][j]=max(dp[i][j],max(t,dp[k][l]));
			}
			ans = max(ans,dp[i][j]);
		}
		printf("%d\n",ans);
	}
	return 0;
}

C++: #include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#define int long long
#define for0(i, n) for(int i = 0; i < (n); i++)
#define for1(i, n) for(int i = 1; i <= (n);i++)
using namespace std;
int n, m, a[1234];
vector<int>v;
void solve() {
	for1(i, n) { scanf("%d", &a[i]); }
	v.clear();
	for0(i, n + 1)for (int j = i; j <= n; j++) {
		if (a[i] + a[j] <= m) v.push_back(a[i] + a[j]);
	}
	sort(v.begin(), v.end());
	unique(v.begin(), v.end());
	int ans = 0;
	for (int p : v) {
		if (p + v.back() <= m) {
			ans = max(ans, p + v.back());
		}
		else {
			int r = 0, l = v.size() - 1;
			while (l - r > 1) {
				int mid = (l + r) / 2;
				if (p + v[mid] <= m)r = mid;
				else l = mid;
			}
			ans = max(ans, p + v[r]);
		}
	}
	printf("%d\n", ans);
}
signed main() {
	while (cin >> n >> m, n, m)solve();
}

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

#define max(a,b) (a>b?a:b)

typedef unsigned int uint;

int main() {
	int n, m, a, ans;
	vector<int> p, p2;
	while(1) {
		cin >> n >> m;
		if(!n&&!m) break;
		p.clear(); p2.clear(); ans = 0;
		for(int i=0; i<n; ++i) {
			cin >> a;
			p.push_back(a); p2.push_back(a);
		}
		for(int i=0; i<n; ++i) for(int j=0; j<n; ++j) {
				if(p2[i]+p2[j]<=m) p.push_back(p2[i]+p2[j]);
		}
		p.push_back(0);
		sort(p.begin(), p.end());
		for(uint i=0; i<p.size(); ++i) {
			vector<int>::iterator it = --lower_bound(p.begin(), p.end(), m-p[i]);
			ans = max(ans, *it+p[i]);
		}
		cout << ans << endl;
	}
	return 0;
}