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

```python
import gurobipy as gp

# Create a new model
m = gp.Model("Work_Hour_Optimization")

# Create variables
laura_hours = m.addVar(lb=0, name="laura_hours")
paul_hours = m.addVar(lb=0, name="paul_hours")
bill_hours = m.addVar(lb=0, name="bill_hours")
mary_hours = m.addVar(lb=0, name="mary_hours")

# Set objective function
m.setObjective(9 * laura_hours + 6 * paul_hours + 5 * bill_hours + 3 * mary_hours, gp.GRB.MAXIMIZE)

# Add constraints
m.addConstr(10 * laura_hours + 14 * mary_hours >= 46, "c1")
m.addConstr(10 * laura_hours + 6 * bill_hours >= 49, "c2")
m.addConstr(12 * paul_hours + 6 * bill_hours + 14 * mary_hours >= 30, "c3")
m.addConstr(8 * paul_hours + 3 * mary_hours >= 47, "c4")
m.addConstr(9 * laura_hours + 12 * bill_hours + 3 * mary_hours >= 49, "c5")
m.addConstr(7 * laura_hours + 9 * bill_hours >= 66, "c6")
m.addConstr(14 * paul_hours + 9 * bill_hours >= 27, "c7")
m.addConstr(9 * bill_hours + 1 * mary_hours >= 47, "c8")

m.addConstr(10 * laura_hours + 6 * bill_hours <= 142, "c9")
m.addConstr(12 * paul_hours + 14 * mary_hours <= 232, "c10")
m.addConstr(12 * paul_hours + 6 * bill_hours <= 153, "c11")
m.addConstr(10 * laura_hours + 6 * bill_hours + 14 * mary_hours <= 172, "c12")
m.addConstr(10 * laura_hours + 12 * paul_hours + 6 * bill_hours <= 138, "c13")
m.addConstr(10 * laura_hours + 12 * paul_hours + 6 * bill_hours + 14 * mary_hours <= 138, "c14")

m.addConstr(6 * laura_hours + 7 * bill_hours <= 129, "c15")
m.addConstr(6 * laura_hours + 8 * paul_hours <= 179, "c16")
m.addConstr(6 * laura_hours + 11 * mary_hours <= 195, "c17")
m.addConstr(8 * paul_hours + 11 * mary_hours <= 240, "c18")
m.addConstr(8 * paul_hours + 7 * bill_hours <= 164, "c19")
m.addConstr(8 * paul_hours + 7 * bill_hours + 11 * mary_hours <= 174, "c20")
m.addConstr(6 * laura_hours + 8 * paul_hours + 7 * bill_hours + 11 * mary_hours <= 174, "c21")

m.addConstr(8 * paul_hours + 12 * bill_hours <= 177, "c22")
m.addConstr(8 * paul_hours + 3 * mary_hours <= 185, "c23")
m.addConstr(9 * laura_hours + 8 * paul_hours + 12 * bill_hours + 3 * mary_hours <= 185, "c24")

m.addConstr(7 * laura_hours + 9 * bill_hours <= 272, "c25")
m.addConstr(9 * bill_hours + 1 * mary_hours <= 146, "c26")
m.addConstr(14 * paul_hours + 1 * mary_hours <= 222, "c27")
m.addConstr(7 * laura_hours + 14 * paul_hours + 9 * bill_hours + 1 * mary_hours <= 222, "c28")


# Optimize model
m.optimize()

# Print results
if m.status == gp.GRB.OPTIMAL:
    print('Obj: %g' % m.objVal)
    for v in m.getVars():
        print('%s %g' % (v.varName, v.x))
elif m.status == gp.GRB.INFEASIBLE:
    print("The model is infeasible.")
else:
    print("Optimization ended with status %d" % m.status)

```
