greatest common divisor algorithm