Buggy python submission (verdict: Time Limit Exceeded):
import sys
input = sys.stdin.buffer.readline


def solve(mid):
    """のぞいてもいいカードならTrueを返す"""
    dp = [False] * (k + 1)
    dp[0] = True
    if k <= a[mid]:
        return False
    for i, weight in enumerate(a):
        if i == mid:
            continue
        for w in range(k + 1)[::-1]:
            if w - weight < 0:
                continue
            dp[w] |= dp[w - weight]

    return True not in dp[k - a[mid]:k]
     

n, k = map(int, input().split())
a = list(map(int, input().split()))

a.sort()
ok = 0
ng = n
if not solve(ok):
    print(0)
    exit()

while abs(ok - ng) > 1:
    mid = (ok + ng) // 2
    if solve(mid):
        ok = mid
    else:
        ng = mid
print(ok + 1)

Fixed submission:
import sys
input = sys.stdin.buffer.readline


def solve(mid):
    """のぞいてもいいカードならTrueを返す"""
    dp = 1
    mask = (1 << k) - 1
    if k <= a[mid]:
        return False
    for i, weight in enumerate(a):
        if i == mid:
            continue
        dp |= dp << min(weight, k + 10)
        dp &= mask
    return dp >> (k - a[mid]) == 0
     

n, k = map(int, input().split())
a = list(map(int, input().split()))

a.sort()
ok = 0
ng = n
if not solve(ok):
    print(0)
    exit()

while abs(ok - ng) > 1:
    mid = (ok + ng) // 2
    if solve(mid):
        ok = mid
    else:
        ng = mid

print(ok + 1)

Buggy python submission (verdict: Time Limit Exceeded):
import bisect


n, k = map(int, input().split())
a = list(map(int, input().split()))
a = sorted(a)
end = bisect.bisect_right(a, k)
a = a[0:end]
n = len(a)

def subset_sum(mid):
    if a[mid] >= k:
        return True
    dp = [False]*k
    dp[0] = True    
    for i in range(n):
        if i == mid:
            continue
        for j in range(k)[::-1]:
            if j - a[i] < 0:
                break
            else:
                dp[j] |= dp[j - a[i]]
 
    return sum(dp[k-a[mid]:])
  
ok = -1
ng = n
while abs(ng - ok) > 1:
    mid = (ok + ng) // 2
    if subset_sum(mid):
        ng = mid
    else:
        ok = mid
print(ng)

Fixed submission:
import sys
input = sys.stdin.buffer.readline


def solve(mid):
    """のぞいてもいいカードならTrueを返す"""
    dp = 1
    mask = (1 << k) - 1
    if k <= a[mid]:
        return False
    for i, weight in enumerate(a):
        if i == mid:
            continue
        dp |= dp << min(weight, k + 10)
        dp &= mask
    return dp >> (k - a[mid]) == 0
     

n, k = map(int, input().split())
a = list(map(int, input().split()))

a.sort()
ok = 0
ng = n
if not solve(ok):
    print(0)
    exit()

while abs(ok - ng) > 1:
    mid = (ok + ng) // 2
    if solve(mid):
        ok = mid
    else:
        ng = mid

print(ok + 1)

Buggy python submission (verdict: Time Limit Exceeded):
import bisect


n, k = map(int, input().split())
a = list(map(int, input().split()))

a = sorted(a)
end = bisect.bisect_right(a, k)
a = a[0:end]
n = len(a)

#rightの部分和の集合を予め求めておく
right_subset_sum = [None] * (n+1)
right_subset_sum[-1] = set([0])
for i in range(n)[::-1]:
    a_i = a[i]
    tmp_set = set([])
    if a_i <= k:
        tmp_set.add(a_i)
    for j in right_subset_sum[i+1]:
        if j + a_i <= k:
            tmp_set.add(j + a_i)
    right_subset_sum[i] = right_subset_sum[i+1] | tmp_set

ans = 0
left_subset_sum = set([0])

for i in range(n):
    a_i= a[i]
    li = sorted(list(right_subset_sum[i+1]))
    for num in left_subset_sum:
        left = k - a_i - num
        right = k - num
        if bisect.bisect_left(li, right) - bisect.bisect_left(li, left) > 0:
            break
    else:
        ans += 1
    #leftの集合にa_iを含めた部分和を追加する
    tmp_set = set([])
    if a_i <= k:
        tmp_set.add(a_i)
    for j in left_subset_sum:
        if j + a_i <= k:
            tmp_set.add(j + a_i)
    left_subset_sum = left_subset_sum | tmp_set
print(ans)


Fixed submission:
import sys
input = sys.stdin.buffer.readline


def solve(mid):
    """のぞいてもいいカードならTrueを返す"""
    dp = 1
    mask = (1 << k) - 1
    if k <= a[mid]:
        return False
    for i, weight in enumerate(a):
        if i == mid:
            continue
        dp |= dp << min(weight, k + 10)
        dp &= mask
    return dp >> (k - a[mid]) == 0
     

n, k = map(int, input().split())
a = list(map(int, input().split()))

a.sort()
ok = 0
ng = n
if not solve(ok):
    print(0)
    exit()

while abs(ok - ng) > 1:
    mid = (ok + ng) // 2
    if solve(mid):
        ok = mid
    else:
        ng = mid

print(ok + 1)