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 <vector>
#include <algorithm>
using namespace std;

int main(){
	int n,m,i,j;
	while(cin >> n >> m, n && m){	
		int ret = 0;
		vector<int> data(n+1);
		vector<int> all;
		for(i=0;i<n;i++)cin >> data[i];
		for(i=0;i<n+1;i++)
			for(j=i;j<n+1;j++)
				all.push_back(data[i]+data[j]);
		sort(all.begin(),all.end());
		
		for(i=0;i<all.size();i++){
			int t = m-all[i];
			vector<int>::iterator it = upper_bound(all.begin(),all.end(),t);
			if(it != all.begin()){
				ret = max(ret,all[i] + *(it-1) );
			}
		}
		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;
multimap<ll,ll> mm;
vary(ll,s,1001,0);
ll dfs(ll cnt, ll sum){
  auto r = mm.equal_range(sum);
  for(auto it = r.fi; it != r.se; ++ it){
    if(it->se <= cnt){
      return sum;
    }
  }
  if(cnt == 4) return sum;
  mm.insert(make_pair(sum,cnt));
  ll res = sum;
  rep(i,n){
    if(sum + s[i] <= m){
      res = max(res,dfs(cnt+1,sum + s[i]));
    }
  }
  return res;
}

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  while(cin >> n >> m && n && m){
    rep(i,n){
      cin >> s[i];
    }
    sort(s.begin(),s.begin()+n);
    mm.clear();
    cout << dfs(0,0) << endl;
  }
  return 0;
}

C++: #include<iostream>
using namespace std;
int main(){
  int n,m,s,k;
  while(cin>>n>>m){
    if(n==0&&m==0) break;
    int t[m+1];
    for(int i=0;i<=m;i++) t[i] = 0;
    for(int i=0;i<n;i++){
      cin >> k;
      for(int j=0;j<4;j++){
	for(int g=m-1;g>=0;g--){
	  if(t[g]>=1&&g+k<=m&&t[g]<4){
	    if(t[g+k]==0||t[g+k]>t[g]+1) t[g+k] = t[g] + 1;
	  }
	  if(g==0) t[k] = 1;
	}
      }
    }
    for(int i=m;i>=0;i--){
      if(t[i]!=0){
	cout << i << endl;
	break;
      }
    }
  }
  return 0;
}

C++: #include<iostream>
#include<string>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<list>
#include<iomanip>
#include<vector>
#include<functional>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef long long ll;
const long long inf = 8000000000000000;
struct P {
	ll pos, cost;
};
bool operator<(P a, P b) { return a.cost < b. cost; }
bool operator>(P a, P b) { return a.cost > b. cost; }
int main() {
	ll a[1000], n, m;
	while (cin >> n >> m&&n != 0 && m != 0) {
		for (int i = 0; i < n; i++) cin >> a[i];
		ll b[1000];
		fill(b, b + n, -1);
		b[0] = a[0];
		priority_queue<P, vector<P>, greater<P>>p;
		p.push(P{ 0,a[0] });
		while (!p.empty()) {
			P t = p.top(); p.pop();
			for (int i = 0; i < n; i++) {
				if (a[i] + b[t.pos] > b[i] && a[i] + b[t.pos] <= m) {
					b[i] = a[i] + b[t.pos];
					p.push(P{ i,b[i] });
				}
			}
		}
		cout << max(b[n - 1],(ll)0) << endl;
	}
}

C++: #include<iostream>
#include<vector>
#include<map>
#include<cassert>
#define MAX 200000010
using namespace std;

int main(){
  int N,M;
  vector<int> vec[5];
  map<int,bool> used;
  while(true){
  cin >> N >> M;
  if(N+M == 0)break;
  int val[N];
  for(int i=0;i<5;i++)vec[i].clear();
  used.clear();
  int mex = -1;
  int master = -1;
  
  for(int i=0;i<N;i++){
    cin >> val[i];
    used[val[i]] = true;
    mex = max(mex,val[i]);
    vec[1].push_back(val[i]);
  }
  master = mex;
  if(mex == M){
    cout << M << endl;
    continue;
  }
  bool fin = false;
  for(int i=2;i<=4;i++){       
     
      for(int j=0;j<vec[i-1].size();j++){
	if(vec[i-1][j]+master <= mex)continue;
	for(int k=0;k<N;k++){
	  if(val[k] >= M)continue;

	  //if(used[vec[i-1][j]+val[k]])continue;
	  if(i == 4 && vec[i-1][j]+val[k] <= mex)continue;

	  //used[vec[i-1][j]+val[k]] = true;
	  vec[i].push_back(vec[i-1][j]+val[k]);
	

	if(M >= vec[i-1][j]+val[k])mex = max(mex,vec[i-1][j]+val[k]);

	if(mex == M){
	  fin = true;
	  break;
	}
      }
      if(fin)break;
    }
    if(fin)break;
 
  }
  assert(mex != -1);
  cout << mex << endl;	
  }
  return 0;
}

C++: #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<functional>
#include<vector>
using namespace std;

int main(){
	int N,M;
	while(cin>>N>>M,N||M){
		int latte[1001],ans=0;
		vector<int> comb;
		latte[0]=0;
		for(int i=1;i<=N;i++){
			cin>>latte[i];
		}
		for(int i=0;i<N;i++){
			for(int j=0;j<N;j++){
				comb.push_back(latte[i]+latte[j]);
			}
		}
		sort(comb.begin(),comb.end());
		//for(int i=0;i<comb.size();i++) printf("%d ",comb[i]); puts("");
		for(int i=0;i<=N;i++){
			for(int j=0;j<=N;j++){
				vector<int>::iterator itr;
				itr = upper_bound(comb.begin(),comb.end(),M-latte[i]-latte[j]);
				if(itr!=comb.begin()) ans = max(ans,latte[i]+latte[j]+*(itr-1));
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}

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

using namespace std;

bool Finding(const int&);

int x;

int main(){
  int i, j, k, n, m, p, q, ans, _ans;
  vector<int> data;
  vector<int>::iterator iter;

  while(1){
    cin >> n >> m;
    if(n == 0 && m == 0) break;

    for(i=0; i<n; ++i){
      cin >> p;
      iter = find(data.begin(), data.end(), p);
      if(p <= m && iter == data.end()) data.push_back(p);
    }

    sort(data.begin(), data.end(), greater<int>());

    ans = 0;
    for(j=0; j<data.size(); ++j){
      if(ans == m || ans >= 4*data[j]) break;

      _ans = 0;
      for(k=0; k<4; ++k){
	x = m - _ans;
	iter = find_if(data.begin()+j, data.end(), Finding);
	if(iter == data.end()) break;
	_ans += *iter;
	if(_ans == m) break;
      }
      if(ans < _ans) ans = _ans;
    }

    cout << ans << endl;
    data.clear();
  }

  return 0;
}

bool Finding(const int& a){
  if(a <= x) return true;
  else return false;
}