CodeEff/ECCO huggingface dataset:
# Original solution
# coding: utf-8
# Your code here!
n,W = [int(i) for i in input().split()]
wv = [[int(i) for i in input().split()] for j in range(n)] # 縦「n」行
V=10**5
MAX=10**12
dp = [MAX]*(V+1)
dp[0]=0
newdp = [MAX]*(V+1)
for i in range(n):
    w, v = wv[i]
    for j in range(V+1):
        newdp[j] = dp[j]
    for j in range(V+1):
        if j+v <= V:
            newdp[j+v] = min(dp[j] + w, newdp[j+v])
    newdp, dp = dp, newdp
#    print(dp)

print((max([i for i,c in enumerate(dp) if c <= W])))


#print(dp)

# Optimized solution
# coding: utf-8
# Your code here!
n,W = [int(i) for i in input().split()]
wv = [[int(i) for i in input().split()] for j in range(n)] # 縦「n」行
V=10**5
MAX=10**12
dp = [MAX]*(V+1)
dp[0]=0
newdp = [MAX]*(V+1)
for i in range(n):
    w, v = wv[i]
    newdp = dp[:]
    for j in range(V+1):
        if j+v <= V:
            newdp[j+v] = min(dp[j] + w, newdp[j+v])
    newdp, dp = dp, newdp
#    print(dp)

print((max([i for i,c in enumerate(dp) if c <= W])))


#print(dp)
# Original solution
a= input().split()
N = int(a[0])
W = int(a[1])
wv_list = []
max_value = 0
 
#価値と重さのやつをリストにしてる
for i in range(N):
  b = input().split()
  w = int(b[0])
  v = int(b[1])
  max_value += v
 
  wv_list.append([w, v])
 
#初期化
#とりあえず、全部最大になるように
n_list = [[float('inf') for i in range(max_value + 1)] for j in range(N)]
 
#
n_list[0][wv_list[0][1]] = wv_list[0][0]
 
for i in range(1, N):
 
  for j in range(max_value):
 
    s = j + wv_list[i][1]
 
    if s <= max_value:
      n_list[i][s] = min(n_list[i - 1][j] + wv_list[i][0], n_list[i][s])
    n_list[i][j] = min(n_list[i - 1][j], n_list[i][j])
    n_list[i][wv_list[i][1]] = wv_list[i][0]
 
for i in range(1, max_value):
 
  if n_list[-1][-i] <= W:
    print((max_value - i + 1))
    break


# Optimized solution
a= input().split()
N = int(a[0])
W = int(a[1])
wv_list = []
max_value = 0

#価値と重さのやつをリストにしてる
for i in range(N):
  b = input().split()
  w = int(b[0])
  v = int(b[1])
  max_value += v

  wv_list.append([w, v])

#初期化
#とりあえず、全部最大になるように
inf=float('inf')
n_list = [[inf for i in range(max_value + 1)] for j in range(N)]

#最初のアイテムに関して、重みを適切な価値のところにいれている
n_list[0][wv_list[0][1]] = wv_list[0][0]

for i in range(1, N):
  # 今まで全く選んでなかった場合に、i番目のアイテムを選んだ時
  n_list[i][wv_list[i][1]] = wv_list[i][0]
  for j in range(max_value):

    s = j + wv_list[i][1]
    #アイテムを選んだらこうなりますよってのを更新
    if s <= max_value:
      n_list[i][s] = min(n_list[i - 1][j] + wv_list[i][0], n_list[i][s])

    #選ばんかったらこうなりますよってのを更新？
    n_list[i][j] = min(n_list[i - 1][j], n_list[i][j])
  
for i in range(1, max_value):

  if n_list[-1][-i] <= W:
    print((max_value - i + 1))
    break
# Original solution
N,W = list(map(int,input().split()))
L = [list(map(int,input().split())) for i in range(N)]

supremum = 10**5

dp = [float("inf") for i in range(supremum+1)]
dp[0] = 0

for i in range(N) :
    weight_i,value_i = L[i]    
    for j in range(supremum,value_i-1,-1) :
        if dp[j-value_i] < float("inf") :
            dp[j] = min(dp[j], dp[j-value_i] + weight_i)

for i in range(supremum,-1,-1) :
    if dp[i] <= W :
        ans = i
        break

