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<algorithm>
#include<vector>

#define MAX_N 1001

using namespace std;

class CNum{
public:
	vector<int> v;
};

bool Find(vector<int> &v, int search){
	for(unsigned int i = 0; i < v.size(); i++){
		if( v[i] == search ){
			return true;
		}
	}
	return false;
}

int main(void){
	while( 1 ){
		int n, m;
		int V[MAX_N] = {0,};
		CNum D[4];
		int Max = 0;

		cin >> n >> m;

		if( n == 0 && m == 0 ){
			break;
		}

		for(int i = 0; i < n; i++){
			cin >> V[i];
		}

		sort(V, V + n);
		reverse(V, V + n);

		for(int i = 0; i < n; i++){
			for(int j = 0; j < 4; j++){
				if( j == 0 ){
					D[j].v.push_back( V[i] );
				}else if( j > 0 ){
					for(unsigned int l = 0; l < D[j - 1].v.size(); l++ ){
						int tmp = V[i] + D[j - 1].v[l];
						if( tmp <= m ){
							int index = -1;
							if( Max < tmp ){
								Max = tmp;
							}
							for(int k = 0; k < n; k++){
								if( tmp + V[k] <= m ){
									index = k;
									break;
								}
							}
							if( index >= 0 && tmp + V[index] >= Max && !Find(D[j].v, tmp) )
								D[j].v.push_back( tmp );
						}
					}
				}
			}
		}

		for(int i = 0; i < 4; i++){
			//cout << " " << j << ":" << '\n';
			for(unsigned int j = 0; j < D[i].v.size(); j++ ){
				//cout << D[j].v[k] << ' ';
				int tmp = D[i].v[j];
				if( tmp <= m && Max < tmp){
					Max = tmp;
				}
			}
			//cout << '\n';
		}
		cout << Max << '\n';
	}
	return 0;
}

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

int kazu[1000000];
int n,m,Max,data[1000];
int main(){
	int s=0;
	std::cin>>n>>m;
	data[0]=0;
	for(int i=0;i<n;i++){
		std::cin>>data[i+1];
	}
	for(int c=0;c<n+1;c++){
		for(int d=0;d<n+1;d++){
			kazu[c*n+d]=data[c]+data[d];
		}
	}
	std::sort(kazu,kazu+n*n);
	for(int a=0;a<n+1;a++){
		for(int b=0;b<n+1;b++){
			while(s<m){
				if(std::binary_search(kazu,kazu+n*n,m-s-data[a]-data[b])){
					Max=std::max(m-s,Max);
					break;
				}
				s++;
			}
			s=0;
		}
	}
	std::cout<<Max<<std::endl;
	return 0;
}

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

int main()
{
while(true) {
int n, m;
vector<int> x, xxx;
scanf("%d%d", &n, &m);
if(n == 0)
break;
x.resize(n);
for(int i = 0; i < n; ++i)
scanf("%d", &x[i]);
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j)
xxx.push_back(x[i] + x[j]);
}
xxx.push_back(0);
sort(xxx.begin(), xxx.end());
int ans = 0;
for(int i = 0; i < xxx.size(); ++i) {
int r = m - xxx[i];
if(r < 0)
continue;
int idx = upper_bound(xxx.begin(), xxx.end(), r) - xxx.begin() - 1;
if(idx < 0)
continue;
ans = max(ans, r + xxx[idx]);
}
printf("%d\n", ans);
}
return 0;
}

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

typedef long long ll;

ll dp[5];
ll dat[1001];

int main() {
  int n, m;
  
  while(cin >> n >> m && (n|m)) {
    for(int i=0; i<n; i++) cin >> dat[i];
    
    fill(dp, dp+5, 0);
    
    ll ans = 0;
    
    for(int i=0; i<4; i++) {
      for(int j=0; j<n; j++) {
	if(dp[i]+dat[j] < m) dp[i+1] = max(dp[i]+dat[j], ans);
	ans = max(dp[i+1], ans);
      }
    }
    
    cout << ans << endl;
  }
  
  return 0;
}

C++: #include <stdio.h>
#include <vector>
#include <algorithm>

using namespace std;

