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<algorithm>
using namespace std;
 
int max_sum(int a[],int as,int b[],int bs,int m){
    int j=bs-1;
    int res=0;
    for(int i=0;i<as;i++){
        while(0<=j && m<a[i]+b[j])j--;
        if(j==-1)break;
        res=max(res,a[i]+b[j]);
    }
    return res;
}
 
int p[1000],p2[1000*1001/2];
int main(){
    int n,m;
    while(cin>>n>>m,n||m){
        int ans=0;
        for(int i=0;i<n;i++){
            cin>>p[i];
            if(p[i]<=m)ans=max(ans,p[i]);
        }
        sort(p,p+n);
        int n2=0;
        for(int i=0;i<n;i++){
            for(int j=i;j<n;j++){
                int a=p[i]+p[j];
                p2[n2++]=a;
                if(a<=m)ans=max(ans,a);
            }
        }
        sort(p2,p2+n2);
        ans=max(ans,max_sum(p,n,p2,n2,m));
        ans=max(ans,max_sum(p2,n2,p2,n2,m));
        cout<<ans<<endl;
    }
    return 0;
}

C++: #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int main(){
  int N, M;
  int P[10001];

  while(cin >> N >> M){
    if(N == 0 && M == 0) break;
    
    for(int i = 0 ; i < N ; i++){
      cin >> P[i];
    }
    
    sort(P, P+N, greater<int>());
    int ans = 0;
    int tmp = M;
    
    for(int i = 0 ; i < N ; i++){
      if(M <= 0) break;
      if(M >= P[i]){
	ans += (M / P[i]) * P[i];
	M -= (M / P[i]) * P[i];
      }
    }
    if(P[N-1] > tmp) ans = 0;
    cout << ans << endl;
  }
  return 0;
}

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

int main(){
	int n,m,t;
	while(cin >> n >> m, n){
		vector<int> data;
		for(int i=0;i<n;i++){
			cin >> t;
			data.push_back(t);
		}
		set<int> dp[4];
		
		for(int i=0;i<n;i++){
			dp[0].insert(data[i]);
		}
		for(int k=1;k<4;k++){
			for(int i=0;i<n;i++){
				for(set<int>::iterator it = dp[k-1].begin(); it != dp[k-1].end();it++){
					dp[k].insert((*it)+data[i]);
				}
			}
		}
		dp[0].insert(dp[1].begin(),dp[1].end());
		dp[0].insert(dp[2].begin(),dp[2].end());
		dp[0].insert(dp[3].begin(),dp[3].end());
		for(set<int>::reverse_iterator it = dp[0].rbegin();it != dp[0].rend();++it){
			if( (*it) <= m){
				cout << (*it) << endl;
				break;
			}
		}
		
		
	}
}

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<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

int main(){
  while(true){
    int n,m,p[1001];
    vector<int> a;
    scanf("%d %d",&n,&m);
    if(n==0&&m==0) return 0;
    p[0] = 0;
    for(int i=0;i<n;i++) scanf("%d",p+i+1);
    n++;
    for(int i=0;i<n;i++){
      for(int j=0;j<n;j++){
        a.push_back(p[i]+p[j]);
      }
    }
    sort(a.begin(),a.end());
    a.erase(unique(a.begin(),a.end()),a.end());
    int ans = 0;
    for(int i=0;i<a.size();i++){
      int x = m - a[i];
      int j = upper_bound(a.begin(),a.end(),x) - a.begin();
      if(j==0) ans = max(ans,a[i]);
      else ans = max(ans,a[i]+a[j-1]);
    }
    printf("%d\n",ans);
  }
}

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

#define loop(i,n) for(int i=0;i<n;i++)
int n,m;
int p[1002];
int pp[1111111];

signed main(){
  while(cin>>n>>m,n){
    loop(i,n)cin>>p[i];
    p[n++]=0;
    loop(i,n)loop(j,n){
      pp[i*n+j]=m-p[i]-p[j];
    }
    sort(pp,pp+n*n);
    int res=0;
    loop(i,n)loop(j,n){
      int s=p[i]+p[j];
      int t=*lower_bound(pp,pp+n*n,s);
      if(t>0)res=max(res,s-t+m);
    }
    cout<<res<<endl;
  }
  return 0;
}

C++: #include<stdlib.h>
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<cstring>
#include<time.h>
#include<cmath>
#include<queue>
using namespace std;
#define INF 100000000
typedef long long ll;
int m,n,p[300];
int pp[5][100000000];
int min(int a,int b){
	if(a<b){
		return a;
	}else{
		return b;
	}
}
int max(int a,int b){
	if(a>b){
		return a;
	}else{
		return b;
	}
}
int under_max(int a,int b,int m){
	if(a>m){
		if(b>m){
			return 0;
		}else{
			return b;
		}
	}else{
		if(b>m){
			return a;
		}else{
			return max(a,b);
		}
	}
}
int main(){
	int maxi=0;
	cin>>n>>m;
	for(int i=0;i<n;i++){
		cin>>p[i];
	}
	for(int i=1;i<=4;i++){
		for(int j=0;j<=m;j++){
			for(int k=0;k<n;k++){
				pp[i][j]=under_max(pp[i-1][j],pp[i-1][j-k]+p[k],m);
				maxi=max(maxi,pp[i][j]);
			}
		}
	}
	cout<<maxi<<endl;
	return 0;
}

C++: 
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int main()
{
	int ans[4];
	int temp;
	double energy,energy_min,energy_now;
	int M, N;
	int* p;
	int i, j;
	double T=100;
	int ret;
	while (1) {
		scanf("%d%d", &N, &M);
		p = (int*)malloc((N+1) * sizeof(int));
		for (i = 0; i < N; i++) {
			scanf("%d", &p[i]);
		}
		p[N] = 0;
		if (N == M && N == 0) {
			break;
		}
		energy_min = pow(10, 300);
		for (j = 0; j < 4; j++) {
			ans[j] = p[(int)((double)(rand() + 1) / (RAND_MAX + 2)*(N+1))];
		}
		
		for (T = 1000001; T > 1000; T--) {
			for (j = 0; j < 4; j++) {
				temp = p[(int)((double)(rand() + 1) / (RAND_MAX + 2)*(N+1))];
				for (j = 0; j < 4; j++) {
					ret = ans[0] + ans[1] + ans[2] + ans[3];
					ret += temp - ans[j];
					energy = M - ret;
					if (M < ret)energy += 100000;

					if (energy < energy_min) {
						energy_min = energy;
						ans[j] = temp;
					}
					else if ((double)(rand() + 1) / (RAND_MAX + 2) < exp((energy_min - energy) / T*1000)) {
						energy_min = energy;
						ans[j] = temp;
					}
				}

			}
		}
		ret=ans[0]+ +ans[1] + ans[2] + ans[3];
		printf("%d\n", ret);
	}
    return 0;
}