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<bits/stdc++.h>
using namespace std;
#define int long long
signed main(){
  int n,m;
  while(cin>>n>>m,n){
    int p[n];
    for(int i=0;i<n;i++) cin>>p[i];
    set<int> s;
    s.insert(0);
    s.insert(m+1);
    for(int i=0;i<n;i++)
      s.insert(p[i]);
    for(int i=0;i<n;i++)
      for(int j=0;j<n;j++)
	s.insert(p[i]+p[j]);
    int ans=0;
    auto latte=--s.end();
    for(int x:s){
      if(x>m) continue;
      while(latte!=s.begin()&&x+*latte>m) --latte;
      int y=*latte;
      if(x+y>m) continue;
      ans=max(ans,x+y);
    }
    cout<<ans<<endl;
  }
  return 0;
}

C++: #include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
#include <cstdio>
#define REP(i, n) for(int i = 0;i < n;i++)
#define REPR(i, n) for(int i = n;i >= 0;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 SORT(v, n) sort(v, v+n);
#define VSORT(v) sort(v.begin(), v.end());
#define llong long long
#define pb(a) push_back(a)
#define INF 999999999
using namespace std;
typedef pair<int, int> P;

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

llong solve(int n, llong m){
	llong p[n];
	REP(i, n) cin >> p[i];
	sort(p, p+n);
	
	llong res=0;
	int c=0;
	REPR(i, n-1){
		if(c>=4) return res;
		while(res<=m && c<4){
			res+=p[i];
			c++;
		}
		if(res>m){
			res-=p[i];
			c--;
		}
	}
	
	return res;
}

int main(){
	while(1){
		int n;
		llong m;
		cin >> n >> m;
		if(n==0 && m==0) return 0;
		cout << solve(n, m) << endl;
	}
}

C++: #include <cstdio>
#include <algorithm>
using namespace std;

int N, M, p[1001], s[1001 * 1001];

int main(){
    while(scanf("%d%d", &N, &M) != EOF && (N|M)){
        for(int x = 0; x < N; x++){
            scanf("%d", p+x);
        }
        p[N++] = 0;
        for(int x = 0; x < N; x++){
            for(int y = 0; y < N; y++){
                s[N*x + y] = p[x] + p[y];
            }
        }
        sort(s, s+N*N);
        int ans = 0;
        for(int x = 0; x < N*N; x++){
            int* lb = lower_bound(s, s + N * N, M - s[x]);
            if(lb != s) --lb;
            if(s[x] + *lb > M) continue;
            ans = max(ans, s[x] + *lb);
        }
        printf("%d\n", ans);
    }
    return 0;
}

C++: #include <bits/stdc++.h>
#define ll long long
#define INF 999999999
#define MOD 1000000007
#define rep(i,n) for(int i=0;i<n;++i)

using namespace std;

typedef pair<int,int>P;

const int MAX_N = 1005;

int a[MAX_N];
int n,m;
vector<int> v;

