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 _, val := range sums {
			rem := M - val
			if rem >= 0 {
				index := sort.Search(len(sums), func(i int) bool { return sums[i] > rem }) - 1
				if index >= 0 {
					m = max(m, val+sums[index])
				}
			}
		}
		fmt.Println(m)
	}
}

C++: #include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
 
int n, m;
vector<int> p1, p2;
int main()
{
  while(true){
    scanf("%d%d", &n, &m);
    if(!n && !m)
      break;

    p1.clear();
    p2.clear();
     
    //chap1
    p1.push_back(0);
    for(int i = 0; i < n; i++){
      int p;
      cin >> p;
      p1.push_back(p);
    }
 
    //chap2
    for(int i = 0; i <= n; i++)
      for(int j = i; j <= n; j++)
    p2.push_back(p1[i] + p1[j]);
 
    sort(p2.begin(), p2.begin() + p2.size());
 
    //chap3
    int ans = 0;
    for(int i = 0; i < p2.size(); i++){
      vector<int>::iterator count2 = upper_bound(p2.begin(), p2.end(), m - p2[i]);
      if(count2 != p2.begin())
    ans = max(ans, *(count2 - 1) + p2[i]);
    }
    cout << ans << endl;
  }
  return 0;
}

C++: #include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <functional>
#include <bitset>
#include <string>
#include <stack>
#include <cmath>
#include <set>
#include <map>
#include <list>
#include <deque>
using namespace std;
#define INF 10000000
#define LLINF 100000000000000
typedef pair<int, int> P;
typedef long long ll;
#define pb push_back
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define all(x) (x).begin(),(x).end()
#define VSORT(v) sort(v.begin(), v.end());
#define fi first
#define se second
#define out(x) cout << x << endl;
int dx[] = { 1, 0, -1, 0 }, dy[] = { 0,1,0,-1 };
ll MOD = 1000000007;
ll ha[1000005] = { 0 };

int main() {
	while (true) {
		ll n, m;
		ll p[1005] = { 0 };
		ll res = 0;
		int cnt = 0;
		cin >> n >> m;
		if (n == 0 && m == 0) return 0;
		for (ll i = 1; i <= n; i++) cin >> p[i];
		for (ll i = 0; i <= n; i++) {
			for (ll j = i; j <= n; j++) {
				ha[cnt++] = p[i] + p[j];
			}
		}
		sort(ha, ha + cnt);
		for (int i = 0; i < cnt; i++) {
			ll sum = ha[i];
			auto a = upper_bound(ha, ha + cnt, m - sum) - ha;
			//out(m-sum);
			if (a >= 1) if (sum + ha[a - 1] <= m) res = max(res, sum + ha[a - 1]);
		}
		out(res);
	}
	return 0;
}

C++: #include <iostream>
#include <string.h>
using namespace std;

int N, M, P[1001], ans;

void rec(int n, int sum){
	if(sum > M)
		return;
	if(n == 4){
		ans = max(ans, sum);
		return;
	}
	
	for(int i = 0; i <= N; ++i){
		rec(n + 1, sum + P[i]);
	}
	return;
}

int main() {
	while(cin >> N >> M && (N || M)){
		ans = 0;
		memset(P, 0, sizeof(P));
		for(int i = 0; i < N; ++i){
			cin >> P[i];
		}
		rec(0, 0);
		cout << ans << endl;
	}
	return 0;
}

C++: #include<cstdio>
#include<math.h>
#include<algorithm>
#include<string.h>

using namespace std;
const int INF =1001001001;
#define rep(i,n) for(int i=0;i<n;i++)
const int MAX_T = 1002*1002;
int M;



int main(){
	int N,M;
	int P[1002];
	scanf("%d %d",&N,&M);
	do{
		rep(i,N)scanf("%d",&P[i]);
		P[N]=0;//投げない場合
		//2回の合計の場合をだす
		int P2[MAX_T];
		int T=-1;
		rep(i,N+1)rep(j,N+1)P2[++T]=P[i]+P[j];
		sort(P2,P2+T);
		//二分探索
		int ans=0;
		rep(i,T){
			int q=M-P2[i];
			int a=0,b=T;
			if(q<0)continue;
			else{
				while(b-a>1){
				int c=(b+a+1)/2;
				if(P2[c]>q){b=c;}
				else{a=c;}
				}
				ans=max(P2[i]+P2[a],ans);					
			}
		}
		printf("%d\n",ans);
		scanf("%d %d",&N,&M);
	}while(N!=0||M!=0);
	return 0;
}

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


using namespace std;

int main(){
    while(true){
        int N,M;
        cin >> N >> M;
        if(N == 0 and M == 0) break;
        const int C = 4;
        vector<set<int>> ps(C+1);
        ps[0].insert(0);
        for(int i=0;i<N;i++){
            int p;cin >> p;
            for(int j=0;j<C;j++){
                for(auto k : ps[j]){
                    if(k+p <= M){
                        ps[j+1].insert(k+p);
                    }
                }
            }
        }

        int ret = 0;
        for(int i=0;i<C+1;i++){
            for(auto k : ps[i]){
                ret = max(ret,k);
            }
        }
        cout << ret << endl;
    }
    return 0;
}

C++: #include<stdio.h>
#include<algorithm>
using namespace std;
int n,lim;
int point[1010] = {0};
int f(int now,int mem,int maxp)
{
    //printf("%d %d %d\n",now,mem,maxp);
    int sum = 0;
    if(now == n)return maxp;
    for(int i = mem; i < 5 && lim >= maxp + point[now] * (i - mem); i++)
    {
        sum = max(sum,f(now + 1,i,maxp + point[now] * (i - mem)));
    }
    return sum;
}
int main()
{
    while(scanf("%d%d",&n,&lim),n + lim)
    {
        for(int i = 0; i < n; i++)scanf("%d",&point[i]);
        printf("%d\n",f(0,0,0));
    }
    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+1];

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>=80){
						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 <vector>
#include <set>
#include <map>
#include <sstream>
#include <string>
#include <cstdio>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
#include <functional>
#include <cstring>
#include <tuple>
#include <utility>
#include <list>
#include <cmath>

using namespace std;

typedef long long LL;
typedef vector<int> Array;
typedef pair<int, int> P;

const LL LINF = 1LL << 60;
const LL MOD = 100000;
#define rep(i,n) for(int i=0;i<(int)n;++i)
#define all(c) (c).begin(), (c).end()

struct edge{ LL to, cost; edge(int t, LL c) :to(t), cost(c){} };

int dxk[] = { 1, 1, 1, 0, -1, 0 };
int dxg[] = { 0, 1, 0, -1, -1, -1 };
int dy[] = { -1, 0, 1, 1, 0, -1 };

int main()
{
	int n;
	LL m;
	vector<LL> anses;
	while (cin >> n >> m && n)
	{
		vector<LL> nums(n);
		rep(i, n) cin >> nums[i];
		vector<LL> arr(n*n + n);
		rep(i, n) rep(j, n)
		{
			arr[i * n + j] = nums[i] + nums[j];
		}
		rep(i, n) arr[n*n + i] = nums[i];
		sort(all(arr));

		LL ans = 0;
		for (auto x : arr)
		{
			LL rem = m - x;
			auto it = upper_bound(all(arr), rem);
			if (it != arr.begin())
			{
				LL num = *(--it);
				ans = max(ans, num + x);
			}
		}
		cout << ans << endl;
		anses.push_back(ans);
	}
	cout << "anses" << endl;
	for (auto x : anses) cout << x << endl;
	cin >> n;
	return 0;
}