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++: #include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

vector<long long>F1;
vector<long long>F2;

long long n,m;
long long a[10000];
long long maxn;
long long l,r,M;

int main(){
	while(true){
		maxn=0;
		cin>>n>>m;
		if(n==0 && m==0){break;}
		for(int i=0;i<n;i++){
			cin>>a[i];
		}
		F1.clear();
		F2.clear();
		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++){
				F1.push_back(a[i]+a[j]);
			}
		}
		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++){
				F2.push_back(a[i]+a[j]);
			}
		}
		sort(F2.begin(),F2.end());
		for(int i=0;i<F1.size();i++){
			if(F1[i]<=m){
				l=0;r=F2.size();
				for(int j=0;j<32;j++){
					M=(l+r)/2;
					if(F1[i]+F2[M]>m){
						r=M;
					}
					else if(M==F1.size()-1){
						l=M;
					}
					else if(F1[i]+F2[M+1]<=m){
						l=M;
					}
				}
				maxn=max(maxn,F1[i]+F2[M]);
			}
		}
		cout<<maxn<<endl;
	}
	return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;

int main(){
	int n,m;
	while(cin>>n>>m,n,m){
		int mat[1002];
		vector<int>hanzen;
		for(int i=0;i<n;i++)cin>>mat[i];
		mat[n]=0;
		
		for(int i=0;i<=n;i++)
		for(int j=i;j<=n;j++)hanzen.push_back(mat[i]+mat[j]);
		
		sort(hanzen.begin(),hanzen.end());
		
		int ans=0;
		
		for(int i=0;i<hanzen.size();i++){
			int a=m-hanzen[i];
			
			int li=-1,ub=hanzen.size();
			while(ub-li>1){
				int md=(li+ub)/2;
				if(hanzen[md]>=a){
					ub=md;
					}
				else{
					li=md;
					if(ans<hanzen[i]+hanzen[md])ans=hanzen[i]+hanzen[md];
					if(ans==m)goto finloop;
					}	
				}
			}
			finloop:
			cout<<ans<<endl;
		}
		return 0;
	}

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

using namespace std;

int main(void)
{
	int n, m;
	int s;
	
	while (1){
		
	vector<int> p = vector<int>();
	vector<int> s2 = vector<int>();
	
	scanf("%d %d", &n, &m);
	
	if (n == 0 && m == 0){
		break;
	}
	
	for (int i = 0; i < n; i++){
		int k;
		scanf("%d", &k);
		p.push_back(k);
	}
	
	p.push_back(0);
	for (int i = 0; i < p.size(); i++){
		for (int j = 0; j < p.size(); j++){
			s2.push_back(p[i] + p[j]);
		}
	}
	
	sort(s2.begin(), s2.end());
	int max = -1;
	for (int i = 0; i < s2.size(); i++){
		vector<int>::iterator it = upper_bound(s2.begin(), s2.end(), m - s2[i]);
		//printf("%d\n", *(it - 1));
		
		if (it != s2.begin() && max < s2[i] + *(it - 1)){
			max = s2[i] + *(it - 1);
		}
	}
	
	printf("%d\n", max);
	
	}
	
	return (0);
}

C++: #include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include <cstdio>
#include <string>
#include <cmath>
#include <cfloat>
#include <map>
using namespace std;
int main(){
	
	long long n;
	long long m;
	while(cin>>n>>m,n!=0||m!=0){
		int k=0;
	long long  s=0;
		vector<long long> y(n);
		for(long long int i=0;i<n;i++)
			cin>>y[i];
		sort(y.begin(),y.end());
		while(n>0&&k!=4){
			if(s+y[n-1]<=m){
				s=s+y[n-1];
				k++;
			}
			else
				n--;
			
		}
		cout<<s<<endl;
	}
	
}

C++: #include <cstdio>
#include <algorithm> // sort, max

using namespace std;

#define MAX_N 1001

