To solve this optimization problem, we first need to define the decision variables and the objective function. Let's denote:

- \(x\) as the number of reams of lined paper produced.
- \(y\) as the number of reams of unlined paper produced.

The profit from selling \(x\) reams of lined paper is $5\(x\), and the profit from selling \(y\) reams of unlined paper is $3\(y\). Therefore, the total profit \(P\) can be represented by the objective function:

\[ P = 5x + 3y \]

We aim to maximize this profit.

Next, we need to consider the constraints. Each machine has a limited availability of 400 minutes per day.

- For the printing machine, it takes 2 minutes to produce a ream of lined paper and 1 minute for a ream of unlined paper. Thus, the constraint can be written as:
\[ 2x + y \leq 400 \]
- For the scanning machine, it takes 5 minutes for a ream of lined paper and 2 minutes for a ream of unlined paper. So, the constraint is:
\[ 5x + 2y \leq 400 \]

Additionally, \(x\) and \(y\) must be non-negative since they represent quantities of products.

Now, let's translate this problem into Gurobi code in Python:

```python
from gurobipy import *

# Create a new model
model = Model("Paper Production")

# Define the decision variables
x = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="lined_paper")
y = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="unlined_paper")

# Define the objective function: Maximize profit
model.setObjective(5*x + 3*y, GRB.MAXIMIZE)

# Add constraints
model.addConstr(2*x + y <= 400, "printing_machine")
model.addConstr(5*x + 2*y <= 400, "scanning_machine")

# Optimize the model
model.optimize()

# Print the results
if model.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Produce {x.x} reams of lined paper")
    print(f"Produce {y.x} reams of unlined paper")
    print(f"Maximum profit: ${model.objVal}")
else:
    print("No optimal solution found")

```