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++: //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){
			long rem=m-q[i];
			if(rem<0) break;
			
			//2分探索
			long left=0, right=now;
			while(left<right){
				long center=(left+right)/2;
				if(rem>q[center]){
					left=center+1;
				}
				else if(rem<q[center]){
					right=center;
				}
				else	break;
			}
			
			ans=max(ans, q[i]+q[right-1]);
		}
		
		printf("%ld\n", ans);
	}
}

C++: #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <stack>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#include <cmath>
#include <complex>
#include <map>
#include <climits>
#include <sstream>
using namespace std;
 
#define int long long 
#define reep(i,a,b) for(int i=(a);i<(b);++i)
#define rep(i,n) reep((i),0,(n))
#define ALL(v) (v).begin(),(v).end()
#define PB push_back
#define EPS 1e-8
#define F first
#define S second
#define mkp make_pair
 
static const double PI=6*asin(0.5);
typedef long long ll;
typedef complex<double> CP;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vint;
static const int INF=1<<24;
 
template <class T>
void initvv(vector<vector<T> > &v,int a,int b, const T  &t = T()){
    v.assign(a,vector<T>(b,t));
}
 
//v.erase(unique(v.begin(),v.end()),v.end());

signed main(){
	int n;
	int m;
	while(cin>>n>>m,n||m){
		// int n;
		// cin>>n;
		// int m;
		// cin>>m;
		vint v(n);
		rep(i,n){
			cin>>v[i];
		}
		v.PB(0);
		vint tmp;
		rep(i,n+1){
			rep(j,n+1){
				tmp.PB(v[i]+v[j]);
			}
		}
		sort(ALL(tmp));
		int ans=0;
		tmp.erase(unique(ALL(tmp)),tmp.end());
		rep(i,tmp.size()){
			vint::iterator it=upper_bound(ALL(tmp),m-tmp[i]);
			it--;
			if(*it+tmp[i]<=m){
				ans=max(ans,*it+tmp[i]);
			}
		}
		cout<<ans<<endl;
	}
}

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

using namespace std;

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

int main()
{
    int N;
    long long M;

    cin >> N >> M;

    while(N!=0 && M!=0) {
        vector<long long> p;

        long long ans=0;

        for(int i=0; i<N; ++i) {
            long long temp;
            cin >> temp;
            p.push_back(temp);
            ans=MAX(ans,temp);
        }

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

        for(int i=0; i<N; ++i) {
            for(int j=i; j<N; ++j) {
                if(p[i]+p[j]>M) break;
                p.push_back(p[i]+p[j]);
                ans=MAX(ans,p[i]+p[j]);
            }
        }

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

        for(int i=0; i<(int)p.size(); ++i) {
            auto itr=upper_bound(p.begin(),p.end(),M-p[i]);
            if(itr==p.begin()) break;
            else --itr;
            ans=MAX(ans,p[i]+*itr);
        }

        cout << ans << endl;
        cin >> N >> M;
        p.clear();
    }
    return 0;
}

C++: #include<stdio.h>
#include<stdio.h>
#include<bits/stdc++.h>
#include<vector>
#define int long long int
#define rep(a,b,c) for(int a=b;a<c;a++)
using namespace std;
/*
void a1(){
    int i, len = 3;
    char str[] = "abc";
    for(i=0;i<len;i++){
        printf("%c\n",str[2-i]);
    }
    return;
}

int length(char str[5]){
    int cut=0;
    while(*(str+cut)!='\0'){
        cut++;
    }
    return cut;
}

void a2(){
    char a[4][5]={"ab","cdef","g","hij"};
    int i;
    for(i=0; i<4; i++){
        printf("%d\n",length(a[i]));
    }
    return;
}

void a3(){
    char str[4];
    strcpy(str,"abc");
    printf("%s\n",str);
    return;
}

void a4(){
    char a[7]="saitou",b[7] = "suzuki";
    int i;

    for(i=0;i<7;i++){
        int k = a[i]-b[i];
        if(k > 0){
            printf("%c",a[i]);
        }else if(k < 0){
            printf("%c",b[i]);
        }else{
            printf("0");
        }
    }
    printf("\n");
    return;
}

void a5(){
    char *a[3];
    int n,i,j,cut = 0;
    for(i=0;i<3;i++){
        scanf("%d",&n);
        a[i]=(char *)malloc((n+1)*sizeof(char));
        scanf("%s",a[i]);
    }
    for(i=0;i<3;i++){
        for(j=0;j<strlen(a[i]);j++){
            if(a[i][j]=='P'||a[i][j]=='p'){
                cut++;
            }
        }
    }
    printf(">> %d\n",cut);
    for(i=0;i<3;i++){
        free(a[i]);
    }
}*/

void y(){
    int n,m;
    vector<int> v,v2;
    while(1){
    cin >> n >> m;
    v.clear();v2.clear();
    if(n==0&&m==0)break;
    v.push_back(0);
    rep(i,0,n){
        int x;cin >> x;
        v.push_back(x);
    }
    rep(i,0,v.size()){
        rep(j,0,v.size()){
            v2.push_back(v[i]+v[j]);
        }
    }
    v2.erase(unique(v2.begin(),v2.end()),v2.end());
    sort(v2.begin(),v2.end());
    int ans=0;
    //cout << v2.size() << " a " <<  endl;
    bool a=false;
    for(int j=v2.size()-1;j>=0;j--){
        int an=0;
        for(int i=j-1;i>=0;i--){
            if(v2[i]+v2[j]<m){
                if(i==(j-1))a=true;
                ans=max(ans,v2[i]+v2[j]);
                break;
            }

        //    cout << an << " a " << endl;
        }
        if(a)break;
    }
    cout << ans << endl;
    }
    return;
}

signed main(){
    y();
    return 0;
}

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

using namespace std;

typedef vector<int> vi;

#define PB push_back
#define rep(i,x) for(int i=0;i<(x);++i)
#define rep1(i,x) for(int i=1;i<=(x);++i)
#define all(a) a.begin(),a.end()

int P[1001];

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);

	int N, M;
	
	while (cin >> N >> M, N || M) {
		rep1(i, N) cin >> P[i];

		vi A;

		rep(i, N + 1) rep(j, i + 1) if (P[i] + P[j] <= M) A.PB(P[i] + P[j]);

		sort(all(A));

		int ma = 0;

        int l = 0, r = A.size() - 1;

        while (l < r) {
            while (A[l] + A[r] > M) r--;
            ma = max(ma, A[l] + A[r]);
            l++;
        }

		cout << ma << endl;
	}
}