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 <map>
#include <algorithm>
#define INF (2LL << 58)
using namespace std;

typedef long long ll;

map<pair<int, int>, ll> dp;
int n, m, p[1111];

ll rec(int sum, int cnt){
    
    if(sum < 0) return -INF;
    if(cnt == 4) return 0;
    if(dp[make_pair(sum, cnt)]) return dp[make_pair(sum, cnt)];
    
    ll ret = -INF;
    for(int i = 0; i < n; i++){
        ret = max(ret, max(rec(sum - p[i], cnt + 1) + p[i], rec(sum, cnt + 1)));
    }
    return dp[make_pair(sum, cnt)] = ret;
}

int main(){
    
    while(cin >> n >> m, n||m){
        dp.clear();
        for(int i = 0; i < n; i++) cin >> p[i];
        cout << rec(m, 0) << endl;
    }
}

C++: #include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
using namespace std;

int main()
{
  int n,m;
  for(;cin>>n>>m,n;)
    {
      int ans=0;
      int data[n];
      map<int,bool>hash;
      queue<int> qu1;
      for(int i=0;i<n;i++)
	{
	  cin>>data[i];
	  //	  cout<<"count "<<hash.count(data[i])<<endl;
	  if(data[i]<=m && hash.count(data[i])==0)
	    {
	      //  cout<<"f "<<data[i]<<endl;
	      ans=max(ans,data[i]);
	      qu1.push(data[i]);
	      hash[data[i]]=true;
	    }
	}

      for(int x=0;x<3;x++)
	{
	  queue<int> qu2;
	  while(!qu1.empty())
	    {
	      int po=qu1.front();
	      qu1.pop();
	      /*
	      if(hash.count(po)!=0)
		continue;
	      */
	      for(int i=0;i<n;i++)
		{
		  if(po+data[i]<=m && hash.count(po+data[i])==0)
		    {
		      ans=max(ans,po+data[i]);
		      qu2.push(po+data[i]);
		      hash[po+data[i]]=true;
		    }
		}
	    }
	  qu1=qu2;
	}
      cout<<ans<<endl;
    }
}

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

using namespace std;

int main() {
  
  int n, m;
  
  while(cin >> n >> m && (n|m)) {
    int data[1001];
    int Q[1000001];
    
    n++;
    data[0] = 0;
    for(int i=1; i<n; i++) {
      cin >> data[i];
    }
    
    int T = 0;
    
    for(int i=0; i<n; i++) {
      Q[T++] = data[i];
    }
    
    for(int i=0; i<n; i++) {
      for(int j=0; j<n; j++) {
	Q[T++] = data[i] + data[j];
      }
    }
    
    sort(Q, Q+T);

    // for(int i=0; i<T; i++) cout << Q[i] << endl;
    
    int ans = 0;
    
    for(int i=0; i<T; i++) {
      int M = m - Q[i];
      if(M < 0) break;
      
      int lb = 0, ub = T;
      
      while(ub - lb > 1) {
	int mid = (lb + ub) / 2;
	
	if(Q[mid] <= M) {
	  lb = mid;
	} else {
	  ub = mid;
	}
      }
      ans = max(ans, Q[i]+Q[lb]);
    }
    
    cout << ans << endl;
  }
  
  return 0;
}

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


int main(){
  ll n,m,p[1010];
  while(cin >> n >> m){
    if(n==0 && m==0)break;

    rep(i,n)cin >> p[i];
    vector<ll> sum;

    sum.push_back(0);
    rep(i,n){
      sum.push_back(p[i]);
      Rep(j,i,n)sum.push_back(p[i]+p[j]);
    }
    sort(all(sum));
    sum.erase(unique(all(sum)),sum.end());

    ll res = 0;
    rep(i,sum.size()){
      if(m<sum[i])break;
      int pos = upper_bound(all(sum),m-sum[i]) - sum.begin();
      if(pos>0)res = max(res, sum[pos-1] + sum[i]);
    }
    cout << res << endl;
  }
}

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

#define loop(i,n) for(int i=1;i<=n;i++)
int n,m;
int p[1002];
set<int> s1;
set<int> s2;

signed main(){
  while(cin>>n>>m,n){
    loop(i,n)cin>>p[i];
    s1.clear();
    s2.clear();
    s1.insert(0);
    loop(a,4){
      for(int x:s1){
        s2.insert(x);
        loop(i,n){
          s2.insert(x+p[i]);
        }
      }
      swap(s1,s2);
    }
    int mx=0;
    for(int x:s1){
      if(x<=m)mx=max(x,mx);
    }
    cout<<mx<<endl;
  }
  return 0;
}

C++: #include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <queue>
#include <bitset>
#include <algorithm>
#include <functional>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>

using namespace std;

#define sz			size()
#define lgt			length()
#define rep(i,n)	for (int i = 0; i < n; i++)
#define ALL(X)		(X).begin(),(X).end()
#define RALL(X)		(X).rbegin(),(X).rend()
#define pb			push_back
#define SORT(a)		sort(ALL(a));
#define RSORT(a)	sort(RALL(a));
#define mp			make_pair
#define dump(x)		cerr<<#x<<" = "<<(x)<<endl;
#define fir			first
#define sec			second

typedef pair<int,int> P;
typedef vector<int> vi;
typedef vector<string> vs;

int toInt(string s){int v;istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}
vs form(string a,char s){vs v;string b;rep(i,a.lgt){if(a[i]==s){v.pb(b);b="";}else b+=a[i];}v.pb(b);return v;}
vi formint(string a,char s){vi v;string b;rep(i,a.lgt){if(a[i]==s){v.pb(toInt(b));b="";}else b+=a[i];}v.pb(toInt(b));return v;}

const double EPS=1e-10,PI=acos(-1.0);
const int INF=2100000000;

int main(void)
{
	int n, m, tmp;
	while (cin >> n >> m, n && m){
		int res = 0;
		vi v, v1;
		
		v.pb(0);
		for (int i = 0; i < n; i++){
			cin >> tmp;
			v.pb(tmp);
		}
		for (int i = 0; i < v.sz; i++){
			for (int j = 0; j < v.sz; j++){
				v1.pb(v[i] + v[j]);
			}
		}
		SORT(v1);
		
		for (int i = 0, j = v1.sz - 1; i < v1.sz && 0 <= j;){
			if (m < v1[i] + v1[j]) j--;
			else {
				res = max(res, v1[i] + v1[j]);
				i++;
			}
		}
		
		cout << res << endl;
		v.clear();
	}
	
	return 0;
}