Buggy python submission (verdict: Time Limit Exceeded):
def main():
  import sys
  sys.setrecursionlimit(10**7)
  N,W=list(map(int,sys.stdin.readline().split()))

  dp=[[0]*N for _ in range(W+1)]#W*N

  WL=[0]* N
  VL=[0]*N

  for i in range(N):
      w,v=list(map(int,sys.stdin.readline().split()))
      WL[i]=w
      VL[i]=v


  def dfs(W,i):
      if i==N:
          return 0
      if dp[W][i]:
          return dp[W][i]
      if W-WL[i]>=0:
          dp[W][i]=max(dfs(W,i+1),dfs(W-WL[i],i+1)+VL[i])
          return dp[W][i]
      else:
          dp[W][i]=dfs(W,i+1)
          return dp[W][i]

  print(dfs(W,0))

main()


Fixed submission:
def main():
    import sys
    sys.setrecursionlimit(10**7)
    N,W=list(map(int,sys.stdin.readline().split()))

    dp=[[0]*(W+1) for _ in range(N+1)]#N*W

    WL=[0]*N
    VL=[0]*N

    for i in range(N):
        w,v=list(map(int,sys.stdin.readline().split()))
        WL[i]=w
        VL[i]=v

    for i in range(1,N+1):
        for w in range(1,W+1):
            if w>=WL[i-1]:
                a=dp[i-1][w-WL[i-1]]+VL[i-1]
                b=dp[i-1][w]
                dp[i][w]=max(a,b)
            else:
                dp[i][w]=dp[i-1][w]
    print(dp[-1][-1])
main()

Buggy python submission (verdict: Time Limit Exceeded):
def main():
  import sys
  sys.setrecursionlimit(10**7)
  N,W=list(map(int,sys.stdin.readline().split()))

  dp=[[0]*N for _ in range(W+1)]#W*N

  WL=[0]* N
  VL=[0]*N

  for i in range(N):
      w,v=list(map(int,sys.stdin.readline().split()))
      WL[i]=w
      VL[i]=v


  def dfs(W,i):
      if i==N:
          return 0
      if dp[W][i]:
          return dp[W][i]
      if W-WL[i]>=0:
          dp[W][i]=max(dfs(W,i+1),dfs(W-WL[i],i+1)+VL[i])
          return dp[W][i]
      else:
          dp[W][i]=dfs(W,i+1)
          return dp[W][i]

  print(dfs(W,0))

main()

Fixed submission:
def main():
    import sys
    sys.setrecursionlimit(10**7)
    N,W=list(map(int,sys.stdin.readline().split()))

    dp=[[0]*(W+1) for _ in range(N+1)]#N*W

    WL=[0]*N
    VL=[0]*N

    for i in range(N):
        w,v=list(map(int,sys.stdin.readline().split()))
        WL[i]=w
        VL[i]=v

    for i in range(1,N+1):
        for w in range(1,W+1):
            if w>=WL[i-1]:
                a=dp[i-1][w-WL[i-1]]+VL[i-1]
                b=dp[i-1][w]
                dp[i][w]=max(a,b)
            else:
                dp[i][w]=dp[i-1][w]
    print(dp[-1][-1])
main()

Buggy python submission (verdict: Time Limit Exceeded):
import sys
sys.setrecursionlimit(10**7)
N,W=list(map(int,sys.stdin.readline().split()))

dp=[[0]*N for _ in range(W+1)]#W*N

WL=[0]* N
VL=[0]*N

for i in range(N):
    w,v=list(map(int,sys.stdin.readline().split()))
    WL[i]=w
    VL[i]=v


def dfs(W,i):
    if i==N:
        return 0
    if dp[W][i]:
        return dp[W][i]
    if W-WL[i]>=0:
        dp[W][i]=max(dfs(W,i+1),dfs(W-WL[i],i+1)+VL[i])
        return dp[W][i]
    else:
        dp[W][i]=dfs(W,i+1)
        return dp[W][i]

print(dfs(W,0))

Fixed submission:
def main():
    import sys
    sys.setrecursionlimit(10**7)
    N,W=list(map(int,sys.stdin.readline().split()))

    dp=[[0]*(W+1) for _ in range(N+1)]#N*W

    WL=[0]*N
    VL=[0]*N

    for i in range(N):
        w,v=list(map(int,sys.stdin.readline().split()))
        WL[i]=w
        VL[i]=v

    for i in range(1,N+1):
        for w in range(1,W+1):
            if w>=WL[i-1]:
                a=dp[i-1][w-WL[i-1]]+VL[i-1]
                b=dp[i-1][w]
                dp[i][w]=max(a,b)
            else:
                dp[i][w]=dp[i-1][w]
    print(dp[-1][-1])
main()