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

import (
	"fmt"
	"sort"
)

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

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

		arr := make([]int, N+1)
		for i := 1; i <= N; i++ {
			fmt.Scan(&arr[i])
		}
		sort.Ints(arr)

		sums := make([]int, 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.Ints(sums)

		m := 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++: //http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2676345#1
//http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2676345#1
#include <iostream>
#include<cstdlib>
#include<queue>
#include<set>
#include<vector>
#include<string>
#include<algorithm>
#include<stack>
#include<map>
#include<cstdio>
#include<fstream>
#include<cstring>
using namespace std;
#define rep(i,a) for(int i=0;i<a;i++)
#define mp make_pair
#define P pair<int,int>
#define ll __int64

int n,m;
int t[10000];
const int MA=1000000;
int s1[MA],s2[MA];

int ya[4];

int main(){

while(cin>>n>>m,n||m){
rep(i,MA)s1[i]=s2[i]=0;
rep(i,10000)t[i]=0;

for(int i=1;i<=n;i++)cin>>t[i];
int g=0;

for(int i=0;i<=n;i++){
	for(int j=0;j<=n;j++){
		s1[i*(n+1)+j]=t[i]+t[j];
		//s2[i*(n+1)+j]=t[i]+t[j];	
		g++;
	}
}


sort(s1,s1+g);
rep(i,g)s2[i]=s1[i];
//sort(s2,s2+g);

//rep(i,g)cout<<s1[i]<<" ";cout<<endl;

int ans=0;

for(int i=0;i<g;i++){
	int now=s1[i];

	int l=0;
	int r=g-1;
	int mid=(l+r)/2;
	int x=s2[mid];

	for(int i=0;i<60;i++){
		if(x+now==m)break;
		if(x+now>m){
			r=mid;
			mid=(r+l)/2;
			x=s2[mid];
		}
		else{
			l=mid;
			mid=(r+l)/2;
			x=s2[mid];
		}
	}

	//cout<<" "<<x<<" "<<now<<" "<<x+now<<endl;
	if(x+now<=m)
	ans=max(ans,x+now);
}
cout<<ans<<endl;
}
	return 0;
}

C++: #include <cstdio>
#include <algorithm>
using namespace std;
long long m;
int n;
long long num[1001];
long long sum[1000005];
int main(){
	while(1){
	scanf("%d %lld",&n,&m);
	if(!n) break;
	for(int i=0;i<n;i++){
		scanf("%lld",&num[i]);
	}
	num[n]=0;
	int ro=0;
	for(int i=0;i<=n;i++){
		for(int j=i;j<=n;j++){
			sum[ro]=num[i]+num[j];
			ro++;
		}
	}
	long long ans=0;
	sort(sum,sum+ro);
	for(int i=0;i<ro;i++){
		if(sum[i]>m){ break;}
		int rp=lower_bound(sum,sum+ro,m-sum[i])-sum;
			rp--;
			ans=max(ans,sum[i]+sum[rp]);
	}
	printf("%d\n",ans);
}
	return 0;
}

C++: #include <iostream>

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,j) FOR(i,0,j)

typedef unsigned long long ull;

ull dp[1000][5];

int main(){
    int N;
    ull M, P[1000];

    while(std::cin >> N >> M, N){
        REP(i, N){
            std::cin >> P[i];
        }

        REP(i, 1000){
            REP(j, 5){
                dp[i][j] = 0;
            }
        }

        REP(i, 5){
            if(P[0] * i <= M){
                dp[0][i] = P[0] * i;
            }
        }

        REP(i, N-1){
            REP(j, 5){
                REP(k, j+1){
                    if(P[i+1] * k + dp[i][j-k] <= M){
                        dp[i+1][j] = std::max(P[i+1] * k + dp[i][j-k], dp[i+1][j]);
                    }
                }
            }
        }

        ull res = 0;
        REP(i, 5){
            res = std::max(dp[N-1][i], res);
        }

        std::cout << res << std::endl;
    }

    return 0;
}

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

#define ef(e, a, b) ((e) ? (a) : (b))

using namespace std;

