#include<stdio.h>

#define MAX(x,y) ((x>y)?x:y)
#define MIN(x,y) ((x<y)?x:y)

int prime[30000];	//素因数分解用に素数を求めておく.
int count;
int 素因数A[30000],素因数B[30000];	//素因数を入れる。

int GetPrime(int num);	//num以下の素数をprime[i]に保存
void DevPrime(int *p,int num);	//numを素因数分解。素因数prime[i]の数を*(p+i)に保存。
int GetLCM(int *pa,int *pb);
int GetGCD(int *pa,int *pb);

int pwd(int tei,int sisuu){
	int ans = 1;
	for(int i = 0;i < sisuu;i++)
		ans *= tei;
	return ans;
}

int main(){
	count = GetPrime(50000); 

	int a,b;
	int LCM[200],GCD[200],cor = 0;
	while(~scanf("%d%d",&a,&b)){
		DevPrime(素因数A,a);
		DevPrime(素因数B,b);
		LCM[cor] = GetLCM(素因数A,素因数B);
		GCD[cor] = GetGCD(素因数A,素因数B);
		cor++;
	}
	for(int i = 0;i < cor;i++)
		printf("%d %d\n",GCD[i],LCM[i]);
	return 0;
}

int GetPrime(int num){
	int count = 0,i,j;
	for(i = 2;i <= num;i++){
		for(j = 0;j < count;j++){
			if(i%prime[j] == 0)                                                                                                                                                                                                                                               
				break;
		}
		if(j < count)
			continue;
		prime[count] = i;
		count++;
	}
	return count;
}
void DevPrime(int *p,int num){
	int i;
	for(i = 0;i < count;i++){
		//保存したい配列を初期化
		p[i] = 0;
		//割りきれなくなるまでその素数で割る。
		while(num%prime[i]==0){
			num /= prime[i];
			p[i]++;
		}
	}
}
int GetLCM(int *pa,int *pb){
	int ans = 1;
	for(int i = 0;i < count;i++){
		ans *= pwd(prime[i],MAX(pa[i],pb[i]));
	}
	return ans;
}
int GetGCD(int *pa,int *pb){
	int ans = 1;
	for(int i = 0;i < count;i++){
		ans *= pwd(prime[i],MIN(pa[i],pb[i]));
	}
	return ans;
}