Go: ///
// File:  0529.go
// Author: ymiyamoto
//
// Created on Wed Feb 28 20:39:28 2018
//
package main

import (
	"fmt"
	"sort"
)

func max(n, m int64) int64 {
	if n < m {
		return m
	} else {
		return n
	}
}

func main() {
	for {
		var N int
		var M int64
		fmt.Scan(&N, &M)
		if N == 0 && M == 0 {
			break
		}

		arr := make([]int64, N+1)
		for i := 1; i <= N; i++ {
			fmt.Scan(&arr[i])
		}
		sort.Slice(arr, func(i, j int) bool { return arr[i] < arr[j] })

		sums := make([]int64, len(arr)*len(arr))
		for i := 0; i < len(arr); i++ {
			for j := 0; j < len(arr); j++ {
				sums[i*len(arr)+j] = arr[i] + arr[j]
			}
		}

		sort.Slice(sums, func(i, j int) bool { return sums[i] < sums[j] })

		var m int64 = 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<set>
#include<vector>
using namespace std;
typedef unsigned int uint;
uint maxv;
void solve(uint now,uint m,uint *a,int n){
  int r=n-1,l=0,mid;
  while(l <=r){
    mid = (l+r)/2;
    if ( a[mid]+now>m)r=mid-1;
    else if ( a[mid]+now <m)l=mid+1;
    else break;

  }
  if ( now+a[mid]>maxv&& now+a[mid]<=m)maxv=now+a[mid];
}


main(){
  int n;
  uint m;
  while(scanf("%d%d",&n,&m) && n){
    set<uint> S;    
    uint one[n];
    uint two[n*n];
    int p=0;
    for(int i=0;i<n;i++)scanf("%d",&one[i]);
    for(int i=0;i<n;i++){
      for(int j=i;j<n;j++){
	//if ( S.find(one[i]+one[j]) == S.end())S.insert(one[i]+one[j]),two[p++]=one[i]+one[j];
	two[p++]=one[i]+one[j];
      }
    }
    sort(one,one+n);
    sort(two,two+p);
    maxv=0;
    for(int i=0;i<p;i++){
      //if ( two[i]+one[0]>m)break;
      //if ( two[i]+two[0]<=m)solve(two[i],m,two,p);
      //if ( two[i]+one[0]<=m)solve(two[i],m,one,n);
      solve(two[i],m,two,p);
      solve(two[i],m,one,n);
    }
    printf("%d\n",maxv);
  }
  return false;
}

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]);
		}
		if(n != 1){
			for(int i=0; i<n; i++){
				for(int j=i; j<=i; j++){
					a.push_back(p[i] + p[j]);
					f(p[i] + p[j]);
				}
			}
			if(n != 2){
				for(int i=0; i<n; i++){
					for(int j=0; j<a.size(); j++){
						f(p[i] + a[j]);
					}
				}
				if(n != 3){
					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 <cstdio>
#include <fstream>
#include <algorithm>
using namespace std;

#define MAX_N 1000
int P[MAX_N + 1];
int N, M;
int table[(MAX_N + 1) * (MAX_N + 1)];

int main(){
	ifstream ifs("input.txt");
	ofstream ofs("output.txt");
	
	ifs >> N >> M;
	
	P[0] = 0;
	for(int i = 1; i <= N; i++) ifs >> P[i];
	
	for(int i = 0; i < N + 1; i++){
		for(int j = 0; j < N + 1; j++){
			table[(N + 1) * i + j] = P[i] + P[j];
		}
	}
	sort(table, table + (N + 1) * (N + 1));
	
	int right = (N + 1) * (N + 1) - 1;
	int res = 0;
	for(int i = 0; i < (N + 1) * (N + 1); i++){
		while(right >= 0){
			if(table[i] + table[right] <= M){
				res = max(res, table[i] + table[right]);
				break;
			}
			if(table[i] == table[right]) goto OUT;
			right--;
		}
	}
	OUT:
	
	ofs << res << endl;
	
	return 0;
}

C++: #include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;

using int64 = int64_t;

constexpr int64 MOD = 1000000007;

int N, M, arr[1000];

int main() {
    cin.tie(0); ios::sync_with_stdio(false);
    while (true) {
        cin >> N >> M;
        if (N == 0 && M == 0) break;
        arr[0] = 0; ++N;
        for (int j = 1; j < N; ++j) {
            cin >> arr[j];
        }
        vector<int> arr2;
        for (int j = 0; j < N; ++j) for (int k = j+1; k < N; ++k) {
            arr2.push_back(arr[j] + arr[k]);
        }
        sort(begin(arr2), end(arr2));
        const int NN = arr2.size();

        int ans = 0, r = NN-1;
        for (int j = 0; j < NN; ++j) {
            while (arr2[j] + arr2[r] > M) --r;
            ans = max(ans, arr2[j] + arr2[r]);
        }

        cout << ans << endl;
    }
    return 0;
}

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

int n, m;
vector<int> p1, p2;
int main()
{
  while(cin >> n >> m && n && m){
    p1.clear();
    p2.clear();
    
    //chap1
    p1.push_back(0);
    for(int i = 0; i < n; i++){
      int p;
      cin >> 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 = lower_bound(p2.begin(), p2.end(), m - p2[i]);
      if(count2 != p2.begin())
	ans = max(ans, *(count2 - 1) + p2[i]);
    }
    cout << ans << endl;
  }
  return 0;
}

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

using namespace std;

int main()
{
	int N, M, D;

	while (true)
	{
		scanf("%d", &N);
		scanf("%d", &M);

		if (N == 0 && M == 0) { break; }

		vector<int> C; C.push_back(0);

		for (int i = 0; i < N; i++)
		{
			scanf("%d", &D);

			if (D <= M)
			{
				C.push_back(D);
			}
		}

		vector<int> r;

		for (int i = 0; i < C.size(); i++)
		{
			for (int j = i; j < C.size(); j++)
			{
				if (C[i] + C[j] <= M)
				{
					r.push_back(C[i] + C[j]);
				}
			}
		}

		sort(r.begin(), r.end());

		int ret = 0;

		for (int i = 0; i < r.size(); i++)
		{
			int ptr = upper_bound(r.begin(), r.end(), M - r[i]) - r.begin() - 1;
			
			if (ptr >= 0)
			{
				ret = max(ret, r[i] + r[ptr]);
			}
		}

		printf("%d\n", ret);
	}

	return 0;
}

C++: #include <iostream>
#include <vector>
#include <queue>
#include <functional>
#include <cmath>

using namespace std;

int main() {
	int n, m;
	while (cin >> n >> m) {
		if (n == 0 && m == 0) {
			break;
		}
		vector<long long int> hyou(n+1);
		priority_queue<long long int, vector<long long int>, greater<long long int> > pq;
		long long int a;
		pq.push(0);
		for (int i = 0; i < n; i++) {
			cin >> a;
			pq.push(a);
		}
		for (int i = 0; i < n+1; i++) {
			hyou[i] = pq.top();
			pq.pop();
		}
		long long int MAX = 0;
		long long int toku = 0;
		for (int i = 0; i < n+1; i++) {
			toku = 0;
			toku += hyou[i];
			if (toku > m) {
				break;
			}
			for (int j = i; j < n+1; j++) {
				long long int toku2 = toku + hyou[j];
				if (toku2 > m) {
					break;
				}
				for (int k = j; k < n+1; k++) {
					long long int toku3 = toku2 + hyou[k];
					if (toku3 > m) {
						break;
					}
					for (int l = k; l < n+1; l++) {
						long long int toku4 = toku3 + hyou[l];
						if (toku4 > m) {
							break;
						} else {
							MAX = max(MAX, toku4);
						}
					}
				}
			}
		}
		cout << MAX << endl;
	}
	return 0;
}