#include <string>
#include <vector>
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<stack>
#include<queue>
#include<cmath>
#include<algorithm>
#include<functional>
#include<list>
#include<deque>
#include<bitset>
#include<set>
#include<map>
#include<unordered_map>
#include<unordered_set>
#include<cstring>
#include<sstream>
#include<complex>
#include<iomanip>
#include<numeric>
#include<cassert>
#define X first
#define Y second
#define pb push_back
#define rep(X,Y) for (int (X) = 0;(X) < (Y);++(X))
#define reps(X,S,Y) for (int (X) = S;(X) < (Y);++(X))
#define rrep(X,Y) for (int (X) = (Y)-1;(X) >=0;--(X))
#define rreps(X,S,Y) for (int (X) = (Y)-1;(X) >= (S);--(X))
#define repe(X,Y) for ((X) = 0;(X) < (Y);++(X))
#define peat(X,Y) for (;(X) < (Y);++(X))
#define all(X) (X).begin(),(X).end()
#define rall(X) (X).rbegin(),(X).rend()
#define eb emplace_back
#define UNIQUE(X) (X).erase(unique(all(X)),(X).end())
#define Endl endl
#define NL <<"\n"

using namespace std;
using ll=long long;
using pii=pair<int,int>;
using pll=pair<ll,ll>;
template<class T> using vv=vector<vector<T>>;
template<class T> inline bool MX(T &l,const T &r){return l<r?l=r,1:0;}
template<class T> inline bool MN(T &l,const T &r){return l>r?l=r,1:0;}
//#undef NUIP
#ifdef NUIP
#include "../benri.h"
#else
#define out
#endif
#ifdef __cpp_init_captures
template<typename T>vector<T> table(int n, T v){ return vector<T>(n, v);}
template <class... Args> auto table(int n, Args... args){auto val = table(args...); return vector<decltype(val)>(n, move(val));}
#endif
const ll MOD=1e9+7; //998244353

string bf(string s){
	int n=s.size();
	assert(n<=30);
	string re;
	rep(i,1<<n){
		int len=__builtin_popcount(i);
		if(len%3 || len<=re.size()) continue;
		string t;
		rep(j,n)if(i>>j&1) t+=s[j];
		int k=t.size()/3;
		auto tt=t;
		sort(all(tt));
		int ok=1;
		reps(i,1,len)if(t[i]==t[i-1]){ ok=0; break;}
		if(ok && tt[k-1]!=tt[k] && tt[2*k-1]!=tt[2*k]) re=t;
	}
	return re;
}

string fun(const string &s,char a,char b,int rem){
	//out(s,a,b,rem,1);
	string re;
	for(char c:s){
		if(rem && re.size()>=2 &&
			 ((re.back()==a && re[re.size()-2]==b)
				||(re.back()==b && re[re.size()-2]==a))
			 && (re.size()==2 || re[re.size()-3]!=c)){
			re.pop_back();
			re.back()=c;
			--rem;
		}else{
			re+=c;
		}
	}
	if(rem && re.size()>=2 &&
		 ((re.back()==a && re[re.size()-2]==b)
			||(re.back()==b && re[re.size()-2]==a))){
			re.pop_back();
			re.pop_back();
			--rem;
		 }
		 
	return re;
}

string solve(string s){
	vector<pii> cnt{{0,0},{0,1},{0,2}};
	for(char c:s) ++cnt[c-'A'].X;
	sort(all(cnt));
	// out(cnt,1);
	{
		auto t=s; s.clear();
		for(char c:t){
			if(cnt[2].X>cnt[1].X && s.size() && cnt[2].Y+'A'==s.back() && (s.size()==1 || s[s.size()-2]!=c)){
				s.back()=c;
				--cnt[2].X;
			}else{
				s+=c;
			}
		}
		if(s.size() && cnt[2].X>cnt[1].X && cnt[2].Y+'A'==s.back()){
			s.pop_back();
			--cnt[2].X;
		}
	}
	 // out(s,cnt,1);
	if(cnt[1].X==cnt[2].X){
		s=fun(s,cnt[1].Y+'A',cnt[2].Y+'A',cnt[1].X-cnt[0].X);
	}else{
		int t=cnt[1].X-cnt[0].X;
		s=fun(s,cnt[1].Y+'A',cnt[2].Y+'A',t);
		cnt[1].X-=t; cnt[2].X-=t;
		//out(s,1);
		t=cnt[2].X-cnt[1].X;
		s=fun(s,cnt[0].Y+'A',cnt[2].Y+'A',t);
		s=fun(s,cnt[1].Y+'A',cnt[2].Y+'A',t);
	}
	// out(s,1);
	return s;
}

int main(){
  ios_base::sync_with_stdio(false); cin.tie(0);
  cout<<fixed<<setprecision(0);
	//out(solve("ABCABCABABCABCAB"),1); return 0;
	if(0){
		const int N=15;
		rep(o,3)rep(i,1<<N){
			vector<int> v{o};
			rep(j,N) v.pb((v.back()+1+(i>>j&1))%3);
			string s(N+1,'A');
			rep(i,N+1) s[i]+=v[i];
			auto re=solve(s);
			auto ans=bf(s);
			reps(i,1,re.size())if(re[i]==re[i-1]){ out(re,s,1); exit(0);}
			if(re.size()!=ans.size()){ out(re,1,ans,s,1); exit(0);}
		}
	}
	out("done",1);
	string s;
	cin>>s;
	UNIQUE(s);
	cout<<solve(s)<<endl;
  return 0;
}


Measured memory_bytes: 4252