#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long ll; #define sz size() #define pb push_back #define mp make_pair #define fi first #define se second #define all(c) (c).begin(), (c).end() #define rep(i,a,b) for(ll i=(a);i<(b);++i) #define per(i,a,b) for(ll i=b-1LL;i>=(a);--i) #define clr(a, b) memset((a), (b) ,sizeof(a)) #define ctos(c) string(1,c) #define print(x) cout<<#x<<" = "< > > ans; // 指定した行rを右にa個だけRotate (-N<=a<=N) void rotR(string &s, ll r, ll a){ a *= -1; a += N; a %= N; if(a!=0)ans.pb(mp("R",mp(r,(a+2)%N))); rep(i,0,a){ rep(j,0,N-1){ swap(s[r*N+j],s[r*N+j+1]); } } } // 指定した列cの下にa個だけRotate (-N<=a<=N) void rotC(string &s, ll c, ll a){ a *= -1; a += N; a %= N; if(a!=0)ans.pb(mp("C",mp(c,(a+2)%N))); rep(i,0,a){ rep(j,0,N-1){ swap(s[j*N+c],s[(j+1)*N+c]); } } } // 最下段の整合性を無視することである文字を指定位置へ移動。 void move(string &s, char ch, ll r1, ll c1){ ll r2,c2; rep(i,0,N*N){ if(s[i]==ch){ r2 = i/N; c2 = i%N; } } ll c3; rep(i,0,N){ if(i!=c1&&i!=c2){ c3 = i; break; } } rotC(s,c2,(N-1)-r2); rotR(s,N-1,c3-c2); rotC(s,c2,r2-(N-1)); rotC(s,c1,(N-1)-r1); rotR(s,N-1,c1-c3); rotC(s,c1,r1-(N-1)); } // 指定した文字を1つ左へ (右の文字と入れ替え) N=4に限る void toLeft(string &s, char ch){ ll r,c; rep(i,0,N*N){ if(s[i]==ch){ r = i/N; c = i%N; } } rotR(s,r,-1); rotC(s,c,-1); rotR(s,r,-1); rotC(s,c,1); rotR(s,r,-1); rotC(s,c,-1); rotR(s,r,-2); rotC(s,c,1); } int main() { string s; rep(i,0,4){ string s1; cin>>s1; s += s1; } string s2 = s; sort(all(s2)); if(s2!=A){ cout << -1 << endl; return 0; } rep(i,0,N*(N-1)){ move(s,A[i],i/N,i%N); } ll c; rep(i,0,N*N){ if(s[i]==A[N*(N-1)]){ c = i%N; } } rotR(s,N-1,-c); rep(i,1,N){ char ch = A[N*(N-1)+i]; per(j,i+1,N){ if(s[N*(N-1)+j]==ch){ toLeft(s,ch); } } } cout << ans.sz << endl; rep(i,0,ans.sz){ cout << ans[i].fi << " " << ans[i].se.fi << " " << ans[i].se.se << endl; } return 0; }