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

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

#define int long long int
#define rep(a,b,c) for(int a=b;a<c;a++)
#define repm(a,b,c) for(int a=(b);a>c;a--)
#define pb push_back
#define str string
#define sf(a) scanfs("%d",&a)
#define pb push_back
#define mp make_pair
#define Fi first
#define Se second
#define ALL(v) (v).begin(), (v).end()

using namespace std;

const int INF = 1e18 + 9;
const int Mod = 1e9 + 7;
inline int replac(str s){double ans=0;rep(i,0,s.length()){ans+=(s[i]-'0')*pow(10,s.length()-i-1);}return (int)ans;}
inline string numstr(int m){str s="";while(m>0){char c;int a=m/10;if(a>0)a=m%(a*10);else a=m;c=(char)('0'+a);s+=c;m/=10;}str st="";for(int i=s.size()-1;i>=0;i--){st+=s[i];}return st;}
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef vector<pii> vii;
int n,m;
vi a;
int dp[200000001];
signed main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    while(1){
    cin >> n >> m;
    if(n==0&&m==0)break;
    rep(i,0,20000001){dp[i]=0;}
    rep(i,0,n){
        int x;
        cin >> x;
        a.pb(x);
    }
    sort(ALL(a));
    dp[0]=1;
    rep(i,0,a.size()){
        for(int j=0;j<m;j++){
            rep(k,1,5){
                if((j+a[i]*k)<=m){
                    if(dp[a[i]*k+j]>0&&dp[j]>0)dp[a[i]*k+j]=min(dp[a[i]+j],dp[j]+1);
                    if(dp[j]>0)dp[a[i]*k+j]=dp[j]+1;
                }
            }
        }
    }
    int ans=0;
    rep(i,0,m+1){
        if(dp[i]!=0&&dp[i]<=4){
            ans=i;
            //cout << i << " " << dp[i] <<endl;
        }
    }
    //cout << dp[m-2] << endl;
    cout << ans << endl;
    }
    return 0;
}

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

class Solve {
private:

public:
	bool is_last_query{};
	Solve()
	{
		int N, M;
		scanf("%d%d", &N, &M);
		if (N == 0)
		{
			is_last_query = true;
			return;
		}
		std::vector<int> P(N);
		for (auto& e: P) scanf("%d", &e);
		std::vector<int> former;
		former.reserve((N + 1) * (N + 1));
		former.push_back(0);
		for (auto& e: P) former.push_back(e);
		for (int i{}; i < N; i++)
			for (int j{}; j < N; j++)
				if (P[i] + P[j] <= M)
					former.push_back(P[i] + P[j]);
		std::sort(former.begin(), former.end());
		former.erase(std::unique(former.begin(), former.end()), former.end());
		int max{};
		for (int i{}, pair{(int)former.size() - 1}; i < (int)former.size(); i++)
		{
			while (former[i] + former[pair] > M) pair--;
			max = std::max(max, former[i] + former[pair]);
		}
		printf("%d\n", max);
	}
};

int main()
{
	while (!Solve().is_last_query);

	return 0;
}