print(ans)


# Optimized solution
N,W = list(map(int,input().split()))
L = [list(map(int,input().split())) for i in range(N)]

supremum = 10**5

dp = [float("inf") for i in range(supremum+1)]
dp[0] = 0

for i in range(N) :
    weight_i,value_i = L[i]    
    for value in range(supremum,value_i-1,-1) :
        if dp[value-value_i] + weight_i <= W :
            dp[value] = min(dp[value], dp[value-value_i] + weight_i)

for i in range(supremum,-1,-1) :
    if dp[i] <= W :
        ans = i
        break

print(ans)
# Original solution
N, W = list(map(int, input().split()))

w = [0] * N
v = [0] * N
for i in range(N):
    w[i], v[i] = list(map(int, input().split()))

dp = {0: 0}
for i in range(N):
    for cw, cv in list(dp.items()):
        if cw + w[i] > W:
            continue
        dp[cw + w[i]] = max(
            dp.get(cw + w[i], 0),
            cv + v[i])
print((max(dp.values())))

# Optimized solution
N, W = list(map(int, input().split()))

w = [0] * N
v = [0] * N
for i in range(N):
    w[i], v[i] = list(map(int, input().split()))

dp = {0: 0}
for i in range(N):
    for cv, cw in list(dp.items()):
        if cw + w[i] > W:
            continue
        dp[cv + v[i]] = min(
            dp.get(cv + v[i], float('inf')),
            cw + w[i])
print((max(dp)))
# Original solution
#!/usr/bin/env python3

N, W = list(map(int, input().split()))
item_list = []

for _ in range(N):
    w, v = list(map(int, input().split()))
    item_list.append((w, v))

max_v = (10 ** 3) * 100
dp_table = [[0] + [float("inf")] * (max_v + 1) for _ in range(N + 1)]
total_v = 0

for i in range(1, N + 1):
    w, v = item_list[i - 1]
    # 品物iまで考慮したときの価値の最大値
    total_v += v
    for j in range(total_v + 1):
        # 品物iを入れない場合
        dp_table[i][j] = dp_table[i - 1][j]
        before_min_weight = dp_table[i - 1][j]
        # dp_table[i][j] = before_min_weight
        # 品物iを入れる場合
        if j - v < 0:
            continue
        weight = dp_table[i - 1][j - v] + w
        min_weight = min(before_min_weight, weight)
        dp_table[i][j] = min_weight
        if i == N:
            if min_weight <= W:
                max_value = j


# max_value = 0
# for i, w in enumerate(dp_table[-1]):
#     if w <= W:
#         max_value = i
ans = max_value
print(ans)


# Optimized solution
#!/usr/bin/env python3

N, W = list(map(int, input().split()))
item_list = []

for _ in range(N):
    w, v = list(map(int, input().split()))
    item_list.append((w, v))

max_v = (10 ** 3) * 100
dp_table = [[0] + [float("inf")] * (max_v + 1) for _ in range(N + 1)]
total_v = 0

for i in range(1, N + 1):  # 最大で10**2
    w, v = item_list[i - 1]
    # 品物iまで考慮したときの価値の最大値
    total_v += v
    for j in range(total_v + 1):  # 最大で10 ** 5
        # 品物iを入れない場合
        dp_table[i][j] = dp_table[i - 1][j]
        before_min_weight = dp_table[i - 1][j]
        # dp_table[i][j] = before_min_weight
        # 品物iを入れる場合
        if j - v < 0:
            continue
        weight = dp_table[i - 1][j - v] + w
        min_weight = min(before_min_weight, weight)
        dp_table[i][j] = min_weight
        if i == N:
            if min_weight <= W:
                max_value = j

ans = max_value
print(ans)
# Original solution
MAX_V = 100100
MAX_N = 101
INF = pow(2, 70)

N, W = list(map(int, input().split()))
w = [0 for _ in range(N)]
v = [0 for _ in range(N)]
for i in range(N):
    w[i], v[i] = list(map(int, input().split()))

dp = [[INF for _ in range(MAX_V)] for _ in range(N + 1)]
dp[0][0] = 0
for i in range(N):
    for sum_v in range(MAX_V):
        # print(i, sum_v, sum_v - v[i] >= 0)
        if sum_v - v[i] >= 0:
            dp[i+1][sum_v] = min(dp[i+1][sum_v], dp[i][sum_v - v[i]] + w[i])
        dp[i+1][sum_v] = min(dp[i+1][sum_v], dp[i][sum_v])
        # print(dp[i + 1][sum_v])

