Go: ///
// File:  0529.go
// Author: ymiyamoto
//
// Created on Wed Feb 28 20:39:28 2018
//
package main

import (
	"fmt"
	"sort"
)

func max(n, m int) int {
	if n < m {
		return m
	} else {
		return n
	}
}

func main() {
	for {
		var N, M int
		fmt.Scan(&N, &M)
		if N == 0 && M == 0 {
			break
		}

		arr := make([]int, N+1)
		for i := 1; i <= N; i++ {
			fmt.Scan(&arr[i])
		}
		sort.Ints(arr)

		sums := make([]int, 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.Ints(sums)

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

#define REP(i,a,n) for(int i=(a); i<(int)(n); i++)
#define rep(i,n) REP(i,0,n)

int p[1024];
int main(){
	int n,m;
	while(cin>>n>>m,n|m){
		int ret = 0;
		vector<int> v;
		rep(i,n)scanf("%d",&p[i]);
		p[n++] = 0;
		rep(i,n){
			for(int j=i; j<n; j++)if( p[i]+p[j]<=m ){
				v.push_back(p[i]+p[j]);
			}
		}
		sort(v.begin(),v.end());
		/*
		rep(i,v.size()){
			printf("%d\n",v[i]);
		}
		*/
		
		rep(i,n){
			for(int j=i; j<n; j++)if( p[i]+p[j]<=m ){
				int k = p[i]+p[j];
				int l = 0;
				int r = v.size()-1;
				while( l<r ){
					int mid = (l+r)/2 + 1;
					if( v[mid]+k > m ){
						r = mid - 1;
					}else{
						l = mid;
					}
				}
				ret = max(ret, k+v[l]);
			}
		}
		printf("%d\n",ret);
	}
	return 0;
}

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

const int size = 1001;
int n, m;
int p1[size+1];
int p2[size*size+1];

int main() {
  while ( cin >> n >> m && n && m ) {
    p1[0] = 0;
    for ( int i = 0; i < n; i++ ) {
      cin >> p1[i+1];
    }
    for ( int i = 0; i < n+1; i++ ) {
      for ( int j = 0; j < n+1; j++ ) {
	p2[i*(n+1)+j] = p1[i] + p1[j];
      }
    }
    int p2size = (n+1)*(n+1);
    sort( p2, p2+p2size );

    // syakutori method
    int answer = 0;
    for ( int i = 0; i < p2size; i++ ) {
      for ( int j = 0; j < p2size; j++ ) {
	if ( p2[i] + p2[j] <= m ) answer = max( answer, p2[i] + p2[j]  );
      }
    }

    cout << answer << endl;
  }
  return 0;
}

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

int main() {  
    long long N, M;
    while (cin >> N >> M) {
        if (!(N && M)) break;
        long long P[N + 1];
        for (long long i = 0; i < N; ++i) cin >> P[i];
        P[N] = 0;

        long long PP[(N + 1) * (N + 1)];
        for (int i = 0; i < N + 1; ++i) {
            for (int j = 0; j < N + 1; ++j) {
                PP[(N + 1) * i + j] = P[i] + P[j];
            }
        }
        sort(PP, PP + (N + 1) * (N + 1));

        long long ans = 0;
        for (int i = 0; i < (N + 1) * (N + 1); ++i) {
            int l = 0, r = (N + 1) * (N + 1);
            while (r - l >= 1) {
                int pnt = (r + l) / 2;
                if (PP[i] + PP[pnt] > M) r = pnt;
                else {
                    ans = max(ans, PP[i] + PP[pnt]);
                    l = pnt + 1;
                }
            }
        }

        cout << ans << endl;
    }
    
    return 0;
}

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

using namespace std;

int m,n;
int a[1002];
int aa[1002001];

int ans,Max;

int main(){
	
	while (1) {
		scanf("%d%d",&n,&m);
		ans=0;
		if (n==0&&m==0) {
			break;
		}
		for (int i=0; i<n; i++) {
			scanf("%d",&a[i]);
		}
		a[n++]=0;
		
		int size=0;
		for(int c=0;c<n;c++){
			for (int d=0; d<n; d++) {
				aa[size++]=a[c]+a[d];
			}
		}
		sort(aa,aa+size);
		
		for (int i=0; i<n; i++) {
			for (int j=0; j<n; j++) {
				if (m-a[i]-a[i]>=0) {
					int l=0,r=size;
					Max=0;
					while (l<=r) {
						int k=(l+r)/2;
						if (aa[k]<(m-a[i]-a[j])&&aa[k]>Max) {
							Max=aa[k];
						}
						if(aa[k]<(m-a[i]-a[j]))l=k+1;
						else r=k-1;
					}
					if (Max+a[i]+a[j]>ans) {
						ans=Max+a[i]+a[j];
					}
				}
			}
		}
		printf("%d\n",ans);
	}
	
	
}

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

using namespace std;
typedef long long ll;

vector<int> memo;//x+x
int ns[1000];
int N,M;

int score(int x){
	if(x > M){
		return 0;
	}else{
		return x;
	}
}

int solve(){
	int ans = 0;
	for(const auto x : memo){
		ans = max(ans,score(x));
		if(x < M){
			auto it = upper_bound(memo.begin(),memo.end(),M-x);
			if(it!=memo.begin()){
				--it;
				ans = max(ans,score(x+ *it));
			}
		}
	}
	return ans;
}

int main(){
	cin >> N >> M;
	for(int i=0;i<N;++i){
		int t;
		scanf("%d",&t);
		ns[i] = t;
	}
	memo.push_back(0);
	for(int i=0;i<N;++i){
		memo.push_back(ns[i]);
		for(int j=i;j<N;++j){
			memo.push_back(ns[i]+ns[j]);
		}
	}
	sort(memo.begin(),memo.end());
	memo.erase(unique(memo.begin(),memo.end()),memo.end());
	cout << solve() << endl;
	return 0;
}

C++: #include<iostream>
#include<string>
#include<vector>
#include<utility>
#include<queue>
#include<algorithm>
#include<cmath>
#define INF 2147483647
#define llINF 9223372036854775807
#define pb push_back
#define mp make_pair 
#define F first
#define S second
#define ll long long

using namespace std;
int main(){
  int n,m;
  while(cin>>n>>m,n+m){
    vector<ll>num(n);
    for(int i=0;i<n;i++)cin>>num[i];
    vector<ll>zen;
    vector<ll>kou;
    for(int i=0;i<n;i++){
      for(int j=i;j<n;j++){
	zen.pb(num[i]+num[j]);
      }
      zen.pb(num[i]);
    }
    zen.pb(0);
    sort(zen.begin(),zen.end());
    ll ans=0;
    for(int i=0;i<zen.size();i++){
      ll left=0,right=zen.size()-1;
      ll mid;
      while(left!=right){
	mid=(left+right)/2;
	if(zen[mid]+zen[i]<=m)
	  left=mid+1;
	else if(zen[mid]+zen[i]>m)
	  right=mid;
	else
	  break;
	//	cout<<left<<" "<<right<<endl;
      }
      if(left>0&&zen[i]+zen[left-1]<=m)
	ans=max(ans,zen[i]+zen[left-1]);
      else if(zen[i]+zen[left]<=m)
	ans=max(ans,zen[i]+zen[left-1]);
    }
    cout<<ans<<endl;
  }
  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%u",&n,&m) && n){
    set<uint> S;
    uint one[n];
    uint two[n*n];
    int p=0;
    maxv=0;
    for(int i=0;i<n;i++)scanf("%d",&one[i]);
    for(int i=0;i<n;i++){
      if ( one[i]>maxv &&one[i] <=m)maxv=one[i];
      for(int j=i;j<n;j++){
	if ( one[i]+one[j]>m)continue;
	if ( S.find(one[i]+one[j]) != S.end())continue;
	S.insert(one[i]+one[j]);
	two[p++]=one[i]+one[j];
	if (two[p-1]>maxv&&two[p-1]<=m)maxv=two[p-1];
      }
    }
    sort(one,one+n);
    sort(two,two+p);
    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);
      //solve(two[i],m,two,p);
      //      solve(two[i],m,one,n);
    }
    printf("%u\n",maxv);
  }
  return false;
}