int N;			// 的の部分の個数 (1≦N≦1000)
int M;			// 得点上限(1 ≦ M ≦ 200000000 = 2 × 10^8)
int P[MAX_N];	// 得点(1 ≦ Pi ≦ 100000000 = 10^8)
int Q[MAX_N * MAX_N];	// 2回投げた時の可能な得点
 
int main() {

	// 読込み
	scanf("%d%d", &N, &M);

	while(N > 0 && M > 0) {
		// 得点の読み込み
		P[0] = 0;
		for(int i = 1; i <= N; i++) scanf("%d", &P[i]);

		// 2回合計
		int cnt = 0;
		for(int i = 0; i <= N; i++) 
			for(int j = 0; j <= N; j++) 
				Q[cnt ++] = P[i] + P[j];

		// 昇順並べ替え O(N^2log N)
		sort(Q, Q + cnt);
		
		int s, t = cnt - 1;
		int Max = 0;

		// 探索 O(N^2)
		for(s = 0; s < cnt; s++) {
			// 
			while(Q[s] + Q[t] > M) t--;
			// 候補なし
			if(t < 0) break;
			// 最大値更新
			Max = max(Max, Q[s] + Q[t]);
		}
		// 最大値出力
		printf("%d\n", Max);
		// 
		scanf("%d%d", &N, &M);
	}
	return 0;
}

C++: #include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long int ll;

int main(){
  while(1){
    int n,m; cin >> n >> m;
    if(n==0&&m==0)break;
    vector<int> a(n);
    for(int i=0;i<n;i++){
        cin >> a[i];
    }
    a.push_back(0);
    vector<ll> v;
    for(int i=0;i<=n;i++){
      for(int j=0;j<=n;j++){
        v.push_back(a[i]+a[j]);
      }
    }
    sort(v.begin(),v.end());
    ll ans=0;
    for(int i=0;i<v.size();i++){
        if(m-v[i]>=0){
            int left=-1,right=v.size();
            while(right-left>1){
                int mid=(right+left)/2;
                if(v[mid]<=m-v[i]){
                    left=mid;
                }
                else{
                    right=mid;
                }
            }
            ans=max(ans,v[i]+v[left]);
        }
    }
    cout << ans << endl;
  }
  return 0;
}

C++: #include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <valarray>
#include <vector>

#define EPS 1e-9
#define INF 1070000000LL
#define MOD 1000000007LL
#define fir first
#define foreach(it,X) for(auto it=(X).begin();it!=(X).end();it++)
#define ite iterator
#define mp make_pair
#define mt make_tuple
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<(n);i++)
#define pb push_back
#define sec second
#define sz(x) ((int)(x).size())

using namespace std;

struct timer{
	time_t start;
	timer(){start=clock();}
	~timer(){cerr<<1.*(clock()-start)/CLOCKS_PER_SEC<<" secs"<<endl;}
};

typedef istringstream iss;
typedef long long ll;
typedef pair<ll,ll> pi;
typedef stringstream sst;
typedef vector<ll> vi;

ll N,M,P[1010],a[1100000];

int main2(){
	cin.tie(0);
	ios_base::sync_with_stdio(0);
	
	if(cin>>N>>M,!N)return 1;
	rep(i,N)cin>>P[i];
	P[N++]=0;
	rep(i,N)rep(j,N)a[i*N+j]=-(P[i]+P[j]);
	sort(a,a+N*N);
	ll ans=0;
	rep(i,N*N){
		ll b=-a[i];
		int id=lower_bound(a,a+N*N,-(M-b))-a;
		if(id==N*N)continue;
		ans=max(ans,b-a[id]);
	}
	cout<<ans<<endl;
	return 0;
}

int main(){
	while(!main2());
}

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

int n;
long m, p[1100];
long dp[6][1100];

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

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);
		
		memset(dp, -1, sizeof(dp));
		printf("%ld\n", rec(0,0));
	}
}