(Adapted from UWCSE501)