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++: #define _USE_MATH_DEFINES
#define INF 100000000
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <limits>
#include <map>
#include <string>
#include <cstring>
#include <set>
#include <deque>
#include <bitset>
#include <list>

using namespace std;

typedef long long ll;
typedef pair <int,int> P;

static const double EPS = 1e-8;

int dp[100000000];

int main(){
	int N,M;	
	while(~scanf("%d %d",&N,&M)){
		if(N==M && M==0) break;
		vector<int> Points;
		Points.push_back(0);
		for(int i=0;i<N;i++){
			int p;
			scanf("%d",&p);
			Points.push_back(p);
		}

		vector<int> Points2;
		for(int i=0;i<=N;i++){
			for(int j=0;j<=N;j++){
				Points2.push_back(Points[i]+Points[j]);
			}
		}

		sort(Points2.begin(),Points2.end());
		vector<int>::iterator it = unique(Points2.begin(),Points2.end());
		Points2.erase(it,Points2.end());


		int res=0;
		for(vector<int>::iterator it = Points2.begin();it != Points2.end();it++){
			if(M-*it<0) continue;

			vector<int>::iterator it2 = lower_bound(Points2.begin(),Points2.end(),M-*it);
			if(it2==Points2.end()) continue;
			res = max((it2 == Points2.begin() ? 0 : *(it2-1)) + *it,res);
		}

		printf("%d\n",res);
	}
}

C++: #include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;i++)
using namespace std;
int n,m,a[1001];
int s[500501],stop;
int main(){
	while(true){
	cin>>n>>m;
	if(!n&&!m)break;
	stop=1,a[0]=0,s[0]=0;
	rep(i,n){
		cin>>a[i+1];
		rep(j,i+2)if(s[i+1]+s[j]<=m)s[stop]=a[i+1]+a[j],stop++;
	}
	sort(s,s+stop);
	int ans=0;
	rep(i,stop){
		int left=0,right=stop,mid,key=m-s[i];
		if(key>=0){
		while(left<right){
			mid=(left+right)/2;
			if(s[mid]<key)left=mid+1;
			else right=mid;
		}
		if(s[mid]>key)mid--;
		if(mid+1<stop)if(s[mid+1]<=key)mid++;
		if(mid+1)ans=max(ans,s[mid]+s[i]);
		}
	}
	cout<<ans<<endl;
	}
	return 0;
}

C++: #include<algorithm>
#include<iostream>
#include<string>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
int main(){
  int i,j;
  int a[1001],b[1002001],m,n;
  int mx;
  a[0]=0;
  while(cin>>n>>m&&n+m){
    for(i=1;i<n+1;i++)
      cin>>a[i];
    for(i=0;i<n+1;i++)
      for(j=0;j<n+1;j++)
	b[(n+1)*i+j]=a[i]+a[j];
    n=(n+1)*(n+1);
    sort(b,b+n);
    mx=0;
    j=n-1;
    for(i=0;i<n&&b[i]<=m;i++){
      for(;b[i]+b[j]>m;j--);
      mx=max(mx,b[i]+b[j]);
    }
    cout<<mx<<endl;
  }
  return 0;
}

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

int main(){
  int n,m;
  int p[1001];
  int s[1001000];
  for(;;){
    cin >> n >> m;
    if(!n && !m)break;

    for(int i=0;i<n;i++)cin >> p[i];
    p[n] = 0;

    for(int i=0;i<=n;i++)
      for(int j=0;j<=n;j++)s[i*(n+1)+j] = p[i] + p[j];

    int N = (n+1)*(n+1);
    sort(s,s+N);
      
    int ans = 0;
    for(int i=0;i<N;i++){
      int hoge = upper_bound(s,s+N,m-s[i]) - s;
      //cout << s[i] << " " << s[hoge-1] << endl;
      if(hoge == 0)break;
      else if(hoge == N)ans = max(ans,s[i]);
      else ans = max(ans,s[i] + s[hoge-1] );
    }

    cout << ans << endl;
  }
}

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

using namespace std;

