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<bits/stdc++.h>

#define _GLIBCXX_DEBUG
#define all(v) (v).begin(),(v).end()

using namespace std;

using ll=long long;
using pii=pair<int, int>;
using vi=vector<int>;
using vii=vector<vector<int>>;

const ll LINF=1LL<<60;
const int INF=1<<29;
const int MOD=1e9+7;


int main(){
    int N, M;
    while(cin >> N >> M){
        if(N == 0 && M == 0) break;
        vector<ll> P(N+1);
        P[0]=0;
        for(int i=1; i<=N; i++) cin >> P[i];
        ll res=0;
        vector<ll> PP;
        for(int i=0; i<=N; i++){
            for(int j=0; j<=N; j++){
                PP.push_back(P[i]+P[j]);
            }
        }
        sort(all(PP));
        for(int i=0; i<=N; i++){
            for(int j=0; j<=N; j++){
                auto it=upper_bound(all(PP), M-P[i]-P[j]);
                ll sum=P[i]+P[j]+(it == PP.begin() ? 0:*(--it));
                if(sum <= M) res=max(res, sum);
            }
        }
        cout << res << endl;
    }
    return 0;
}

C++: #include<iostream>
#include<set>
#define rep(i,n) for(int i=0;i<n;i++)
using namespace std;
int n,m,p[1001],ans;
int main(){
	while(cin>>n>>m,n){
		rep(i,n)cin>>p[i+1]; ans=0;
		set<int> q; rep(i,n+1)rep(j,n+1)q.insert(p[i]+p[j]);
		for(set<int>::iterator i=q.begin(),j;i!=q.end()&&*i<=m;i++){
			j=q.upper_bound(m-*i); if(*j!=m-*i)j--;
			if(ans<*i+*j)ans=*i+*j;
		}
		cout<<ans<<endl;
	}
	return 0;
}

C++: #include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
   
int n, m;
vector<int> p1, p2;
int main()
{
  while(true){
    scanf("%d%d", &n, &m);
    if(!n && !m)
      break;
  
    p1.clear();
    p2.clear();
       
    //chap1
    p1.push_back(0);
    for(int i = 0; i < n; i++){
      int p;
      scanf("%d", &p);
      p1.push_back(p);
    }
   
    //chap2
    for(int i = 0; i <= n; i++)
      for(int j = i; j <= n; j++)
    p2.push_back(p1[i] + p1[j]);
   
    sort(p2.begin(), p2.begin() + p2.size());
   
    //chap3
    int ans = 0;
    for(int i = 0; i < p2.size(); i++){
      vector<int>::iterator count2 = upper_bound(p2.begin(), p2.end(), m - p2[i]);
      if(count2 != p2.begin())
    ans = max(ans, *(count2 - 1) + p2[i]);
    }
    printf("%d\n", ans);
  }
  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 = 1000009; T > 1000; 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 += 100000;

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

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

C++: //http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2676345#1
//http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2676345#1
#include <iostream>
#include<cstdlib>
#include<queue>
#include<set>
#include<vector>
#include<string>
#include<algorithm>
#include<stack>
#include<map>
#include<cstdio>
#include<fstream>
#include<cstring>
using namespace std;
#define rep(i,a) for(int i=0;i<a;i++)
#define mp make_pair
#define P pair<int,int>
#define ll __int64

int n,m;
int t[10000];
const int MA=1000000;
int s1[MA],s2[MA];

int ya[4];

int main(){

while(cin>>n>>m,n||m){
rep(i,MA)s1[i]=s2[i]=0;
rep(i,10000)t[i]=0;
for(int i=1;i<=n;i++)cin>>t[i];
for(int i=0;i<=n;i++){
	for(int j=0;j<=n;j++){
		s1[i*(n+1)+j]=t[i]+t[j];
		s2[i*(n+1)+j]=t[i]+t[j];
	}
}
int g=(n+1)*(n+1);

sort(s1,s1+g);
sort(s2,s2+g);

//rep(i,g)cout<<s1[i]<<" ";cout<<endl;

int ans=0;

for(int i=0;i<g;i++){
	int now=s1[i];

	int l=0;
	int r=g-1;
	int mid=(l+r)/2;
	int x=s2[mid];

	for(int i=0;i<100;i++){
		if(x+now==m)break;
		if(x+now>m){
			r=mid;
			mid=(r+l)/2;
			x=s2[mid];
			if(x+now>m)break;
		}
		else{
			l=mid;
			mid=(r+l)/2;
			x=s2[mid];
			if(x+now<m)break;
		}
	}

	//cout<<" "<<x<<" "<<now<<" "<<x+now<<endl;
	if(x+now<=m)
	ans=max(ans,x+now);
}
cout<<ans<<endl;
}
	return 0;
}

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

using namespace std;
vector<int> point;
int N, M;
int ans = 0;

void DFS(int depth, int use, int sum, vector<int>& p)
{
	if (depth == N || use == N)
	{
		ans = max(ans, sum);
		return;
	}
	if (sum + p[depth] > M)
	{
		DFS(depth + 1, use, sum, p);
	}
	else
	{
		DFS(depth, use + 1, sum + p[depth], p);
		DFS(depth + 1, use, sum, p);
	}
}

void solve()
{
	while (cin >> N >> M, N || M)
	{
		ans = 0;
		point.clear();
		point.resize(N);
		for (int i = 0; i < N; ++i)
		{
			cin >> point[i];
		}
		DFS(0, 0, 0, point);
		cout << ans << endl;
	}
}

int main()
{
	solve();
	return(0);
}

C++: #include <bits/stdc++.h>
using namespace std;
int main(){
	int n,m;
	while(true){
		cin>>n>>m;
		if(n==0)	return 0;
		vector<int> p(n);
		for(int i=0;i<n;i++)	cin>>p[i];
		p.push_back(0);
		set<int> s;
		for(int i=0;i<n+1;i++){
			for(int j=0;j<n+1;j++)	s.insert(p[i]+p[j]);
		}
		int ans=0;
		for(auto it=s.begin();it!=s.end();it++){
			if(*it>=m)	break;
			auto it2=s.lower_bound(m-*it);
			if(it2!=s.begin())	it2--;
			ans=max(ans,*it+*it2);
		}
		cout<<ans<<endl;
	}
}

C++: #include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <map>
#include <stack>
#include <queue>
#include <set>
#include <cstring>

using namespace std;
// ascending order
#define vsort(v) sort(v.begin(), v.end())
// descending order
#define vsort_r(v) sort(v.begin(), v.end(), greater<int>())
#define vunique(v) v.erase(unique(v.begin(), v.end()), v.end())
#define mp make_pair
#define ts(x) to_string(x)
#define rep(i, a, b) for(int i = (int)a; i < (int)b; i++)
#define repm(i, a, b) for(int i = (int)a; i > (int)b; i--)
#define bit(a) bitset<8>(a)
#define des_priority_queue priority_queue<int, vector<int>, greater<int> >
typedef long long ll;
typedef pair<int, int> P;
const ll INF = 1e18;

#define MAX_V 1000000

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);

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

		vector<int> P;
		rep(i, 0, N) {
			int p;
			cin >> p;
			P.push_back(-p);
		}

		vsort(P);

		int total_point = 0;
		while(M > -P[P.size() - 1]) {
			int get_point = -1 * (*lower_bound(P.begin(), P.end(), -M));
			M -= get_point;
			total_point += get_point;
		}
		rsl.push_back(total_point);
	}

	rep(i, 0, rsl.size()) cout << rsl[i] << endl;


}