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 _, val := range sums {
			rem := M - val
			if rem >= 0 {
				index := sort.Search(len(sums), func(i int) bool { return sums[i] > rem }) - 1
				if index >= 0 {
					m = max(m, val+sums[index])
				}
			}
		}
		fmt.Println(m)
	}
}

C++: #include <bits/stdc++.h>
using namespace std;
#define FOR(i, s, n) for(int i = s; i < (int)n; i++)
#define per(i, n) for(int i = n; i >= 0; i--)
#define ROF(i, s, n) for(int i = s; i >= (int)n; i--)
#define FORIT(i, A) for (auto i : A)
#define PRINT(x) cout << (x) << "\n"
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define MP make_pair
#define EACH(i, n) for (__typeof((n).begin()) i = (n).begin(); i != (n).end(); ++i)
#define SZ(a) int((a).size())
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort((c).begin(),(c).end())
#define CLR(a) memset((a), 0 ,sizeof(a))
#define dump(x) cout << #x << " = " << (x) << "\n";
#define debug(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << "\n";
#define sq(n) (n) * (n)
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef priority_queue<int> maxpq;
typedef priority_queue< int, vector<int>, greater<int> > minpq;
static const double EPS = 1e-10;
static const double PI = acos( -1.0 );
static const int mod = 10007;
static const int INF = 1 << 25;
static const LL LL_INF = 1152921504606846976;
static const int dx[] = { 1, -1, 0,  0 };
static const int dy[] = { 0,  0, 1, -1 };

int n, m, ans;
VI ar;
int solve( int now, int d, int cnt ) {
	if ( cnt == 4 || now == n || d + ar[now] > m) {
		return d;
	}
	int res = 0;
	for ( int i = 0; i + cnt <= 4 && d + ar[now] * i <= m; i++ ) {
		res = max( solve( now + 1, d + ar[ now ] * i, cnt + i ), res );
	}
	return res;
}
int main() {
	while ( ~scanf( "%d %d", &n, &m ) && n && m ) {
		ar.resize( n );
		for ( int i = 0; i < n; i++ ) {
			scanf( "%d", &ar[ i ] );
		}
		sort( ar.begin(), ar.end() );
		unique( ar.begin(), ar.end() );
		n = ar.end() - ar.begin();
		ans = solve( 0, 0, 0 );
		printf( "%d\n", ans );
	}
	return 0;
}

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

int N, M;
int score[1002001];
int point[1001];
int bin_search(int n){
    int h=0, t=(N+1)*(N+1);
    int temp;
    int status;
    while(h<=t){
        temp = (t+h)/2;
        if(n == score[temp]) return -1;
        else if(n > score[temp]){
            h = temp + 1;
            status = 1;
        }else{
            t = temp - 1;
            status = 0;
        }
    }
    if(status){
        return score[temp];
    }else{
        return score[temp-1];
    }
}
int main(){
    int a;
    int size;
    int b;
    int m;
    cin >> N >> M;
    while(N || M){
        m = 0;
        point[0] = 0;
        for(int i=1;i<=N;i++){
            cin >> point[i];
        }
        size = -1;
        for(int i=0;i<=N;i++){
            for(int j=0;j<=N;j++){
                score[size++] = point[i]+point[j];
            }
        }
        sort(score,score+size);
        for(int i=0;i<size && score[i] < M;i++){
            b = bin_search(M-score[i]);
            if(b == -1){
                break;
            }else{
                m = max(m, b+score[i]);
            }
        }
        cout << m << endl;
        cin >> N >> M;
    }
}

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

#define REP(i,a,n) for(int i=(a); i<(int)(n); i++)
#define rep(i,n) REP(i,0,n)

int dp[5][1024];
int p[1024];
int main(){
	int n,m;
	while(cin>>n>>m,n|m){
		int ret = 0;
		rep(i,n)scanf("%d",&p[i]);
		rep(i,5)rep(j,n+1)dp[i][j]=0;
		
		REP(i,1,n+1){
			for(int j=0; j<=i; j++){
				rep(k,4)if( dp[k][j]+p[i-1]<=m ){
					dp[k+1][i] = max(dp[k+1][i], dp[k][j]+p[i-1]);
					ret = max(ret,dp[k+1][i]);
				}
			}
		}
		/*
		rep(i,n+1){
			rep(j,5){
				printf("%d:%d  %d\n",i,j,dp[j][i]);
			}
		}
		*/
		printf("%d\n",ret);
	}
	return 0;
}

C++: #include <bits/stdc++.h>
//---------------------------
using namespace std;
//---------------------------
#define REP(i,n) for(int i = 0; i < (n); i++)
#define P(x) cout << (x) << "\n"

#define MOD 1000000007 // 1e9+7
#define PI 3.1415926525
#define ll long long int // 10^18
#define INF 1000000001 // 1e9+1

int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
//---------------------------
int n;ll m;
ll p[2000];
int main(){
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);

  // ifstream in("input.txt");
  // cin.rdbuf(in.rdbuf());

  while(true){
    cin>>n>>m;
    if(n==0 && m==0)break;
    REP(i,n){
      cin>>p[i+1];
    }
    sort(p,p+n+1);
    ll maxn=0;
    for(int i=0;i<=n;i++){
      for(int j=0;j<=n;j++){
        for(int k=0;k<=n;k++){
          ll sump=p[i]+p[j]+p[k];
          if(sump>m)continue;
          ll ub = upper_bound(p,p+n+1,m-sump)-p-1;
          maxn=max(maxn, p[ub]+sump);
        }
      }
    }
    P(maxn);
  }
  return 0;
}

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

int main()
{
  int n, m;
  while (cin >> n >> m, n || m){
    int a[1010] = {0};
    for (int i = 1; i <= n; i++){
      cin >> a[i];
    }

    vector<int> A;

    for (int i = 0; i <= n; i++){
      for (int j = 0; j <= n; j++){
        if (a[i] + a[j] > m) continue;
        A.push_back(a[i] + a[j]);
      }
    }

    sort(A.begin(), A.end());
    A.erase(unique(A.begin(), A.end()), A.end());

    int maxs = 0;
    for (int l = 0, r = A.size() - 1; l <= r; l++){
      while (A[l] + A[r] > m) r--;
      maxs = max(maxs, A[l] + A[r]);
    }

    cout << maxs << endl;
  }
}

C++: #include <stdio.h>
#include <vector>
#include <algorithm>

using namespace std;

int main(void)
{
	int n, m;
	int s;
	vector<int> p;
	vector<int> s2;
	
	while (1){
	scanf("%d %d", &n, &m);
	
	if (n == 0 && m == 0){
		break;
	}
	
	for (int i = 0; i < n; i++){
		int k;
		scanf("%d", &k);
		p.push_back(k);
	}
	
	p.push_back(0);
	for (int i = 0; i < p.size(); i++){
		for (int j = 0; j < p.size(); j++){
			s2.push_back(p[i] + p[j]);
		}
	}
	
	sort(s2.begin(), s2.end());
	int max = -1;
	for (int i = 0; i < s2.size(); i++){
		vector<int>::iterator it = upper_bound(s2.begin(), s2.end(), m - s2[i]);
		//printf("%d\n", *(it - 1));
		
		if (it != s2.begin() && max < s2[i] + *(it - 1)){
			max = s2[i] + *(it - 1);
		}
		else if (max < s2[i]) {
			max = s2[i];
		}
	}
	
	printf("%d\n", max);
	
	}
	
	return (0);
}