#include<iostream>
#include<vector>
#include<sstream>
#include<string>
#include<numeric>
#include <algorithm>
#include<math.h>
#include<cstdio>
#include<string.h>
#include<unistd.h>
#include <array>
#include <map>
#include<stdio.h>
#include<queue>
#include<tuple>

#define ALL(a)  (a).begin(),(a).end()
const long long MOD = 1e9+7;

//いろんなstlの使い方　https://qiita.com/tukejonny/items/f4013547df761a0b3523
//http://y-mazun.hatenablog.com/entry/20111202/1322840281



using namespace std;


long long gcd(long long a, long long b) {
    if (a > b) {
        return gcd(b, a);
    }
    return a == 0 ? b : gcd(b % a, a);
}

int lcm(int m, int n) {
    // 引数に０がある場合は０を返す
    if ((0 == m) || (0 == n))
        return 0;

    return ((m / gcd(m, n)) * n); // lcm = m * n / gcd(m,n)
}//lcm


int moji(char in) {
    int ans = (int) in - (int) 'a';
    if ((ans < 0) || (ans > 25)) {
        ans = 26;
    }
    return ans;
}


int compare_int(const void *a, const void *b)//qsort(quick sort利用時に使用)
{
    return *(int *) a - *(int *) b;
}



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

//formerは前方のindex(自分自身を含んで良い)
template<class T>
int former(const vector<T> &v, T x) {
    return upper_bound(v.begin(), v.end(), x) - v.begin() - 1;
}

//latterは後方のindex(自分自身を含んで良い)
template<class T>
int latter(const vector<T> &v, T x) {
    return lower_bound(v.begin(), v.end(), x) - v.begin();
}



//indexを用いてvectorから要素削除
template<typename T>
void remove(std::vector<T> &vector, unsigned int index) {
    vector.erase(vector.begin() + index);
}


//遅延セグ木
struct LazySegmentTree{
private:
    int n;
    vector<long long>node,lazy;
public:
    LazySegmentTree(vector<long long>v){
        int sz=(int)v.size();
        n=1;
        while(n<sz){
            n*=2;
        }
        node.resize(2*n-1);
        lazy.resize(2*n-1,0);//0で初期化
        for(int i=0;i<sz;i++){
            node[i+n-1]=v[i];
        }
        for(int i=n-2;i>=0;i--){
            node[i]=node[i*2+1]+node[i*2+2];
        }
    }
    //k番目のノードについて遅延評価
    void eval(int k,int l,int r){
        //遅延評価が空でない時、自ノード、子ノードへの値の伝搬が起こる
        if(lazy[k]!=0){
            node[k]+=lazy[k];
            if(r-l>1){
                //子が存在する時に
                lazy[2*k+1]+=lazy[k]/2;
                lazy[2*k+2]+=lazy[k]/2;
            }
            lazy[k]=0;
        }
    }
    void add(int a,int b,long long x,int k=0,int l=0,int r=0){
        if(r<0){
            r=n;
        }
        //範囲外なら何もしない
        if(l<=b||a>=r){
            return;
        }
        if(a<=l&&b>=r){
            //要求区間が対象区間を完全に覆っている
            lazy[k]+=(r-l)*x;//元の配列全てに対し一様に値が増加するので
            eval(k,l,r);
        }else{
            //完全に被覆していないので被覆する所を探そうや
            add(a,b,x,2*k+1,l,(l+r)/2);
            add(a,b,x,2*k+2,(l+r)/2,r);
            //更新
            node[k]=node[2*k+1]+node[2*k+2];
        }

    }
    //区間和を取得する
    long long getsum(int a,int b,int k=0,int l=0,int r=-1){
        if(r<0){
            r=n;

        }
        if(b<=l||r<=a){
            //区間外
            return 0;
        }
        eval(k,l,r);
        if(a<=l&&r<=b){
            return node[k];
        }
        long long vl=getsum(a,b,2*k+1,l,(l+r)/2);
        long long vr=getsum(a,b,2*k+2,(l+r)/2,r);
        return vl+vr;
    }
};




int main() {
    long long N;
     long long K;
    cin>>N>>K;
    long long sum=K;
    for(int i=1;i<N;i++){
        sum*=K-1;
    }
    cout<<sum<<endl;





    }
















Measured memory_bytes: 256