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)
	}
}

Python: import bisect
while 1:
    n,m=map(int,input().split())
    if n==0:break
    s,a=[],[0]*(n+1)
    for i in range(1,n+1):
        a[i]=int(input())
        for j in range(i+1):
            if a[i]+a[j]<=m:s+=[a[i]+a[j]]
            else:break
    s.sort()
    print(max(i+s[bisect.bisect_right(s,m-i)-1]for i in s))

Python: import bisect
def main():
	while True:
		n,m=map(int,input().split())
		if n==0 and m==0:
			break
		p=list()
		for i in range(n):
			p.append(int(input()))
		p.append(0)
		st=set()
		for i in p:
			for j in p:
				if i+j<=m:
					st.add(i+j)
		ls=list(st)
		ans=0
		for x in ls:
			idx=bisect.bisect_right(ls,m-x)
			idx-=1
			ans=max(ans,x+ls[idx])

		print(ans)

if __name__=="__main__":
	main()

Python: import sys

file_input = sys.stdin

NM = file_input.readline()

import itertools, bisect

while NM != '0 0\n':
    N, M = map(int, NM.split())
    P = [int(file_input.readline()) for i in range(N)]
    P.append(0)
    scores = map(sum, itertools.combinations_with_replacement(P, 2))
    scores = filter(lambda x: x <= M, scores)
    scores = list(set(scores))
    scores.sort()
    print(max(s + scores[bisect.bisect_right(scores, M - s) - 1] for s in scores))
    NM = file_input.readline()

Python: import sys

file_input = sys.stdin

NM = file_input.readline()

import itertools

while NM != '0 0\n':
    N, M = map(int, NM.split())
    P = [int(file_input.readline()) for i in range(N)]
    P.append(0)
    P = list(set(P))
    P.sort()
    scores = map(sum, itertools.combinations_with_replacement(P, 4))
    print(max(filter(lambda x: x <= M, scores)))
    NM = file_input.readline()

Python: def solve(darts, scores, point, target):
    if darts == 4:
        if point > target:
            return 0
        else:
            return point

    max_score = 0
    for s in scores:
        result1 = solve(darts + 1, scores, point + s, target)  # ???????????´???
        result2 = solve(darts + 1, scores, point, target)      # ?????°????????£?????´???
        max_score = max(max_score, result1, result2)
    return max_score


if __name__ == '__main__':
    # ??????????????\???
    while True:
        N, M = [int(x) for x in input().split(' ')]
        scores = [int(input()) for _ in range(N)]

        if N == 0 and M == 0:
            break

        # ???????????????????????????????¨????
        scores.sort()  # ???????????°??????????????????????????????
        ans = solve(0, scores, 0, M)

        # ???????????¨???
        print(ans)

Python: while True:
  n,m = map(int,input().split())
  if not n and not m: break
  lst = []
  lst2 = []
  for i in range(n):
    lst.append(int(input()))
  for i in lst:
    for j in lst:
      lst2.append(i + j)
  lst2 = lst2 + lst
  lst2.sort()
  ans = 0
  def search(x, l, r):
    y = len(l)
    if y == 0:
      return r
    elif y == 1:
      if x >= l[0]:
        return l[0]
      else:
        return r
    elif l[y//2] == x:
      return x
    elif l[y//2] > x:
      return search(x, l[:y//2], r)
    elif l[y//2] < x:
      r = l[y//2]
      return search(x, l[y//2 + 1:], r)
  for i in lst2:
    if i <= m:
      ans = max(ans, i + search(m - i, lst2, 0))
    else:
      break
  print(ans)

Python: import bisect
# python template for atcoder1
import sys
sys.setrecursionlimit(10**9)
input = sys.stdin.readline


def solve():
    N, M = map(int, input().split())
    if N*M == 0:
        return False
    P = [0]+[int(input()) for _ in range(N)]
    # solve
    k = [p1+p2 for p1, p2 in zip(P, P)]
    k = sorted(k)

    ret = 0
    for i in range(N):
        for j in range(N):
            tmp = P[i]+P[j]
            if tmp > M:
                continue
            else:
                r = M-tmp
                l = bisect.bisect_right(k, r)
                if l >= len(k):
                    tmp += k[-1]
                elif l != 0:
                    tmp += k[l-1]
            ret = max(ret, tmp)
    return ret


ans = []
while True:
    ret = solve()
    if ret:
        ans.append(ret)
    else:
        break
print("\n".join(map(str, ans)))

Python: import bisect

while True:
  N,M = map(int,input().split())
  if N == 0 and M == 0: break
  targets = [0]+[ int(input()) for _ in range(N) ]
  targets.sort()

  cans = [targets[i]+targets[j] for i in range(N+1) for j in range(i,N+1) if targets[i]+targets[j] <= M]
  cans.sort()

  res = 0

  for l in cans:
    y = cans[bisect.bisect_right(cans, M-l)-1]
    res = max(res, l+y)

  print(res)

Python: def solve():
  while True:
    n,m = map(int,input().split())
    if not n and not m: break
    lst = []
    lst2 = []
    for i in range(n):
      x = int(input())
      if x <= m:
        lst.append(x)
    lst2 = [i + j for i in lst for j in lst if i <= j]
    #for i in lst:
    #  for j in lst:
    #    if i + j <= m:
    #      lst2.append(i + j)
    #lst2 = list(set(lst2 + lst))
    lst2.sort()
    def binary(x, left, right):
      center = (left + right) // 2
      length = right - left + 1
      v = lst2[center]
      if length == 1 or length == 2:
        if v > x:
          return center - 1
        else:
          return center
      elif v == x: return x
      elif v < x: return binary(x, center + 1, right)
      elif v > x: return binary(x, left, center - 1)
    A = []
    #ans = 0
    for i in lst2:
      if i + lst2[-1] <= m:
        A.append(i + lst2[-1])
        #ans = max(ans, i + lst2[-1])
      elif i <= m:
        A.append(i + lst2[binary(m - i, 0 , len(lst2) - 1)])
        #ans = max(ans, i + lst2[binary(m - i, 0, len(lst2) - 1)])
      else:
        break
    print(max(A))
    #print(ans)
solve()

Python: while True:
    n, m = map(int, input().split())
    if not n:
        break

    ps = {int(input()) for _ in range(n)}
    ss = [False] * (m + 1)
    min_p, max_p = 1e8, 0
    for p in ps:
        ss[p] = True
        if min_p > p: min_p = p
        if max_p < p: max_p = p

    max_s = 0

    for t in range(1, 4):
        new_ss = [False] * (m + 1)
        for i in range(min(m, max_p * t), min_p * t - 1, -1):
            if ss[i]:
                for p in ps:
                    if i + p <= m:
                        new_ss[i + p] = True

        ss = new_ss

        p = m
        while p:
            if ss[p]:
                if max_s < p:
                    max_s = p
                break

    print(max_s)

Python: import bisect
while True:
    n, m = map(int, input().split())
    if n == 0:
        break
    p = list(int(input()) for i in range(n))
    point = [] + p
    for i in p:
        for j in p:
            a = i + j
            if a <= m and a not in point:
                point.append(a)
    point.sort()
    maxp = 0
    for i in point:
        if m - i in point:
            print(m)
            break
        pp = i + point[bisect.bisect_left(point, m - i) - 1]
        if pp > maxp:
            maxp = pp
    else:
        print(maxp)