ans = max([i for i in range(len(dp[N])) if dp[N][i] <= W])
# for l in dp:
#     print([n for n in l if not n == INF])

print(ans)


# Optimized solution
MAX_V = 100100
MAX_N = 101
INF = pow(2, 64)

N, W = list(map(int, input().split()))
w = [0 for _ in range(N)]
v = [0 for _ in range(N)]
for i in range(N):
    w[i], v[i] = list(map(int, input().split()))

dp = [[INF for _ in range(MAX_V)] for _ in range(N + 1)]
dp[0][0] = 0
for i in range(N):
    for sum_v in range(MAX_V):
        # print(i, sum_v, sum_v - v[i] >= 0)
        if sum_v - v[i] >= 0:
            dp[i+1][sum_v] = min(dp[i+1][sum_v], dp[i][sum_v - v[i]] + w[i])
        dp[i+1][sum_v] = min(dp[i+1][sum_v], dp[i][sum_v])
        # print(dp[i + 1][sum_v])

ans = max([i for i in range(len(dp[N])) if dp[N][i] <= W])
# for l in dp:
#     print([n for n in l if not n == INF])

print(ans)
# Original solution
MAX_V = 100100
MAX_N = 101
INF = pow(2, 64)

N, W = list(map(int, input().split()))
w = [0 for _ in range(N)]
v = [0 for _ in range(N)]
for i in range(N):
    w[i], v[i] = list(map(int, input().split()))

dp = [[INF for _ in range(MAX_V)] for _ in range(N + 1)]
dp[0][0] = 0
for i in range(N):
    for sum_v in range(MAX_V):
        # print(i, sum_v, sum_v - v[i] >= 0)
        if sum_v - v[i] >= 0:
            dp[i+1][sum_v] = min(dp[i+1][sum_v], dp[i][sum_v - v[i]] + w[i])
        dp[i+1][sum_v] = min(dp[i+1][sum_v], dp[i][sum_v])
        # print(dp[i + 1][sum_v])

ans = max([i for i in range(len(dp[N])) if dp[N][i] <= W])
# for l in dp:
#     print([n for n in l if not n == INF])

print(ans)


# Optimized solution
MAX_V = 100100
MAX_N = 101
INF = pow(2, 60)

N, W = list(map(int, input().split()))
w = [0 for _ in range(N)]
v = [0 for _ in range(N)]
for i in range(N):
    w[i], v[i] = list(map(int, input().split()))

dp = [[INF for _ in range(MAX_V)] for _ in range(N + 1)]
dp[0][0] = 0
for i in range(N):
    for sum_v in range(MAX_V):
        # print(i, sum_v, sum_v - v[i] >= 0)
        if sum_v - v[i] >= 0:
            dp[i+1][sum_v] = min(dp[i+1][sum_v], dp[i][sum_v - v[i]] + w[i])
        dp[i+1][sum_v] = min(dp[i+1][sum_v], dp[i][sum_v])
        # print(dp[i + 1][sum_v])

ans = max([i for i in range(len(dp[N])) if dp[N][i] <= W])
# for l in dp:
#     print([n for n in l if not n == INF])

print(ans)
# Original solution
n, w = list(map(int, input().split()))

dp = [[float('inf') for _ in range(10**5+1)] for i in range(n)]

for i in range(n):
    wi, vi = list(map(int, input().split()))
    if i == 0:
        dp[i][0] = 0
        dp[i][vi] = wi
    else:
        for k in range(10**5+1):
            if k < vi:
                dp[i][k] = dp[i-1][k]
            else:
                dp[i][k] = min(dp[i-1][k], dp[i-1][k-vi]+wi)

for i in range(10**5+1)[::-1]:
    if dp[n-1][i] <= w:
        print(i)
        exit()


# Optimized solution
n, w = list(map(int, input().split()))

dp = [[float('inf') for _ in range(10**5+1)] for i in range(n)]

v_sum = 0

