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<cstdio>
#include<algorithm>
using namespace std;
int a,s,d[1000],f[100000001],g,h,i,j,z,x,c,v;
int main(void)
{
	int high,low,ba,naka,nokori,kore;
	while(1){
		kore=0;
		scanf("%d %d",&a,&s);
		if(a==0&&s==0)
			break;
		d[0]=0;
		for(i=1;i<=a;i++){
			scanf("%d",&d[i]);
		}
		g=0;
		for(i=0;i<=a;i++){
			for(j=i;j<=a;j++){
				f[g]=d[i]+d[j];
				g++;
			}
		}
		sort(f,f+g);
		/*for(i=0;i<g;i++)
			printf("%d\n",f[i]);*/
		for(i=0;i<g;i++){
			v=0;
			low=0;
			high=g-1;
			nokori=s-f[i];
		//	printf("%d %d\n",i,nokori);
			if(nokori>=0){
				while(1){
					if(low>high)
						break;
					/*if(nokori>f[g]){
						ba=f[g];
						v=1;
						break;
					}*/
					naka=(low+high)/2;
				//	printf("%d = %d %d %d %d %d\n",i,f[high],f[naka],f[low],f[i],nokori);
					if(nokori>f[naka]){
						low=naka+1;
					//	printf("%d %d %d low\n",i,nokori,f[naka]);
					}
					if(nokori<f[naka]){
						high=naka-1;
					//	printf("%d %d %d high\n",i,nokori,f[naka]);
					}
					if(nokori==f[naka]){
						ba=f[naka];
						v=1;
						break;
					}
				}
				if(v==0)
					ba=f[high];
			//	printf("%d\n",f[i]+ba);
				if(kore<f[i]+ba)
					kore=f[i]+ba;
			}
		}
		printf("%d\n",kore);
	}
	return 0;
}

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

typedef pair<int,int> P;
int n, m, ans;
int p[1001];
map<P,bool> memo;

void solve(int s, int k){
	if( s > m ) return;
	
	ans = max( ans , s );
	if( k == 0 || memo.count( P(s,k) ) ) return;
	memo[P(s,k)] = true;
	
	for(int i=0 ; i < n ; i++ ){
		solve( s+p[i] , k-1 );
	}
}

int main(){
	while( cin >> n >> m , n || m ){
		memo.clear();
		for(int i=0 ; i < n ; i++ ){
			cin >> p[i];
		}
		ans = 0;
		solve( 0 , 4 );
		cout << ans << endl;
	}
}

C++: #include<iostream>
#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%u",&n,&m) && n){
    uint one[n];
    uint two[n*n];
    int p=0;
    maxv=0;
    for(int i=0;i<n;i++)scanf("%u",&one[i]);
    for(int i=0;i<n;i++){
      if ( one[i]>maxv &&one[i] <=m)maxv=one[i];
      for(int j=i;j<n;j++){
	if ( one[i]+one[j]>m)continue;
	two[p++]=one[i]+one[j];
	if (two[p-1]>maxv)maxv=two[p-1];
      }
    }
    sort(one,one+n);
    sort(two,two+p);
    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);
    }
    printf("%u\n",maxv);
  }
  return false;
}

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

int main(){
    int n,m;
    int P[1010],Q[1000000];

    while(true){
	cin >> n >> m;
	if(n==0&&m==0) break;
	
	P[0]=0;
	for(int i=1;i<=n;i++) scanf("%d",&P[i]);

	int num=0;
	for(int i=0;i<=n;i++){
	    for(int j=i;j<=n;j++){
		Q[num++]=P[i]+P[j];
	    }
	}

	sort(Q,Q+num);

	int key,index,ans=0;
	int *pos;
	for(int i=0;i<num;i++){
	    key=m-Q[i];
	    if(key<0) break;

	    pos=lower_bound(Q,Q+num,key);
	    index=distance(Q,pos)-1;

	    ans=max(ans,Q[i]+Q[index]);
	}
 	cout << ans << endl;
	
    }
    return 0;
}

