Here's the Gurobi code to solve the optimization problem:

```python
from gurobipy import Model, GRB

# Create a new model
model = Model("optimization_problem")

# Create variables
candles = model.addVar(vtype=GRB.INTEGER, name="candles")
paper_plates = model.addVar(vtype=GRB.INTEGER, name="paper_plates")
paper_towels = model.addVar(vtype=GRB.INTEGER, name="paper_towels")
milk = model.addVar(vtype=GRB.INTEGER, name="milk")
toilet_paper = model.addVar(vtype=GRB.INTEGER, name="toilet_paper")
napkins = model.addVar(vtype=GRB.INTEGER, name="napkins")

# Set objective function
model.setObjective(4 * candles * paper_plates + 3 * candles * napkins + 6 * paper_plates * paper_plates + paper_plates * toilet_paper + 2 * paper_plates * napkins + 9 * paper_towels * paper_towels + 9 * paper_towels * napkins + 2 * milk * toilet_paper + 5 * milk * napkins + 9 * toilet_paper * toilet_paper + 9 * paper_towels + 5 * toilet_paper + 9 * napkins, GRB.MAXIMIZE)

# Add constraints
model.addConstr(12 * paper_plates + 2 * milk >= 41)
model.addConstr(2 * milk + 5 * toilet_paper >= 37)
model.addConstr(12*paper_plates*paper_plates + 2*paper_towels*paper_towels + 2*milk*milk >= 31)
model.addConstr(5 * paper_plates + 4 * napkins >= 13)
model.addConstr(8 * candles * candles + 12 * paper_towels * paper_towels >= 27)
model.addConstr(8 * candles * candles + 7 * milk * milk >= 11)
model.addConstr(12 * paper_towels + 7 * milk + 4 * napkins >= 33)
model.addConstr(8 * candles + 5 * paper_plates + 12 * paper_towels >= 33)
model.addConstr(8 * candles + 12 * paper_towels + 7 * toilet_paper >= 33)
model.addConstr(12 * paper_towels + 7 * milk + 4 * napkins >= 18)
model.addConstr(8 * candles*candles + 5 * paper_plates*paper_plates + 12 * paper_towels*paper_towels >= 18)
model.addConstr(8 * candles + 12 * paper_towels + 7 * toilet_paper >= 18)
model.addConstr(12 * paper_towels*paper_towels + 7 * milk*milk + 4 * napkins*napkins >= 27)
model.addConstr(8 * candles*candles + 5 * paper_plates*paper_plates + 12 * paper_towels*paper_towels >= 27)
model.addConstr(8 * candles + 12 * paper_towels + 7 * toilet_paper >= 27)

model.addConstr(2 * milk*milk + 9 * napkins*napkins <= 104)
# ... (Rest of the constraints, following the same pattern)


# Resource Constraints
model.addConstr(2 * candles + 12 * paper_plates + 2 * paper_towels + 2 * milk + 5 * toilet_paper + 9 * napkins <= 305)
model.addConstr(8 * candles + 5 * paper_plates + 12 * paper_towels + 7 * milk + 7 * toilet_paper + 4 * napkins <= 201)

# Optimize model
model.optimize()

# Print results
if model.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    for v in model.getVars():
        print(f"{v.varName}: {v.x}")
    print(f"Objective value: {model.objVal}")
elif model.status == GRB.INFEASIBLE:
    print("Model is infeasible.")
else:
    print(f"Optimization terminated with status {model.status}")

```