for i in range(n):
    wi, vi = list(map(int, input().split()))
    v_sum += vi
    if i == 0:
        dp[i][0] = 0
        dp[i][vi] = wi
    else:
        for k in range(v_sum+1):
            if k < vi:
                dp[i][k] = dp[i-1][k]
            else:
                dp[i][k] = min(dp[i-1][k], dp[i-1][k-vi]+wi)

for i in range(v_sum, -1, -1):
    if dp[n-1][i] <= w:
        print(i)
        exit()
# Original solution
n, W = list(map(int,input().split()))
dp = [W+1]*(10**5 + 1)
vr=[]
for i in range(n):
  w,v= list(map(int,input().split()))
  vr.append(v)
  if i==0:
  	dp[v]=w
  for j in range(10**5-v,-1,-1):
  	cw=w+dp[j]
  	if j==v and vr.count(v)==1:
  		continue
  	if cw<=W:
  		dp[j+v]=min(dp[j+v],cw)
  dp[v]=min(w,dp[v])

for i in range(10**5,-1,-1):
		
			if dp[i]<=W:
				print(i)
				exit()

			
		

 



# Optimized solution
n, W = list(map(int,input().split()))
dp = [W+1]*(10**5 + 1)
maxv=0
for i in range(n):
  w,v= list(map(int,input().split()))
  for j in range(10**5-v,-1,-1):
  	cw=w+dp[j]
  	if cw<=W:
  		dp[j+v]=min(dp[j+v],cw)
  		maxv=max(maxv,j+v)
  dp[v]=min(w,dp[v])
  maxv=max(v,maxv)
print(maxv)
# Original solution
# D-Knapsack 1
N,W = list(map(int,input().split()))
Weight = [0 for _ in range(N)]
Value = [0 for _ in range(N)]
for i in range(N):
    Weight[i],Value[i] = list(map(int,input().split()))

MAX_N = 110
MAX_V = 100100
dp = [[10**15 for i in range(MAX_V)] for j in range(MAX_N)]
dp[0][0] = 0

for i in range(N):
    # あらゆる合計重量sum_wに対して品物iを入れるべきか計算する
    for sum_v in range(MAX_V):
        # i番目を選ぶ場合
        if sum_v - Value[i] >= 0:
            dp[i+1][sum_v] = min(dp[i+1][sum_v], dp[i][sum_v - Value[i]] + Weight[i])

        # i番目を選ばない場合
        dp[i+1][sum_v] = min(dp[i+1][sum_v], dp[i][sum_v])


ans = 0
for sum_v in range(MAX_V):
    if dp[N][sum_v] <= W:
        ans = sum_v
print(ans)

# Optimized solution
# D-Knapsack 1
N,W = list(map(int,input().split()))
Weight = [0 for _ in range(N)]
Value = [0 for _ in range(N)]
for i in range(N):
    Weight[i],Value[i] = list(map(int,input().split()))

MAX_N = 110
MAX_V = 100100

# dp[i+1][v]:= i番目までの品物の中からスコアがv以上になるように選んだときの、重さの総和の最小値
dp = [[10**15 for i in range(MAX_V)] for j in range(MAX_N)]
dp[0][0] = 0

for i in range(N):
    for sum_v in range(MAX_V):
        # i番目を選ぶ場合
        if sum_v - Value[i] >= 0:
            dp[i+1][sum_v] = min(dp[i+1][sum_v], dp[i][sum_v - Value[i]] + Weight[i])

        # i番目を選ばない場合
        dp[i+1][sum_v] = min(dp[i+1][sum_v], dp[i][sum_v])

ans = 0
# 重さの総和<=Wである最大スコアを探す
for sum_v in range(MAX_V):
    if dp[N][sum_v] <= W:
        ans = sum_v
print(ans)
# Original solution
N,W=list(map(int,input().split()))
w=[]
v=[]

for i in range(N):
    x,y=list(map(int,input().split()))
    w.append(x)
    v.append(y)

S=sum(v)

DP=[[1000000000000]*(S+1) for i in range(N+1)]
for i in range(N+1):
    DP[i][0]=0



for i in range(N):
    for v1 in range(S+1):
        DP[i+1][v1]=min(DP[i][v1-v[i]]+w[i],DP[i][v1])

for i in range(S,0,-1):
    if DP[N][i]<=W:
        print(i)
        exit()

