Full solution -- credit to Jason Hill for helping