#include <cstdint>
#include <vector> // factoring

namespace Integer {
  using Int = std::int_fast64_t;
  using Vec = std::vector<Int>;
  template<typename T, Int N> struct Seq {
    T ary[N];
    constexpr Seq() : ary{} {};
    constexpr T& operator[](Int n) { return ary[n]; }
    constexpr T const& operator[](Int n) const { return ary[n]; }
    constexpr Int size() const { return N; }
  };

  namespace RunTime {
    constexpr Int Max = 1e6+7;

    Vec a{0, 1, 2};
    Vec p{2};

    inline void init(Int const& n=Max) {
      if(Max < n || n <= (Int)a.size()) return;
      const Int m = (Int)a.size();
      a.resize(n);
      for(Int i=m; i<n; ++i) a[i] = i;
      for(Int i=2; i*i<n; ++i) {
        if(a[i] < i) continue;
        for(Int j=(m/i<i?m/i:i)*i; j<n; j+=i) if(a[j] == j) a[j] = i;
      }
      for(Int i=m; i<n; ++i) if(a[i] == i) p.push_back(i);
    }

    inline Int min_divisor(Int const& n) {
      init(n+1);
      if(n < Max) return a[n];
      if(n > (Max-1)*(Max-1)) return 0;
      for(Int i=0; i<(Int)p.size(); ++i) if(n % p[i] == 0) return p[i];
      return n;
    }

    inline bool is_prime(Int const& n) {
      return n == min_divisor(n);
    }

    inline auto factoring(Int n) {
      Vec res{};
      while(n>1) {
        res.push_back(min_divisor(n));
        n /= res.back();
      }
      return res;
    }
  }

  namespace ConstExpr {
    constexpr Int Max = 1e5+7;

    template<Int M=Max> constexpr auto osk_a() {
      Seq<Int, M> res{};
      for(Int i=0; i<M; ++i) res.ary[i] = i;
      for(Int i=2; i*i<M; ++i) {
        if(res.ary[i] < i) continue;
        for(Int j=i*i; j<M; j+=i) if(res.ary[j] == j) res.ary[j] = i;
      }
      return res;
    }
    constexpr auto a = osk_a();

    template<typename S=decltype(a), S& s=a> constexpr Int prime_count() {
      Int cnt = 0;
      for(Int i=2; i<s.size(); ++i) if(s.ary[i] == i) ++cnt;
      return cnt;
    }
    constexpr Int PC = prime_count();

    template<typename S=decltype(a), S& s=a, Int N=PC> constexpr auto prime_list() {
      Seq<Int, N> res{};
      for(Int i=0,j=2; j<s.size(); ++j) if(s.ary[j] == j) res.ary[i++] = j;
      return res;
    }
    constexpr auto p = prime_list();

    template<typename S1=decltype(a), S1& s=a, typename S2=decltype(p), S2& q=p> constexpr Int min_divisor(Int const& n) {
      if(n < s.size()) return s.ary[n];
      if(n > (s.size()-1)*(s.size()-1)) return 0;
      for(Int i=0; i<q.size(); ++i) if(n % q.ary[i] == 0) return q.ary[i];
      return n;
    }

    template<typename S1=decltype(a), S1& s=a, typename S2=decltype(p), S2& q=p> constexpr bool is_prime(Int const& n) {
      return n == min_divisor<S1, s, S2, q>(n);
    }

    template<typename S1=decltype(a), S1& s=a, typename S2=decltype(p), S2& q=p> inline auto factoring(Int n) {
      std::vector<Int> res{};
      while(n>1) {
        res.push_back(min_divisor<S1, s, S2, q>(n));
        n /= res.back();
      }
      return res;
    }
  }

}

#include <iostream>
#include <utility>

template<typename T> constexpr T gcd2(T a, T b) { while(b) { T t=b; b=a%b; a=t; } return a; }
template<class C> inline auto RLE(C const& v) { // run length encoding
  using T = typename C::value_type;
  using U = typename C::size_type;
  std::vector<std::pair<T, U>> w{};
  auto t=std::begin(v);
  U cnt=0;
  for(auto i=std::begin(v); i!=std::end(v); ++i) {
    if(*t == *i) ++cnt;
    else w.emplace_back(*t, cnt), t=i, cnt=1;
  }
  if(cnt > 0) w.emplace_back(*t, cnt);
  return w;
}

signed main() {
  using namespace std;
  cin.tie(0); cout.tie(0);
  ios_base::sync_with_stdio(false);
  cout << boolalpha;

  constexpr int n = 101;
  static_assert(Integer::ConstExpr::is_prime(n), "n is not prime");

  Integer::RunTime::init();

  Integer::Int A, B;
  cin >> A >> B;
  const auto D = gcd2(A, B);
  const auto L = RLE(Integer::RunTime::factoring(D));
  int cnt = 1 + L.size();
  cout << cnt << endl;

  return 0;
}

Measured memory_bytes: 9336