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 <string>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>	// require sort next_permutation count __gcd reverse etc.
#include <cstdlib>	// require abs exit
#include <cstdio>	// require scanf printf
#include <functional>
#include <numeric>	// require accumulate
#include <cmath>
#include <climits>
#include <limits>
#include <cfloat>
#include <iomanip>	// require setw
#include <sstream>	// require stringstream 
#include <cstring>	// require memset
#include <cctype>	// require tolower, toupper
#include <fstream>	// require freopen
#include <ctime>
#define rep(i,n) for(int i=0;i<(n);i++)
#define ALL(A) A.begin(), A.end()

using namespace std;

typedef long long ll;
typedef pair<int, int> P;
int dp[5][1005];

int main()
{
//	cut here before submit 
//	freopen ("testcase.darts", "r", stdin );
	int n, m;
	while (cin >> n >> m && n && m ){
		memset (dp, 0, sizeof (dp ) );
		vector<int> p (n, 0 );
		rep (i, n ){
			cin >> p[i];
		} // end rep
//		sort (ALL (p ) );

		rep (i, n ){
			dp[0][i] = (p[i] <= m ? p[i] : 0 );
		} // end rep
		rep (i, 4 ){
			rep (j, n ){
				if (dp[i][j] != 0 ){
					rep (k, n ){
						dp[i+1][k] = (p[k] + dp[i][j] <= m ? max (dp[i+1][k] , p[k] + dp[i][j] ) : dp[i+1][k] );
					} // end rep
				} // end if
			} // end rep
		} // end rep
/*
		rep (i, 4 ){
			rep (j, n ){
				cout << setw(3) << dp[i][j];
			} // end rep
			cout << endl;
		} // end rep
*/
		int res = 0;
		rep (i, 4 ){
			for (int j = m; j >= 0; j-- ){
				if (dp[i][j] != 0 ){
					res = max (res, dp[i][j] );
					break;
				} // end if
			} // end for
		} // end rep
		cout << res << endl;

	} // end loop
		
	return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;
vector<long int> po;
long int n,a,low,m,lastans,memo[1005],ss;
void solve(int dp,long int sum);

int main(){
    while(1){
        ss=0;
        lastans=0;
        po.clear();
        low=100000000;
        for(int i=0;i<1005;i++)memo[i]=0;

        cin >> n >> m;
        if(n==0&&m==0)break;
        for(int i=0;i<n;i++){
            cin >> a;
            po.push_back(a);
            low=min(low,a);
        }
        sort(po.begin(),po.end());
        cout << po[0] << endl;
        solve(0,0);
        cout << lastans << endl;
        //cout <<"ss=" << ss << endl;
    }

    return 0;
}

void solve(int dp,long int sum){
    //long int ans=0;
    //ss++;
    //cout <<"ss=" << ss << endl;
    if(dp==4)return ;
    else{
    // memo[dp]=max(sum,memo[dp]);

     for(int i=0;i<n;i++){
        if(sum+po[i]<m){
            lastans=max(lastans,sum+po[i]);
            //ans=max(ans,sum+po[i]);
            solve(dp+1,sum+po[i]);
            }else break;
        }
    }
    return;
}

C++: #include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
	while(1){
		int i,j,n,m,s=0,o=1;
		static int p[1001]={0},up[1001*1001]={0};
		scanf("%d%d",&n,&m);
		if(n==0&&m==0)return 0;
		up[0]=0;
		for(i=1;i<=n;i++){
			scanf("%d",&p[i]);
			for(j=i;j>=0;j--){
				up[o]=p[i]+p[j];
				o++;
			}
		}
		sort(up,up+o);
		for(i=0;i<o;i++){
			for(j=i;up[i]+up[j]<m&&j<o;j++);
			if(up[i]+up[j-1]<=m)s=max(s,up[i]+up[j-1]);
		}
		printf("%d\n",s);
	}
	return 0;
}

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;
	}
}