Code from http://www.ark.cs.cmu.edu/mheilman/questions/