//Grzegorz Wierzowiecki 2005

//Ładniej zapisana wersja bloczków.
//Powinna co do dziąłania być identyczna do wersjii 1.
// Jednak nieco optymalniejsza (wyeleminowane wielokrotne wykonywanie tej samej czynnosci)
// Ale nie jest ona dostatecznie przesestowana, wiec nie obiecuje poprawności.

//Stala DEB dla informacjii dodatkowych o działaniu programu.
//#define DEB

#include <stdio.h>
#include <set>

typedef unsigned long int ULI;
typedef std::set<ULI> ULIset;

//Liczba komórke na których oprujemy.
#define N (2*n+2)

ULI n, w; // n - n z zadanie, w - wolne pola ( pozycja pierwszego z nich)
ULIset TA, TB; // BST tree with letter positions
char *t; //nasz ciag

void move( ULI x ){ //przenies z pozycjii x na wolne miejsce
	//Usówamy stare pozycje z drzew.
	TA.erase( x ); TA.erase( x + 1 ); //operacja usun(x) , dla x-a ktory nie istnieje nie szkodzi.
	TB.erase( x ); TB.erase( x + 1 );
	//Przeluzmy dwie literki
	t[ w   ] = t[ x ];
	t[ w+1 ] = t[ x+1 ];	
	t[x] = t[x+1] = '_';
	// I ustawmy ich nowe pozycje
	for( ULI i=0; i<2; ++i )
		if( t[w+i] == 'A' ){
			TA.insert( w+i );
		} else {
			TB.insert( w+i );
		};
	w = x;
};
	
int main(){
	ULI i, x;
	char *p, ch;
	ULIset::iterator it, iend;
	bool done = false;
	
	//Wczytajmy dane
	scanf("%lu", &n );
	t = new char[ N+1 ];
	p = t;
	for( *p = 'x' ; *p!='A' && *p!='B' && *p!='_' ; ) scanf("%c" , p );
	for( i=0; i< (N-1); ++i) scanf( "%c", (++p) );
	*(++p) = '\0';
#ifdef DEB	
	printf("%s - wycztana\n", t ); 
#endif

	//Umiescmy informacje o pozycjach literek w drzewie
	for( i=0; i<N; ++i )
		switch( t[i] ){
			case 'A':
				TA.insert( i );
				break;
			case 'B':
				TB.insert( i );
				break;
			case '_':
				w = i;
				break;
		}
	--w; //wolne miejsce

#ifdef DEB	
	printf("TA = {"); for( it = TA.begin(); it != TA.end(); ++it ) printf("%lu ", (*it) ); printf( " } \n" );
	printf("TB = {"); for( it = TB.begin(); it != TB.end(); ++it ) printf("%lu ", (*it) ); printf( " } \n" );
	printf( "wole = %lu \n", w );
#endif

//Pozycja ostatniego elementu -> Stała dla zwiększenia czytalności.
#define OSTATNI ( N - 1 )	
//Minimalna pozycja B , tzn. pierwsza z lewej.	
#define MINB ( *(TB.begin()) )	
//Analogicznie pierwsze A z prawej	
#define MAXA ( *(TA.rbegin()) )
//Pierwsze A po danej pozycjii. Potrzebne do sprawdzania najbliższego A po wolnym polu.	
#define AAFTER(x) ( TA.lower_bound( x ) )
//przenosi bloczek z miejsca x na wolne	
	
	int breakl = 0;
	while( ! done  ){
#ifdef DEB
	printf("TA = {"); for( it = TA.begin(); it != TA.end(); ++it ) printf("%lu ", (*it) ); printf( " } \n" );
	printf("TB = {"); for( it = TB.begin(); it != TB.end(); ++it ) printf("%lu ", (*it) ); printf( " } \n" );
	printf( "wole = %lu \n", w );
#endif
		printf("%s\n", t );
		if( MINB < w ){ //czy jakiś B przed dziurą
			if( MINB == (w-1) ) { //czy samo przed dziura 
				//prowizoryczne rozwiazanie przypadku
				move( w + 2 ); //pierwsze po dziurze
			} else { //nie jest samo przed dziura wiec przestawiamy pare gdzie B jest pierwsze
				move( MINB );
			};
			
		} else { //nie ma już B przed dziurą
			if( AAFTER( w ) != TA.end() ){ //czy jest A po dziurze
				if( (* AAFTER(w) ) == OSTATNI ){
					
					x = w;
					move( OSTATNI - 1 );
					++x;
					move( x );
					
					move( OSTATNI - 2 );
				} else {
					move( * ( AAFTER(w) ) );
				};
			} else { // => nie ma A po dziurze
				done = true;
			};
			
		}
		if( MAXA < MINB ) done = true;
		//if( ++breakl > 5 ) done = true;
	};
	printf("%s\n", t );
	
	return 0;
};
