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 <vector>
#include <algorithm>

using namespace std;

typedef vector<int> vi;

#define PB push_back
#define rep(i,x) for(int i=0;i<(x);++i)
#define rep1(i,x) for(int i=1;i<=(x);++i)
#define all(a) a.begin(),a.end()

int P[1001];

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);

	int N, M;
	
	while (cin >> N >> M, N || M) {
		rep1(i, N) cin >> P[i];

		vi A;

		A.PB(0);

		rep(i, N + 1) rep(j, N + 1) if (P[i] + P[j] <= M) A.PB(P[i] + P[j]);

		sort(all(A));

		int ma = 0;

		rep(i, A.size()) {
			int tmp;

			int pos = upper_bound(all(A), M - A[i]) - A.begin();

			if (pos == A.size()) {
				tmp = A.back();
			} else if (pos - 1 == -1) {
				tmp = 0;
			} else {
				tmp = A[pos - 1];
			}

			if (A[i] + tmp <= M) {
				ma = max(ma, A[i] + tmp);
			}
		}

		cout << ma << endl;
	}
}

C++: #include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <map>
#include <list>
#include <set>
#include <numeric>
#include <queue>
#include <stack>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <climits>
#include <cfloat>
#include <ctime>
#include <complex>
#include <cassert>
#include <iomanip>
using namespace std;
typedef long long LL;
typedef pair<int,int> P;

int N,M;
int main() {
while(1){
	cin >> N >> M;
	if(N==0&&M==0)return 0;
	vector<int> in;
	for(int i=0;i<N;i++){
		int a;
		cin >> a;
		in.push_back(a);
	}
	in.push_back(0);
	vector<int> p;
	for(int i=0;i<in.size();i++){
		for(int j=i;j<in.size();j++){
			p.push_back(in[i]+in[j]);
		}
	}
	int s=0,t=p.size()-1;
	sort(p.begin(),p.end());
	int ret=0;
	while(s<=t){
		int v=p[s]+p[t];
		if(v<=M){
			ret=max(ret,v);
			s++;
		}
		else{
			t--;
		}
	}
	cout << ret << endl;
}
}

C++: #include <bits/stdc++.h>
using namespace std ;

#define pb(n) push_back(n)
#define fi first
#define se second
#define all(r) (r).begin(),(r).end()
#define gsort(st,en) sort((st),(en),greater<int>())
#define vmax(ary) *max_element(all(ary))
#define vmin(ary) *min_element(all(ary))
#define debug(x) cout<<#x<<": "<<x<<endl
#define fcout(n) cout<<fixed<<setprecision((n))
#define scout(n) cout<<setw(n)
#define vary(type,name,size,init) vector< type> name(size,init)

#define rep(i,n) for(int i = 0; i < (int)(n);++i)
#define REP(i,a,b) for(int i = (a);i < (int)(b);++i)
#define repi(it,array) for(auto it = array.begin(),end = array.end(); it != end;++it)
#define repa(n,array) for(auto &n :(array))

using ll = long long;
using vi = vector<int>;
using vl = vector<ll>;
using dict = map<string,int>;
using pii = pair<int,int> ;
using pll = pair<ll,ll> ;

const int mod = 1000000007;
constexpr int imax = ((1<<30)-1)*2+1 ;
constexpr int inf = 1000000000;
constexpr double PI = acos(-1.0) ;
double eps = 1e-10 ;
const int dy[] = {-1,0,1,0};
const int dx[] = {0,-1,0,1};

inline bool value(int x,int y,int w,int h){
  return (x >= 0 && x < w && y >= 0 && y < h);
}

ll n,m;
vector<set<ll>> dp(5);

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  while(cin >> n >> m && n && m){
    vary(ll,s,1001,0);
    rep(i,n){
      cin >> s[i];
    }
    sort(s.begin(),s.begin()+n);
    dp = vector<set<ll>>(5);
    dp[0].insert(0LL);
    rep(i,4){
      for(auto &&e : dp[i]){
        if(e > m) break;
        dp[i+1].insert(e) ;
        rep(k,n){
          if(e+s[k] <= m)
            dp[i+1].insert(e+s[k]);
        }
      }
      dp[i].clear();
    }
    cout << *(dp[4].rbegin()) << endl;
//     ll ans = -1;
//     for(auto rit = dp[4].rbegin(); rit != dp[4].rend(); ++rit){
//       if(rit->se){
//         ans = max(ans,rit->fi);
//         break;
//       }
//     }
//     cout << ans << endl;
  }
  return 0;
}

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

using namespace std;

#define MAX(a,b) ((a)>(b)?(a):(b))

int main()
{
    int N;
    long long M;

    cin >> N >> M;

    while(N!=0 && M!=0) {
        vector<long long> p(N);
        set<long long> st[2];

        long long ans=0;

        for(int i=0; i<N; ++i) {
            cin >> p[i];
        }

        sort(p.begin(),p.begin()+N);

        for(int i=0; i<N; ++i) {
            if(p[i]<=M) st[0].insert(p[i]);
            ans=MAX(ans,p[i]);
        }

        for(int i=0; i<N; ++i) {
            for(auto itr=st[0].begin(); itr!=st[0].end(); ++itr) {
                if(p[i]+*itr<=M) {
                    st[1].insert(p[i]+*itr);
                    ans=MAX(ans,p[i]+*itr);
                }
            }
        }

        for(auto itr0=st[0].begin(); itr0!=st[0].end(); ++itr0) {
            auto itr1=upper_bound(st[1].begin(),st[1].end(), M-*itr0);
            if(itr1==st[1].begin()) break;
            --itr1;
            ans=MAX(ans,*itr0+*itr1);
        }

        for(auto itr0=st[1].begin(); itr0!=st[1].end(); ++itr0) {
            auto itr1=upper_bound(st[1].begin(),st[1].end(), M-*itr0);
            if(itr1==st[1].begin()) break;
            --itr1;
            ans=MAX(ans,*itr0+*itr1);
        }

        cout << ans << endl;


        cin >> N >> M;
    }
    return 0;
}

C++: #include<iostream>
#include<set>
#include<vector>
using namespace std;
typedef unsigned int uint;
uint maxv;
void solve(uint now,uint m,uint *a,int n){
  int r=n-1,l=0,mid;
  while(l <=r){
    mid = (l+r)/2;
    if ( a[mid]+now>m)r=mid-1;
    else if ( a[mid]+now <m)l=mid+1;
    else break;

  }
  if ( now+a[mid]>maxv&& now+a[mid]<m)maxv=now+a[mid];
}


main(){
  int n;
  uint m;
  while(scanf("%d%d",&n,&m) && n){
    set<uint> S;    
    uint one[n];
    uint two[n*n];
    int p=0;
    for(int i=0;i<n;i++)scanf("%d",&one[i]);
    for(int i=0;i<n;i++){
      for(int j=i;j<n;j++){
	if ( S.find(one[i]+one[j]) == S.end())S.insert(one[i]+one[j]),two[p++]=one[i]+one[j];
      }
    }
    sort(one,one+n);
    sort(two,two+p);
    maxv=0;
    for(int i=0;i<p;i++){
      if ( two[i]+one[0]>m)break;
      if ( two[i]+two[0]<=m)solve(two[i],m,two,p);
      if ( two[i]+one[0]<=m)solve(two[i],m,one,n);
    }
    printf("%d\n",maxv);
  }
  return false;
}