Introduction to the Theory of Computation 3rd Edition by Michael Sipser