The CPU time limit is a cumulative limit across the whole transaction. Essentially, what is happening is that your Flow, plus your Process invocations, plus the NPSP triggers that are run consequent upon the updates you are making, are taking too long to execute in a single transaction (10 seconds of CPU time).
Because the CPU time limit is a cumulative limit, it can be really tricky to put your finger on the cause without careful profiling using the Developer Console. What you see in any logs you might look at following the error is often just the proverbial straw that killed the camel, not the root cause.
Here, I feel fairly confident in saying that this is related to the volume of data that you are trying to update. You've got some moderately large number of Accounts in this Tier, and those Accounts have some number of Opportunities each. Triggers have to run on the updates of all of those records, and that consumes time.
The ultimate fix would probably be to move this functionality to a Batch Apex class, where you have considerably more control over which functionality runs when and can batch your data volume across multiple transactions. Given your client restrictions, I understand the Flow, but I think the result is going to push you to push the client to change their minds.
I previously wrote up an answer about using Wait events to segment a Flow into multiple transactions, and I think that might be something you could apply here.
My proposal - and I will admit that I've only tried this at a PoC level in my own org, and the success or failure will be pretty specific to your Flow - is that your Step 3 is the best place to intervene:
Next, the flow finds all Accounts with the same Tier and updates a Price Book lookup field to match the Price Book that was just found.
Since Accounts are changed after they've passed through this step, I think you could use a Wait element in a loop to query batches of Accounts, update them, Wait to start a new transaction, and then do the next batch.
Get Records in Flow doesn't support a
LIMIT clause on its query, which makes this dramatically more difficult. The way I did it was to initialize a Text collection variable with letters of the alphabet, and query Accounts in a loop over that collection using a Starts With condition. Then a Wait skips to a new transaction after each letter.
Here's a rough outline:
Your actual Flow may need to use finer-grained criteria in its loop to break the transactions into small enough pieces. And, as cropredy rightly points out, it's assuming that breaking along Account lines will be enough. It might not be. If one Account has hundreds of Opportunities (or even dozens of Opportunities - in some orgs it doesn't take that much to bounce off the CPU time limiter), chunking by Accounts might not fix the issue anyway.
Honestly, this is a hideous solution. It's clunky as all get out, I don't think the performance will be very good, and it's not all that maintainable like a Flow should be because it's trying to handle data volume that's way too high. Plus, there's a high probability something will change down the road that'll result in the client coming back to complain about new limits problems.
A better solution would be a well-architected, configurable batch process that invokes declarative automation to run smaller pieces of functionality. I would try hard to sell that to the client myself.