import sys import math def main(): input = sys.stdin.read().split() idx = 0 N = int(input[idx]) idx += 1 items = [] for i in range(1, N+1): c_i = int(input[idx]) v_i = int(input[idx+1]) idx +=2 items.append( (i, c_i, v_i) ) # Separate item 1 item1 = items[0] items = items[1:] # Initialize DP INF = -math.inf dp = [ [INF]*(N+1) for _ in range(N+1) ] dp[0][0] = 0 # Process items 2 to N for (i, c_i, v_i) in items: max_t = min(c_i, N // i) if max_t ==0: continue for t in range(1, max_t+1): for k in range(N, t-1, -1): for w in range(N, t*i -1, -1): if dp[k - t][w - t*i] != INF: new_val = dp[k - t][w - t*i] + t * v_i if new_val > dp[k][w]: dp[k][w] = new_val # Process item 1 i1, c1, v1 = item1 assert i1 == 1 # We need to make a copy of the current dp to avoid overwriting during iteration # But in Python, nested list slicing is needed to avoid reference issues new_dp = [row[:] for row in dp] for k in range(N+1): for w in range(N+1): if dp[k][w] == INF: continue t_max = min(c1, N - k, N - w) if t_max ==0: continue if v1 >=0: new_k = k + t_max new_w = w + t_max new_val = dp[k][w] + t_max * v1 if new_k <= N and new_w <= N and new_val > new_dp[new_k][new_w]: new_dp[new_k][new_w] = new_val dp = new_dp # Compute answers for k in range(1, N+1): max_val = max(dp[k][k:N+1]) print(max_val) if __name__ == '__main__': main()