// doot diddly donger cuckerino Hahahahahah


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx")
#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace __gnu_cxx;
using namespace std;

using ll = long long;
using ld = long double;
using pll = pair<ll, ll>;
using vi = vector<int>;

template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

const ld PI = acos(-1);

template <typename T> inline T mini(T& x, T y) { return x = min(x, y); }
template <typename T> inline T maxi(T& x, T y) { return x = max(x, y); }
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());







#ifdef LOCAL
void signalHandler(int) {
  throw "Abort detected";
}
#endif

void doReplace() {
}

template <typename T, typename U, typename...Vs>
void doReplace(T &t, const U &u, Vs &&...vs) {
  t = u;
  doReplace(vs...);
}

template <typename T, typename...Us>
T minim(T &was, const T &cand, Us &&...us) {
  if (was > cand) {
    was = cand;
    doReplace(us...);
  }
  return was;
}

template <typename T, typename...Us>
T maxim(T &was, const T &cand, Us &&...us) {
  if (was < cand) {
    was = cand;
    doReplace(us...);
  }
  return was;
}

template <typename T>
T gcd(T a, T b) {
  a = abs(a);
  b = abs(b);
  while (b != 0) {
    a = a % b;
    swap(a, b);
  }
  return a;
}

template <typename T>
T lcm(T a, T b) {
  return a / gcd(a, b) * b;
}

template <typename T>
T power(const T& a, long long b) {
  if (b == 0) {
    return 1;
  }
  if ((b & 1) == 0) {
    T res = power(a, b >> 1);
    return res * res;
  } else {
    return power(a, b - 1) * a;
  }
}

long long power(long long a, long long b, long long mod) {
  long long res = 1;
  while (b) {
    if (b & 1) {
      res = (res * a) % mod;
    }
    a = (a * a) % mod;
    b /= 2;
  }
  return res;
}

template <typename T>
T factorial(int n) {
  T result = 1;
  for (int i = 2; i <= n; i++) {
    result *= i;
  }
  return result;
}

template <typename T>
std::vector<T> factorials(int length) {
  std::vector<T> result(length);
  if (length > 0) {
    result[0] = 1;
  }
  for (int i = 1; i < length; i++) {
    result[i] = result[i - 1] * i;
  }
  return result;
}

template <typename T>
std::vector<T> powers(T base, int length) {
  std::vector<T> result(length);
  if (length > 0) {
    result[0] = 1;
  }
  for (int i = 1; i < length; i++) {
    result[i] = result[i - 1] * base;
  }
  return result;
}


struct Sieve {
  int maxn;
public:
  std::vector<long long> spf;
  std::vector<long long> primes;
  std::vector<long long> mobius;
  std::vector<long long> phi;
  std::vector<bool> isPrime;
  
  Sieve(int _n = 2e6 + 7) : maxn(_n + 1) {
    spf.resize(maxn, 1);
    isPrime.resize(maxn, true);
    primes.clear();
    
    isPrime[0] = isPrime[1] = false;
    
    for (long long i = 2; i < maxn; ++i) {
      if (isPrime[i]) {
        primes.push_back(i);
        spf[i] = i;
      }
      for (long long j = 0; j < (int) primes.size() && (i * primes[j]) < maxn && primes[j] <= spf[i]; ++j) {
        isPrime[i * primes[j]] = false;
        spf[i * primes[j]] = primes[j];
      }
    }
  }
  
  void genPhi() {
    phi.resize(maxn + 1, 0);
    phi[1] = 1;
    for (int i = 2; i <= maxn; i++) phi[i] = i - 1;
    
    for (int i = 2; i <= maxn; i++)
      for (int j = 2 * i; j <= maxn; j += i)
        phi[j] -= phi[i];
  }
  
  void genMobius() {
    mobius.clear();
    mobius.resize(maxn, 0);
    mobius[1] = 1;
    for (ll i = 2; i < maxn; ++i) {
      if (spf[i / spf[i]] == spf[i]) {
        mobius[i] = 0;
      } else {
        mobius[i] = -mobius[i / spf[i]];
      }
    }
  }
  
  long long nextPrime(long long x, bool strict = false) {
    auto it = upper_bound(primes.begin(), primes.end(), x);
    if (!strict and isPrime[x]) return x;
    next(it);
    return *it;
  }
  
  long long numDivisors(long long val) {
    auto div = primeFactors(val);
    long long ans = 1;
    for (const auto& p: div) {
      ans *= p.second + 1;
    }
    return ans;
  }
  
  long long countDivisors(long long n) {
    if (n == 1) return 1;
    long long ans = 1;
    for (int i = 0;; i++) {
      if (primes[i] * primes[i] * primes[i] > n) break;
      int cnt = 1;
      while (n % primes[i] == 0) {
        n /= primes[i];
        cnt++;
      }
      ans *= cnt;
    }
    
    if (isPrime[n])
      ans = ans * 2;
    else if (isPrime[sqrt(n)] && (long long) sqrt(n) == sqrt(n))
      ans = ans * 3;
    else if (n != 1)
      ans = ans * 4;
    return ans;
  }
  
  vector<pll> divisorPair(long long x) {
    vector<pll> res;
    for (long long i = 1; i * i <= x; i++) {
      if (x % i == 0) {
        if (x / i == i) {
          res.emplace_back(i, i);
        } else {
          res.emplace_back(i, x / i);
        }
      }
    }
    return res;
  }
  
  map<long long, long long> primeFactors(ll val) {
    if (val >= maxn) return primeFactorBrute(val);
    map<long long, long long> fac;
    while (val > 1) {
      int pf = spf[val];
      ll cnt = 0;
      while (val % pf == 0) {
        cnt++;
        val /= pf;
      }
      fac[pf] = cnt;
    }
    return fac;
  }
  
  map<long long, long long> primeFactorBrute(ll val) {
    map<long long, long long> mp;
    for (ll i = 2; i * i <= val; i += 2) {
      while (val % i == 0) {
        mp[i]++;
        val /= i;
      }
    }
    if (val > 2) {
      mp[val]++;
    }
    return mp;
  }
  
  set<long long> divisorsBrute(long long val) {
    set<long long> res;
    for (long long i = 1; i * i <= val; i++) {
      if (val % i == 0) {
        if ((val / i) == i) {
          res.insert(i);
        } else {
          res.insert(i);
          res.insert(val / i);
        }
      }
    }
    return res;
  }
};


class DDisjointSetOfCommonDivisors {
public:
  
  void solve(std::istream& cin, std::ostream& cout) {
    ll a, b;
    cin >> a >> b;
    Sieve sieve;
    ll g = gcd(a, b);
    int cnt = 0;
    for (auto p: sieve.primes) {
      if (g % p == 0) ++cnt;
      while (g % p == 0) g /= p;
    }
    if (g != 1) ++cnt;
    cout << cnt + 1 << endl;
  }
};

int32_t main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
	DDisjointSetOfCommonDivisors solver;
	std::istream& in(std::cin);
	std::ostream& out(std::cout);
	solver.solve(in, out);
	return 0;
}


Measured memory_bytes: 21208