import sys def main(): input = sys.stdin.read().split() ptr = 0 N = int(input[ptr]) ptr += 1 c = [] v = [] for _ in range(N): ci = int(input[ptr]) vi = int(input[ptr+1]) c.append(ci) v.append(vi) ptr += 2 # Initialize DP for other items (excluding the first item) dp_other = [[-float('inf')] * (N + 1) for _ in range(N + 1)] dp_other[0][0] = 0 # Process items from 2 to N (index 1 to N-1 in the list) for i in range(1, N): current_i = i + 1 # weight is i+1 as per problem statement current_c = c[i] current_v = v[i] max_t = min(current_c, N // current_i) if max_t == 0: continue # cannot take any of this item # Binary decomposition s = 1 remaining = max_t while remaining > 0: take = min(s, remaining) weight = take * current_i value = take * current_v # Update DP in reverse to avoid overwriting for k in range(N, take - 1, -1): for w in range(N, weight - 1, -1): if dp_other[k - take][w - weight] != -float('inf'): if dp_other[k][w] < dp_other[k - take][w - weight] + value: dp_other[k][w] = dp_other[k - take][w - weight] + value remaining -= take s *= 2 # Preprocess max_val[k][w] which is the maximum value for k items with weight <= w max_val = [[-float('inf')] * (N + 1) for _ in range(N + 1)] for k in range(N + 1): current_max = -float('inf') for w in range(N + 1): if dp_other[k][w] > current_max: current_max = dp_other[k][w] max_val[k][w] = current_max # Process the first item (weight 1, count c[0] = N) v1 = v[0] ans = [-float('inf')] * (N + 1) for k in range(1, N + 1): max_total = -float('inf') for k_prime in range(0, k + 1): t = k - k_prime w_max = N - t if w_max < 0: continue w_max = min(w_max, N) current_max = max_val[k_prime][w_max] if current_max == -float('inf'): continue total = current_max + t * v1 if total > max_total: max_total = total ans[k] = max_total for k in range(1, N + 1): print(ans[k]) if __name__ == '__main__': main()