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 <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 long long INT;
typedef vector <INT> VI;
typedef set <INT> SI;

INT solve( VI Q, INT M ) {
    INT answer = 0;
    int n = Q.size();
    for ( int i = 0; i < n; ++ i ) {
        int q = Q[i];
        int L = 0;
        int R = n;
        INT m = M - q;
        if ( q + Q[R-1] < answer ) continue;
        if ( q + Q[R-1] > M ) continue;
        while ( L < R ) {
            int p = ( R - L ) / 2 + L;
            INT t = q + Q[p];
            if ( t > M ) t = 0;
            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;
        VI P( n );
        for ( int i = 0; i < n; ++ i ) {
            cin >> P[i];
        }
        SI Q_;
        Q_.insert( 0 );
        for ( int i = 0; i < n; ++ i ) {
            Q_.insert( P[i] > m ? 0 : P[i] );
            for ( int j = 0; j < n; ++ j ) {
                Q_.insert( ( P[i] + P[j] > m ? 0 : P[i] + P[j] ) );
            }
        }
        VI Q( Q_.begin(), Q_.end() );
        cout << solve( Q, m ) << endl;
    }
    return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;
 
#define REP(i,s,n) for(int i=s;i<n;++i)
#define rep(i,n) REP(i,0,n)
#define SORT(c) sort((c).begin(),(c).end())
#define IINF INT_MAX
#define LLINF LLONG_MAX
 
typedef long long ll;
typedef pair<int, int> ii;

#define DEBUG false

int main(){

	ll n, m;
	while(cin >> n >> m){
		if(n == 0 && m == 0) break;
		vector<ll> p(n+1);
		rep(i, n) cin >> p[i];
		
		rep(i, n){
			REP(j, i, n){
				p.push_back(p[i] + p[j]);
			}
		}
		
		SORT(p);
		
		ll ans = 0;

		rep(i, p.size()){
			auto it2 = upper_bound(p.begin(), p.end(), m - p[i]);
			if(it2 == p.begin()) continue;
			it2--;
			if(p[i] > *it2) break;
			ans = max(ans, p[i] + *it2);
		}
		
		cout << ans << endl;
		
	}
	
	return 0;
}

C++: #include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <map>
#include <set>

#define REP(i,k,n) for(int i=k;i<n;i++)
#define rep(i,n) for(int i=0;i<n;i++)
#define INF 1<<30
#define pb push_back
#define mp make_pair

using namespace std;
typedef long long ll;
typedef pair<int,int> P;

int main() {
	int n, m;
	while(cin >> n >> m) {
		if(n == 0 && m == 0) break;

		vector<int> v(n);
		rep(i, n) cin >> v[i];

		sort(v.begin(), v.end(), greater<int>());

		ll ans = m;
		rep(i, n) {
			if(ans < v[i]) continue;
			ans %= v[i];
		}

		cout << m - ans << endl;
	}

	return 0;
}

C++: #include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
#include <cstdio>
#define REP(i, n) for(int i = 0;i < n;i++)
#define REPR(i, n) for(int i = n;i >= 0;i--)
#define FOR(i, m, n) for(int i = m;i < n;i++)
#define FORR(i, m, n) for(int i = m;i >= n;i--)
#define SORT(v, n) sort(v, v+n);
#define VSORT(v) sort(v.begin(), v.end());
#define llong long long
#define pb(a) push_back(a)
#define INF 999999999
using namespace std;
typedef pair<int, int> P;

int dy[]={0, 0, 1, -1};
int dx[]={1, -1, 0, 0};

int solve(int n, int m){
	int p[n];
	REP(i, n) cin >> p[i];
	SORT(p, n);
	
	int res=0, c=0;
	REP(i, n){
		while(res<=m && c<4){
			res+=p[i];
			c++;
		}
		if(res>m){
			res-=p[i];
			c--;
		}
	}
	
	return res;
}

int main(){
	while(1){
		int n, m;
		cin >> n >> m;
		if(n==0 && m==0) return 0;
		cout << solve(n, m) << endl;
	}
}

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 long long INT;
typedef vector <INT> VI;
typedef set <INT> SI;

INT solve( VI Q, INT M ) {
    INT answer = 0;
    int n = Q.size();
    for ( int i = 0; i < n; ++ i ) {
        int q = Q[i];
        int L = 0;
        int R = n;
        INT m = M - q;
        if ( q + Q[R-1] < answer ) continue;
        if ( q + Q[R-1] > M ) continue;
        while ( L < R ) {
            int p = ( R - L ) / 2 + L;
            INT t = q + Q[p];
            if ( t > M ) t = 0;
            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;
        VI P;
        for ( int i = 0; i < n; ++ i ) {
            INT p;
            cin >> p;
            P.push_back( p );
        }
        P.push_back( 0 );
        VI Q;
        for ( int i = 0; i < n + 1; ++ i ) {
            for ( int j = 0; j < n + 1; ++ j ) {
                Q.push_back( P[i] + P[j] );
            }
        }
        sort( Q.begin(), Q.end() );
        unique( Q.begin(), Q.end() );
        cout << 0 << endl;
        // VI Q( Q_.begin(), Q_.end() );
        // cout << solve( Q, m ) << endl;
    }
    return 0;
}

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

int m, n, p[1000], pp[1000*1000];

int main(){
    while( true ){
        cin >> n >> m;
        if( m == 0 && n == 0 ) break;
        for(int i = 0; i < n; i++){
            cin >> p[i];
        }
        sort(p, p+n);
        for(int i = 0; i < n*n; i++){
            pp[i] = p[i/n] + p[i%n];
        }
        sort(pp, pp + n*n);
        int c = n/p[n-1];
        if( c >= 4 ){
            cout << p[n-1]*4;
            continue;
        }
        int cand = 0;
        if( c <= 3 ){
            int j = n*n-1;
            for(int i = 0; i <= n*n/2; i++){
                while( pp[i] + pp[j] > m && j > 0 ) j--;
                cand = max(cand, pp[i] + pp[j]);
            }
        }
        if( c <= 2 ){
            int j = n*n-1;
            for(int i = 0; i <= n/2; i++){
                while( p[i] + pp[j] > m && j > 0 ) j--;
                cand = max(cand, p[i] + pp[j]);
            }
        }
        if( c <= 1 ){
            int j = n-1;
            for(int i = 0; i <= n/2; i++){
                while( p[i] + p[j] > m && j > 0 ) j--;
                cand = max(cand, p[i] + p[j]);
            }
        }
        int k;
        for(k = n-1; p[k] > m && k > 0; k--);
        cand = max(cand, p[k]);
        cout << cand << endl;
    }
    return 0;
}