#include <bits/stdc++.h>
#define fio ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define int long long
#define endl '\n'
#define pb push_back
#define mp make_pair
#define bash int n; cin >> n; int a[n]; for(int i = 0; i < n; i++) cin >> a[i];
#define debug(x) cout<<#x<<" "<<x<<endl;
const int mod = 1e9 + 7;
const int MAX = 1e5 + 9;
const int INF = 1e18 ;
const double pi = 3.141592653589793238460;
using namespace std;

#define TRACE
#ifdef TRACE
    #define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template <typename Arg1>
    void __f(const char* name, Arg1&& arg1){
        cerr << name << " : " << arg1 << endl;
    }
    template <typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names + 1, ',');
        cerr.write(names, comma - names) << " : " << arg1<<" | ";
        __f(comma+1, args...);
    }
#else
    #define trace(...)
#endif

bool is_pal (string s){
    return equal(s.begin(), s.begin() + s.size()/2, s.rbegin()) ? 1 : 0;
}

int power(int x,int y, int res = 1) {
    x %= mod; 
    for( ; y ; y >>= 1LL ) {
        if(y & 1LL){ 
            res = res * x % mod;
        }
        x = x * x % mod;
    }
    return res;
}

int modInv (int x){
    return ( power(x,mod-2) + mod ) % mod;
}

int fact[MAX], inv[MAX];

void compFact(void){
    fact[0] = fact[1] = inv[1] = inv[0] = 1;
    for (int i = 1; i < MAX; i++) { 
        fact[i] = (fact[i - 1] * i % mod + mod) % mod; 
    } 
}

void compInv(void){
    for(int i = 2; i < MAX; ++i){
        inv[i] = (mod - (mod / i) * inv[mod % i] % mod + mod) % mod;
    }
}

int nCr (int n, int r){
    if(n < r || n < 0){
        return 0;
    }
    return ( ( ( ( fact[n] % mod ) * ( inv[fact[n-r]] % mod ) ) % mod ) * ( inv[fact[r]] % mod ) + mod) % mod; 
}

int factMod(int n, int res = 1) {
    while (n > 1) {
        res = (res * ((n/mod) % 2 ?  mod-1 : 1)) % mod;
        for (int i = 2; i <= n % mod; ++i)
            res = (res * i) % mod;
        n /= mod;
    }
    return res % mod;
}

int max (int x, int y){
    return x>y ? x : y;
}

int min (int x, int y){
    return x<y ? x : y;
}

int lcm (int x, int y){
    return (x*y)/__gcd(x,y);
}

int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};

int N;

bool under_bound(int x, int y){
    return x >= 0 && y <= 0 && x < N && y < N;
}

bool prime[MAX]; 

void SieveOfEratosthenes(int n){
     
    memset(prime, true, sizeof(prime)); 
    for (int p=2; p*p < n; p++){ 
        if (prime[p] == true){ 
            for (int i=p*p; i<=n; i += p) 
                prime[i] = false; 
         } 
    }  
}

multiset<int> A;

void primeFact(int n){
    while (n % 2 == 0)  {  
        A.insert(2); 
        n = n/2;  
    }  
    for (int i = 3; i <= sqrt(n); i = i + 2)  {  
        while (n % i == 0)  {  
            A.insert(i); 
            n = n/i;  
        }  
    }  
  
    if (n > 2)  
        A.insert(n);  
}

int spf[MAX];

void SieveOfEuler(){ 
    spf[1] = 1; 
    
    for (int i=2; i < MAX; i++) 
    spf[i] = i; 
  
    for (int i=4; i < MAX; i+=2) 
        spf[i] = 2; 
  
    for (int i=3; i*i < MAX; i++){ 
        if (spf[i] == i){ 
            for (int j = i*i; j < MAX; j += i) 
                  if (spf[j]==j) 
                    spf[j] = i; 
        } 
    } 
}

map < pair<int, int>, int > factFreq;

void getFactorization(int x) {
    while(x > 1){
        int pt = spf[x], f = 0;
        while (x % pt == 0){
            x /= pt;
            f++;
            factFreq[{pt,f}]++;
        }
    }
}

int tree[4*MAX], lazy[4*MAX];

int n, q;

void build(int a[], int v, int tl, int tr, int tree[], int lazy[]) {
    if (tl == tr) {
        tree[v] = a[tl];
    } 
    else{
        int tm = (tl + tr) / 2;
        build(a,v*2,tl,tm,tree,lazy);
        build(a,v*2+1,tm+1,tr,tree,lazy);
        tree[v] = tree[2*v] + tree[2*v+1];
    }
}

void push(int v, int tree[], int lazy[]) {
    tree[v*2] += lazy[v];
    lazy[v*2] += lazy[v];
    tree[v*2+1] += lazy[v];
    lazy[v*2+1] += lazy[v];
    lazy[v] = 0;
}

void updatePOINT(int v, int tl, int tr, int pos, int new_val) {
    if (tl == tr) {
    	tree[v] += new_val;
    } 
    else {
        int tm = (tl + tr) / 2;
        if (pos <= tm)
            updatePOINT(v*2, tl, tm, pos, new_val);
        else
            updatePOINT(v*2+1, tm+1, tr, pos, new_val);
        tree[v] = tree[2*v] + tree[2*v+1];
    }
}

int find(int v, int tl, int tr, int x) {
	if(tl == tr){
		assert(tree[v] == 1);
		return tl;
	}
	int tm = (tl + tr) >> 1;
	if(tree[2*v] < x){
		return find(2*v+1, tm+1, tr, x-tree[2*v]);
	}
    else{
    	return find(2*v, tl, tm, x);
    }
}

int sum(int v, int tl, int tr, int l, int r) {
    if (l > r) 
        return 0;
    if (l == tl && r == tr) {
        return tree[v];
    }
    int tm = (tl + tr) / 2;
    return sum(v*2, tl, tm, l, min(r, tm))
           + sum(v*2+1, tm+1, tr, max(l, tm+1), r);
}

void solve(void){
	// cin >> n >> q ;
	// int a[n + 1] = {0};
	// build(a, 1, 1, n, tree, lazy);
	// while(q--){
		// int Q;
		// cin >> Q;
		// if(Q & 1){
			// int l, r, v;
			// cin >> l >> r >> v, l++, r++;
			// updatePOINT(1, 1, n, l, v);;
			// updatePOINT(1, 1, n, r, -1*v);
		// }
		// else{
			// int i;
			// cin >> i, i++;
			// cout << sum(1, 1, n, 1, i) << endl;
		// }
	// }
	int a, b;
	cin >> a >> b;
	cout << (max(a, b) / __gcd(a, b)) * min(a, b);
}
signed main() {
fio;
int t = 1;
// cin >> t;    
	while(t--)
    solve();

    return 0;
}



Measured memory_bytes: 3680