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 <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <set>
#include <map>
#include <queue>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <cctype>
#include <cassert>
#include <cmath>
#include <limits>
#include <functional>

#define REP(i,n) for(int i=0;i<n;i++)
#define FOR(i,m,n) for(int i=m;i<n;i++)
#define FORR(i,m,n) for(int i=m;i>=n;i--)
#define pb(x) push_back(x) 
#define SORT(x) sort((x).begin(),(x).end())
#define INF 999999999

using namespace std;

#define int long long

signed main(){
	while(1){
		int n, m;
		cin >> n >> m;
		if(n==0) return 0;
		
		vector<int> p(n);
		REP(i, n){
			cin >> p[i];
		}
		p.push_back(0);
		sort(p.begin(), p.end());
		n++;
		
		vector<int> v;
		REP(i, n){
			REP(j, n){
				if(p[i]+p[j]<=m) v.push_back(p[i]+p[j]);
			}
		}
		sort(v.begin(), v.end());
		
		int l=0, r=v.size()-1, ans=0;
		for(; l<r; l++){
			if(v[l]+v[r]>m) r--;
			ans=max(ans, v[l]+v[r]);
		}
		
		cout << ans << endl;
	}
}

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

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;
		long long int b;
		for (int i = 0; i < n; i++) {
			cin >> b;
			if (b <= m) {
				data.push_back(b);
			}
		}
		sort(data.begin(), data.end());
		vector<long long int> data2;
		for (long long int i = 0; i < data.size(); i++) {
			data2.push_back(data[i]);
			for (long long int j = i; j < data.size(); j++) {
				if (data[i]+data[j] <= m) {
					data2.push_back(data[i]+data[j]);
				} else {
					break;
				}
			}
		}
		sort(data2.begin(), data2.end());
		data.clear();
		for (long long int i = 0; i < data2.size(); i++) {
			long long int a = data2[i];
			data.push_back(a);
			for (long long int j = i+1; j < data2.size(); j++) {
				if (data2[j] == a) {
					i++;
				} else {
					break;
				}
			}
		}
		data2.clear();
		for (long long int i = 0; i < data.size(); i++) {
			data2.push_back(data[i]);
			for (long long int j = i; j < data.size(); j++) {
				if (data[i]+data[j] <= m) {
					data2.push_back(data[i]+data[j]);
				} else {
					break;
				}
			}
		}
		sort(data2.begin(), data2.end());
		data.clear();
		long long int sz = data2.size();
		cout << data2[sz-1] << endl;
	}
	return 0;
}

C++: #include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <string>
#define SIZE 1005
#define LSIZE 1000005
#define INF 1000000005LL

using namespace std;
typedef long long int ll;
typedef pair <int,int> P;

int n;
ll M;
ll T[SIZE];
ll S[LSIZE];

ll solve()
{
	scanf("%d %lld",&n,&M);
	if(n+M ==0)return -1;
	for(int i=1;i<=n;i++)scanf("%lld",&T[i]);
	T[0]=0;
	for(int i=0;i<=n;i++){
		for(int j=i;j<=n;j++){
			S[i*(n+1)+j] = T[i]+T[j];
		}
	}
	ll maxv=0;
	ll v;
	sort(S,S+(n+1)*(n+1));
	for(int i=0;i<=n;i++){
		for(int j=i;j<=n;j++){
			if(T[i]+T[j]<=M){
				v = T[i]+T[j]+S[upper_bound(S,S+(n+1)*(n+1),M-T[i]-T[j])-S-1];
				maxv = max(maxv,v);
			}
		}
	}
	return maxv;
}

int main()
{
	while(1){
		ll ans = solve();
		if(ans==-1)break;
		else printf("%lld\n",ans);
	}
	return 0;
}

C++: #include<algorithm>
#include<iostream>
#include<string>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
int main(){
  int i,j,k,l;
  int a[1000],m,n,p;
  while(cin>>n>>m&&n+m){
    for(i=0;i<n;i++)
      cin>>a[i];
    sort(a,a+n,greater<int>());
    p=0;
    for(i=0;i<n&&a[i]>m;i++);
    if(i!=n)
      p=a[i];
    for(j=n-1;j>=i;j--){
      if(a[i]+a[j]>m){
	i++;
	j++;
      }else{

	for(k=n-1;k>=j;k--){
	  if(a[i]+a[j]+a[k]>m)
	    break;
	  else{

	    for(l=n-1;l>=k;l--){
	      if(a[i]+a[j]+a[k]+a[l]>m)
		break;
	      else
		p=max(p,a[i]+a[j]+a[k]+a[l]);
	    }

	    p=max(p,a[i]+a[j]+a[k]);
	  }
	}

	p=max(p,a[i]+a[j]);
      }
    }
    cout<<p<<endl;
  }
  return 0;
}

C++: #include <iostream>
#include <algorithm>
#include <set>
#define N_MAX 1001
using namespace std;

int N, M;
int P[N_MAX];
set<int> sp;

int solve() {
  set<int> s;
  for(int i = 0; i <= N; i++) {
    for(int j = i; j <= N; j++) {
      for(int k = j; k <= N; k++) {
        int tmp = P[i] + P[j] + P[k];
        if(tmp > M) tmp = 0;
        if(tmp == 0) continue;
        s.insert(tmp);
      }
    }
  }

  for(int i = 0; ; i++) {
    for(set<int>::iterator it = s.begin(); it != s.end(); it++) {
      int tmp = M - *it - i;
      if(sp.find(tmp) != sp.end()) return tmp + *it;
    }
  }
}

int main() {
  while((cin >> N >> M) && N && M) {
    P[0] = 0;
    sp.clear();
    sp.insert(0);
    for(int i = 1; i <= N; i++) {
      cin >> P[i];
      sp.insert(P[i]);
    }
    cout << solve() << endl;
  }
  return 0;
}

C++: #include <cstdio>

int main()
{
while(true) {
int n, m;
vector<int> x, xxx;
scanf("%d%d", &n, &m);
if(n == 0)
break;
x.resize(i);
for(int i = 0; i < n; ++i)
scanf("%d", &x[i]);
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j)
xxx.push_back(x[i] + x[j]);
}
xxx.push_back(0);
sort(xxx.begin(), xxx.end());
int ans = 0;
for(int i = 0; i < xxx.size(); ++i) {
int r = m - xxx[i];
if(r < 0)
continue;
int idx = upper_bound(xxx.begin(), xxx.end(), r) - xxx.begin() - 1;
if(idx < 0)
continue;
ans = max(ans, r + xxx[idx]);
}
printf("%d\n", ans);
}
return 0;
}