# Optimized solution
N,W=list(map(int,input().split()))
w=[]
v=[]

for i in range(N):
    x,y=list(map(int,input().split()))
    w.append(x)
    v.append(y)

S=sum(v)

DP=[1000000000000]*(S+1)
DP[0]=0


for i in range(N):
    for v1 in range(S,v[i]-1,-1):
        DP[v1]=min(DP[v1-v[i]]+w[i],DP[v1])

for i in range(S,0,-1):
    if DP[i]<=W:
        print(i)
        exit()
# Original solution
N, W = [int(i) for i in input().split()]
w, v = [0]*N, [0]*N
 
for i in range(N):
  w[i], v[i] = [int(_) for _ in input().split()]
V = sum(v)
 
dp = [[float('inf')] * (V+1) for _ in range(N+1)]
# dp[i][j] i番目までの荷物で価値がj以上になるように選んだときの重さの最小値
dp[0][0] = 0
for i in range(N):
  for j in range(V+1):
    if v[i] <= j:# 荷物v[i]の価値がjに足りてないのでi番目の荷物を入れる可能性がある
      dp[i+1][j] = min(dp[i][j], dp[i][j-v[i]] + w[i])
    else:      
      dp[i+1][j] = dp[i][j]
 
ans = 0
for j in range(V + 1):
  if dp[N][j] <= W:
    ans = j    
      
print(ans)


# Optimized solution
N, W = list(map(int, input().split()))
w, v = [0]*(N+1),[0]*(N+1)
for i in range(N):
    w[i+1], v[i+1] = [int(_) for _ in input().split()]
V = sum(v)

dp = [[10**12]*(V+1) for _ in range(N+1)]
dp[0][0] = 0
# dp[i][j]:i番目以前の商品を見たときの価値総和jとしたときの重さの最小値

ans = 0
for i in range(1,N+1):
    for j in range(V+1): # なんか間違えて1スタートにしててハマった
        if v[i] <= j: #v[i]が入るとjになるときの計算なので，v[i]がjよりでかいのはあり得ない。j-v[i]>0だしね。
            # i-1番目までの商品で価値jの場合とi番目の商品を入れて価値jの場合の比較
            dp[i][j] = min(dp[i-1][j], dp[i-1][j-v[i]] + w[i])
        else:
            dp[i][j] = dp[i-1][j]


for j in range(V+1):
    if dp[N][j] <= W:
        ans = max(ans, j)

print(ans)
# Original solution
from collections import defaultdict
N, W = [int(i) for i in input().split()]
Things = [[int(i) for i in input().split()] for j in range(N)]

dp = defaultdict(lambda: float('inf'))
dp[0] = 0
for w, v in Things:
    for nv, nw in list(dp.items()):
        if nw + w <= W:
            dp[nv + v] = min(dp[nv + v], nw + w)
ans = 0
for v, w in list(dp.items()):
    if w <= W and v >= ans:
        ans = v
print(ans)

# Optimized solution
def e_knapsack2(N, W, Goods):
    """
    Dと同じ設定だが、制約が違う(1 <= v_i <= 10^3 と価値の制約がゆるめ)
    """
    from collections import defaultdict

    # dp[v]: 価値vを達成するために要求される重さの最小値
    dp = defaultdict(lambda: float('inf'))
    dp[0] = 0
    # w, vの順序が逆になっているのはdpテーブルの都合上
    for w, v in Goods:
        for nv, nw in list(dp.items()):
            if nw + w <= W:
                dp[nv + v] = min(dp[nv + v], nw + w)
    # 遷移の仕方により、keyの値を達成する品物の重さの和がWを超えることは
    # ないので、keyの最大値を解とすればいい
    return max(dp.keys())

N, W = [int(i) for i in input().split()]
Goods = [[int(i) for i in input().split()] for j in range(N)]
print((e_knapsack2(N, W, Goods)))
# Original solution
import sys

read = sys.stdin.read
INF = 1 << 60


