PASCAL = Array.new(21) { Array.new(21, 0i64) } PASCAL.size.times do |i| PASCAL[i][0] = PASCAL[i][i] = 1i64 end PASCAL.size.times do |i| 1.upto(i - 1) do |j| PASCAL[i][j] = PASCAL[i - 1][j] + PASCAL[i - 1][j - 1] end end a, b = read_line.split.map(&.to_i64) c = a.gcd(b) d = 2i64 cnt = 0 while c > 1 && d < 10_000_000 if c % d == 0 while c % d == 0 c //= d end cnt += 1 end d += 1 end if c > 1 sq = (c ** 0.5).to_i64 while sq * sq < c sq += 1 end if sq * sq == c cnt += 1 c = 1 end end if c > 1 if miller_rabin(c) cnt += 1 else cnt += 2 end end ans = 0i64 0.upto(cnt) do |i| ans += PASCAL[cnt][i] * (i % 2 == 0 ? 1 : -1) end puts ans def miller_rabin(n) return true if n == 2 return false if n % 2 == 0 || n == 1 if n < 4759123141i64 test = [2i64, 7i64, 61i64] elsif n < 341550071728321i64 test = [2i64, 3i64, 5i64, 7i64, 11i64, 13i64, 17i64] else test = [2i64, 3i64, 5i64, 7i64, 11i64, 13i64, 17i64, 19i64, 23i64, 29i64, 31i64, 37i64, 41i64, 43i64, 47i64] end s = (n - 1).trailing_zeros_count d = (n - 1) >> s return !test.any? do |a| y = pow(a.to_i128, d, n) is_composite = y != 1 if is_composite (s - 1).times do if y == n - 1 is_composite = false break end y = y * y % n end if y == n - 1 is_composite = false end end is_composite end end def pow(v, p, mod) ret = 1i128 while p > 0 if (p & 1i64) != 0 ret *= v ret %= mod end v *= v v %= mod p >>= 1 end ret end