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

using namespace std;

typedef vector<int> VI;

int binary_search(int tmp_m, VI &second, int i) {
    int left = 0;
    int right = second.size() - 1;
    int mid = (left + right) / 2 + 1;
    while(1) {
        if (right - left <= 1) {
            return second[left] + second[i];
        }
        mid = (left + right) / 2;
        if (second[mid] + second[i] <= tmp_m) {
            left = mid;
        } else {
            right = mid;
        }
    }
    return 0;
}

int main(void) {
    while (1) {
        int n;
        int m;
        cin >> n >> m;
        if (n == 0 && m == 0) {
            break;
        }
        VI table(n + 1);
        VI first;

        table[0] = 0;
        for (int i = 0; i < n; i++) {
            int temp;
            cin >> temp;
            if (temp <= m) {
                table.push_back(temp);
            }
        }

        for (int i = 0; i < (int)table.size(); i++) {
            for (int j = i; j < (int)table.size(); j++) {
                int sum = table[i] + table[j];
                if (sum <= m) {
                    first.push_back(table[i] + table[j]);
                }
            }
        }
        sort(first.begin(), first.end());

        int ans = 0;
        for (int i = 0; i < (int)(first.size()); i++) {
            int total = binary_search(m, first, i);
            if (total <= m && ans < total) {
                ans = total;
            }
        }
        cout << ans << endl;
    }
    return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;
#define Rep(i, N) for(int i = 0; i < N; i++)
 
int main()
{
  int N, M;
  
  while(cin >> N >> M, N || M) {
    int A[1005] = {0};
    vector<int>sum;
    int maxv = 0;
    sum.push_back(0);
    for(int i = 1; i <= N; i++) {
      cin >> A[i];
      Rep(j, i + 1) {
	if(A[i] + A[j] <= M) sum.push_back(A[i] + A[j]);
      }
    }
    sort(sum.begin(), sum.end());
    Rep(i, sum.size()) {
      maxv = max(maxv, sum[i] + *(upper_bound(sum.begin(), sum.end(), M - sum[i]) - 1));
    }
    cout << maxv << endl;
  }
  return 0;
}

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[501501],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<stdio.h>
#include<math.h>
#include<vector>
#include<stack>
#include<set>
#include<string.h>
#include<iostream>
#include<algorithm>
#define MAXSIZE 1005
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;

int main()
{
    set<int,greater<int> >S;
    vector<int>v;
    int a[MAXSIZE];
    int n,m,ans;
    while(scanf("%d%d",&n,&m),n+m)
    {
        ans = 0;
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
            v.push_back(a[i]),S.insert(a[i]);
        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
                v.push_back(a[i]+a[j]),S.insert(a[i]+a[j]);
        }
        sort(v.begin(),v.end());
        for(int i=0;i<(int)v.size();i++)
        {
            if(v[i] >= m)
                break;
            int num = *S.lower_bound(m-v[i]);
            if(num+v[i] < m)
                ans = max(ans,num+v[i]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

C++: #include<bits/stdc++.h>
#define LL long long
using namespace std;
int main(void){
	int n;
	int m;
	int a[1001];
	int i,j;
	LL sum;
	int x,y;
	while(1){
		cin>>n>>m;
		if(n==0&&m==0)	break;
		//cout<<n<<m<<endl;
		for(i=0;i<n;i++){
			cin>>a[i];
		}
		sort(a,a+n,greater<int>());
		x=m/a[0];
		//cout<<"x="<<x<<endl;
		sum=0;
		sum+=(LL)x*a[0];
		//cout<<sum<<endl;
		for(i=1;i<n;i++){
			while(1){
				if(sum+a[i]<=m){
					sum+=(LL)a[i];
				}
				else	break;
			}
		}
		cout<<sum<<endl;
	}
	return 0;
}

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

int n, m;
int p[1000];
int ans;
vector<int> v;

void solve(){
	ans = 0;
	v.clear();
	v.push_back(0);
	for(int i = 0; i < n; i++){
		scanf("%d", &p[i]);
		if(p[i] <= m) v.push_back(p[i]);
	}
	sort(v.begin(),v.end());
	for(int i = 0; i < n; i++){
		for(int j = 0; j < n; j++){
			if(p[i]+p[j] <= m) v.push_back(p[i]+p[j]);
		}
	}
	sort(v.begin(),v.end());
	int j = v.size()-1;
	for(int i = 0; i < v.size(); i++){
		while(true){
			if(v[i]+v[j] <= m){
				ans = max(ans,v[i]+v[j]);
				break;
			}
			j--;
		}
	}
	printf("%d\n", ans);
}

int main(){
	while(scanf("%d%d", &n, &m),n||m) solve();
}

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

using namespace std;

int main() {
	int n[1000], m[1000], p[10][1000],ans=0, i = 0;
	vector<int> v;
	while (cin >> n[i] >> m[i]) {
		if (n[i] == 0)break;
		for (int j = 0; j < n[i]; j++)cin >> p[i][j];
		i++;
	}
	for (int k = 0; k < i; k++) {
		ans = 0;
		v = vector<int>(1,0);
		for (int a = 0; a < n[k]; a++) {
			v.push_back(p[k][a]);
			for (int b = 0; b < n[k]; b++)
				v.push_back(p[k][a] + p[k][b]);
		}
		sort(v.begin(), v.end());
		for (int j = 0; j < v.size(); j++) {
			if (v[j] > m[k])break;
			decltype(v)::iterator itr= upper_bound(v.begin(), v.end(), m[k]-v[j]);
			itr--;
			ans = max(ans, v[j] + *itr);
		}
		cout << ans << endl;
	}
	return 0;
}

C++: #include <iostream>
#include <algorithm>
#include <set>
#define N_MAX 1001

using namespace std;

int N, M;
int P[N_MAX];
int S[1002001];
void solve() {
  int cnt = 0;
  for(int i = 0; i <= N; ++i) {
    for(int j = i; j <= N; ++j) {
      int tmp = P[i] + P[j];
      if(tmp > M) continue;
      S[cnt++] = tmp;
    }
  }

  sort(S, S+cnt);
  int ans = 0;
  for(int i = 0; i < cnt; ++i) {
    int *tmp = upper_bound(S, S+cnt, M - S[i]);
    --tmp;
    ans = max(ans, *tmp + S[i]);
  }
  cout << ans << endl;
}

int main() {
  while((cin >> N >> M) && N && M) {
    P[0] = 0;
    for(int i = 1; i <= N; i++) {
      cin >> P[i];
    }
    solve();
  }
  return 0;
}

C++: #include "bits/stdc++.h"
#define in std::cin
#define out std::cout
#define rep(i,N) for(int i=0;i<N;++i)
typedef long long int LL;

LL N, M, P[1123];
LL seek, cou, ans;

int main()
{
	while (true)
	{
		N = M = seek = cou = ans = 0;
		memset(P, 0, sizeof(P));

		in >> N >> M;
		if (N == 0 && M == 0) { break; }
		rep(i, N) { in >> P[i]; }

		std::sort(P, P + N, std::greater<LL>());
		while (M > 0 && seek < N && cou < 4)
		{
			while (P[seek] > M) { ++seek; }
			M -= P[seek];
			ans += P[seek];
			++cou;
		}

		out << ans << std::endl;
	}
	return 0;
}