def main():
    N, W, *WV = list(map(int, read().split()))
    weight = WV[::2]
    value = WV[1::2]

    V = sum(value)
    dp = [[INF] * (V + 1) for _ in range(N + 1)]
    dp[0][0] = 0
    for i in range(N):
        for v in range(V + 1):
            if v - value[i] >= 0:
                dp[i + 1][v] = dp[i][v - value[i]] + weight[i]
            else:
                dp[i + 1][v] = weight[i]
            if dp[i + 1][v] > dp[i][v]:
                dp[i + 1][v] = dp[i][v]

    ans = 0
    for v in range(V + 1):
        if dp[N][v] <= W:
            ans = v
    print(ans)
    return


if __name__ == '__main__':
    main()


# Optimized solution
import sys

read = sys.stdin.read
INF = 1 << 60


def main():
    N, W, *WV = list(map(int, read().split()))
    weight = WV[::2]
    value = WV[1::2]

    V = sum(value)
    dp = [[INF] * (V + 1) for _ in range(N + 1)]
    dp[0][0] = 0
    for i in range(N):
        for v in range(V + 1):
            if v - value[i] >= 0:
                dp[i + 1][v] = dp[i][v - value[i]] + weight[i]
            if dp[i + 1][v] > dp[i][v]:
                dp[i + 1][v] = dp[i][v]

    ans = 0
    for v in range(V, 0, -1):
        if dp[N][v] <= W:
            ans = v
            break

    print(ans)
    return


if __name__ == '__main__':
    main()
# Original solution
import pprint
N, W = list(map(int, input().split()))
weight = []
value = []
for _ in range(N):
    w, v = list(map(int, input().split()))
    weight.append(w)
    value.append(v)
value_sum = sum(value)
dp = []
for _ in range(N + 1):
    dp_val = [float('inf') for _ in range(value_sum + 1)]
    dp.append(dp_val)
# print(dp)
dp[0][0] = 0
# for v in range(value_sum):
#     dp[0][v] = 0
for idx in range(N):
    for v in range(value_sum + 1):
        if value[idx] <= v:
            dp[idx + 1][v] = min(dp[idx][v], dp[idx][v - value[idx]] + weight[idx])
        else:
            dp[idx + 1][v] = dp[idx][v]
ans = 0
# print(dp)
for i in range(value_sum + 1):
    if dp[-1][i] <= W:
        ans = i
print(ans)

# Optimized solution
N, W = list(map(int, input().split()))
weight = []
value = []
for _ in range(N):
    w, v = list(map(int, input().split()))
    weight.append(w)
    value.append(v)
value_sum = sum(value)
dp = []
for _ in range(N + 1):
    dp_val = [float('inf') for _ in range(value_sum + 1)]
    dp.append(dp_val)
dp[0][0] = 0

for idx in range(N):
    for v in range(value_sum + 1):
        if value[idx] <= v:
            dp[idx + 1][v] = min(dp[idx][v], dp[idx][v - value[idx]] + weight[idx])
        else:
            dp[idx + 1][v] = dp[idx][v]
ans = 0
# print(dp)
for i in range(value_sum + 1):
    if dp[-1][i] <= W:
        ans = i
print(ans)
# Original solution
N, W = list(map(int, input().split()))
w, v = [0] * N, [0] * N
for i in range(N):
	w[i], v[i] = list(map(int, input().split()))

V = sum(v)
# dp[i][j]:i番目までの品物から価値がj以上になるよう選んだときの重さの総和の最小値
dp = [[float("inf")] * (V + 1) for _ in range(N + 1)]
dp[0][0] = 0
for i in range(N):
	for j in range(V + 1):
		# i+1番目を選ぶ場合
		if j - v[i] >= 0:
			dp[i + 1][j] = min(dp[i + 1][j], dp[i][j - v[i]] + w[i])
		# i+1番目を選ばない場合
		dp[i + 1][j] = min(dp[i + 1][j], dp[i][j])

# dp[N][j]がW以下であるようなjの最大値が答えになる
ans = 0
for j in range(V + 1):
	if dp[N][j] <= W:
		ans = j

print(ans)


# Optimized solution
# import bisect
# import copy
# import fractions
# import math
# import numpy as np
# from collections import Counter, deque
# from itertools import accumulate,permutations, combinations,combinations_with_replacement,product

