#include<bits/stdc++.h>
using namespace std;
const int N = 10;
char g[2][4];
unordered_map<string, pair<char, string>>pre; //一个字符串映射到一个操作和一个状态
unordered_map<string, int>dist;
void Set(string state){ //将二维数组重新赋给字符串
for(int i = 0; i < 4; i ++ ) g[0][i] = state[i];
for(int i = 0, j = 7; i < 4; i ++ , j -- ) g[1][i] = state[j];
}
string get(){ //用于将魔板状态放入临时二维数组g内
string res;
for(int i = 0; i < 4; i ++ ){
res += g[0][i]; //放第一行
}
for(int i = 3; i >= 0; i -- ) res += g[1][i]; //放第二行
return res;
}
string move0(string start){ //交换上下两行
Set(start);
for(int i = 0; i < 4; i ++ ){
swap(g[0][i], g[1][i]);
}
return get();
}
string move1(string start){ //将最右边的一列插入到最左边
Set(start);
char s1 = g[0][3];
char s2 = g[1][3];
for(int i = 3; i >= 0; i -- ){
g[0][i] = g[0][i - 1];
g[1][i] = g[1][i - 1];
}
g[0][0] = s1;
g[1][0] = s2;
return get();
}
string move2(string start){ //将中间四个数顺时针旋转
Set(start);
char s = g[0][1];
g[0][1] = g[1][1];
g[1][1] = g[1][2];
g[1][2] = g[0][2];
g[0][2] = s;
return get();
}
int bfs(string start, string end){
if(start == end) return 0;
queue<string>q;
q.push(start); //把这种初始魔板字符串状态放入队列
dist[start] = 0; //记录到达这个状态的步数为0
while(!q.empty()){
auto op = q.front(); //从队列中取出
q.pop();
string m[3];
//按照规则进行三种状态变化
m[0] = move0(op);
m[1] = move1(op);
m[2] = move2(op);
for(int i = 0; i < 3; i ++ ){
if(!dist.count(m[i])){ //这一步很关键,count就是查找在优先队列中m[i]的数量
//如果这种状态没有出现过
dist[m[i]] = dist[op] + 1; //记录步数
pre[m[i]] = {'A' + i, op};
q.push(m[i]);
if(end == m[i]) return dist[m[i]];
}
}
}
return -1;
}
int main()
{
int x;
string start, end;
for(int i = 0; i < 8; i ++ ){
cin>>x;
end += char(x + '0'); //end是以字符串形式记录的初始魔板序列
}
for(int i = 1; i <= 8; i ++ ) start += char(i + '0'); //start是记录的基本状态的魔板序列
int step = bfs(start, end); //宽搜得到最短序列长度
cout<<step<<endl;
string res; //res是用于记录的空字符串
while(end != start){ //当魔板状态不是初始状态时
res += pre[end].first; //pre.first记录的是上一步的操作
end = pre[end].second; //pre.second记录的是上一步的状态
}
reverse(res.begin(), res.end());
//因为记录命令序列的时候是从理想状态倒推出的初始状态,所以输出时要对命令字符串逆序
if(step > 0) cout<<res<<endl;
return 0;
}