// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

typedef pair<int,int> P;

typedef long long ll;

typedef vector<int> vi;

typedef vector<ll> vll;

#define pb push_back

#define mp make_pair

#define eps 1e-9

#define INF 2000000000

#define LLINF 1000000000000000ll

#define sz(x) ((int)(x).size())

#define fi first

#define sec second

#define all(x) (x).begin(),(x).end()

#define sq(x) ((x)*(x))

#define rep(i,n) for(int (i)=0;(i)<(int)(n);(i)++)

#define repn(i,a,n) for(int (i)=(a);(i)<(int)(n);(i)++)

#define EQ(a,b) (abs((a)-(b))<eps)

#define dmp(x) cerr << __LINE__ << " " << #x << " " << x << endl;

template<class T> void chmin(T& a,const T& b){if(a>b)a=b;}

template<class T> void chmax(T& a,const T& b){if(a<b)a=b;}

template<class T>

using MaxHeap = priority_queue<T>;

template<class T>

using MinHeap = priority_queue<T,vector<T>,greater<T> >;

template<class T,class U>

ostream& operator << (ostream& os,pair<T,U>& p){

  os << p.fi << ',' << p.sec; return os;

}

template<class T,class U>

istream& operator >> (istream& is,pair<T,U>& p){

  is >> p.fi >> p.sec; return is;

}

template<class T>

ostream& operator << (ostream &os,const vector<T> &vec){

  for(int i=0;i<vec.size();i++){

    os << vec[i];

    if(i+1<vec.size())os << ' ';

  }

  return os;

}

template<class T>

istream& operator >> (istream &is,vector<T>& vec){

  for(int i=0;i<vec.size();i++)is >> vec[i];

  return is;

}

void fastio(){

  cin.tie(0);

  ios::sync_with_stdio(0);

  cout<<fixed<<setprecision(20);

}

const ll MOD = 1000000007ll; // if inv is needed, this shold be prime.

struct ModInt{

	ll val;

	ModInt():val(0ll){}

	ModInt(const ll& v):val(((v%MOD)+MOD)%MOD){}

	ModInt exp(ll y)const{

		if(!y)return ModInt(1ll);

		ModInt a = exp(y/2ll);

		a *= a;

		if(y&1)a*=(*this);

		return a;

	}

	bool operator==(const ModInt& x)const{return val==x.val;}

	inline bool operator!=(const ModInt& x)const{return !(*this==x);}

	bool operator<(const ModInt& x)const{return val<x.val;}

	bool operator>(const ModInt& x)const{return val>x.val;}

	inline bool operator>=(const ModInt& x)const{return !(*this<x);}

	inline bool operator<=(const ModInt& x)const{return !(*this>x);}

	ModInt& operator+=(const ModInt& x){if((val+=x.val)>=MOD)val-=MOD;return *this;}

	ModInt& operator-=(const ModInt& x){if((val+=MOD-x.val)>=MOD)val-=MOD;return *this;}

	ModInt& operator*=(const ModInt& x){(val*=x.val)%=MOD;return *this;}

	ModInt operator+(const ModInt& x)const{return ModInt(*this)+=x;}

	ModInt operator-(const ModInt& x)const{return ModInt(*this)-=x;}

	ModInt operator*(const ModInt& x)const{return ModInt(*this)*=x;}

  friend istream& operator>>(istream&i,ModInt& x){ll v;i>>v;x=v;return i;}

  friend ostream& operator<<(ostream&o,ModInt& x){o<<x.val;return o;}

  ModInt pow(ModInt a,ll x) const {

    ModInt res = ModInt(1ll);

    while(x){

      if(x&1)res *= a;

      x >>= 1;

      a = a*a;

    }

    return res;

  }

};

vector<ModInt> inv,fac,facinv;

// notice: 0C0 = 1 

ModInt nCr(int n,int r){

	assert(!(n<r));

	assert(!(n<0||r<0));

	return fac[n]*facinv[r]*facinv[n-r];

}

void init(int SIZE){

  fac.resize(SIZE+10);

  inv.resize(SIZE+10);

  facinv.resize(SIZE+10);

	fac[0]=ModInt(1ll);

	for(int i=1;i<=SIZE;i++)fac[i]=fac[i-1]*ModInt(i);

	inv[1]=ModInt(1ll);

	for(int i=2;i<=SIZE;i++)inv[i]=ModInt(0ll)-ModInt(MOD/i)*inv[MOD%i];

	facinv[0]=ModInt(1ll);

	for(int i=1;i<=SIZE;i++)facinv[i]=facinv[i-1]*inv[i];

	return;

}

ll A,B;

ll mygcd(ll a,ll b){

  if(b==0ll)return a;

  else return mygcd(b,a%b);

}

int main(){

  fastio();

  cin >> A >> B;

  ll g = mygcd(A,B);  

  int ans = 1;

  for(ll i=2ll;i*i<=g;i++){

    if(g%i==0ll){

      while(g%i==0ll)g/=i;

      ans++;

    }

  }

  if(g!=1ll)ans++;

  cout << ans << endl;

  return 0;

}


// Optimized solution to the same problem (faster):
#include <stdio.h>

 

long long int gcd(long long int x, long long int y)

{

  while(x > 0 && y > 0) {

    if(x > y) {

      x = x - y;

    }

    else {

      y = y - x;

    }

  }

 

  if(x == 0) {

    return y;

  }

  else {

    return x;

  }

}

 

long long int approximate_sqrt(long long int x)

{

  long long int root = x/4;

 

  if(x <= 3) {

    return 1;

  }

  

  while(1) {

    root = (root + (x / root)) / 2;

 

    if(root * root <= x && x <= (root+1) * (root+1)) {

      return root;

    }

  }

}

 

int number_of_factors(long long int x)

{

  long long int root_x = approximate_sqrt(x);

  long long int x_iter = x;

  int num = 0;

 

  if(x == 1) {

    return 0;

  }

 

  if(x_iter % 2 == 0) {

    num++;

  }

  while(x_iter % 2 == 0) {

    x_iter = x_iter / 2;

  }

 

  long long int i = 3;

  while(i <= root_x + 1) {

 

    if(x_iter % i == 0) {

      num++;

 

      do {

        x_iter = x_iter / i;

      } while(x_iter % i == 0);

    }

 

    i += 2;

  }

 

  if(x_iter > 1) {

    num++;

  }

 

  return num;

}

 

int main(void)

{

  long long int a, b;

  scanf("%lld%lld", &a, &b);

 

  printf("%d\n", 1 + number_of_factors(gcd(a,b)));

  return 0;

}

// Fastest known solution for this problem: