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 <cstdio>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main(){
  int i,j,k,l,n,m,a[1000],ans;
  while(1){
    cin >> n >> m;
    if(n == 0 && m == 0) break;
    for(i=0;i<n;i++) cin >> a[i];

    sort(a,a+n);
    ans = 0;

    for(i=n-1;i>=0;i--){
      if(a[i] <= m) ans = max(ans,a[i]);

      if(a[i] < m){
	for(j=i;j>=0;j--){
	  if(a[i] + a[j] <= m) ans = max(ans,a[i] + a[j]);
	  
	  if(a[i] + a[j] < m){
	    for(k=j;k>=0;k--){
	      if(a[i] + a[j] + a[k] <= m) ans = max(ans,a[i] + a[j] + a[k]);
	      
	      if(a[i] + a[j] + a[k] < m){
		for(l=k;l>=0;l--){
		  if(a[i] + a[j] + a[k] + a[l] <= m){
		    ans = max(ans,a[i] + a[j] + a[k] + a[l]);
		    break;
		  }
		}
	      }
	    }
	  }
	}
      }
    }

    cout << ans << endl;

  }
  return 0;
}

C++: #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <cctype>
#include <numeric>
using namespace std;

#define rep(i,n) for(int (i)=0; (i)<(int)(n); ++(i))
#define foreach(c,i) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++)
#define all(a) (a).begin(),(a).end()

const int kN = 1002;
int N, M, NN;
int a[kN];
int m[kN*kN];

int solve() {
  sort(a, a + N);
  sort(m, m + NN);  
  if (binary_search(a ,a + N, M)
      || binary_search(m, m + NN, M)) {
    return M;
  }

  rep(i,NN) {
    int val = m[i];
    if (val > M) continue;
    if (binary_search(a, a + N, M - val)
        || binary_search(m, m + NN, M - val)) {
      return M;
    }
  }

  int ans = -1;
  rep(i,NN) {
    int val = m[i];
    if (val > M) continue;
    int *p = lower_bound(a, a + N, M - val);
    --p;
    // printf("val=%d, *p=%d\n", val, *p);
    ans = max(ans, val + *p);
    p = lower_bound(m, m + NN, M - val);
    --p;
    ans = max(ans, val + *p);
    // printf("-val=%d, *p=%d\n", val, *p);
  }
  return ans;
}

int main() {
  while (cin >> N >> M, N | M) {
    rep(i,N) cin >> a[i];
    rep(i,N) rep(j,N) {
      m[i * N + j] = a[i] + a[j];
    }
    NN = N * N;
    printf("%d\n", solve());
  }
  
  return 0;
}

C++: #include<iostream>
using namespace std;
int ans;
void max_ans(int *p,int N,int M ,int s,int k){
  for(int i=0;i<N;i++){
    if(k<4&&s+p[i]<=M) max_ans(p,N,M,s+p[i],k+1);
    else if(k==4&&s+p[i]>ans&&s+p[i]<=M) ans = s+p[i];
  }
  if(k<4) max_ans(p,N,M,s,k+1);
  else if(k==4&&s>ans&&s<=M) ans = s; 
}
int main(){
  int N,M;
  while(cin>>N>>M){
    if(N==0&&M==0) break;
    int p[N];
    for(int i=0;i<N;i++) cin >> p[i];
    ans = 0;
    max_ans(p,N,M,0,1);
    cout << ans << endl;
  }
  return 0;
}

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

int main(){

    int N, M, p[1011];

    while(cin >> N >> M, N){
        vector <int> sum;
        p[0] = 0;
        for(int i = 1; i <= N; i++) cin >> p[i];
    
        for(int i = 0; i <= N; i++){
            for(int j  = 0; j <= N; j++){
                if(p[i] + p[j] > M) continue;
                sum.push_back(p[i] + p[j]);
            }
        }
    
        sort(sum.begin(), sum.end());
        int res = 0;
        for(int i = 0; i  < sum.size(); i++){
            vector <int>::iterator it = lower_bound(sum.begin(), sum.end(), M - sum[i]);
            res = max(res, sum[i] + *(it - 1));
        }
        cout << res << endl;
    }
}

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

using namespace std;

int main ( void )
{
	int n, m;
	int p[1000];
	set<int> S;
	
	while ( cin >> n >> m, (n | m) )
	{
		int ans = 0;
		S.clear();
		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;
}

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

using namespace std;

int main(void)
{
	int n, m;

	while (cin >> n >> m, n || m){
		vector <int> p(n + 1);
		for (int i = 0; i < n; i++){
			scanf("%d", &p[i]);
		}
		p[n] = 0;
		n++;

		vector <int> sum(n * n);
		int cnt = 0;
		for (int i = 0; i < n; i++){
			for (int j = 0; j < n; j++){
				sum[cnt] = p[i] + p[j];
				// cout << sum[cnt] << " " << p[i] << " " << p[j] << endl;
				cnt++;
			}
		}

		sort(sum.begin(), sum.end());
		int ret = 0;
		for (int i = 0; i < n * n; i++){
			int diff = m - sum[i];
			if (diff < 0) continue;
			int up = *(upper_bound(sum.begin(), sum.end(), diff)-1);
			ret = max(ret, sum[i] + up);
		}

		cout << ret << endl;
	}

	return 0;
}

C++: 
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int main()
{
	int ans[4];
	int temp;
	double energy,energy_min,energy_now;
	int M, N;
	int* p;
	int i, j;
	double T=100;
	int ret;
	while (1) {
		scanf("%d%d", &N, &M);
		p = (int*)malloc((N+1) * sizeof(int));
		for (i = 0; i < N; i++) {
			scanf("%d", &p[i]);
		}
		p[N] = 0;
		if (N == M && N == 0) {
			break;
		}
		energy_min = pow(10, 300);
		for (j = 0; j < 4; j++) {
			ans[j] = p[(int)((double)(rand() + 1) / (RAND_MAX + 2)*(N+1))];
		}
		
		for (T = 5000000; T > 100; T--) {
			for (j = 0; j < 4; j++) {
				temp = p[(int)((double)(rand() + 1) / (RAND_MAX + 2)*(N+1))];
				for (j = 0; j < 4; j++) {
					ret = ans[0] + ans[1] + ans[2] + ans[3];
					ret += temp - ans[j];
					energy = M - ret;
					if (M < ret)energy += 100000000;

					if (energy < energy_min) {
						energy_min = energy;
						ans[j] = temp;
					}
					else if ((double)(rand() + 1) / (RAND_MAX + 2) < exp((energy_min - energy) / T*10)) {
						energy_min = energy;
						ans[j] = temp;
					}
				}

			}
		}
		ret=ans[0]+ +ans[1] + ans[2] + ans[3];
		printf("%d\n", ret);
	}
    return 0;
}

C++: #include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
#include<vector>

using namespace std;

int n,m;
int p[1000];

int solve(int num,int sum){
  if(sum > m)return 0;
  if(num == 5)return 0;

  int ret = sum;
  for(int i = 0;i<n;i++){
    ret = max(ret,solve(num+1,sum+p[i]));
  }
  return ret;
	      
}

int main(){
  while(cin>>n>>m){
    if(n==0&&m==0)break;
    for(int i = 0;i<n;i++){
      cin>>p[i];
    }
    
    cout<<solve(0,0)<<endl;
  }
  return 0;
}