Given coin denominations `coins` (unlimited supply of each) and an `amount`, return the fewest coins needed to make up that amount, or -1 if it is impossible.