int main(void)
{
	vector<int> twoThrow;
	int n;
	int m;
	int point[1000];
	int ans;
	
	while (1){
		twoThrow.clear();
		
		scanf("%d%d", &n, &m);
		
		if (n == 0){
			break;
		}
		
		for (int i = 0; i < n; i++){
			scanf("%d", &point[i]);
		}
		
		
		twoThrow.push_back(0);
		for (int i = 0; i < n; i++){
			twoThrow.push_back(point[i]);
			for (int j = i; j < n; j++){
				twoThrow.push_back(point[i] + point[j]);
			}
		}
		sort(twoThrow.begin(), twoThrow.end());
		
		int t;
		ans = 0;
		for (int i = 0; i < twoThrow.size(); i++){
			vector<int>::iterator it = upper_bound(twoThrow.begin(), twoThrow.end(), m - twoThrow[i]);
			if (it == twoThrow.begin()){
				continue;
			}
			it--;
			t = *it;
			if (ans < t + twoThrow[i]){
				ans = t + twoThrow[i];
			}
		}
		
		printf("%d\n", ans);
	}
	
	return (0);
}

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

long long int n, m;
long long int p[1000];
long long int s;
vector<long long int> a;
vector<long long int> b;

void f(long long int x){
	if(x <= m) s = max(s, x);
}

int main(){
	while(1){
		scanf("%lld %lld", &n, &m);
		if(n == 0 && m == 0) break;
		memset(p, 0, sizeof(p));
		for(int i=0; i<n; i++) scanf("%lld", &p[i]);
		a = b;
		s = 0;

		for(int i=0; i<n; i++){
			f(p[i]);
		}
		for(int i=0; i<n; i++){
			for(int j=0; j<=i; j++){
				a.push_back(p[i] + p[j]);
				f(p[i] + p[j]);
			}
		}
		for(int i=0; i<n; i++){
			for(int j=0; j<a.size(); j++){
				f(p[i] + a[j]);
			}
		}
		for(int i=0; i<a.size(); i++){
			for(int j=0; j<a.size(); j++){
				f(a[i] + a[j]);
			}
		}
		printf("%lld\n", s);

	}
	return 0;
}

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

int kazu[1002001];//1001^2
int n,m,Max,data[1001];
int main(){
	while(true){
		int s=0;
		std::cin>>n>>m;
		if(n==0&&m==0)break;
		data[0]=0;
		for(int i=0;i<n;i++){
			std::cin>>data[i+1];
		}
		for(int c=0;c<n+1;c++){
			for(int d=0;d<n+1;d++){
				kazu[c*n+d]=data[c]+data[d];
			}
		}
		std::sort(kazu,kazu+n*n);
		for(int a=0;a<n+1;a++){
			for(int b=0;b<n+1;b++){
				while(s<m&&Max<m-s){
					if(std::binary_search(kazu,kazu+n*n,m-s-data[a]-data[b])){
						Max=std::max(m-s,Max);
						break;
					}
					s++;
				}
				s=0;
			}
		}
		std::cout<<Max<<std::endl;
		Max=0;
	}
	return 0;
}

C++: #include<iostream>
#include<algorithm>
using namespace std;
/*bool ok(int *q,int m,int h,int count){
  for(int i=0;i<count;i++){
    if(q[i]>m) continue;
    for(int j=0;j<count;j++){
      if(q[i]+q[j]<=m&&q[i]+q[j]>h) return true;
    }
  }
  return false;
  }*/
int main(){
  int n,m;
  while(cin>>n>>m){
    if(n==0&&m==0) return 0;
    int data[n+1];
    int q[(n+1)*(n+1)/2];
    int ans = 0;
    for(int i=0;i<n;i++) cin >> data[i];
    data[n] = 0;
    int count = 0;
    for(int i=0;i<=n;i++){
      for(int j=i;j<=n;j++){
	if(data[i]+data[j]>m) continue; 
	  q[count] = data[i] + data[j];
	  count++;
      }
    }
    sort(q,q+count);
    int j = count - 1;
    for(int i=0;i<count;i++){
      while(0<=j&&m<q[i]+q[j]) j--;
      if(j==-1) break;
	ans = max(ans,q[i]+q[j]);
    }
    cout << ans << endl;
  }
}

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

using namespace std;

void solve(int N, int M, int P[1010])
{
	int score = 0;
	sort(P, P + N, greater<int>());
	
	for(int j = 0; j < 4; j++){		
		int i = 0;
		while(true){
			if(score + P[i] > M){
				if(i == N) break;
				else i++;
			}
			else{
				score += P[i];
				break;
			}
		}
	}
	
	cout << score << endl;
}


int main()
{
		int N, M;
		int P[1010];

	while(true){
		cin >> N;
		cin >> M;
		if(N == 0 && M == 0) break;

		for(int i = 0; i < N; i++){
			cin >> P[i];
		}

		solve(N, M, P);
	}

	return 0;
}