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<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[MAX_N][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[i][j].v.push_back( V[i] );
				}else if( j > 0 ){
					for(int k = 0; k <= i; k++){
						for(unsigned int l = 0; l < D[k][j - 1].v.size(); l++ ){
							int tmp = V[i] + D[k][j - 1].v[l];
							if( tmp <= m ){
								if( !Find(D[i][j].v, tmp) ){
									D[i][j].v.push_back( tmp );
								}
							}
						}
					}
				}
			}
		}

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

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

int main()
{
  int N, M;
  while (cin >> N >> M) {
    if ((N|M) == 0)
      break;

    vector<int> P(N+1, 0);
    for (int i = 0; i < N; ++i)
      cin >> P[i];

    vector<int> PP;
    for (int i = 0; i < N+1; ++i) {
      for (int j = 0; j < N+1; ++j)
	PP.push_back(P[i]+P[j]);
    }
    sort(PP.begin(), PP.end());

    int ans = 0;
    for (int i = 0; i < PP.size(); ++i) {
      int tar = M - PP[i];
      vector<int>::iterator it = upper_bound(PP.begin(), PP.end(), tar);
      if (it != PP.begin())
	ans = max(ans, PP[i] + *(it-1));
    }
    cout << ans << endl;
  }
  return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;

int main(){
	while(1){
		vector<int> a, v;
		int n, m, t1;
		scanf("%d%d", &n, &m);
		if(n+m == 0)break;
		a.push_back(0);
		for(int i = 0;i < n;i++){
			scanf("%d", &t1);
			a.push_back(t1);
		}
		n++;
		for(int i = 0;i < n;i++){
			for(int j = i;j < n;j++){
				v.push_back(a[i]+a[j]);
			}
		}
		int s = v.size(), ans = 0;
		sort(v.begin(), v.end());
		//for(int i = 0;i < s;i++)printf("%d ", v[i]);
		for(int i = s-1;i >= 0;i--){
			int t = upper_bound(v.begin(), v.end(), m-v[i])-v.begin();
			if(t == 0){
				if(v[i] <= m)ans = max(ans, v[i]);
			}else{
				if(v[i]+v[t-1] <= m)ans = max(ans, v[i]+v[t-1]);
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}

C++: #include <iostream>
#include <sstream>
#include <vector>
#include <list>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
using namespace std;

typedef int INT;
typedef vector <INT> VI;
typedef set <INT> SI;

INT P[1002];
INT Q[1002001];

INT solve( int N, INT M ) {
    INT answer = 0;
    for ( int i = 0; i < N; ++ i ) {
        int q = Q[i];
        int L = 0;
        int R = N;
        INT m = M - q;
        while ( L < R ) {
            int p = ( R - L ) / 2 + L;
            INT t = q + Q[p];
            if ( t <= M ) answer = max( answer, t );
            if ( Q[p] > m ) {
                R = p - 1;
            } else {
                L = p + 1;
            }
        }
    }
    return answer;
}

int main() {
    int n, m;
    while ( cin >> n >> m ) {
        if ( n == 0 && m == 0 ) break;
        for ( int i = 0; i < n; ++ i ) {
            INT p;
            cin >> p;
            P[i] = p;
        }
        P[n] = 0;
        for ( int i = 0; i < n + 1; ++ i ) {
            for ( int j = 0; j < n + 1; ++ j ) {
                Q[i * ( n + 1 ) + j] = P[i] + P[j];
            }
        }
        int length = ( n + 1 ) * ( n + 1 );
        sort( Q, Q + length );
        cout << solve( length, m ) << endl;
    }
    return 0;
}

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

int kazu[1000000];
int n,m,Max,data[1000];
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 <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

vector<int> *points;
vector<int> *twice;
vector<int>::iterator mem;
int prev;

void deldup(vector<int> *vec) {
    vector<int>::iterator it = vec->begin();
    bool is_straight = false;
    int save = -1;

    while (it != vec->end()) {
        if (*it == save) {
            vec->erase(it++);
            is_straight = true;
            continue;
        } else {
            save = *it;
            if (is_straight) {
                vec->erase(it++);
                is_straight = false;
                continue;
            }
            is_straight = false;
        }
        it++;
    }
}

int search(vector<int> *target, int standard) {

    while (mem != target->end()) {
        if (standard < *mem) {
            return prev;
        }
        prev = *mem;
        mem++;
    }

    return -1;
}

int main() {
    while (1) {
        int i;
        int n, m;
        int max = 0;

        scanf("%d %d", &n, &m);
        if (n == 0 && m == 0) return 0;

        points = new vector<int>();
        twice = new vector<int>();

        points->push_back(0);
        for (i=0;i<n;i++) {
            int k;
            scanf("%d", &k);
            points->push_back(k);
        }

        vector<int>::iterator it = points->begin();
        while (it != points->end()) {
            vector<int>::iterator it2 = points->begin();
            while (it2 != points->end()) {
                twice->push_back(*it + *it2);
                it2++;
            }
            it++;
        }

        sort(twice->begin(), twice->end());
        deldup(twice);

        mem = twice->begin();
        prev = -1;
        vector<int>::reverse_iterator it1 = twice->rbegin();
        while (it1 != twice->rend()) {
            int ret = search(twice, m - *it1);
            if (ret != -1) {
                int got = *it1 + ret;
                if (max < got) max = got;
            }
            it1++;
        }

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