C++: #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <complex>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <iostream>
#include <map>
#include <set>
using namespace std;
typedef pair<int,int> P;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define INF 2000000000
#define sz(x) ((int)(x).size())
#define fi first
#define sec second
#define EQ(a,b) (abs((a)-(b))<EPS)
int p[1001];
int ans;
vector<int> ab,cd;
int n,m;
int main()
{
	while(1)
	{
		memset(p,0,sizeof(p));
		ab.clear();cd.clear();
		cin >> n >> m;
		ans=0;
		if(n==0&&m==0)break;
		for(int i=0;i<n;i++)
		{
			cin >> p[i];
		}
		for(int i=0;i<=n;i++)
		{
			for(int j=0;j<=n;j++)
			{
				ab.pb(p[i]+p[j]);
				cd.pb(m-(p[i]+p[j]));
			}
		}
		sort(cd.begin(),cd.end());
		for(int i=0;i<sz(ab);i++)
		{
			vector<int>::iterator it=lower_bound(cd.begin(),cd.end(),ab[i]);
			ans=max((*it)*-1+m+ab[i],ans);
		}
		cout << ans << endl;
	}
	return 0;
}

C++: #include<iostream>
#include<vector>
#include<algorithm>
#include<cstdio>
using namespace std;
int n,m,size,ans;
int  t[100000];
int dp[100000][2];
bool flg;

void init(){
  dp[0][0]=1;
  dp[0][1]=2;
  size=0;
  flg=false;
  ans=0;
}

int main(){

  while(cin>>n>>m&&n&&m){
    init();
    for(int i=0;i<m;i++){
      scanf("%d",&t[size]);
      if(t[size]==0)flg=true;
      else size++;
    }
    sort(t,t+m);
    for(int i=1;i<size;i++){
      if(t[i]-1==t[i-1]){
	dp[i][0]=dp[i-1][0]+1;
	dp[i][1]=dp[i-1][1]+1;
      }else if(t[i]-2==t[i-1]){
	dp[i][1]=dp[i-1][0]+2;
	dp[i][0]=1;
      }else{
	dp[i][0]=1;
	dp[i][1]=2;
      }
      ans=max(ans,dp[i][0]);
      if(flg)ans=max(ans,dp[i][1]);
    }
    if(ans>n)ans--;
    cout<<ans<<endl;
  }
}

C++: #include <bits/stdc++.h>
using namespace std;
#define FOR(i,k,n) for(int i = (k); i < (n); i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(a) begin(a),end(a)
#define MS(m,v) memset(m,v,sizeof(m))
#define D10  fixed<<setprecision(5)
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<short, short> P;
typedef complex<double> Point;
typedef long long ll;
const int INF = 114514810;
const int MOD = 100000007;
const double EPS = 1e-10;
const double PI = acos(-1.0);
struct edge
{
	int from, to, cost;
	bool operator < (const edge& e) const { return cost < e.cost; }
	bool operator >(const edge& e) const { return cost > e.cost; }
};
///*************************************************************************************///
///*************************************************************************************///
///*************************************************************************************///

int n, m;
int main()
{
	while (cin >> n >> m, n)
	{
		vector<int> v, w;
		REP(i, n)
		{
			int a;
			cin >> a;
			w.push_back(a);
		}
		w.push_back(0);
		set<int> used;
		REP(i, w.size())REP(j, w.size())
		{
			int t = w[i] + w[j];
			if (used.find(t) == end(used))
			{
				used.insert(t);
				v.push_back(w[i] + w[j]);
			}
		}
		sort(ALL(v));
		int ans = 0;
		REP(i, v.size())
		{
			if (v[i] > m / 2) break;
			int tmp = m - v[i];
			if (tmp < 0) continue;
			int k = *(upper_bound(ALL(v), tmp) - 1);
			ans = max(ans, v[i] + k);
		}
		cout << ans << endl;
	}
	return 0;
}