#include<bits/stdc++.h>
#define ll long long 
#define hell 1000000007 
#define F first
#define re 15000000
#define S second
#define pb push_back
#define all(a)  (a).begin(),(a).end()
#define rep(i,a,b) for(ll int i = a;i<b;i++)
#define pi 3.1415926536
#define Mod 998244353
//char a[2000][2000];
using namespace std;
int sum (ll a)
{
    int sum =0;
    while(a>0)
    {
        sum = sum + (a%10);
        a=a/10;
    }
    return sum;
}
int count_digit(ll n)
{
   int  count =0;
    while(n>0)
    {
        n = n/10;
        count++;
        //count++;
    }
    return count;
}
int binarySearch(int x,int y ,ll z ,ll v[])
{
    int low = x;
    int high = y;
    int mid = x+(y-x)/2;
    while(low<=high)
    {
        if(v[mid]==z)
            return mid;
        if(v[mid]<z)
            return binarySearch(mid+1,high,z,v);
        if(v[mid]>z)
            return binarySearch(low,mid-1,z,v);
    }
    return -1;
}
ll modularExponentiation(ll x,ll n,ll M)
{
    if(n==0)
        return 1;
    else if(n%2 == 0)        //n is even
        return modularExponentiation((x*x)%M,n/2,M);
    else                             //n is odd
        return (x*modularExponentiation((x*x)%M,(n-1)/2,M))%M;
 
} 
ll binaryExponentiation(ll x,ll n)
{
    if(n==0)
        return 1;
    else if(n%2 == 0)        //n is even
        return binaryExponentiation(x*x,n/2);
    else                             //n is odd
        return x*binaryExponentiation(x*x,(n-1)/2);
}
 
 
 
 
set<ll> s;
//vector<ll> v;
void genrate(ll n,int len,int max)
{
    if(len>max)
        return ;
    s.insert(n);
    genrate(n*10+1,len+1,max);
    genrate(n*10+0,len+1,max);
}
/*bool visited[100005];
vector<ll> v[100005];
bool recur[100005];
bool dfs(int x)
{
    if(recur[x])
        return true;
    if(visited[x])
        return false;
    recur[x] = true;
    visited[x]= true;
    for(int i =0;i<v[x].size();i++)
    {
        if(visited[v[x][i]]!=1 ,dfs(v[x][i]))
            return true;
            
        else if (recur[v[x][i]])
            return true;
    }
    recur[x] = false;
    return false;
 
}*/
//memset(level,0,sizeof(level));    
/*void topological_sort(int x)
{
    visited[x] = 1;
  //  sort(all(v[x]));
    for(int i =0;i<v[x].size();i++)
    {
        if(visited[v[x][i]]!=1){
            //level[v[x][i]] = level[x]+1;
            topological_sort(v[x][i]);
        }
    }
    ans.pb(x);
}*/
//char a2001][2001];
//int largest;
void max_heap(int a[] ,int n,int index)
{
  int left = 2*index;
  int right = 2*index+1;
  int largest; 
  if(left <= n && a[left] > a[index])
      largest = left;
  else
    largest = index;
  if(right <= n && a[right] > a[largest])
    largest = right;
 
  if(largest!=index)
  {
    swap(a[index],a[largest]);
    max_heap(a,n,largest);
  }
}
void heapify(int a[] ,int n)
{
  for(int i = n/2;i>0;i--)
      max_heap(a,n,i);
}
int a[10000];
int arr[10000];
void  segmentTree(int node, int start,int end)
{
  if(start == end){
    arr[node] = a[start];
    return ;
  }
  int mid = (start+end)/2;  
   segmentTree(2*node,start,mid);
   segmentTree(2*node+1,mid+1,end);
   arr[node] = arr[2*node] + arr[2*node+1];
  //a[node] = p1+p2;
  //return ;
}
int query(int l ,int r, int start,int end,int node)
{
  if(r < start || l > end)
      return 0;
  if(l<= start && end<=r)
      return arr[node];
  int mid = (start+end)/2;
  int p1 = query(l,r,start , mid,2*node);
  int p2 = query(l,r,mid+1,end,2*node+1);
  return p1+p2;
}
int b[1001][1001];
void printup(int l,int r,int row){
  if(l==r){
    cout<<b[row][l]<<" ";
    return ;
  }
  printup(l+1,r-1,row-1);
  cout<<b[row][l]<<" "<<b[row][r]<<" ";
 
}
void printdown(int l,int r,int row){
  if(l==r){
    cout<<b[row][l]<<" ";
    return ;
  }
  cout<<b[row][l]<<" "<<b[row][r]<<" ";
  printdown(l+1,r-1,row+1);
  
 
}
int check(int x){
  map<int,int> m;
  int temp = x;
  if(temp == 0)
    m[x]++;
  while(temp){
    m[temp%10]++;
    temp = temp/10;
  }
  temp = 99999-x;
  if(temp==0)
     m[temp]++;
  while(temp){
    m[temp%10]++;
    temp = temp/10;
  }
  if(m.size()==2)
    return 1;
  else
    return 0;
}
vector<ll> p1;
void SieveOfEratosthenes(ll n) 
{ 
    // Create a boolean array "prime[0..n]" and initialize 
    // all entries it as true. A value in prime[i] will 
    // finally be false if i is Not a prime, else true. 
    bool prime[n+1]; 
    memset(prime, true, sizeof(prime)); 
  
    for (ll p=2; p*p<=n; p++) 
    { 
        // If prime[p] is not changed, then it is a prime 
        if (prime[p] == true) 
        { 
            // Update all multiples of p greater than or  
            // equal to the square of it 
            // numbers which are multiple of p and are 
            // less than p^2 are already been marked.  
            for (ll i=p*p; i<=n; i += p) 
                prime[i] = false; 
        } 
    } 
  
    // Print all prime numbers 
    for (int p=2; p<=n; p++) 
       if (prime[p]) 
            p1.pb(p); 
} 

int main()
{   
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);            
    //std::setprecision(20);    
    int tests=1;
      //freopen("input.txt", "r", stdin);
   // cin>>tests;
  while(tests--)
    {
      ll a,b;
      cin>>a>>b;
      map<ll,int> m1,m2;
      for(int i = 1;i<=sqrt(a);i++)
      {
        if(a%i == 0){
          m1[i]++;
          m1[a/i]++;
        }
      }
      for(int i = 1;i<=sqrt(b);i++){
        if(b%i==0){
          m2[i]++;
          m2[b/i]++;
        }
      }
      vector<ll> com;
      for(auto it=m1.begin();it!=m1.end();it++){
        if(m2[it->F]){
          com.pb(it->F);
        }
      }
      int cnt = 0;
      sort(all(com));
      int x =0;
      for(int i = 1;i<com.size();i++){
            x = 0;
            for(ll j = 2;j<=sqrt(com[i]);j++){
                if(com[i]%j == 0){
                  x = 1;
                  break;
                }
            }
            if(x == 0)
               cnt++;
      }
      cnt++;
      cout<<cnt;
    }
}

Measured memory_bytes: 1280