int main()
{
	while(1){
		scanf("%d%d",&n,&m);
		if(n==0&&m==0){
			break;
		}
		v.clear();
		rep(i,n){
			scanf("%d",&a[i]);
		}
		a[n] = 0;
		rep(i,n+1){
			for(int j=i;j<=n;j++){
				v.push_back(a[i]+a[j]);
			}
		}
		v.erase(unique(v.begin(),v.end()),v.end());
		sort(v.begin(),v.end());
		int ans = 0;
		rep(i,v.size()){
			if(v[i] == m){
				ans = m;
				break;
			}
			if(v[i] < m){
				vector<int>::iterator it = upper_bound(v.begin(),v.end(),m-v[i]);
				int s = v[i] + *(it-1);
				if(m-ans > m-s){
					ans = s;
				}
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}

C++: #include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;

void solve(){
    ll n,m;
    ll ans;
    vector<ll> v,sum_v;

    cin>>n>>m;

    for(int i=0;i<n;i++){
        ll t;
        cin >> t;
        v.push_back(t);
    }

    v.push_back(0);

    for( auto t:v ){
        for( auto s:v ){
            sum_v.push_back(t+s);
        }
    }

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

    ans=-1;
    for( auto t:sum_v ){
        if( binary_search(sum_v.begin(),sum_v.end(),m-t) ){
            ans=m;
            break;
        }else{
            auto it=upper_bound(sum_v.begin(),sum_v.end(),m-t);
            if( it != sum_v.begin() ){
                ans=max(ans,t + *(upper_bound(sum_v.begin(),sum_v.end(),m-t)-1));
            }
        }
    }

    cout<<ans<<endl;
}

int main(){
    solve();
    return 0;
}

C++: #include <bits/stdc++.h>

const int MOD = 1e9 + 7;
const int iINF = 1000000000;
const long long int llINF = 1000000000000000000;
const double PI = acos(-1.0);
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;
using ll = long long int;
using P = pair<int, int>;
using edge = struct
{
    int to;
    int cost;
};

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

int main()
{
    int N, M;
    while (cin >> N >> M && N)
    {
        vector<ll> P(N + 1);
        P[0] = 0;
        rep(i, N) cin >> P[i + 1];

        vector<ll> candi;

        rep(i, N + 1)
        {
            for (int j = i + 1; j <= N; j++)
            {
                candi.push_back(P[i] + P[j]);
            }
        }

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

        ll ans = 0;

        rep(i, candi.size())
        {
            auto itr = upper_bound(candi.begin(), candi.end(), M - candi[i]);

            if(itr == candi.begin()) continue;

            if(M < candi[i] + *(itr - 1)) continue;

            ans = max(ans, candi[i] + *(itr - 1));
        }

        cout << ans << endl;
    }

    return 0;
}

C++: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class T>
using Table = vector<vector<T>>;
const ld eps=1e-9;

//// < "D:\D_Download\Visual Studio 2015\Projects\programing_contest_c++\Debug\a.txt" > "D:\D_Download\Visual Studio 2015\Projects\programing_contest_c++\Debug\b.answer"

int main() {
	while (1) {
		int N, M; cin >> N >> M;
		if (!N)break;
		vector<int>ns(N);
		for (int i = 0; i < N; ++i) {
			cin >> ns[i];
		}
		ns.push_back(0);
		vector<int>scores;
		for (int i = 0; i <= N; ++i) {
			for (int j = 0; j <= N; ++j) {
				scores.push_back(ns[i] + ns[j]);
			}
		}
		sort(scores.begin(), scores.end());
		scores.erase(unique(scores.begin(), scores.end()), scores.end());
		int ans = 0;
		for (auto it = scores.begin(); it != scores.end(); it++) {
			int rest = M - *it;
			auto jt = upper_bound(scores.begin(), scores.end(), rest);
			if (jt != scores.begin()) {
				ans = max(ans, M-(rest - *prev(jt)));
			}
		}
		cout << ans << endl;
	}
	
	return 0;
}

C++: #include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <functional> //sort(A,A.end(),greater<int>());???????????????
#include <queue>
#include <stack>
#include <vector>

#define INF 10 << 10

long p[1001];
long dp[4][1001];

int main() {
	int n;
	long m;
	while (cin >> n >> m && n != 0 && m != 0) {
		for (int i = 1; i <= n; ++i) {
			cin >> p[i];
		}
		for (int i = 0; i < 4; ++i) { dp[i][0] = 0; }
		for (int i = 0; i < 4; ++i) {
			for (int i2 = 1; i2 <= n; ++i2) {
				if (i == 0) {
					if (p[i2] <= m) {
						dp[i][i2] = max(dp[i][i2 - 1], p[i2]);
					}
					else { dp[i][i2] = dp[i][i2 - 1]; }
				}
				else {
					for (int i3 = 0; i3 <= n; ++i3) {
						if (dp[i - 1][i3] + p[i2] <= m) {
							dp[i][i2] = max(dp[i][i2], dp[i - 1][i3] + p[i2]);
						}
					}
				}
			}
		}

		cout << dp[3][n] << endl;
	}
}