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;

int main() {
	int n;
	long long int m;
	while (cin >> n >> m) {
		if (n == 0 && m == 0) {
			break;
		}
		vector<long long int> data(n);
		for (int i = 0; i < n; i++) {
			cin >> data[i];
		}
		sort(data.begin(), data.end());
		vector<char> data2(m+1, '0');
		for (int i = 0; i < n; i++) {
			if (data[i] <= m) {
				data2[data[i]] = '1';
			}
		}
		data2[0] = '1';
		vector<char> data3 = data2;
		for (int i = 0; i < 3; i++) {
			data2 = data3;
			for (long long int j = 0; j <= m; j++) {
				if (data2[j] == '1') {
					for (int k = 0; k < n; k++) {
						if (j+data[k] <= m) {
							data3[j+data[k]] = '1';
							//cout << j+data[k] << endl;
						} else {
							break;
						}
					}
				}
			}
			//cout << endl;
		}/*
		for (int i = 0; i <= m; i++) {
			cout << data3[i];
		}
		cout << endl;*/
		for (long long int i = m; i >= 0; i--) {
			if (data3[i] == '1') {
				cout << i << endl;
				break;
			}
		}
	}
	return 0;
}

C++: #include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main(){

    int N,M;
    while(cin>>N>>M,N){
        int p[1200];
        p[0] = 0;
        for(int i = 1;i <= N;i++)cin>>p[i];
        vector<int> V;
        for(int i = 0;i <= N;i++){
            for(int j = 0;j <= N;j++){
                V.push_back(p[i]+p[j]);
            }
        }
        sort(V.begin(),V.end());
        int ans = 0;
        for(int i = 0;i < V.size();i++){
            if(V[i]>M)continue;
            vector<int>::iterator it = lower_bound(V.begin(),V.end(),M-V[i]);
            it--;
            //cout<<V[i]<<" "<<*it<<endl;
            ans = max(ans,V[i] + *it);
        }
        cout<<ans<<endl;
    }

    return 0;
}

C++: #include <iostream>
#include <algorithm>
#include <vector>
#define N1 1001
using namespace std;
int Search(int);
int N,M,P[N1];
vector<int> V;
int main(){
  int i,j,maxv,r;
  while(1){
    cin >> N >> M;
    if(N==0&&M==0) break;
    for(i=0;i<N;i++){
      cin >> P[i];
      V.push_back(P[i]);
    }
    V.push_back(0);
    for(i=0;i<N;i++){
      for(j=i;j<N;j++){
	V.push_back(P[i]+P[j]);
      }
    }
    sort(V.begin(),V.end());
    //    for(i=0;i<V.size();i++) cout << V[i] << endl;
    maxv=0;
    for(i=0;i<V.size();i++){
      if(V[i]<M){
	r=Search(V[i]);
	maxv=max(maxv,V[i]+r);
      }
    }
    cout << maxv << endl;
    V.clear();
  }
  return 0;
}
int Search(int a){
  int left=0,right=V.size(),mid;
  while(left<right){
    //x    cout << left << ' ' << right << endl;
    mid=(right+left)/2;
    if(a+V[mid]<=M) left=mid+1;
    else if(a+V[mid]>M) right=mid;
  }
  return V[left-1];
}

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

using namespace std;

int m,n;
int a[1002];
int aa[1002*1002];

int ans,Max;

int main(){
	
	while (1) {
		scanf("%d%d",&n,&m);
		ans=0;
		if (n==0&&m==0) {
			break;
		}
		for (int i=0; i<n; i++) {
			scanf("%d",&a[i]);
		}
		a[n++]=0;
		
		int size=0;
		for(int c=0;c<n;c++){
			for (int d=0; d<n; d++) {
				aa[size++]=a[c]+a[d];
			}
		}
		sort(aa,aa+size);
		
		for (int i=0; i<n; i++) {
			for (int j=0; j<n; j++) {
				if (m-a[i]-a[i]>=0) {
					int l=0,r=size-1;
					Max=0;
					while (l<=r) {
						if (aa[size-1]+a[i]+a[j]<ans) {
							break;
						}
						int k=(l+r)/2;
						if (aa[k]<(m-a[i]-a[j])&&aa[k]>Max) {
							Max=aa[k];
						}
						if(aa[k]<(m-a[i]-a[j]))l=k+1;
						else r=k-1;
					}
					if (Max+a[i]+a[j]>ans) {
						ans=Max+a[i]+a[j];
					}
				}
			}
		}
		
		printf("%d\n",ans);
	}
}

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

#define f first
#define s second
#define mp make_pair

#define REP(i,n) for(int i=0; i<(int)(n); i++)
#define FOR(i,c) for(__typeof((c).begin()) i=(c).begin(); i!=(c).end(); i++)
#define ALL(c) (c).begin(), (c).end()
#define IN(x,s,g) ((x) >= (s) && (x) < (g))
#define ISIN(x,y,w,h) (IN((x),0,(w)) && IN((y),0,(h)))
#define print(x) printf("%d\n",x)

using namespace std;

typedef unsigned int uint;
typedef long long ll;

const int _dx[] = {0,1,0,-1};
const int _dy[] = {-1,0,1,0};

int getInt(){
  int ret = 0,c;
  c = getchar();
  while(!isdigit(c)) c = getchar();
  while(isdigit(c)){
    ret *= 10;
    ret += c - '0';
    c = getchar();
  }
  return ret;
}

int main(){
  int n,m;
  while(n = getInt(), m = getInt(), n+m){
    set<int> s; s.insert(0);
    REP(i,n) s.insert(getInt());
    set<int> s2;
    FOR(it,s){
      for(set<int>::iterator it2 = it; it2 != s.end(); ++it2){
        int sum = *it + *it2;
        if(sum <= m)
          s2.insert(sum);
      }
    }
    int ans = 0;
    FOR(it,s2){
      int a = *it;
      int b = m - a;
      set<int>::iterator it2 = lower_bound(ALL(s2), b);
      if(it2 != s2.begin()) --it2;
      ans = max(ans, a + *it2);
    }

    print(ans);
  }
  return 0;
}