#include <fstream>
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <utility>
#include <string>
#include <bitset>
#include <set>
#include <utility>
#include <vector>
#include <utility>
#include <cstring>
#include <cstdlib>
#define NN 1000
#include <tr1/unordered_map>

#define mp make_pair
#define f first
#define s second
#define pb push_back
using namespace std;

int prim[NN] ;
int mm = 0;
int nn = 0;
bitset<NN>uz;
pair< int , int >desc[NN];

void ciur( )
{
    for( int i=2 ; i<=NN ; i++)
        if ( !uz[i] )
        {
            prim[++mm] = i;
                for( int j = ( i << 1 ); j<=NN ; j+=i )
                    uz[j] = 1;
        }
}


int main()
{

    int n ;
    int R ;
    cin >> n >> R;

    int pas = n - 1;
    int pas2 = 3;

    long long sum = 0;
    for( int i = 1  ; i<=n-3 ; i++)
    {
        sum = pas2 * ( n - pas);
        pas--;
        pas2++;
    }

    ciur();

     for( int i=1 ; i<=mm && 1LL * ( prim[i] * prim[i] ) <=sum ; i++)
    {
        long long pow = 0;

        if ( sum % prim[i] )
            continue;

        while( sum % prim[i] == 0 )
        {
            ++pow;
            sum/=prim[i];
        }

        if ( pow )
        {
            ++nn;
            desc[nn].f = prim[i];
            desc[nn].s = pow;
        }
    }
        if( sum > 1  )
        {
            ++nn;
            desc[nn].f = sum;
            desc[nn].s = 1;
        }

      if(R == 1)
      {
          for( int i=1; i<=nn ; i++)
            if( i!=nn)
            cout << desc[i].f << "*";
          else
            cout << desc[i].f;
      }


      else
      {
          for( int i = 1 ; i<=nn ; i++)
            desc[i].s += R - 1;

        for( int i=1; i<=nn ; i++)
            if( i!= nn)
        cout << desc[i].f << "^" << desc[i].s << "*" ;
        else
            cout <<  desc[i].f << "^" << desc[i].s;

      }
      //for( int i=1; i<=nn ; i++)
        //cout << desc[i].f << " " << desc[i].s << " " << '\n';

    return 0;
}