def resolve():
    N, W = list(map(int, input().split()))
    weight, value = [0] * N, [0] * N
    for i in range(N):
        weight[i], value[i] = list(map(int, input().split()))



    # この前段階で、荷物の数N、ウェイトの上限W、
    # weightの表weightとvalueの表valueは用意しておく。
    def knapsack(N, W, weight, value):

        V=sum(value)
        # dp[i][v]はvを運べる最小のウェイトを意味する。
        # 求めたいのは、dp[N][v]<=Wなるvのmax
        dp = [[float('inf')] * (V + 1) for _ in range(N + 1)]
        dp[0][0]=0

        for i in range(N):
            for v in range(V + 1):
                if v >= value[i]:
                    dp[i + 1][v] = min(dp[i][v], dp[i][v - value[i]] + weight[i])
                else:
                    dp[i + 1][v] = dp[i][v]

        # dp[N][j]がW以下であるようなjの最大値が答えになる
        ans = 0
        for v in range(V + 1):
            if dp[N][v] <= W:
                ans = v

        return ans




    print((knapsack(N, W, weight, value)))


resolve()
# Original solution
def main():
    width, height, target = list(map(int, input().split()))
    answer = False
    if target == 0:
        answer = True
    else:
        for i in range(height):
            if answer:
                break
            for j in range(width):
                if (width - j) * (height - i) + i * j == target:
                    answer = True
                    break
    print(("Yes" if answer else "No"))


if __name__ == '__main__':
    main()



# Optimized solution
def main():
    n, m, k = list(map(int, input().split()))
    answer = False
    for i in range(n + 1):
        if answer:
            break
        for j in range(m + 1):
            if i * j + (n - i) * (m - j) == k:
                answer = True
                break
    print(("Yes" if answer else "No"))


if __name__ == '__main__':
    main()
# Original solution
n,m,k=list(map(int,input().split()))
for i in range(n+1):
    for j in range(m+1):
        if m*i+n*j-2*(i*j)==k:
            print("Yes")
            exit()
print("No")   

# Optimized solution
n,m,k=list(map(int,input().split()))
s=[]
u=n
for i in range(1,n+1):
    u-=2
    for j in range(m+1):
        s.append(m*i+u*j)
if k in s:
    print("Yes")
else:
    print("No")
# Original solution
#!/usr/bin/env python3
n, m, k = list(map(int, input().split()))
for i in range(n + 1):
    for j in range(m + 1):
        if m * i + j * n - 2 * i * j == k:
            print("Yes")
            exit()
print('No')


# Optimized solution
#!/usr/bin/env python3
n, m, k = list(map(int, input().split()))
for i in range(n + 1):
    a = k - i * m
    b = n - 2 * i
    if b != 0 and a % b == 0 and 0 <= a // b <= m:
        print("Yes")
        exit()
print("No")
# Original solution
N,M,K = list(map(int,input().split()))
ans = "No"

for k in range(N+1):
  for l in range(M+1):
    if k*(M-l) + l*(N-k) == K:
      ans = "Yes"
print(ans)

# Optimized solution
N,M,K = list(map(int,input().split()))
ans = "No"

for a in range(N+1):
  if N - 2*a != 0:
    if (K - a*M) % (N - 2*a) == 0:
      if M >= (K - a*M) / (N - 2*a) >= 0:
        ans = "Yes"
print(ans)
# Original solution
n, m, k = list(map(int, input().split()))
for i in range(n + 1):
    for j in range(m + 1):
        if m * i + n * j - i * j * 2 == k:
            print('Yes')
            exit()
print('No')


# Optimized solution
n, m, k = list(map(int, input().split()))
for i in range(n + 1):
    for j in range(m + 1):
        if i * (m - j) + j * (n - i) == k:
            print('Yes')
            exit()
print('No')
# Original solution
def main():
    N, M, K = list(map(int, input().split()))

    for n in range(N + 1):
        for m in range(M + 1):
            overlap = 2 * n * m
            cnt = n * M + m * N - overlap
            if cnt == K:
                print("Yes")
                return
    else:
        print("No")
        return


main()


# Optimized solution
import sys

sys.setrecursionlimit(10 ** 6)
INF = float("inf")
MOD = 10 ** 9 + 7


def input():
    return sys.stdin.readline().strip()


def main():
    N, M, K = list(map(int, input().split()))
    for n in range(N + 1):
        for m in range(M + 1):
            num = N * m + M * n - 2 * m * n
            if K == num:
                print("Yes")
                return

    print("No")
    return


if __name__ == "__main__":
    main()