int main(){
    while(true){
        int N,M;
        cin >> N >> M;
        if(N == 0 and M == 0) break;

        vector<int> ps;
        ps.push_back(0);
        for(int i=0;i<N;i++){
            int p;cin >> p;
            ps.push_back(p);
        }
        vector<int> d;
        for(size_t i=0;i<ps.size();i++){
            for(size_t j=i;j<ps.size();j++){
                d.push_back(ps[i]+ps[j]);
            }
        }
        sort(d.begin(),d.end());
        int ret = 0;
        for(size_t i=0;i<d.size();i++){
            if(d[i] > M) break;
            ret = max(ret,d[i]+*(lower_bound(d.begin(),d.end(),M-d[i])-1));
        }
        cout << ret << endl;
    }
    return 0;
}

C++: #include <algorithm>
#include <cstdio>
#include <iostream>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#include <stdlib.h>
#include <stdio.h>
#include <bitset>
#include <cstring>
#include <deque>
using namespace std;
#define FOR(I,A,B) for(int I = (A); I < (B); ++I)
#define CLR(mat) memset(mat, 0, sizeof(mat))
typedef long long ll;
int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0);
  ll N, M;
  while(cin>>N>>M,N||M) {
    vector<ll> P(N+1);
    FOR(i,0,N) cin >> P[i];
    P[N] = 0;
    // ????????¨??????
    vector<ll> v1;
    FOR(i,0,N+1) {
      FOR(j,0,N+1) {
        v1.push_back(P[i] + P[j]);
      }
    }
    sort(v1.begin(), v1.end());
    ll ans = 0;
    FOR(i,0,N+1) {
      FOR(j,0,N+1) {
        int a = lower_bound(v1.begin(), v1.end(), M - P[i] - P[j]) - v1.begin();
        FOR(k,-1,2) {
          if(a + k >= 0 && a + k < (N + 1) * (N + 1) && P[i] + P[j] + v1[a + k] <= M) {
            ans = max(ans, P[i] + P[j] + v1[a + k]);
          }
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}

C++: #include <iostream>
using namespace std;
 
int main() {
	for(;;){
		/*入力*/
		int N,M,count=0;
		cin >> N >> M;
		if(N==0 && M==0)exit(0);
		int P[N+1],array[M+1]={0};
		P[0]=0;
		for(int i=1;i<=N;i++)cin >> P[i];
		for(int i=0;i<=N;i++)array[P[i]]=1;
 
		/*２投(０投１投を含む)で1からMまでが可能か判定*/
		for(int i=0;i<=N;i++){
			for(int j=0;j<=N;j++){
				if(P[i]+P[j] <= M)array[P[i]+P[j]]=1;
			}
		}
 
		/*４投に拡張*/
		for(int i=0;i<=M;i++){
			if(array[i]==1)count++;
		}
		int k=0,p[count];
		for(int i=0;i<=M;i++){
			if(array[i]==1){
				p[k]=i;
				k++;
			}
		}
		for(int i=0;i<=count;i++){
			for(int j=0;j<=count;j++){
				if(p[i]+p[j] <= M)array[p[i]+p[j]]=1;
			}
		}
 
		/*判定出力*/
		for(int i=M;i>0;i--){
			if(array[i]==1){
				cout << i << endl;
				break;
			}
		}
	}
	return 0;
}

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

using namespace std;

int main ( void )
{
	int n, m;
	int p[1000];

	while ( cin >> n >> m, (n | m) )
	{
		int ans = 0;
		set<int> S;
		S.insert(0);
		for ( int i = 0; i < n; ++i )
        {
            cin >> p[i];
            if ( p[i] < m )
            {
                S.insert(p[i]);
                ans = max( ans, p[i] );
            }
        }
        for ( int i = 0; i < n; ++i )
        {
            for ( int j = i; j < n; ++j )
            {
                int x = p[i] + p[j];
                if ( x <= m )
                {
                    S.insert(x);
                    int y = m - x;
                    set<int>::iterator it = lower_bound( S.begin(), S.end(), y );
                    if ( *it > y )	--it;
                    ans = max( ans, (x + *it) );
                }
            }
        }
		cout << ans << endl;
	}
	return 0;
}