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<algorithm>
using namespace std;

int A[2000];
int KK[2000000];
int N,M;
int k;
void getK()
{
	k = 0;
	for(int i =0; i<=N; i++)
		for(int j = i; j<=N; j++)
			KK[k++] = A[i]+A[j];	
	
	sort(KK,KK+k);		

}


int binarySearch(int a)
{
	int left = 0;
	int right = k;
	int mid;
	while(left+1<right)
	{
		mid = (left+right)/2;
		if(KK[mid] <= a) left = mid;
		else right = mid;
	}

	return KK[left];
}
void solve()
{
	
	int maxS = 0;
	for(int i =0; i<=N;i++)
		for(int j = 0; j <=N; j++)
		{
			int temp = binarySearch(M-A[i]-A[j])+A[i]+A[j];	
			if(temp > maxS && temp <= M)
				maxS = temp;
		}
	cout << maxS << endl;
}

int main()
{
	A[0] = 0;
	while(cin >>N>>M && N||M)
	{
		
		for(int i = 1; i<=N;i++)
			cin >> A[i];
		sort(A,A+N+1);
		getK();
		solve();
	}
}

C++: #include<bits/stdc++.h>
using ll = long long;
using namespace std;
const ll INF = 1000000000000000000;
const ll mod = 1000000007;
ll ok[12345678];
signed main() {
	for (int z = 0; z < 11; z++) {
		ll n, m, a, ans = 0; cin >> n >> m;
		if (n == 0 && m == 0) { return 0; }
		for (int h = 0; h < n; h++) {
			cin >> ok[h];
		}
		vector<ll> v;
		//最後の二本
		for (int h = 0; h <= n; h++) {
			for (int i = 0; i <= n; i++) {
				v.push_back(ok[h] + ok[i]);
			}
		}
		sort(v.begin(), v.end());
		//最初の二本+最後の二本の二分探索
		for (int h = 0; h <= n; h++) {
			for (int i = 0; i <= n; i++) {
				ll sum = ok[h] + ok[i];
				if (sum > m) { continue; }
				ll ng = lower_bound(v.begin(), v.end(), m - sum) - v.begin();
				if (ng == 0) { continue; }
				ans = max(ans, sum + v[ng - 1]);
			}
		}
		cout << ans << endl;
	}
	return 0;
}

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

int main(){
  long n,m,p[1001];
  while(cin>>n>>m,n||m){
    for(int i=1;i<=n;++i) cin>>p[i];
    p[0]=0;
    vector<long> s(0);
    for(int i=0;i<=n;++i){
      for(int j=0;j<=n;++j) s.push_back(p[i]+p[j]);
    }
    sort(s.begin(),s.end());
    long a=0;
    for(vector<long>::iterator it=s.begin();*it>m/2;++it){
      a=max(a,*it+*(upper_bound(s.begin(),s.end(),m-*it)-1));
    }
    cout<<a<<endl;
  }
  return 0;
}

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

int solve(vector<int>, int);
int main(){
  int n, points;
  vector<int> ans;
  while(cin>>n>>points, n!=0 && points!=0){
    vector<int> darts;
    darts.push_back(0);//投げない場合を含めておく
    for(int i=0; i<n; i++){
      int temp; cin >> temp;
      darts.push_back(temp);
    }
    ans.push_back(solve(darts, points));
  }

  for(int i=0; i<ans.size(); i++){
    cout << ans[i] << endl;
  }

  return 0;
}

int solve(vector<int> darts, int point){
  vector<int> temp;
  //2本投げ終わった後の合計点数を探索
  for(int i=0; i<darts.size(); i++){
    for(int j=0; j<darts.size(); j++){
      temp.push_back(darts[i]+darts[j]);
      sort(temp.begin(), temp.end());
    }
  }

  int ans=0;
  for(int i=0; i<darts.size()*darts.size(); i++){
    int aim = point-temp[i];
    int last = *(upper_bound(temp.begin(), temp.end(), aim)-1);
    if(temp[i]+last<=point) ans=max(ans, temp[i]+last);
  }

  return ans;
}

C++: #include<bits/stdc++.h>
using namespace std;
int n,m,p[101];
vector<int>v;
int nibuntansaku(int x){
  int l=0,r=v.size();
  while(l<r){
    int mid=(l+r)/2;
    if(v[mid]>x)r=mid;
    else l=mid+1;
  }
  if(v[l]>x&&l!=0)l--;
  return v[l];
}
int main(){
  while(cin>>n>>m,n){
    v.clear();
    v.push_back(0);
    for(int i=0;i<n;i++){
      cin>>p[i];
      v.push_back(p[i]);
    }
    for(int i=0;i<n;i++)
      for(int j=i+1;j<n;j++)
        v.push_back(p[i]+p[j]);
    sort(v.begin(),v.end());
    int sum=0;
    for(int i=0;i<v.size();i++){
      int x=nibuntansaku(m-v[i])+v[i];
      if(x<=m)sum=max(x,sum);
    }
    cout<<sum<<endl;
  }
}

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];
int g=0;

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];	
		g++;
	}
}


sort(s1,s1+g);
rep(i,g)s2[i]=s1[i];
//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<25;i++){
		if(x+now==m)break;
		if(x+now>m){
			r=mid;
			mid=(r+l)/2;
			x=s2[mid];
		}
		else{
			l=mid;
			mid=(r+l)/2;
			x=s2[mid];
		}
	}

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

C++: #include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include <cstdio>
#include <string>
#include <cmath>
#include <cfloat>
#include <map>
using namespace std;
int main(){
	
	long long n;
	unsigned long long m;
	while(cin>>n>>m,n!=0||m!=0){
	long long int s=0;
		vector<long long int> y(n);
		for(long long int i=0;i<n;i++)
			cin>>y[i];
		sort(y.begin(),y.end());
		while(n>0){
			if(s+y[n-1]<=m){
				s=s+y[n-1];
			}
			else
				n--;
		}
		cout<<s<<endl;
	}
	
}

C++: #include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string>
#include <cmath>
using namespace std;
#define MOD 1000000007
#define INF 1<<30
#define LINF (ll)1<<62
#define MAX 510000
#define rep(i,n) for(ll i=0; i<(n); i++)
#define REP(i,a,b) for(ll i=(a); i<(b); i++)
#define all(x) (x).begin(),(x).end()
#define uni(q) unique(all(q)),q.end()
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef pair<ll, ll> P;
typedef vector<pair<ll, ll>> vpl;

int main(){
    while(1){
        ll n,m; cin >> n >> m;
        if(n==0 && m==0) break;
        vl a(n);
        vl sums;
        sums.push_back(0);
        rep(i,n) {
            cin >> a[i];
            sums.push_back(a[i]);
        }
        rep(i,n){
            REP(j,i,n){
                sums.push_back(a[i]+a[j]);
            }
        }
        sort(all(sums));
        ll ans = 0;
        for(auto i : sums){
            auto itr = upper_bound(all(sums), m-i);
            if(itr == sums.begin()) continue;
            itr--;
            ans = max(ans, i+*itr);
        }
        cout << ans << endl;
        sums.clear();
    }
}