int main ( void )
{
	int n, m;
	int p[1000];

	while ( cin >> n >> m, (n | m) )
	{
		int ans = 0;
		
		for (int i = 0; i < n; ++i)
		{
			cin >> p[i];
		}
		
		for (int i = 0; i < n; ++i)
		{
			if (p[i] > m) { break; }
			ans = max(ans, p[i]);
			for (int j = 0; j < n; ++j)
			{
				if (p[i] + p[j] > m) { break; }
				ans = max(ans, p[i] + p[j]);
				for (int k = 0; k < n; ++k)
				{
					if (p[i] + p[j] + p[k] > m) { break; }
					ans = max(ans, p[i] + p[j] + p[k]);
					for (int l = 0; l < n; ++l)
					{
						if (p[i] + p[j] + p[k] + p[l] > m) { break; }
						ans = max(ans, p[i] + p[j] + p[k] + p[l]);
						
					}
				}
			}
		}
		cout << ans << endl;
	}
	return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;
int n,ma;
int m,p[1001];
int dfs(int k){
  if(k == 4) return 0;
  int ret = 0;
  for(int i=0;i<n;i++){
    if(dfs(k+1)+p[i]-m > 0) break;
    ret = max(ret,dfs(k+1)+p[i]);
  }
  ma = max(ma,ret);
  return ret;
}
int main(){
  while(cin >> n >> m && n!=0 && m!= 0){
    ma = 0;
    for(int i=0;i<n;i++){
      cin >> p[i];
    }
    sort(p,p+n);
    dfs(0);
    cout << ma << endl;
  }
  return (0);
}

C++: #include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <map>
#include <sstream>
#include <queue>
#include <cstdlib>
#include <algorithm>
#include <iterator>
#include <stack>
#include <list>
using namespace std;
#define INF 100000000
typedef long long int lli;
typedef pair<int,int> P;

int p[1001];
int h[1000*1000+1001];

int main(){
	int n,m,ans;
	while(cin>>n>>m){
		if(n==0&&m==0) break;
		p[0]=0;
		ans=0;
		for(int i=1; i<=n; ++i){
			cin >> p[i];
		}
		for(int i=0; i<=n; ++i){	
			for(int j=0; j<=n; ++j){
				h[i*n+j]=p[i]+p[j];
			}
		}
		sort(h,h+n*n+1);
		/*
		for(int i=0; i<=n*n; ++i){
			cout << h[i] << "\n";
		}
		*/
		for(int i=0; i<=n; ++i){	
			for(int j=0; j<=n; ++j){	
				int tmp=p[i]+p[j];
				int l=0,r=n*n;
				int cnt=0;
				while(1){
					int mid=(r+l)/2;
					if(cnt>=30){
						if(h[mid]+tmp<=m) ans=max(ans,h[mid]+tmp);
						break;
					}
					if(h[mid]+tmp>m){
						r=mid;
					} else if(h[mid]+tmp<m){
						l=mid;
					} else if(h[mid]+tmp==m){
						ans=m;
						break;
					}
					++cnt;
				}
			}
		}
		cout << ans << "\n";
	}
	return 0;
}

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


int point2[1000000];

int search(int a[], int n, int key) {
	int left = 0;
	int right = n;
	int mid;
	while (left < right) {
		mid = (left + right) / 2;
		if (a[mid] == key) return a[mid];
		else if (a[mid] < key) left = mid + 1;
		else right = mid;
	}
	return a[left-1];
}

int main() {
	while (true) {
		int n, m;
		cin >> n >> m;
		if (n == 0 && m == 0) return 0;
		int point[n+1];
		for (int i = 0; i < n; i++) cin >> point[i];
		point[n] = 0;
		int k = 0;
		for (int i = 0; i < n + 1; i++) {
			for (int j = i; j < n + 1; j++) {
				point2[k] = point[i] + point[j];
				k++;	
			}
		}
		int np = k;
		sort(point2, point2 + np);

		int ans = 0;
		for (int i = 0; i < np; i++) {
			if (point2[i] > m) break;
			int s = search(point2, np, m - point2[i]);
			int t = s + point2[i];
			if (t > ans) ans = t;
		}
		cout << ans << endl;
	}
}

C++: #include<bits/stdc++.h>
#define rep(i,n)for(ll i=0;i<n;i++)
using namespace std;
typedef long long ll;

ll k[1000010];
ll p[1010];
int main() {
	ll n, m;
	while (scanf("%lld%lld", &n, &m), n) {
		memset(p, 0, sizeof(p));
		rep(i, n)scanf("%lld", &p[i]);
		ll c = 0;
		rep(i, n + 1)for (ll j = i; j < n + 1; j++) {
			k[c++] = p[i] + p[j];
		}
		sort(k, k + c);
		ll Max = 0;
		rep(i, n + 1)for (ll j = i; j < n + 1; j++) {
			ll*a = upper_bound(k, k + c, m - p[i] - p[j]);
			if (a == k)continue;
			Max = max(Max, *(a - 1) + p[i] + p[j]);
		}
		printf("%lld\n", Max);
	}
}