Problem:
アローダイス
アローダイス (arrow dice) とは，立方体の各面の中央部にその面を構成する 4 辺のいずれかの中心を向いた矢印が 1 つずつ書かれたものである．図 F-1 にその一例を示す．
図 F-1 アローダイスの一例
ここで，2 つのアローダイスの相違度を「それぞれを任意に回転させたあとで立方体として完全に重なり合うように重ね合わせたときに，対応する面について向きの異なる矢印の個数の最小値」と定義する．
n
個のアローダイスが与えられるので，すべてのペアに対してその相違度を求めてほしい．
Input
入力は最大 50 データセットからなり，各データセットは次の形式で表される．
n
x
1,1
x
1,2
...x
1,5
x
2,1
x
2,2
...x
2,5
...
x
5n,1
x
5n,2
...x
5n,5
各データセットの 1 行目には与えられるアローダイスの個数
n
(
2 ≤ n ≤ 200
)，続く
5n
行には
n
個のアローダイスの情報が 5 行ずつ与えられる．
5i-4
行目から
5i
行目までの入力が
i
個目のアローダイスの情報である．
各アローダイスは
5 × 5
のグリッドで表現される．
グリッド上で '^', 'v', '<', '>' はそれぞれ上下左右を向いた矢印が書かれたマスを表し，'.' は余白を表す．
グリッドから余白を取り除いて得られる図形に対して，隣接するマスの間を山折りにして得られる立体がこのグリッドが表現するアローダイスである．入力として与えられるどの図形に関しても，正しく組み立てることでアローダイスが 1 つ出来上がることが保証されている．
例えば，サンプルの最初のケースの 1 つ目の入力が表す図形は図 F-2 の通りであり，図 F-1はこれを組み立てて得られるアローダイスを表している．
図 F-2
入力の終わりは 1 つのゼロからなる行で表される．
Output
各データセットに対して，
i
行目の
j
文字目に
i
個目のアローダイスと
j
個目のアローダイスの相違度を出力せよ．つまり，長さ
n
の数字列を
n
行出力することになる．なお，2 つのアローダイスの相違度は 1 桁の整数となることが証明できる．
Sample Input
3
..^..
.<v>.
..>..
..<..
.....
..^..
.<^>.
..>..
..<..
.....
..>..
..^v.
.^>..
.v...
.....
8
..<^.
...^<
...<.
...<.
.....
.<...
<>...
.^<..
.v...
.....
.....
.....
.>...
^>><.
<....
.....
...<.
..v^.
..>..
.<v..
.....
...<.
..^v.
...<>
...>.
.....
...^.
..>v.
.v^..
.<...
.....
..<..
.vv..
^v...
.^...
.....
....>
.v^vv
...<.
.....
0
Output for the Sample Input
010
101
010
02222232
20432043
24013422
23103331
22330223
20432043
34232402
23213320

Submitted solutions:

code_snippet: //#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;

#define rep2(i, m, n) for (int i = (m); i < (n); ++i)
#define rep(i, n) rep2(i, 0, n)
#define drep2(i, m, n) for (int i = (m)-1; i >= (n); --i)
#define drep(i, n) drep2(i, n, 0)
#define all(...) std::begin(__VA_ARGS__), std::end(__VA_ARGS__)
#define INF (long long)1001001001001001001
#define inf 1001001000
#define fi first
#define se second

using ll = long long;
using vi = vector<int>;
using vl = vector<long long>;
using pii = pair<int, int>;
using pll = pair<long long, long long>;
using LL = __int128_t;

ll gcd(ll x, ll y) {if (x == 0) return y;	return gcd(y%x, x);} 
ll lcm(ll x, ll y) { __int128_t xx,yy; xx=x; yy=y; __int128_t ans=xx * yy / gcd(x, y); ll ans2=ans; return ans2; }
template<typename T>
T POW(T x, ll n){T ret=1;	while(n>0){		if(n&1) ret=ret*x;		x=x*x;		n>>=1;	}	return ret;}
template<typename T>
T modpow(T a, ll n, T p) {	if(n==0) return (T)1;  if (n == 1) return a % p;  if (n % 2 == 1) return (a * modpow(a, n - 1, p)) % p;  T t = modpow(a, n / 2, p);  return (t * t) % p;}
template<typename T>
T modinv(T a, T m) {	if(m==0)return (T)1;	T b = m, u = 1, v = 0;	while (b) {		T t = a / b;		a -= t * b; swap(a, b);		u -= t * v; swap(u, v);	}	u %= m;	if (u < 0) u += m;	return u;}
ll REM(ll a, ll b){ return (a % b + b) % b;}
ll QUO(ll a, ll b){ return (a - REM(a, b)) / b;}
/*
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> dist1(1, 100); [1,100]
int random_value = dist1(gen);
*/
/*
auto start = chrono::steady_clock::now(); //時間計測の開始
auto now = std::chrono::steady_clock::now(); //現在時刻と開始時刻の差を測定
double elapsed = std::chrono::duration<double>(now - start).count(); //時間をdouble型で取得
*/
/*
const int MAXCOMB=510000;
std::vector<mint> FAC(MAXCOMB), FINV(MAXCOMB), INV(MAXCOMB);
void COMinit() {FAC[0] = FAC[1] = 1;FINV[0] = FINV[1] = 1;INV[1] = 1;for (int i = 2; i < MAXCOMB; i++) {FAC[i] = FAC[i - 1] * i;INV[i] = mint(0) - INV[mint::mod() % i] * (mint::mod() / i);FINV[i] = FINV[i - 1] * INV[i];}}
mint COM(int n, int k) {if (n < k) return 0;if (n < 0 || k < 0) return 0;return FAC[n] * FINV[k] * FINV[n - k];}
*/

template <typename T> inline bool chmax(T &a, T b) { return ((a < b) ? (a = b, true) : (false));}
template <typename T> inline bool chmin(T &a, T b) { return ((a > b) ? (a = b, true) : (false));}

/////////////////////////////////////////////////////////////////////////////////////////
int SOLVEFIN = 0;

struct cube{
    vector<int> face = {-1,-1,-1,-1,-1,-1}; //0上,1左,2下,3右
    int x = 0;
    int y = 0;
};

void upmove(cube &cub)
{
    vector<int> face = cub.face;
    vector<int> newface(6,-1);
    newface[0] = face[3];
    newface[3] = face[5];
    newface[5] = face[1];
    newface[1] = face[0];
    if(face[2]!=-1)
    newface[2] = (face[2] + 3) % 4;
    if(face[4]!=-1)
    newface[4] = (face[4] + 1) % 4;
    cub.face = newface;
}
void downmove(cube &cub){
    vector<int> face = cub.face;
    vector<int> newface(6,-1);
    newface[3] = face[0];
    newface[5] = face[3];
    newface[1] = face[5];
    newface[0] = face[1];
    if(face[2]!=-1)
    newface[2] = (face[2] + 1) % 4;
    if(face[4]!=-1)
    newface[4] = (face[4] + 3) % 4;
    cub.face = newface;
}
void rightmove(cube &cub){
    vector<int> face = cub.face;
    vector<int> newface(6,-1);
    if(face[4]!=-1)
        newface[5] = (face[4] + 3) % 4;
    else
        newface[5] = -1;
    if (face[5] != -1)
        newface[2] = (face[5] + 3) % 4;
    else
        newface[2] = -1;
    if (face[2] != -1)
        newface[0] = (face[2] + 3) % 4;
    else
        newface[0] = -1;
    if (face[0] != -1)
        newface[4] = (face[0] + 3) % 4;
    else
        newface[4] = -1;

    if (face[1] != -1)
        newface[1] = (face[1] + 3) % 4;
    if(face[3]!=-1)
        newface[3] = (face[3] + 1) % 4;
    cub.face = newface;
}
void leftmove(cube &cub){
    vector<int> face = cub.face;
    vector<int> newface(6,-1);
    if(face[4]!=-1)
        newface[0] = (face[4] + 1) % 4;
    else
        newface[0] = -1;
    if (face[2] != -1)
        newface[5] = (face[2] + 1) % 4;
    else
        newface[5] = -1;
    if (face[0] != -1)
        newface[2] = (face[0] + 1) % 4;
    else
        newface[2] = -1;
    if (face[5] != -1)
        newface[4] = (face[5] + 1) % 4;
    else
        newface[4] = -1;
    if (face[1] != -1)
        newface[1] = (face[1] + 1) % 4;
    if(face[3]!=-1)
        newface[3] = (face[3] + 3) % 4;
    cub.face = newface;
}
void rotate(cube &cub){
    vector<int> face = cub.face;
    vector<int> newface(6,-1);
    newface[2] = face[1];
    if(face[2]!=-1)
        newface[3] = (face[2]+2)%4;
    else
        newface[3] = -1;
    if(face[3]!=-1)
        newface[4] = (face[3]+2)%4;
    else
        newface[4] = -1;
    newface[1] = face[4];

    if (face[5] != -1)
        newface[5] = (face[5] + 1) % 4;
    if(face[0]!=-1)
        newface[0] = (face[0] + 3) % 4;
    cub.face = newface;
}
void add_face(cube &cub, char u){
    if(cub.face[0]==-1){
        if(u=='^')
            cub.face[0] = 2;
        if(u=='<')
            cub.face[0] = 1;
        if(u=='v')
            cub.face[0] = 0;
        if(u=='>')
            cub.face[0] = 3;
    }
}
int diff(cube &cub1, cube &cub2){
    int ans = 0;
    rep(i, 6)
    {
        if(cub1.face[i]!=cub2.face[i])
            ans++;
    }
    // cout << "DIFF1: ";
    // rep(i, 6)
    // {
    //     cout << cub1.face[i] << " ";
    // }
    // cout << endl;
    // cout << "DIFF2: ";
    // rep(i, 6)
    // {
    //     cout << cub2.face[i] << " ";
    // }
    // cout << endl;
    return ans;
}

// ぽてじんをする！

void solve(){
    int n;
    cin >> n;
    if(n==0){
        SOLVEFIN = 1;
        return;
    }
    vector<string> s(5 * n);
    rep(i, 5 * n) cin >> s[i];
    vector<cube> cubes(n);
    vector<int> dx = {0, 1, 0, -1};
    vector<int> dy = {1, 0, -1, 0};
    vector<vector<int>> seen(5, vi(5, 0));

    auto dfs = [&](auto &&dfs, int i) -> void
    {
        add_face(cubes[i], s[i * 5 + cubes[i].x][cubes[i].y]);
        seen[cubes[i].x][cubes[i].y] = 1;
        pii now = {cubes[i].x, cubes[i].y};
        rep(dir, 4)
        {
            int nx = now.fi + dx[dir];
            int ny = now.se + dy[dir];
            if (nx < 0 || ny < 0 || nx >= 5 || ny >= 5)
                continue;
            if (seen[nx][ny] != 0)
                continue;
            if(s[i*5+nx][ny]=='.')
                continue;
            seen[nx][ny] = 1;
            if (dir == 0)
            {
                rightmove(cubes[i]);
                cubes[i].y++;
                dfs(dfs, i);
                leftmove(cubes[i]);
                cubes[i].y--;
            }
            if (dir == 1)
            {
                downmove(cubes[i]);
                cubes[i].x++;
                dfs(dfs, i);
                upmove(cubes[i]);
                cubes[i].x--;
            }
            if (dir == 2)
            {
                leftmove(cubes[i]);
                cubes[i].y--;
                dfs(dfs, i);
                rightmove(cubes[i]);
                cubes[i].y++;
            }
            if (dir == 3)
            {
                upmove(cubes[i]);
                cubes[i].x--;
                dfs(dfs, i);
                downmove(cubes[i]);
                cubes[i].x++;
            }
        }
    };

    rep(i,n){
        rep(j,5){
            rep(k,5){
                seen[j][k] = 0;
            }
        }
        rep(j,5){
            int fin = 0;
            rep(k, 5)
            {
                if(s[i*5+j][k]!='.'){
                    cubes[i].x=j;
                    cubes[i].y = k;
                    dfs(dfs, i);
                    fin=1;
                    break;
                }
            }
            if(fin)
                break;
        }
    }
    // rep(i,n){
    //     rep(j,6){
    //         cout << cubes[i].face[j] << " ";
    //     }
    //     cout << endl;
    // }

    vector<vi> ans(n, vi(n,inf));
    rep(i, n)
    {
        rep(j,n){
            if(i==j)
                ans[i][j] = 0;
            if (i >= j)
                continue;
            cube cubei = cubes[i];
            rep(k, 4) {
                chmin(ans[i][j], diff(cubei, cubes[j]));
                rotate(cubei);
            }
            upmove(cubei);
            rep(k, 4)
            {
                chmin(ans[i][j], diff(cubei, cubes[j]));
                rotate(cubei);
            }
            upmove(cubei);
            rep(k, 4)
            {
                chmin(ans[i][j], diff(cubei, cubes[j]));
                rotate(cubei);
            }
            upmove(cubei);
            rep(k, 4)
            {
                chmin(ans[i][j], diff(cubei, cubes[j]));
                rotate(cubei);
            }
            upmove(cubei);
            leftmove(cubei);
            rep(k, 4)
            {
                chmin(ans[i][j], diff(cubei, cubes[j]));
                rotate(cubei);
            }
            upmove(cubei);
            upmove(cubei);
            rep(k, 4)
            {
                chmin(ans[i][j], diff(cubei, cubes[j]));
                rotate(cubei);
            }
            ans[j][i] = ans[i][j];
        }
    }
    rep(i,n){
        rep(j,n){
            cout << ans[i][j];
        }
        cout << endl;
    }
}

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);
	while(SOLVEFIN == 0) solve();
}
accuracy: 1
time_ms: 930
memory_kb: 3588
final_rank: 12

code_snippet: //#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;

#define rep2(i, m, n) for (int i = (m); i < (n); ++i)
#define rep(i, n) rep2(i, 0, n)
#define drep2(i, m, n) for (int i = (m)-1; i >= (n); --i)
#define drep(i, n) drep2(i, n, 0)
#define all(...) std::begin(__VA_ARGS__), std::end(__VA_ARGS__)
#define INF (long long)1001001001001001001
#define inf 1001001000
#define fi first
#define se second

using ll = long long;
using vi = vector<int>;
using vl = vector<long long>;
using pii = pair<int, int>;
using pll = pair<long long, long long>;
using LL = __int128_t;

ll gcd(ll x, ll y) {if (x == 0) return y;	return gcd(y%x, x);} 
ll lcm(ll x, ll y) { __int128_t xx,yy; xx=x; yy=y; __int128_t ans=xx * yy / gcd(x, y); ll ans2=ans; return ans2; }
template<typename T>
T POW(T x, ll n){T ret=1;	while(n>0){		if(n&1) ret=ret*x;		x=x*x;		n>>=1;	}	return ret;}
template<typename T>
T modpow(T a, ll n, T p) {	if(n==0) return (T)1;  if (n == 1) return a % p;  if (n % 2 == 1) return (a * modpow(a, n - 1, p)) % p;  T t = modpow(a, n / 2, p);  return (t * t) % p;}
template<typename T>
T modinv(T a, T m) {	if(m==0)return (T)1;	T b = m, u = 1, v = 0;	while (b) {		T t = a / b;		a -= t * b; swap(a, b);		u -= t * v; swap(u, v);	}	u %= m;	if (u < 0) u += m;	return u;}
ll REM(ll a, ll b){ return (a % b + b) % b;}
ll QUO(ll a, ll b){ return (a - REM(a, b)) / b;}
/*
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> dist1(1, 100); [1,100]
int random_value = dist1(gen);
*/
/*
auto start = chrono::steady_clock::now(); //時間計測の開始
auto now = std::chrono::steady_clock::now(); //現在時刻と開始時刻の差を測定
double elapsed = std::chrono::duration<double>(now - start).count(); //時間をdouble型で取得
*/
/*
const int MAXCOMB=510000;
std::vector<mint> FAC(MAXCOMB), FINV(MAXCOMB), INV(MAXCOMB);
void COMinit() {FAC[0] = FAC[1] = 1;FINV[0] = FINV[1] = 1;INV[1] = 1;for (int i = 2; i < MAXCOMB; i++) {FAC[i] = FAC[i - 1] * i;INV[i] = mint(0) - INV[mint::mod() % i] * (mint::mod() / i);FINV[i] = FINV[i - 1] * INV[i];}}
mint COM(int n, int k) {if (n < k) return 0;if (n < 0 || k < 0) return 0;return FAC[n] * FINV[k] * FINV[n - k];}
*/

template <typename T> inline bool chmax(T &a, T b) { return ((a < b) ? (a = b, true) : (false));}
template <typename T> inline bool chmin(T &a, T b) { return ((a > b) ? (a = b, true) : (false));}

/////////////////////////////////////////////////////////////////////////////////////////
int SOLVEFIN = 0;

struct cube{
    vector<int> face = {-1,-1,-1,-1,-1,-1}; //0上,1左,2下,3右
    int x = 0;
    int y = 0;
};

void upmove(cube &cub)
{
    vector<int> face = cub.face;
    vector<int> newface(6,-1);
    newface[0] = face[3];
    newface[3] = face[5];
    newface[5] = face[1];
    newface[1] = face[0];
    if(face[2]!=-1)
    newface[2] = (face[2] + 3) % 4;
    if(face[4]!=-1)
    newface[4] = (face[4] + 1) % 4;
    cub.face = newface;
}
void downmove(cube &cub){
    vector<int> face = cub.face;
    vector<int> newface(6,-1);
    newface[3] = face[0];
    newface[5] = face[3];
    newface[1] = face[5];
    newface[0] = face[1];
    if(face[2]!=-1)
    newface[2] = (face[2] + 1) % 4;
    if(face[4]!=-1)
    newface[4] = (face[4] + 3) % 4;
    cub.face = newface;
}
void rightmove(cube &cub){
    vector<int> face = cub.face;
    vector<int> newface(6,-1);
    if(face[4]!=-1)
        newface[5] = (face[4] + 3) % 4;
    else
        newface[5] = -1;
    if (face[5] != -1)
        newface[2] = (face[5] + 3) % 4;
    else
        newface[2] = -1;
    if (face[2] != -1)
        newface[0] = (face[2] + 3) % 4;
    else
        newface[0] = -1;
    if (face[0] != -1)
        newface[4] = (face[0] + 3) % 4;
    else
        newface[4] = -1;

    if (face[1] != -1)
        newface[1] = (face[1] + 3) % 4;
    if(face[3]!=-1)
        newface[3] = (face[3] + 1) % 4;
    cub.face = newface;
}
void leftmove(cube &cub){
    vector<int> face = cub.face;
    vector<int> newface(6,-1);
    if(face[4]!=-1)
        newface[0] = (face[4] + 1) % 4;
    else
        newface[0] = -1;
    if (face[2] != -1)
        newface[5] = (face[2] + 1) % 4;
    else
        newface[5] = -1;
    if (face[0] != -1)
        newface[2] = (face[0] + 1) % 4;
    else
        newface[2] = -1;
    if (face[5] != -1)
        newface[4] = (face[5] + 1) % 4;
    else
        newface[4] = -1;
    if (face[1] != -1)
        newface[1] = (face[1] + 1) % 4;
    if(face[3]!=-1)
        newface[3] = (face[3] + 3) % 4;
    cub.face = newface;
}
void rotate(cube &cub){
    vector<int> face = cub.face;
    vector<int> newface(6,-1);
    newface[2] = face[1];
    if(face[2]!=-1)
        newface[3] = (face[2]+2)%4;
    else
        newface[3] = -1;
    if(face[3]!=-1)
        newface[4] = (face[3]+2)%4;
    else
        newface[4] = -1;
    newface[1] = face[4];

    if (face[5] != -1)
        newface[5] = (face[5] + 1) % 4;
    if(face[0]!=-1)
        newface[0] = (face[0] + 3) % 4;
    cub.face = newface;
}
void add_face(cube &cub, char u){
    if(cub.face[0]==-1){
        if(u=='^')
            cub.face[0] = 2;
        if(u=='<')
            cub.face[0] = 1;
        if(u=='v')
            cub.face[0] = 0;
        if(u=='>')
            cub.face[0] = 3;
    }
}
int diff(cube &cub1, cube &cub2){
    int ans = 0;
    rep(i, 6)
    {
        if(cub1.face[i]!=cub2.face[i])
            ans++;
    }
    // cout << "DIFF1: ";
    // rep(i, 6)
    // {
    //     cout << cub1.face[i] << " ";
    // }
    // cout << endl;
    // cout << "DIFF2: ";
    // rep(i, 6)
    // {
    //     cout << cub2.face[i] << " ";
    // }
    // cout << endl;
    return ans;
}

// ぽてじんをする！

void solve(){
    int n;
    cin >> n;
    if(n==0){
        SOLVEFIN = 1;
        return;
    }
    vector<string> s(5 * n);
    rep(i, 5 * n) cin >> s[i];
    vector<cube> cubes(n);
    vector<int> dx = {0, 1, 0, -1};
    vector<int> dy = {1, 0, -1, 0};
    vector<vector<int>> seen(5, vi(5, 0));

    auto dfs = [&](auto &&dfs, int i) -> void
    {
        add_face(cubes[i], s[i * 5 + cubes[i].x][cubes[i].y]);
        seen[cubes[i].x][cubes[i].y] = 1;
        pii now = {cubes[i].x, cubes[i].y};
        rep(dir, 4)
        {
            int nx = now.fi + dx[dir];
            int ny = now.se + dy[dir];
            if (nx < 0 || ny < 0 || nx >= 5 || ny >= 5)
                continue;
            if (seen[nx][ny] != 0)
                continue;
            if(s[i*5+nx][ny]=='.')
                continue;
            seen[nx][ny] = 1;
            if (dir == 0)
            {
                rightmove(cubes[i]);
                cubes[i].y++;
                dfs(dfs, i);
                leftmove(cubes[i]);
                cubes[i].y--;
            }
            if (dir == 1)
            {
                downmove(cubes[i]);
                cubes[i].x++;
                dfs(dfs, i);
                upmove(cubes[i]);
                cubes[i].x--;
            }
            if (dir == 2)
            {
                leftmove(cubes[i]);
                cubes[i].y--;
                dfs(dfs, i);
                rightmove(cubes[i]);
                cubes[i].y++;
            }
            if (dir == 3)
            {
                upmove(cubes[i]);
                cubes[i].x--;
                dfs(dfs, i);
                downmove(cubes[i]);
                cubes[i].x++;
            }
        }
    };

    rep(i,n){
        rep(j,5){
            rep(k,5){
                seen[j][k] = 0;
            }
        }
        rep(j,5){
            int fin = 0;
            rep(k, 5)
            {
                if(s[i*5+j][k]!='.'){
                    cubes[i].x=j;
                    cubes[i].y = k;
                    dfs(dfs, i);
                    fin=1;
                    break;
                }
            }
            if(fin)
                break;
        }
    }
    // rep(i,n){
    //     rep(j,6){
    //         cout << cubes[i].face[j] << " ";
    //     }
    //     cout << endl;
    // }

    vector<vi> ans(n, vi(n,inf));
    rep(i, n)
    {
        rep(j,n){
            if(i==j)
                ans[i][j] = 0;
            if (i >= j)
                continue;
            cube cubei = cubes[i];
            rep(k, 4) {
                chmin(ans[i][j], diff(cubei, cubes[j]));
                rotate(cubei);
            }
            upmove(cubei);
            rep(k, 4)
            {
                chmin(ans[i][j], diff(cubei, cubes[j]));
                rotate(cubei);
            }
            upmove(cubei);
            rep(k, 4)
            {
                chmin(ans[i][j], diff(cubei, cubes[j]));
                rotate(cubei);
            }
            upmove(cubei);
            rep(k, 4)
            {
                chmin(ans[i][j], diff(cubei, cubes[j]));
                rotate(cubei);
            }
            upmove(cubei);
            leftmove(cubei);
            rep(k, 4)
            {
                chmin(ans[i][j], diff(cubei, cubes[j]));
                rotate(cubei);
            }
            upmove(cubei);
            upmove(cubei);
            rep(k, 4)
            {
                chmin(ans[i][j], diff(cubei, cubes[j]));
                rotate(cubei);
            }
            ans[j][i] = ans[i][j];
        }
    }
    rep(i,n){
        rep(j,n){
            cout << ans[i][j];
        }
        cout << endl;
    }
}

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);
	while(SOLVEFIN == 0) solve();
}
accuracy: 1
time_ms: 710
memory_kb: 3840
final_rank: 19

code_snippet: #include <bits/stdc++.h>
// #include <atcoder/all>
using namespace std;
// using namespace atcoder;
#define rep(i,t,n) for(long long i=t;i<n;i++)
#define rep2(i,A) for(auto &i:A)
#define Sort(a) sort(a.begin(),a.end())
#define rSort(a,n,m) sort(a.begin()+n,a.begin()+m+1)
#define Reverse(a) reverse(a.begin(),a.end())
#define rReverse(a,n,m) reverse(a.begin()+n,a.begin()+m+1)
#define MOD1 998244353LL
#define MOD2 1000000007LL
#define sign(i) -1*pow(-1,i)
#define vi(A,N,i)  vector<long long> A(N,i)
#define vd(A,N,i)  vector<double> A(N,i)
#define vc(A,N,i)  vector<char> A(N,i)
#define vs(A,N,i)  vector<string> A(N,i)
#define vb(A,N,i)  vector<bool> A(N,i)
#define vp(A,N,i)  vector<Pair> A(N,{i,i})
#define vvi(A,N,M,i) vector<vector<long long>> A(N,vector<long long>(M,i))
#define vvp(A,N,M,i) vector<vector<Pair>> A(N,vector<Pair>(M,{i,i}))
#define vvd(A,N,M,i) vector<vector<double>> A(N,vector<double>(M,i))
#define vvc(A,N,M,i) vector<vector<char>> A(N,vector<char>(M,i))
#define vvb(A,N,M,i) vector<vector<bool>> A(N,vector<bool>(M,i))
#define vvs(A,N,M,i) vector<vector<string>> A(N,vector<string>(M,i))
#define vvvi(A,N,M,L,i) vector<vector<vector<ll>>> A(N,vector<vector<ll>>(M,vector<ll>(L,i)))
#define vvvs(A,N,M,L,i) vector<vector<vector<string>>> A(N,vector<vector<string>>(M,vector<string>(L,i)))
#define ll long long
#define INF ((1LL<<62)-(1LL<<31))
#define ALL(a) (a).begin(),(a).end()
template<typename T>
void CIN(vector<T> &A){
  rep(i,0,(ll)A.size()){
    cin>>A[i];
  }
  return;
}
using VVi=vector<vector<ll>>;
using Pair=pair<ll,ll>;
using graphi=vector<vector<ll>>;
using graphp=vector<vector<Pair>>;
vector<ll> X={1,0,-1,0},Y={0,1,0,-1};
vector<vector<string>>TEN={
    {
    ".o.",
    "ooo",
    ".o.",
    ".o.",
    },
    {
    "ooo",
    ".o.",
    ".o.",
    ".o.",
    },
    {
    "oo.",
    ".oo",
    ".o.",
    ".o.",
    },
    {
    "oo.",
    ".o.",
    ".oo",
    ".o.",
    },
    {
    "oo.",
    ".o.",
    ".o.",
    ".oo",
    },
    {
    ".o.",
    "oo.",
    ".oo",
    ".o.",
    },
    {
    "o..",
    "ooo",
    ".o.",
    ".o.",
    },
    {
    "o..",
    "oo.",
    ".oo",
    ".o.",
    },
    {
    "o..",
    "oo.",
    ".oo",
    "..o",
    },
    {
    "o..",
    "oo.",
    ".o.",
    ".oo",
    },
    {
    "o.",
    "o.",
    "oo",
    ".o",
    ".o",
    }
};
void rot(vector<string>&A){
    vs(ret,5,".....");
    rep(i,0,5){
        rep(j,0,5){
            if(A[j][4-i]=='^')ret[i][j]='<';
            else if(A[j][4-i]=='<')ret[i][j]='v';
            else if(A[j][4-i]=='v')ret[i][j]='>';
            else if(A[j][4-i]=='>')ret[i][j]='^';
            else if(A[j][4-i]=='.')ret[i][j]='.';
        }
    }
    A=ret;
    return;
}
void rev(vector<string>&A){
    vs(ret,5,".....");
    rep(i,0,5){
        rep(j,0,5){
            if(A[i][4-j]=='^')ret[i][j]='^';
            else if(A[i][4-j]=='<')ret[i][j]='>';
            else if(A[i][4-j]=='v')ret[i][j]='v';
            else if(A[i][4-j]=='>')ret[i][j]='<';
            else if(A[i][4-j]=='.')ret[i][j]='.';
        }
    }
    A=ret;
    return;
}
void rev2(vector<string>&A){
    vs(ret,4,"...");
    rep(i,0,4){
        rep(j,0,3){
            if(A[i][2-j]=='^')ret[i][j]='^';
            else if(A[i][2-j]=='<')ret[i][j]='>';
            else if(A[i][2-j]=='v')ret[i][j]='v';
            else if(A[i][2-j]=='>')ret[i][j]='<';
            else if(A[i][2-j]=='.')ret[i][j]='.';
        }
    }
    A=ret;
    return;
}
pair<bool,pair<int,int>> match(vector<string>&A,vector<string>&B){
    // rep2(i,A)cerr<<i<<endl;cerr<<endl;
    // rep2(i,B)cerr<<i<<endl;cerr<<endl;
    ll Bx,By;
    Bx=B.size();
    By=B[0].size();
    bool f=0;
    int res1,res2;
    rep(i,0,5-Bx+1){
        rep(j,0,5-By+1){
            bool f2=1;
            rep(k,0,Bx){
                rep(l,0,By){
                    if(B[k][l]=='.'){
                        if(A[k+i][l+j]!='.'){
                            f2=false;
                        }
                    }else{
                        if(A[k+i][l+j]=='.'){
                            f2=false;
                        }
                    }
                }
            }
            if(f2){
                res1=i,res2=j;
            }
            f|=f2;
        }
    }
    return {f,{res1,res2}};
}
char rot2(char s,int cnt){
    rep(i,0,cnt){
        if(s=='^')s='<';
        else if(s=='<')s='v';
        else if(s=='v')s='>';
        else if(s=='>')s='^';
    }
    return s;
}
void rot3(vector<string>&A){
    vs(ret,4,"...");
    ret[1][0]=rot2(A[0][1],1);
    ret[2][1]=rot2(A[1][0],1);
    ret[1][1]=rot2(A[1][1],1);
    ret[0][1]=rot2(A[1][2],1);
    ret[1][2]=rot2(A[2][1],1);
    ret[3][1]=rot2(A[3][1],3);
    
    A=ret;
    // rep2(i,A)cout<<i<<endl;cout<<endl;
    return;
}
void zur(vector<string>&A){
    vs(ret,4,"...");
    ret[0][1]=rot2(A[1][1],0);
    ret[1][0]=rot2(A[1][0],1);
    ret[1][1]=rot2(A[2][1],0);
    ret[1][2]=rot2(A[1][2],3);
    ret[2][1]=rot2(A[3][1],0);
    ret[3][1]=rot2(A[0][1],0);
    
    
    A=ret;
    // rep2(i,A)cout<<i<<endl;cout<<endl;
    return;
}
ll calc(vector<string>&A,vector<string>&B){
    ll ret=0;
    rep(i,0,4){
        rep(j,0,3){
            if(A[i][j]!=B[i][j])ret++;
        }
    }
    return ret; 
}
int main(){
    while(1){
        // cerr<<"SOLVE"<<endl;
        int N;
        cin>>N;
        if(N==0)break;
        vvs(A,N,5,"");
        vvs(F,N,4,"...");
        
        vector<pair<vector<string>,pair<ll,pair<ll,ll>>>>OK(N);
        rep(i,0,N){
            int ww=0;
            CIN(A[i]);
            // if(N==200){
            //     if(i==0){
            //         rep2(k,A[i])cerr<<k<<endl;cerr<<endl;
            //     }
                
            //     if(i==43){
            //         rep2(k,A[i])cerr<<k<<endl;cerr<<endl;
            //     }    
            // }
            rep(l,0,4){
                rep(j,0,11){
                    pair<bool,pair<int,int>> t=match(A[i],TEN[j]);
                    if(t.first){
                        OK[i]={A[i],{j,t.second}};
                        // cerr<<j<<endl;
                    }
                }
                rot(A[i]);
            }
            rev(A[i]);
            rep(l,0,4){
                rep(j,0,11){
                    pair<bool,pair<int,int>> t=match(A[i],TEN[j]);
                    if(t.first){
                        OK[i]={A[i],{j,t.second}};
                        ww=1;
                        // cerr<<j<<endl;
                    }
                }
                rot(A[i]);
            }
            
            
            int x=OK[i].second.second.first;
            int y=OK[i].second.second.second;
            if(OK[i].second.first==0){
                F[i][0][1]=rot2(OK[i].first[0+x][1+y],0);
                F[i][1][0]=rot2(OK[i].first[1+x][0+y],0);
                F[i][1][1]=rot2(OK[i].first[1+x][1+y],0);
                F[i][1][2]=rot2(OK[i].first[1+x][2+y],0);
                F[i][2][1]=rot2(OK[i].first[2+x][1+y],0);
                F[i][3][1]=rot2(OK[i].first[3+x][1+y],0);
            }
            if(OK[i].second.first==1){
                F[i][0][1]=rot2(OK[i].first[0+x][1+y],0);
                F[i][1][0]=rot2(OK[i].first[0+x][0+y],1);
                F[i][1][1]=rot2(OK[i].first[1+x][1+y],0);
                F[i][1][2]=rot2(OK[i].first[0+x][2+y],3);
                F[i][2][1]=rot2(OK[i].first[2+x][1+y],0);
                F[i][3][1]=rot2(OK[i].first[3+x][1+y],0);
            }
            if(OK[i].second.first==2){
                F[i][0][1]=rot2(OK[i].first[0+x][1+y],0);
                F[i][1][0]=rot2(OK[i].first[0+x][0+y],1);
                F[i][1][1]=rot2(OK[i].first[1+x][1+y],0);
                F[i][1][2]=rot2(OK[i].first[1+x][2+y],0);
                F[i][2][1]=rot2(OK[i].first[2+x][1+y],0);
                F[i][3][1]=rot2(OK[i].first[3+x][1+y],0);
            }
            if(OK[i].second.first==3){
                F[i][0][1]=rot2(OK[i].first[0+x][1+y],0);
                F[i][1][0]=rot2(OK[i].first[0+x][0+y],1);
                F[i][1][1]=rot2(OK[i].first[1+x][1+y],0);
                F[i][1][2]=rot2(OK[i].first[2+x][2+y],1);
                F[i][2][1]=rot2(OK[i].first[2+x][1+y],0);
                F[i][3][1]=rot2(OK[i].first[3+x][1+y],0);
            }
            if(OK[i].second.first==4){
                F[i][0][1]=rot2(OK[i].first[0+x][1+y],0);
                F[i][1][0]=rot2(OK[i].first[0+x][0+y],1);
                F[i][1][1]=rot2(OK[i].first[1+x][1+y],0);
                F[i][1][2]=rot2(OK[i].first[3+x][2+y],2);
                F[i][2][1]=rot2(OK[i].first[2+x][1+y],0);
                F[i][3][1]=rot2(OK[i].first[3+x][1+y],0);
            }
            if(OK[i].second.first==5){
                F[i][0][1]=rot2(OK[i].first[0+x][1+y],0);
                F[i][1][0]=rot2(OK[i].first[1+x][0+y],0);
                F[i][1][1]=rot2(OK[i].first[1+x][1+y],0);
                F[i][1][2]=rot2(OK[i].first[2+x][2+y],1);
                F[i][2][1]=rot2(OK[i].first[2+x][1+y],0);
                F[i][3][1]=rot2(OK[i].first[3+x][1+y],0);
            }
            if(OK[i].second.first==6){
                F[i][0][1]=rot2(OK[i].first[0+x][0+y],3);
                F[i][1][0]=rot2(OK[i].first[1+x][0+y],0);
                F[i][1][1]=rot2(OK[i].first[1+x][1+y],0);
                F[i][1][2]=rot2(OK[i].first[1+x][2+y],0);
                F[i][2][1]=rot2(OK[i].first[2+x][1+y],0);
                F[i][3][1]=rot2(OK[i].first[3+x][1+y],0);
            }
            if(OK[i].second.first==7){
                F[i][0][1]=rot2(OK[i].first[0+x][0+y],3);
                F[i][1][0]=rot2(OK[i].first[1+x][0+y],0);
                F[i][1][1]=rot2(OK[i].first[1+x][1+y],0);
                F[i][1][2]=rot2(OK[i].first[2+x][2+y],1);
                F[i][2][1]=rot2(OK[i].first[2+x][1+y],0);
                F[i][3][1]=rot2(OK[i].first[3+x][1+y],0);
            }
            if(OK[i].second.first==8){
                F[i][0][1]=rot2(OK[i].first[0+x][0+y],3);
                F[i][1][0]=rot2(OK[i].first[1+x][0+y],0);
                F[i][1][1]=rot2(OK[i].first[1+x][1+y],0);
                F[i][1][2]=rot2(OK[i].first[2+x][2+y],1);
                F[i][2][1]=rot2(OK[i].first[2+x][1+y],0);
                F[i][3][1]=rot2(OK[i].first[3+x][2+y],3);
            }
            if(OK[i].second.first==9){
                F[i][0][1]=rot2(OK[i].first[0+x][0+y],3);
                F[i][1][0]=rot2(OK[i].first[1+x][0+y],0);
                F[i][1][1]=rot2(OK[i].first[1+x][1+y],0);
                F[i][1][2]=rot2(OK[i].first[3+x][2+y],2);
                F[i][2][1]=rot2(OK[i].first[2+x][1+y],0);
                F[i][3][1]=rot2(OK[i].first[3+x][1+y],0);
            }
            if(OK[i].second.first==10){
                F[i][0][1]=rot2(OK[i].first[1+x][0+y],3);
                F[i][1][0]=rot2(OK[i].first[2+x][0+y],0);
                F[i][1][1]=rot2(OK[i].first[2+x][1+y],0);
                F[i][1][2]=rot2(OK[i].first[0+x][0+y],2);
                F[i][2][1]=rot2(OK[i].first[3+x][1+y],0);
                F[i][3][1]=rot2(OK[i].first[4+x][1+y],0);
            }
            if(ww){
                rev2(F[i]);
            }
            // rep(l,0,5){
            //     vector<string> t=OK[i].first;
            //     cerr<<t[l]<<endl;
            // }
            // cerr<<endl;
            // rep(l,0,4){
            //     vector<string> t=F[i];
            //     cerr<<t[l]<<endl;
            // }
            // cerr<<endl;
        }
        
        rep(i,0,N){
            rep(j,0,N){
                // if(i==0&&j==1){
                    
                // }else continue;
                // if(i!=j&&i==0){
                //     rep2(k,F[i])cerr<<k<<endl;
                //     rep2(k,F[j])cerr<<k<<endl;
                // }
                
                ll ans=188;
                {
                    rep(k,0,4){
                        ans=min(ans,calc(F[i],F[j]));
                        rot3(F[i]);
                    }
                    zur(F[i]);
                }
                {
                    rep(k,0,4){
                        ans=min(ans,calc(F[i],F[j]));
                        rot3(F[i]);
                    }
                    zur(F[i]);
                }
                {
                    rep(k,0,4){
                        ans=min(ans,calc(F[i],F[j]));
                        rot3(F[i]);
                    }
                    zur(F[i]);
                }
                {
                    rep(k,0,4){
                        ans=min(ans,calc(F[i],F[j]));
                        rot3(F[i]);
                    }
                    zur(F[i]);
                    rot3(F[i]);
                    zur(F[i]);
                }
                {
                    rep(k,0,4){
                        ans=min(ans,calc(F[i],F[j]));
                        rot3(F[i]);
                    }
                    zur(F[i]);
                }
                {
                    rep(k,0,4){
                        ans=min(ans,calc(F[i],F[j]));
                        rot3(F[i]);
                    }
                    zur(F[i]);
                }
                {
                    rep(k,0,4){
                        ans=min(ans,calc(F[i],F[j]));
                        rot3(F[i]);
                    }
                    zur(F[i]);
                }
                {
                    rep(k,0,4){
                        ans=min(ans,calc(F[i],F[j]));
                        rot3(F[i]);
                    }
                    zur(F[i]);
                    rot3(F[i]);
                    zur(F[i]);
                }
                cout<<ans;
                // if(N==200){
                //     if(ans!=0){
                //         cout<<i<<" "<<j<<endl;
                //     }
                // }
            }
            cout<<endl;
        }
    }
    // vector<string>G={
    //     ".^.",
    //     "^^^",
    //     ".^.",
    //     ".^.",
    // };
    // rep2(i,G)cout<<i<<endl;
    // rot3(G);
    // rep2(i,G)cout<<i<<endl;
    
    // zur(G);
    // rep2(i,G)cout<<i<<endl;
    // cerr<<rot2('^',2)<<endl;
    // cerr<<rot2('^',2)<<endl;
    // cerr<<rot2('^',2)<<endl;
    // cerr<<rot2('^',2)<<endl;
    // cerr<<rot2('^',2)<<endl;
}
accuracy: 1
time_ms: 3370
memory_kb: 3584
final_rank: 16

code_snippet: #include<iostream>
#include<queue>
#include<vector>
using namespace std;
int N;
int dx[4]={-1,0,1,0};
int dy[4]={0,-1,0,1};
int char2int(char c)
{
	if(c=='^')return 0;
	else if(c=='<')return 1;
	else if(c=='v')return 2;
	else return 3;
}
int dir_rev[4]={2,3,0,1};
struct dice{
	int d[6];
	void rotate(int dir)
	{
		if(dir==0)
		{
			int tmp;
			tmp=d[0];d[0]=d[4];d[4]=d[5];d[5]=d[1];d[1]=tmp;
			d[2]=(d[2]+1)%4;
			d[3]=(d[3]+3)%4;
		}
		else if(dir==1)
		{
			int tmp;
			tmp=d[0];
			d[0]=(d[3]+3)%4;
			d[3]=(d[5]+3)%4;
			d[5]=(d[2]+3)%4;
			d[2]=(tmp+3)%4;
			d[1]=(d[1]+3)%4;
			d[4]=(d[4]+1)%4;
		}
		else if(dir==2)
		{
			rotate(0);
			rotate(0);
			rotate(0);
		}
		else
		{
			rotate(1);
			rotate(1);
			rotate(1);
		}
	}
	void shift()
	{
		d[0]=(d[0]+1)%4;
		d[5]=(d[5]+3)%4;
		int tmp;
		tmp=d[4];
		d[4]=dir_rev[d[2]%4];
		d[2]=d[1];
		d[1]=d[3];
		d[3]=dir_rev[tmp%4];
	}
};
dice input_use;
string s[5];
bool vis[5][5];
void dfs(int x,int y)
{
	vis[x][y]=true;
	input_use.d[0]=char2int(s[x][y]);
	for(int r=0;r<4;r++)
	{
		int tx=x+dx[r],ty=y+dy[r];
		if(tx<0||ty<0||tx>=5||ty>=5||s[tx][ty]=='.'||vis[tx][ty])continue;
		input_use.rotate(r);
		dfs(tx,ty);
		input_use.rotate(dir_rev[r]);
	}
}
dice input(){
	int sx,sy;
	for(int i=0;i<5;i++)
	{
		cin>>s[i];
		for(int j=0;j<5;j++)if(s[i][j]!='.')sx=i,sy=j;
	}
	for(int i=0;i<5;i++)for(int j=0;j<5;j++)vis[i][j]=false;
	dfs(sx,sy);
	return input_use;
};
int diff_use(const dice&A,const dice&B)
{
	int ret=0;
	for(int r=0;r<6;r++)ret+=A.d[r]!=B.d[r];
	return ret;
}
int diff(const dice&A,dice B)
{
	int ret=9;
	for(int v=0;v<4;v++)
	{
		for(int r=0;r<4;r++)
		{
			for(int u=0;u<4;u++)
			{
				ret=min(ret,diff_use(A,B));
				B.shift();
			}
			B.rotate(0);
		}
		B.rotate(1);
	}
	return ret;
}
int main()
{
	while(cin>>N,N)
	{
		vector<dice>A(N);
		for(int i=0;i<N;i++)A[i]=input();
		for(int i=0;i<N;i++)
		{
			for(int j=0;j<N;j++)
			{
				cout<<(i==j?0:diff(A[i],A[j]));
			}
			cout<<endl;
		}
	}
}
accuracy: 1
time_ms: 630
memory_kb: 3456
final_rank: 6

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

int dx[4] = {1,0,-1,0}, dy[4] = {0,1,0,-1};
int rotid[4][6] = {{4,0,2,3,5,1},{3,1,0,5,4,2},{1,5,2,3,0,4},{2,1,5,0,4,3}};
map<char,int> mp;

struct Dice {
    int A[6];
};

Dice Rot(Dice D, int dir) {
    Dice Ret;
    rep(i,0,6) Ret.A[i] = D.A[rotid[dir][i]];
    return Ret;
}

Dice Rot2(Dice D, int dir) {
    Dice Ret;
    rep(i,0,6) Ret.A[i] = rotid[dir^2][D.A[rotid[dir][i]]];
    return Ret;
}

Dice init(vector<vector<char>>& C) {
    vector<vector<Dice>> B(5,vector<Dice>(5));
    vector<vector<bool>> used(5,vector<bool>(5,false));
    rep(i,0,5) {
        rep(j,0,5) {
            if (C[i][j] != '.' && !used[i][j]) {
                queue<pair<int,int>> Q;
                Q.push({i,j});
                used[i][j] = true;
                rep(k,0,6) B[i][j].A[k] = k;
                while(!Q.empty()) {
                    auto [X,Y] = Q.front();
                    Q.pop();
                    rep(k,0,4) {
                        int NX = X + dx[k], NY = Y + dy[k];
                        if (0 <= NX && NX < 5 && 0 <= NY && NY < 5) {
                            if (C[NX][NY] != '.' && !used[NX][NY]) {
                                B[NX][NY] = Rot(B[X][Y],k);
                                Q.push({NX,NY});
                                used[NX][NY] = true;
                            }
                        }
                    }
                }
            }
        }
    }
    Dice Ret;
    rep(i,0,5) {
        rep(j,0,5) {
            if (C[i][j] != '.') {
                Ret.A[B[i][j].A[5]] = B[i][j].A[mp[C[i][j]]];
            }
        }
    }
    return Ret;
}

int Diff(Dice A, Dice B) {
    int Ret = 0;
    rep(i,0,6) if (A.A[i] != B.A[i]) Ret++;
    return Ret;
}

int Solve(Dice A, Dice B) {
    int Ret = 6;
    rep(i,0,2) {
        rep(j,0,4) {
            rep(k,0,4) {
                chmin(Ret,Diff(A,B));
                B = Rot2(B,0);
            }
            B = Rot2(B,1);
        }
        B = Rot2(B,0);
    }
    return Ret;
}

int main() {
    mp['v'] = 1;
    mp['>'] = 2;
    mp['<'] = 3;
    mp['^'] = 4;
while(1) {
    int N;
    cin >> N;
    if (N == 0) return 0;
    vector<Dice> D(N);
    rep(i,0,N) {
        vector<vector<char>> C(5,vector<char>(5));
        rep(j,0,5) rep(k,0,5) cin >> C[j][k];
        D[i] = init(C);
    }
    rep(i,0,N) {
        rep(j,0,N) {
            cout << Solve(D[i],D[j]);
        }
        cout << endl;
    }
}
}
accuracy: 1
time_ms: 650
memory_kb: 3472
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<vvb> vvvb;
typedef vector<vvvb> vvvvb;
typedef pair<ll,ll> pi;
typedef pair<ll,pi> ppi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define RFOR(i,l,r) for(ll i=r-1;i>=l;i--)
#define RREP(i,n) RFOR(i,0,n)
#define sz(A) (ll)(A.size())
#define ALL(A) A.begin(),A.end()
#define LB(A,x) (ll)(lower_bound(ALL(A),x)-A.begin())
#define UB(A,x) (ll)(upper_bound(ALL(A),x)-A.begin())
#define COU(A,x) (UB(A,x)-LB(A,x))
#define F first
#define S second
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
template<typename T1,typename T2>ostream&operator<<(ostream&os,pair<T1,T2>&p){os<<p.F<<" "<<p.S;return os;}
template<typename T1,typename T2>istream&operator>>(istream&is,pair<T1,T2>&p){is>>p.F>>p.S;return is;}
template<typename T>ostream&operator<<(ostream&os,vector<T>&v){REP(i,sz(v))os<<v[i]<<(i+1!=sz(v)?" ":"");return os;}
template<typename T>istream&operator>>(istream&is,vector<T>&v){for(T&in:v)is>>in;return is;}
template<class T>bool chmax(T&a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T>bool chmin(T&a,T b){if(b<a){a=b;return 1;}return 0;}
const ll mod=998244353;
template<const long long int mod=998244353>
struct modint{
  using mint=modint<mod>;
  long long int x;
  modint(long long int _x=0):x(_x%mod){if(x<0)x+=mod;}
  long long int val(){return x;}
  mint&operator=(const mint&a){x=a.x;return *this;}
  mint&operator+=(const mint&a){x+=a.x;if(x>=mod)x-=mod;return *this;}
  mint&operator-=(const mint&a){x-=a.x;if(x<0)x+=mod;return *this;}
  mint&operator*=(const mint&a){x*=a.x;x%=mod;return *this;}
  friend mint operator+(const mint&a,const mint&b){return mint(a)+=b;}
  friend mint operator-(const mint&a,const mint&b){return mint(a)-=b;}
  friend mint operator*(const mint&a,const mint&b){return mint(a)*=b;}
  mint operator-()const{return mint(0)-*this;}
  mint pow(long long int n){
    if(!n)return 1;
    mint a=1;
    mint _x=x;
    while(n){
      if(n&1)a*=_x;
      _x=_x*_x;n>>=1;
    }
    return a;
  }
  mint inv(){return pow(mod-2);}
  mint&operator/=(mint&a){return *this*=a.inv();}
  friend mint operator/(const mint&a,mint b){return mint(a)/=b;}
};
using mint=modint<998244353>;
//udlrfb
vi nexL={2,3,1,0,4,5},nexR={3,2,0,1,4,5},nexF={4,5,2,3,1,0},nexB={5,4,2,3,0,1},nexU={1,0,3,2,4,5};
struct dice{
    vi d;
    dice rotL(){
        vi ret(6);
        REP(i,6)ret[i]=nexL[d[nexR[i]]];
        return dice{ret};
    }
    dice rotU(){
        vi ret(6);
        REP(i,6)ret[i]=nexU[d[nexU[i]]];
        return dice{ret};
    }
    dice rotR(){
        vi ret(6);
        REP(i,6)ret[i]=nexR[d[nexL[i]]];
        return dice{ret};
    }
    dice rotD(){return *this;}
    dice rotF(){
        vi ret(6);
        REP(i,6)ret[i]=nexF[d[nexB[i]]];
        return dice{ret};
    };
    dice rotB(){
        vi ret(6);
        REP(i,6)ret[i]=nexB[d[nexF[i]]];
        return dice{ret};
    }
    dice re(int i){
        if(i==0)return rotD();
        else if(i==1)return rotU();
        else if(i==2)return rotF();
        else if(i==3)return rotB();
        else if(i==4)return rotL();
        else return rotR();
    }
    dice one_rotate(){
        vi nex={0,1,4,5,3,2},pre={0,1,5,4,2,3};
        vi ret(6);
        REP(i,6)ret[i]=nex[d[pre[i]]];
        return dice{ret};
    }
    dice rotate(int i){
        dice ret=*this;
        REP(_,i)ret=ret.one_rotate();
        return ret;
    }
};
dice f(vector<string>S){
    vi ret(6);
    REP(i,5)REP(j,5)if(S[i][j]!='.'){
        vvb seen(5,vb(5));
        vi state={0,1,2,3,4,5};
        function<void(ll,ll)>dfs=[&](ll x,ll y){
            seen[x][y]=1;
            if(S[x][y]=='<')ret[state[0]]=state[2];
            else if(S[x][y]=='>')ret[state[0]]=state[3];
            else if(S[x][y]=='v')ret[state[0]]=state[4];
            else ret[state[0]]=state[5];
            if(x&&S[x-1][y]!='.'&&!seen[x-1][y]){
                vi _state=state;
                REP(i,6)state[i]=_state[nexB[i]];
                dfs(x-1,y);
                state=_state;
            }
            if(x+1<5&&S[x+1][y]!='.'&&!seen[x+1][y]){
                vi _state=state;
                REP(i,6)state[i]=_state[nexF[i]];
                dfs(x+1,y);
                state=_state;
            }
            if(y&&S[x][y-1]!='.'&&!seen[x][y-1]){
                vi _state=state;
                REP(i,6)state[i]=_state[nexL[i]];
                dfs(x,y-1);
                state=_state;
            }
            if(y+1<5&&S[x][y+1]!='.'&&!seen[x][y+1]){
                vi _state=state;
                REP(i,6)state[i]=_state[nexR[i]];
                dfs(x,y+1);
                state=_state;
            }
        };
        dfs(i,j);
        i=j=5;break;
    }
    return dice{ret};
};
ll same_diff(dice D1,dice D2){
    ll ret=0;
    REP(i,6)ret+=D1.d[i]!=D2.d[i];
    return ret;
}
char diff(dice D1,dice D2){
    ll ans=6;
    REP(i,6)REP(j,4)chmin(ans,same_diff(D1,D2.re(i).rotate(j)));
    return '0'+ans;
};
int main(){
    while(1){
        int N;cin>>N;
        if(!N)return 0;
        vector<dice>D(N);
        REP(i,N){
            vector<string>S(5);cin>>S;
            D[i]=f(S);
        }
        vector<string>ans(N,string(N,'6'));
        REP(i,N)REP(j,N)ans[i][j]=diff(D[i],D[j]);
        REP(i,N)cout<<ans[i]<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 5280
memory_kb: 3436
final_rank: 17

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

struct dice {
    array<bool, 4> f = {}, b = {}, u = {}, d = {}, l = {}, r = {};
};
dice RX(dice x) {
    dice y;
    y.f = x.u;
    y.b = x.d;
    y.u = x.b;
    y.d = x.f;
    y.l[0] = x.l[1];
    y.l[1] = x.l[2];
    y.l[2] = x.l[3];
    y.l[3] = x.l[0];

    y.r[0] = x.r[3];
    y.r[1] = x.r[0];
    y.r[2] = x.r[1];
    y.r[3] = x.r[2];
    return y;
}
dice RY(dice x) {
    dice y;
    y.f[0] = x.f[1];
    y.f[1] = x.f[2];
    y.f[2] = x.f[3];
    y.f[3] = x.f[0];

    y.b[0] = x.b[3];
    y.b[1] = x.b[0];
    y.b[2] = x.b[1];
    y.b[3] = x.b[2];

    y.u[0] = x.l[1];
    y.u[1] = x.l[2];
    y.u[2] = x.l[3];
    y.u[3] = x.l[0];

    y.d[0] = x.r[1];
    y.d[1] = x.r[2];
    y.d[2] = x.r[3];
    y.d[3] = x.r[0];

    y.l[0] = x.d[1];
    y.l[1] = x.d[2];
    y.l[2] = x.d[3];
    y.l[3] = x.d[0];

    y.r[0] = x.u[1];
    y.r[1] = x.u[2];
    y.r[2] = x.u[3];
    y.r[3] = x.u[0];
    return y;
}

void solve(int n) {
    vector<dice> ds;
    for(int _ : rep(n)) {
        vector<string> s = in(5);
        dice d;
        vector vis(5, vector(5, false));
        auto dfs = [&](auto self, int x, int y) -> void {
            if(s[x][y] == '<') d.d[0] = true;
            if(s[x][y] == '^') d.d[1] = true;
            if(s[x][y] == '>') d.d[2] = true;
            if(s[x][y] == 'v') d.d[3] = true;
            vis[x][y] = true;
            if(x + 1 < 5 and s[x + 1][y] != '.' and not vis[x + 1][y]) {
                d = RX(d);
                self(self, x + 1, y);
                d = RX(RX(RX(d)));
            }
            if(y + 1 < 5 and s[x][y + 1] != '.' and not vis[x][y + 1]) {
                d = RY(d);
                self(self, x, y + 1);
                d = RY(RY(RY(d)));
            }
            if(0 <= x - 1 and s[x - 1][y] != '.' and not vis[x - 1][y]) {
                d = RX(RX(RX(d)));
                self(self, x - 1, y);
                d = RX(d);
            }
            if(0 <= y - 1 and s[x][y - 1] != '.' and not vis[x][y - 1]) {
                d = RY(RY(RY(d)));
                self(self, x, y - 1);
                d = RY(d);
            }
        };

        [&] {
            for(int x : rep(5)) for(int y : rep(5)) {
                if(s[x][y] != '.') {
                    dfs(dfs, x, y);
                    return;
                }
            }
        }();
        ds.push_back(d);
    }

    auto diff = [&](dice& a, dice& b) {
        int cnt = 0;
        cnt += a.f != b.f;
        cnt += a.b != b.b;
        cnt += a.u != b.u;
        cnt += a.d != b.d;
        cnt += a.l != b.l;
        cnt += a.r != b.r;
        return cnt;
    };

    auto dist = [&](dice& a, dice& b) {
        int res = 6;
        for(int rx : rep(4)) {
            for(int ry : rep(4)) {
                chmin(res, diff(a, b));
                a = RY(a);
            }
            a = RX(a);
        }
        a = RX(RY(a));
        for(int ry : rep(4)) {
            chmin(res, diff(a, b));
            a = RY(a);
        }
        a = RY(RY(RY(RX(RX(RX(a))))));
        a = RX(RX(RX(RY(a))));
        for(int ry : rep(4)) {
            chmin(res, diff(a, b));
            a = RY(a);
        }
        return res;
    };
    for(int i : rep(n)) {
        for(int j : rep(n)) cout << dist(ds[i], ds[j]); cout << "\n";
    }
}

int main() {
    while(true) {
        int n = in(); if(n == 0) return 0;
        solve(n);
    }
}
accuracy: 1
time_ms: 1280
memory_kb: 3404
final_rank: 6

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

struct dice {
    array<bool, 4> f = {}, b = {}, u = {}, d = {}, l = {}, r = {};
    bool operator==(dice x) {
        return this->f == x.f
           and this->b == x.b
           and this->u == x.u
           and this->d == x.d
           and this->l == x.l
           and this->r == x.r;
    }
};
dice RX(dice x) {
    dice y;
    y.f = x.u;
    y.b = x.d;
    y.u = x.b;
    y.d = x.f;
    y.l[0] = x.l[1];
    y.l[1] = x.l[2];
    y.l[2] = x.l[3];
    y.l[3] = x.l[0];

    y.r[0] = x.r[3];
    y.r[1] = x.r[0];
    y.r[2] = x.r[1];
    y.r[3] = x.r[2];
    return y;
}
dice RY(dice x) {
    dice y;
    y.f[0] = x.f[1];
    y.f[1] = x.f[2];
    y.f[2] = x.f[3];
    y.f[3] = x.f[0];

    y.b[0] = x.b[3];
    y.b[1] = x.b[0];
    y.b[2] = x.b[1];
    y.b[3] = x.b[2];

    y.u[0] = x.l[1];
    y.u[1] = x.l[2];
    y.u[2] = x.l[3];
    y.u[3] = x.l[0];

    y.d[0] = x.r[1];
    y.d[1] = x.r[2];
    y.d[2] = x.r[3];
    y.d[3] = x.r[0];

    y.l[0] = x.d[1];
    y.l[1] = x.d[2];
    y.l[2] = x.d[3];
    y.l[3] = x.d[0];

    y.r[0] = x.u[1];
    y.r[1] = x.u[2];
    y.r[2] = x.u[3];
    y.r[3] = x.u[0];
    return y;
}

void solve(int n) {
    vector<dice> ds;
    for(int _ : rep(n)) {
        vector<string> s = in(5);
        dice d;
        vector vis(5, vector(5, false));
        auto dfs = [&](auto self, int x, int y) -> void {
            if(s[x][y] == '<') d.d[0] = true;
            if(s[x][y] == '^') d.d[1] = true;
            if(s[x][y] == '>') d.d[2] = true;
            if(s[x][y] == 'v') d.d[3] = true;
            vis[x][y] = true;
            if(x + 1 < 5 and s[x + 1][y] != '.' and not vis[x + 1][y]) {
                d = RX(d);
                self(self, x + 1, y);
                d = RX(RX(RX(d)));
            }
            if(y + 1 < 5 and s[x][y + 1] != '.' and not vis[x][y + 1]) {
                d = RY(d);
                self(self, x, y + 1);
                d = RY(RY(RY(d)));
            }
            if(0 <= x - 1 and s[x - 1][y] != '.' and not vis[x - 1][y]) {
                d = RX(RX(RX(d)));
                self(self, x - 1, y);
                d = RX(d);
            }
            if(0 <= y - 1 and s[x][y - 1] != '.' and not vis[x][y - 1]) {
                d = RY(RY(RY(d)));
                self(self, x, y - 1);
                d = RY(d);
            }
        };

        [&] {
            for(int x : rep(5)) for(int y : rep(5)) {
                if(s[x][y] != '.') {
                    dfs(dfs, x, y);
                    return;
                }
            }
        }();
        ds.push_back(d);
    }

    auto diff = [&](dice& a, dice& b) {
        int cnt = 0;
        cnt += a.f != b.f;
        cnt += a.b != b.b;
        cnt += a.u != b.u;
        cnt += a.d != b.d;
        cnt += a.l != b.l;
        cnt += a.r != b.r;
        return cnt;
    };

    auto dist = [&](dice& a, dice& b) {
        int res = 6;
        for(int rx : rep(4)) {
            for(int ry : rep(4)) {
                chmin(res, diff(a, b));
                a = RY(a);
            }
            a = RX(a);
        }
        a = RX(RY(a));
        for(int ry : rep(4)) {
            chmin(res, diff(a, b));
            a = RY(a);
        }
        a = RY(RY(RY(RX(RX(RX(a))))));
        a = RX(RX(RX(RY(a))));
        for(int ry : rep(4)) {
            chmin(res, diff(a, b));
            a = RY(a);
        }
        return res;
    };
    for(int i : rep(n)) {
        for(int j : rep(n)) cout << dist(ds[i], ds[j]); cout << "\n";
    }
}

int main() {
    while(true) {
        int n = in(); if(n == 0) return 0;
        solve(n);
    }
}
accuracy: 1
time_ms: 1280
memory_kb: 3376
final_rank: 4

code_snippet: #include<bits/stdc++.h>
#include<cassert>

using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
#define rep(i,n) for(ll i=0;i<ll(n);i++)
#define all(A) A.begin(),A.end()

void chmax(ll& p, ll q) { p = max(p, q); };
void chmin(ll& p, ll q) { p = min(p, q); };

vll dx={1,0,-1,0};
vll dy={0,1,0,-1};
struct dice {
    vll D;
    //下前右奥左上

    void printpt(char C) {
        if (C == '.')return;
        if (C == '^')D[5] = 2;
        if (C == '>')D[5] = 3;
        if (C == '<')D[5] = 1;
        if (C == 'v')D[5] = 0;
        return;
    }


    void dfs(ll y,ll x,set<pair<ll,ll>>&seen,vector<string> &S){
        seen.insert({y,x});
        printpt(S[y][x]);
        rep(d,4){
            ll ny=y+dy[d];
            ll nx=x+dx[d];
            if(ny<0||nx<0||ny>=5||nx>=5)continue;
            if(seen.count({ny,nx}))continue;
            if(S[ny][nx]=='.')continue;
            if(d==2){
                rot(0);
                dfs(ny,nx,seen,S);
                rep(i,3)rot(0);
            }
            else if(d==0){
                rep(i,3)rot(0);
                dfs(ny,nx,seen,S);
                rot(0);
            }
            else if(d==3){
                rep(_,3)rot(1);
                rot(0);
                rot(1);
                dfs(ny,nx,seen,S);
                rep(_,3)rot(0);
                rot(1);
                rot(0);
            }
            else{
                rep(_,3)rot(0);
                rot(1);
                rot(0);
                dfs(ny,nx,seen,S);
                rep(_,3)rot(1);
                rot(0);
                rot(1);
            }
        }
    }

    //展開図からDを作る
    void printer(vector<string> S) {
        D.assign(6, 4);
        ll y = 0, x = 0;
        set<pair<ll, ll>> seen;
        rep(i, 5){
            rep(j, 5) {
                if (S[i][j] != '.') {
                    if(seen.count({i,j}))continue;
                    ll y = i;
                    ll x = j;
                    dfs(y,x,seen,S);
                }
            }
        }
    }

    //type=0:右を下に type=1:右を前に
    void rot(bool type = 0) {
        if (type) {
            vll ND(6);
            if (D[0] != 4)ND[0] = (D[0] + 1) % 4;
            else ND[0] = 4;
            if (D[5] != 4)ND[5] = (D[5] + 1) % 4;
            else ND[5] = 4;
            rep(i, 4) {
                ND[i + 1] = D[(i + 1) % 4 + 1];
            }
            swap(D, ND);
        }
        else {
            vll ND(6);

            if (D[1] != 4)ND[1] = (D[1] + 1) % 4;
            else ND[1] = 4;
            if (D[3] != 4)ND[3] = (D[3] + 3) % 4;
            else ND[3] = 4;

            ND[0] = D[2];
            string TR = "10324";
            ND[0] = TR[ND[0]] - '0';

            ND[2] = D[5];
            TR = "12304";
            ND[2] = TR[ND[2]] - '0';

            ND[5] = D[4];
            TR = "12304";
            ND[5] = TR[ND[5]] - '0';

            ND[4] = D[0];
            TR = "32104";
            ND[4] = TR[ND[4]] - '0';

            swap(D, ND);
        }
    }
    ll prediff(dice& D2) {
        ll res = 0;
        rep(i, 6) {
            if (D2.D[i] != D[i])res++;
        }
        return res;
    }

    ll diff(dice& D2) {
        ll res = 6;

        rep(i, 4) {
            rep(j, 4) {
                chmin(res, prediff(D2));
                rot(1);
            }
            chmin(res, prediff(D2));
            rot(0);
        }
        rot(0); rot(1); rot(0);
        rep(j, 4) {
            chmin(res, prediff(D2));
            rot(1);
        }
        rot(0); rot(0);
        rep(j, 4) {
            chmin(res, prediff(D2));
            rot(1);
        }
        return res;
    }//総回転29回, 6*29=294
};

//やりたくないよ～～2
void solve(ll N) {
    vector<dice> D(N);
    vvll R(N, vll(N, 0));
    rep(i, N) {
        vector<string> S(5);
        rep(i, 5)cin >> S[i];
        D[i].printer(S);
        rep(k, 6)assert(D[i].D[k] != 4);
        rep(j, i) {
            R[i][j] = R[j][i] = D[i].diff(D[j]);
        }
    }
    rep(i, N) {
        rep(j, N)cout << R[i][j];
        cout << endl;
    }

}

int main() {

    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    ll N;
    while (cin >> N) {
        if (N == 0)return 0;
        solve(N);
    }
}
accuracy: 1
time_ms: 860
memory_kb: 3740
final_rank: 14

code_snippet: #include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <deque>
#include <forward_list>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <optional>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#ifdef RUTHEN_LOCAL
#include <debug.hpp>
#else
#define show(x) true
#endif

// type definition
using i64 = long long;
using u32 = unsigned int;
using u64 = unsigned long long;
using f32 = float;
using f64 = double;
using f128 = long double;
template <class T> using pque = std::priority_queue<T>;
template <class T> using pqueg = std::priority_queue<T, std::vector<T>, std::greater<T>>;
// overload
#define overload4(_1, _2, _3, _4, name, ...) name
#define overload3(_1, _2, _3, name, ...) name
#define overload2(_1, _2, name, ...) name
// for loop
#define REP1(a) for (long long _ = 0; _ < (a); _++)
#define REP2(i, a) for (long long i = 0; i < (a); i++)
#define REP3(i, a, b) for (long long i = (a); i < (b); i++)
#define REP4(i, a, b, c) for (long long i = (a); i < (b); i += (c))
#define REP(...) overload4(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__)
#define RREP1(a) for (long long _ = (a)-1; _ >= 0; _--)
#define RREP2(i, a) for (long long i = (a)-1; i >= 0; i--)
#define RREP3(i, a, b) for (long long i = (b)-1; i >= (a); i--)
#define RREP(...) overload3(__VA_ARGS__, RREP3, RREP2, RREP1)(__VA_ARGS__)
#define FORE1(x, a) for (auto&& x : a)
#define FORE2(x, y, a) for (auto&& [x, y] : a)
#define FORE3(x, y, z, a) for (auto&& [x, y, z] : a)
#define FORE(...) overload4(__VA_ARGS__, FORE3, FORE2, FORE1)(__VA_ARGS__)
#define FORSUB(t, s) for (long long t = (s); t >= 0; t = (t == 0 ? -1 : (t - 1) & (s)))
// function
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define SORT(a) std::sort((a).begin(), (a).end())
#define RSORT(a) std::sort((a).rbegin(), (a).rend())
#define REV(a) std::reverse((a).begin(), (a).end())
#define UNIQUE(a)                      \
    std::sort((a).begin(), (a).end()); \
    (a).erase(std::unique((a).begin(), (a).end()), (a).end())
#define LEN(a) (int)((a).size())
#define MIN(a) *std::min_element((a).begin(), (a).end())
#define MAX(a) *std::max_element((a).begin(), (a).end())
#define SUM1(a) std::accumulate((a).begin(), (a).end(), 0LL)
#define SUM2(a, x) std::accumulate((a).begin(), (a).end(), (x))
#define SUM(...) overload2(__VA_ARGS__, SUM2, SUM1)(__VA_ARGS__)
#define LB(a, x) std::distance((a).begin(), std::lower_bound((a).begin(), (a).end(), (x)))
#define UB(a, x) std::distance((a).begin(), std::upper_bound((a).begin(), (a).end(), (x)))
template <class T, class U> inline bool chmin(T& a, const U& b) { return (a > T(b) ? a = b, 1 : 0); }
template <class T, class U> inline bool chmax(T& a, const U& b) { return (a < T(b) ? a = b, 1 : 0); }
template <class T, class S> inline T floor(const T x, const S y) {
    assert(y);
    return (y < 0 ? floor(-x, -y) : (x > 0 ? x / y : x / y - (x % y == 0 ? 0 : 1)));
}
template <class T, class S> inline T ceil(const T x, const S y) {
    assert(y);
    return (y < 0 ? ceil(-x, -y) : (x > 0 ? (x + y - 1) / y : x / y));
}
template <class T, class S> std::pair<T, T> inline divmod(const T x, const S y) {
    T q = floor(x, y);
    return {q, x - q * y};
}
// 10 ^ n
constexpr long long TEN(int n) { return (n == 0) ? 1 : 10LL * TEN(n - 1); }
// 1 + 2 + ... + n
#define TRI1(n) ((n) * ((n) + 1LL) / 2)
// l + (l + 1) + ... + r
#define TRI2(l, r) (((l) + (r)) * ((r) - (l) + 1LL) / 2)
#define TRI(...) overload2(__VA_ARGS__, TRI2, TRI1)(__VA_ARGS__)
// bit operation
// bit[i] (= 0 or 1)
#define IBIT(bit, i) (((bit) >> (i)) & 1)
// (0, 1, 2, 3, 4) -> (0, 1, 3, 7, 15)
#define MASK(n) ((1LL << (n)) - 1)
#define POW2(n) (1LL << (n))
// (0, 1, 2, 3, 4) -> (0, 1, 1, 2, 1)
int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2)
int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(i64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2)
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(i64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
// binary search
template <class T, class F> T bin_search(T ok, T ng, F& f) {
    while ((ok > ng ? ok - ng : ng - ok) > 1) {
        T md = (ng + ok) >> 1;
        (f(md) ? ok : ng) = md;
    }
    return ok;
}
template <class T, class F> T bin_search_real(T ok, T ng, F& f, const int iter = 100) {
    for (int _ = 0; _ < iter; _++) {
        T md = (ng + ok) / 2;
        (f(md) ? ok : ng) = md;
    }
    return ok;
}
// rotate matrix counterclockwise by pi / 2
template <class T> void rot(std::vector<std::vector<T>>& a) {
    if ((int)(a.size()) == 0) return;
    if ((int)(a[0].size()) == 0) return;
    int n = (int)(a.size()), m = (int)(a[0].size());
    std::vector res(m, std::vector<T>(n));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            res[m - 1 - j][i] = a[i][j];
        }
    }
    a.swap(res);
}
// const value
constexpr int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
constexpr int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
// infinity
template <class T> constexpr T INF = 0;
template <> constexpr int INF<int> = 1'000'000'000;                 // 1e9
template <> constexpr i64 INF<i64> = i64(INF<int>) * INF<int> * 2;  // 2e18
template <> constexpr u32 INF<u32> = INF<int>;                      // 1e9
template <> constexpr u64 INF<u64> = INF<i64>;                      // 2e18
template <> constexpr f32 INF<f32> = INF<i64>;                      // 2e18
template <> constexpr f64 INF<f64> = INF<i64>;                      // 2e18
template <> constexpr f128 INF<f128> = INF<i64>;                    // 2e18
// I/O
// input
template <class T> std::istream& operator>>(std::istream& is, std::vector<T>& v) {
    for (auto&& i : v) is >> i;
    return is;
}
template <class... T> void in(T&... a) { (std::cin >> ... >> a); }
void scan() {}
template <class Head, class... Tail> void scan(Head& head, Tail&... tail) {
    in(head);
    scan(tail...);
}
// input macro
#define INT(...)     \
    int __VA_ARGS__; \
    scan(__VA_ARGS__)
#define I64(...)     \
    i64 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define U32(...)     \
    u32 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define U64(...)     \
    u64 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define F32(...)     \
    f32 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define F64(...)     \
    f64 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define F128(...)     \
    f128 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define STR(...)             \
    std::string __VA_ARGS__; \
    scan(__VA_ARGS__)
#define CHR(...)      \
    char __VA_ARGS__; \
    scan(__VA_ARGS__)
#define VEC(type, name, size)     \
    std::vector<type> name(size); \
    scan(name)
#define VEC2(type, name1, name2, size)          \
    std::vector<type> name1(size), name2(size); \
    for (int i = 0; i < size; i++) scan(name1[i], name2[i])
#define VEC3(type, name1, name2, name3, size)                \
    std::vector<type> name1(size), name2(size), name3(size); \
    for (int i = 0; i < size; i++) scan(name1[i], name2[i], name3[i])
#define VEC4(type, name1, name2, name3, name4, size)                      \
    std::vector<type> name1(size), name2(size), name3(size), name4(size); \
    for (int i = 0; i < size; i++) scan(name1[i], name2[i], name3[i], name4[i])
#define VV(type, name, h, w)                       \
    std::vector name((h), std::vector<type>((w))); \
    scan(name)
// output
template <class T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
    auto n = v.size();
    for (size_t i = 0; i < n; i++) {
        if (i) os << ' ';
        os << v[i];
    }
    return os;
}
template <class... T> void out(const T&... a) { (std::cout << ... << a); }
void print() { out('\n'); }
template <class Head, class... Tail> void print(Head&& head, Tail&&... tail) {
    out(head);
    if (sizeof...(Tail)) out(' ');
    print(tail...);
}
// for interactive problems
void printi() { std::cout << std::endl; }
template <class Head, class... Tail> void printi(Head&& head, Tail&&... tail) {
    out(head);
    if (sizeof...(Tail)) out(' ');
    printi(tail...);
}
// bool output
void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void NO(bool t = 1) { YES(!t); }
void No(bool t = 1) { Yes(!t); }
void no(bool t = 1) { yes(!t); }
void POSSIBLE(bool t = 1) { print(t ? "POSSIBLE" : "IMPOSSIBLE"); }
void Possible(bool t = 1) { print(t ? "Possible" : "Impossible"); }
void possible(bool t = 1) { print(t ? "possible" : "impossible"); }
void IMPOSSIBLE(bool t = 1) { POSSIBLE(!t); }
void Impossible(bool t = 1) { Possible(!t); }
void impossible(bool t = 1) { possible(!t); }
void FIRST(bool t = 1) { print(t ? "FIRST" : "SECOND"); }
void First(bool t = 1) { print(t ? "First" : "Second"); }
void first(bool t = 1) { print(t ? "first" : "second"); }
void SECOND(bool t = 1) { FIRST(!t); }
void Second(bool t = 1) { First(!t); }
void second(bool t = 1) { first(!t); }
// I/O speed up
struct SetUpIO {
    SetUpIO() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        std::cout << std::fixed << std::setprecision(15);
    }
} set_up_io;

struct Dice {
    std::array<int, 6> d;
    // 面
    //  2
    // 341
    //  0
    //  5
    // 向き
    //  v
    // vvv
    //  v
    //  v
    Dice() { d = {0, 0, 0, 0, 0, 0}; }
    // v>^< -> 0123
    int ctoi(char c) {
        if (c == 'v') return 0;
        if (c == '>') return 1;
        if (c == '^') return 2;
        if (c == '<') return 3;
        assert(false);
    }
    int cw(int x) { return (x + 3) % 4; }
    int ccw(int x) { return (x + 1) % 4; }
    int rev(int x) { return (x + 2) % 4; }
    void rotate0() {
        // v方向に倒す
        // 面
        //  4
        // 301
        //  5
        //  2
        // 向き
        //  v
        // >v<
        //  v
        //  v
        d = {d[5], cw(d[1]), d[4], ccw(d[3]), d[0], d[2]};
    }
    void rotate1() {
        // >方向に倒す
        // 面
        //  2
        // 415
        //  0
        //  3
        // 向き
        //  <
        // vv^
        //  >
        //  ^
        d = {ccw(d[0]), rev(d[5]), cw(d[2]), d[4], d[1], rev(d[3])};
    }
    void rotate2() {
        // ^方向に倒す
        rotate0();
        rotate0();
        rotate0();
    }
    void rotate3() {
        // <方向に倒す
        rotate1();
        rotate1();
        rotate1();
    }
    void rotate_cw() {
        // 時計回りに回す
        // 面
        //  3
        // 042
        //  1
        //  5
        // 向き
        //  <
        // <<<
        //  <
        //  >
        d = {cw(d[1]), cw(d[2]), cw(d[3]), cw(d[0]), cw(d[4]), ccw(d[5])};
    }
    void rotate_ccw() {
        // 反時計回りに回す
        rotate_cw();
        rotate_cw();
        rotate_cw();
    }
};

Dice read_dice(std::vector<std::string>& s) {
    int h = (int)(s.size());
    assert(h > 0);
    int w = (int)(s[0].size());
    std::vector seen(h, std::vector(w, 0));
    Dice res;
    auto rec = [&](auto f, int x, int y) -> void {
        seen[x][y] = 1;
        res.d[4] = res.ctoi(s[x][y]);
        if (x + 1 < h and s[x + 1][y] != '.' and seen[x + 1][y] == 0) {
            // v
            res.rotate0();
            f(f, x + 1, y);
            res.rotate2();
        }
        if (y + 1 < w and s[x][y + 1] != '.' and seen[x][y + 1] == 0) {
            // >
            res.rotate1();
            f(f, x, y + 1);
            res.rotate3();
        }
        if (x - 1 >= 0 and s[x - 1][y] != '.' and seen[x - 1][y] == 0) {
            // ^
            res.rotate2();
            f(f, x - 1, y);
            res.rotate0();
        }
        if (y - 1 >= 0 and s[x][y - 1] != '.' and seen[x][y - 1] == 0) {
            // <
            res.rotate3();
            f(f, x, y - 1);
            res.rotate1();
        }
    };
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            if (s[i][j] != '.' and seen[i][j] == 0) rec(rec, i, j);
        }
    }
    return res;
}

int difference(Dice& a, Dice& b) {
    int res = 0;
    for (int i = 0; i < 6; i++) res += a.d[i] != b.d[i];
    return res;
}

int min_difference(Dice& a, Dice& b) {
    int res = 6;
    // 4面チェック
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            res = std::min(res, difference(a, b));
            a.rotate_cw();
        }
        a.rotate0();
    }
    // >方向
    a.rotate1();
    for (int j = 0; j < 4; j++) {
        res = std::min(res, difference(a, b));
        a.rotate_cw();
    }
    a.rotate3();
    // <方向
    a.rotate3();
    for (int j = 0; j < 4; j++) {
        res = std::min(res, difference(a, b));
        a.rotate_cw();
    }
    a.rotate1();
    return res;
}

using namespace std;

void solve(int N) {
    vector<Dice> ds(N);
    REP(i, N) {
        VEC(string, S, 5);
        ds[i] = read_dice(S);
    }
    vector<string> ans(N);
    REP(i, N) {
        REP(j, N) {
            auto a = ds[i], b = ds[j];
            auto r = min_difference(a, b);
            ans[i] += '0' + r;
        }
        print(ans[i]);
    }
    return;
}

int main() {
    int N;
    while (cin >> N, N != 0) solve(N);
    return 0;
}
accuracy: 1
time_ms: 300
memory_kb: 3480
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define REP(i, n) for (int i = 0; i < (n); i++)

using D = vector<int>;
D rotate_right(D a) {
    return {a[1], a[2], a[3], a[0], a[4], a[5]};
}
D rotate_left(D a) {
    REP(i, 3) a = rotate_right(a);
    return a;
}
D rotate_top(D a) {
    return {a[4], a[1], a[5], a[3], a[2], a[0]};
}
D rotate_bottom(D a) {
    REP(i, 3) a = rotate_top(a);
    return a;
}
D rotate_clockwise(D a) {
    return {a[0], a[4], a[2], a[5], a[3], a[1]};
}
D rotate_counterclockwise(D a) {
    REP(i, 3) a = rotate_clockwise(a);
    return a;
}

char rotate(char c) {
    static vector<char> vec = {'^', '>', 'v', '<'};
    int i = find(vec.begin(), vec.end(), c) - vec.begin();
    return vec[(i + 1) % 4];
}

const int m = 5;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

using Dice = vector<char>;
Dice rotate_right(Dice a) {
    return {a[1], a[2], a[3], a[0], rotate(a[4]), rotate(rotate(rotate(a[5])))};
}
Dice rotate_left(Dice a) {
    REP(i, 3) a = rotate_right(a);
    return a;
}
Dice rotate_top(Dice a) {
    return {a[4], rotate(rotate(rotate(a[1]))), rotate(rotate(a[5])), rotate(a[3]), rotate(rotate(a[2])), a[0]};
}
Dice rotate_bottom(Dice a) {
    REP(i, 3) a = rotate_top(a);
    return a;
}
Dice rotate_clockwise(Dice a) {
    return {rotate(a[0]), rotate(a[4]), rotate(rotate(rotate(a[2]))), rotate(a[5]), rotate(a[3]), rotate(a[1])};
}
Dice rotate_counterclockwise(Dice a) {
    REP(i, 3) a = rotate_clockwise(a);
    return a;
}

vector<D> ds;

Dice make(vector<string>& S) {
    queue<pair<pair<int, int>, D>> que;
    vector seen(m, vector(m, 0));
    auto ok = [&]() -> bool {
        REP(i, m) {
            REP(j, m) {
                if (S[i][j] != '.') {
                    que.push({{i, j}, {0, 1, 2, 3, 4, 5}});
                    seen[i][j] = 1;
                    return true;
                }
            }
        }
        return false;
    }();
    
    Dice res(6);
    
    while (!que.empty()) {
        auto [cp, cd] = que.front();
        que.pop();
        auto [cx, cy] = cp;
        char c = S[cx][cy];
        D mem = cd;
        while (cd != ds[cd[0]]) {
            c = rotate(c);
            cd = rotate_clockwise(cd);
        }
        res[cd[0]] = c;
        cd = mem;
        REP(k, 4) {
            int nx = cx + dx[k], ny = cy + dy[k];
            if (!(0 <= nx and nx < m and 0 <= ny and ny < m)) continue;
            if (S[nx][ny] == '.') continue;
            if (seen[nx][ny] == 1) continue;
            seen[nx][ny] = 1;
            D nd;
            if (k == 0) nd = rotate_bottom(cd);
            if (k == 1) nd = rotate_right(cd);
            if (k == 2) nd = rotate_top(cd);
            if (k == 3) nd = rotate_left(cd);
            que.push({{nx, ny}, nd});
        }
    }
    return res;
}

int distance(Dice& a, Dice& b) {
    int ans = 0;
    REP(i, 6) ans += a[i] != b[i];
    return ans;
}

int diff(Dice a, Dice b) {
    int res = 10;
    Dice binit = b;
    REP(_, 4) {
        REP(i, 4) {
            res = min(res, distance(a, b));
            b = rotate_clockwise(b);
        }
        b = rotate_right(b);
    }
    b = rotate_top(b);
    REP(i, 4) {
        res = min(res, distance(a, b));
        b = rotate_clockwise(b);
    }
    b = rotate_bottom(b);
    b = rotate_bottom(b);
    REP(i, 4) {
        res = min(res, distance(a, b));
        b = rotate_clockwise(b);
    }
    b = rotate_top(b);
    assert(b == binit);
    return res;
}

void solve(int N) {
    vector<Dice> dices(N);
    REP(i, N) {
        vector<string> x(5);
        REP(j, 5) cin >> x[j];
        dices[i] = make(x);
    }
    REP(i, N) {
        REP(j, N) {
            cout << diff(dices[i], dices[j]);
        }
        cout << '\n';
        
    }
}

int main() {
    ds.push_back({0, 1, 2, 3, 4, 5});
    ds.push_back(rotate_right(ds[0]));
    ds.push_back(rotate_right(ds[1]));
    ds.push_back(rotate_right(ds[2]));
    ds.push_back(rotate_top(ds[0]));
    ds.push_back(rotate_bottom(ds[0]));
    int N;
    while (cin >> N, N != 0) solve(N);
    return 0;
}
accuracy: 1
time_ms: 4260
memory_kb: 3484
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define REP(i, n) for (int i = 0; i < (n); i++)

using D = vector<int>;
D rotate_right(D a) {
    return {a[1], a[2], a[3], a[0], a[4], a[5]};
}
D rotate_left(D a) {
    REP(i, 3) a = rotate_right(a);
    return a;
}
D rotate_top(D a) {
    return {a[4], a[1], a[5], a[3], a[2], a[0]};
}
D rotate_bottom(D a) {
    REP(i, 3) a = rotate_top(a);
    return a;
}
D rotate_clockwise(D a) {
    return {a[0], a[4], a[2], a[5], a[3], a[1]};
}
D rotate_counterclockwise(D a) {
    REP(i, 3) a = rotate_clockwise(a);
    return a;
}

char rotate(char c) {
    static vector<char> vec = {'^', '>', 'v', '<'};
    int i = find(vec.begin(), vec.end(), c) - vec.begin();
    return vec[(i + 1) % 4];
}

const int m = 5;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

using Dice = vector<char>;
Dice rotate_right(Dice a) {
    return {a[1], a[2], a[3], a[0], rotate(a[4]), rotate(rotate(rotate(a[5])))};
}
Dice rotate_left(Dice a) {
    REP(i, 3) a = rotate_right(a);
    return a;
}
Dice rotate_top(Dice a) {
    return {a[4], rotate(rotate(rotate(a[1]))), rotate(rotate(a[5])), rotate(a[3]), rotate(rotate(a[2])), a[0]};
}
Dice rotate_bottom(Dice a) {
    REP(i, 3) a = rotate_top(a);
    return a;
}
Dice rotate_clockwise(Dice a) {
    return {rotate(a[0]), rotate(a[4]), rotate(rotate(rotate(a[2]))), rotate(a[5]), rotate(a[3]), rotate(a[1])};
}
Dice rotate_counterclockwise(Dice a) {
    REP(i, 3) a = rotate_clockwise(a);
    return a;
}

vector<D> ds;

Dice make(vector<string>& S) {
    queue<pair<pair<int, int>, D>> que;
    vector seen(m, vector(m, 0));
    auto ok = [&]() -> bool {
        REP(i, m) {
            REP(j, m) {
                if (S[i][j] != '.') {
                    que.push({{i, j}, {0, 1, 2, 3, 4, 5}});
                    seen[i][j] = 1;
                    return true;
                }
            }
        }
        return false;
    }();
    
    Dice res(6);
    
    while (!que.empty()) {
        auto [cp, cd] = que.front();
        que.pop();
        auto [cx, cy] = cp;
        char c = S[cx][cy];
        D mem = cd;
        while (cd != ds[cd[0]]) {
            c = rotate(c);
            cd = rotate_clockwise(cd);
        }
        res[cd[0]] = c;
        cd = mem;
        REP(k, 4) {
            int nx = cx + dx[k], ny = cy + dy[k];
            if (!(0 <= nx and nx < m and 0 <= ny and ny < m)) continue;
            if (S[nx][ny] == '.') continue;
            if (seen[nx][ny] == 1) continue;
            seen[nx][ny] = 1;
            D nd;
            if (k == 0) nd = rotate_bottom(cd);
            if (k == 1) nd = rotate_right(cd);
            if (k == 2) nd = rotate_top(cd);
            if (k == 3) nd = rotate_left(cd);
            que.push({{nx, ny}, nd});
        }
    }
    return res;
}

int distance(Dice& a, Dice& b) {
    int ans = 0;
    REP(i, 6) ans += a[i] != b[i];
    return ans;
}

int diff(Dice a, Dice b) {
    int res = 10;
    Dice binit = b;
    REP(_, 4) {
        REP(i, 4) {
            res = min(res, distance(a, b));
            b = rotate_clockwise(b);
        }
        b = rotate_right(b);
    }
    b = rotate_top(b);
    REP(i, 4) {
        res = min(res, distance(a, b));
        b = rotate_clockwise(b);
    }
    b = rotate_bottom(b);
    b = rotate_bottom(b);
    REP(i, 4) {
        res = min(res, distance(a, b));
        b = rotate_clockwise(b);
    }
    b = rotate_top(b);
    assert(b == binit);
    return res;
}

void solve(int N) {
    vector<Dice> dices(N);
    REP(i, N) {
        vector<string> x(5);
        REP(j, 5) cin >> x[j];
        dices[i] = make(x);
    }
    REP(i, N) {
        REP(j, N) {
            cout << diff(dices[i], dices[j]);
        }
        cout << '\n';
        
    }
}

int main() {
    ds.push_back({0, 1, 2, 3, 4, 5});
    ds.push_back(rotate_right(ds[0]));
    ds.push_back(rotate_right(ds[1]));
    ds.push_back(rotate_right(ds[2]));
    ds.push_back(rotate_top(ds[0]));
    ds.push_back(rotate_bottom(ds[0]));
    int N;
    while (cin >> N, N != 0) solve(N);
    return 0;
}
accuracy: 1
time_ms: 4270
memory_kb: 3356
final_rank: 13

code_snippet: #include <iostream>
#include <vector>
#include <memory>
#include <queue>
#include <stack>
#include <map>
#include <cassert>
#include <algorithm>

using namespace std;

#define rep(i, n) for(int i = 0; i < int(n); i++)
#define rep2(i, s, n) for(int i = s; i < int(n); i++)
#define eb emplace_back
#define mu make_unique
#define all(x) begin(x),  end(x)

using ll = long long;

// 1 --- 2
// |     |
// |     |
// 4 --- 3

struct S4 {
    map<string, int> mp;
    vector<string> pm;
    S4() : pm(24) {
        string s = "ABCD";
        int i = 0;
        do {
            mp[s] = i;
            pm[i] = s;
            i++;
        } while(next_permutation(all(s)));
    }
} s4;

struct Dice {
    vector<bool> mp;
    Dice() : mp(24) {
    }
    static string fwd(string state) {
        state = state.substr(2, 2) + state.substr(0, 2);
        swap(state[2], state[3]);
        return state;
    }
    static string rotate(string s) {
        s = s.substr(1, 3) + s.substr(0, 1);
        // s = s.substr(3, 1) + s.substr(0, 3);
        return s;
    }
    vector<bool> rotate(int k[4]) {
        vector<bool> res(24);
        rep(i, 24) if(mp[i]) {
            auto s = s4.pm[i];
            auto t = s;
            rep(j, 4) {
                t[j] = k[t[j] - 'A'] + 'A';
            }
            res[s4.mp[t]] = true;
        }
        return res;
    }
};

char dirct[] = "^>v<";
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};

bool in_b(int x, int y) {
    return 0 <= x && x < 5 && 0 <= y && y < 5;
} 

void solve(int n) {
    vector<Dice> d(n);
    for(auto &i : d) {
        vector<string> a(5);
        rep(j, 5) cin >> a[j];
        int x = 0, y = 0;
        rep(j, 5) rep(k, 5) {
            if(a[4-k][j] != '.') {
                x = 4-k;
                y = j;
                break;
            }
        }
        auto dfs = [&a](auto &&f, int x, int y, int d, string state, Dice& dice) -> void {
            if(!in_b(x, y) || a[x][y] == '.') return;
            // cout << x << y << d << " " << state << endl;
            rep(i, 4) {
                if(dirct[(d + i) % 4] == a[x][y]) {
                    auto tmp = state;
                    rep(j, i) tmp = Dice::rotate(tmp);
                    // cout << x << y << (d + i) % 4 << tmp << endl;
                    dice.mp[s4.mp[tmp]] = true;
                    break;
                }
            }
            rep(i, 4) {
                if(i == 2 && d < 4) {
                    state = Dice::rotate(state);
                    continue;
                }
                int ee = (i + d) % 4;
                // cout << state << endl;
                f(f, x + dx[ee], y + dy[ee], ee, Dice::fwd(state), dice);
                state = Dice::rotate(state);
            }
        };
        string s = "ABCD";
        // cout << "======" << endl;
        dfs(dfs, x, y, 4, s, i);
        // rep(j, 24) cout << i.mp[j];
        // cout << endl;
    }
    // rep(i,n) {
    //     rep(j, 24) if(d[i].mp[j]) {
    //         cout << s4.pm[j] << ", ";
    //     }
    //     cout << endl;
    // }
    vector<vector<int>> ans(n, vector<int>(n, 0));
    rep(i, n) rep(j, i) {
        int k[4] = {0, 1, 2, 3};
        do {
            auto p = d[i].rotate(k);
            int cc = 0;
            rep(l, 24) if(p[l]) ++cc;
            assert(cc == 6);
            int c = 0;
            rep(l, 24) if(p[l] && d[j].mp[l]) ++c;
            assert(c <= 6);
            ans[i][j] = max(ans[i][j], c);
        } while(next_permutation(all(k)));
        ans[i][j] = 6 - ans[i][j];
        ans[j][i] = ans[i][j];
    }
    rep(i, n) {
        rep(j, n) {
            cout << ans[i][j];
        }
        cout << "\n";
    }
}

int main() {
    int n;
    while(1) {
        cin >> n;
        if(n == 0) break;
        solve(n);
    }
}
accuracy: 1
time_ms: 6290
memory_kb: 3536
final_rank: 20

code_snippet: #include "bits/stdc++.h"
#define var auto

using namespace std;

using i64 = long long;
using u8  = unsigned char;

char table[4] = { '^', '>', 'v', '<' };

char itoc(u8 d) {
    if (d == 255) return '#';
    assert(0 <= d and d < 4);
    return table[d];
}

int ctoi(char d) {
    for (int i = 0; i < 4; i++) {
        if (table[i] == d) return i;
    }
    assert(false);
}

u8 rr(u8 a) {
    if (a == 255) return -1;
    return (a + 1) % 4;
}
u8 rl(u8 a) {
    if (a == 255) return -1;
    return (a + 3) % 4;
}
u8 rot180(u8 a) {
    if (a == 255) return -1;
    return (a + 2) % 4;
}

struct dice {
    u8 u;
    u8 l;
    u8 f;
    u8 r;
    u8 b;
    u8 d;
    void rotr() {
        d = rl(d);
        u = rr(u);
        var tmp = l;
        l = f;
        f = r;
        r = rot180(b);
        b = rot180(tmp);
    }
    void rotd() {
        l = rl(l);
        r = rr(r);
        var tmp = u;
        u = f;
        f = d;
        d = b;
        b = tmp;
    }
    void movr() {
        movd(); rotr(); movd(); movd(); movd();
    }
    /*void movr() {
        b = rl(b);
        f = rr(f);
        var tmp = u;
        u = rr(l);
        l = rr(d);
        d = rr(r);
        r = rr(tmp);
    }*/
    void movd() {
        rotd(); rotd(); rotd();
    }
    void print() {
        cout << " === " << endl;
        cout << "." << itoc(u) << "." << endl;
        cout << itoc(l) << itoc(f) << itoc(r) << endl;
        cout << "." << itoc(d) << "." << endl;
        cout << "." << itoc(b) << "." << endl;
    }
};

int diff(dice& a, dice& b) {
    return (a.u != b.u) + (a.b != b.b) + (a.l != b.l) + (a.f != b.f) + (a.r != b.r) + (a.d != b.d);
}

dice curd;
vector<string> ss;
void dfs(int i, int j) {
    if (curd.d != 0xff) return;
    curd.d = ctoi(ss[i][j]);
    if (ss[i][j + 1] != '.') {
        curd.movr();
        dfs(i, j + 1);
        curd.movr(); curd.movr(); curd.movr();
    }
    if (ss[i][j - 1] != '.') {
        curd.movr(); curd.movr(); curd.movr();
        dfs(i, j - 1);
        curd.movr();
    }
    if (ss[i + 1][j] != '.') {
        curd.movd();
        dfs(i + 1, j);
        curd.movd(); curd.movd(); curd.movd();
    }
    if (ss[i - 1][j] != '.') {
        curd.movd(); curd.movd(); curd.movd();
        dfs(i - 1, j);
        curd.movd();
    }
}

bool solve(){
    int n;
    cin >> n;
    if (!n) return false;

    vector<dice> dices;
    for (int i = 0; i < n; i++) {
        dice d{0xff,0xff,0xff,0xff,0xff,0xff};
        curd = d;
        ss = vector<string>(5);
        for (var&& s : ss) {
            cin >> s;
            s = "." + s + ".";
        }
        ss.insert(ss.begin(), ".......");
        ss.emplace_back(".......");
        stack<pair<pair<int, int>, dice*>> a;
        // move left;
        for (int i = 0; i < 7; i++) {
            bool flag = false;
            for (int j = 0; j < 7; j++) {
                if (ss[i][j] != '.') {
                    dfs(i, j);
                    flag = true;
                    break;
                }
            }
            if (flag) break;
        }
        // curd.print();
        dices.emplace_back(curd);
    }

    vector<vector<dice>> rots(n);
    for (int i = 0; i < n; i++) {
        var d = dices[i];
        var add = [&](dice d) {
            rots[i].push_back(d);
            // d.print();
            d.rotr();
            rots[i].push_back(d);
            // d.print();
            d.rotr();
            rots[i].push_back(d);
            // d.print();
            d.rotr();
            rots[i].push_back(d);
            // d.print();
            d.rotr();
        };
        add(d);
        {
            var d1 = d;
            d1.rotd();
            add(d1);
        }
        {
            var d1 = d;
            d1.rotr(); d1.rotd();
            add(d1);
        }
        {
            var d1 = d;
            d1.rotr(); d1.rotr(); d1.rotd();
            add(d1);
        }
        {
            var d1 = d;
            d1.rotr(); d1.rotr(); d1.rotr(); d1.rotd();
            add(d1);
        }
        {
            var d1 = d;
            d1.rotd(); d1.rotd();
            add(d1);
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            int res = 114514;
            for (int i1 = 0; i1 < rots[i].size(); i1++) {
                for (int i2 = 0; i2 < rots[j].size(); i2++) {
                    res = min(res, diff(rots[i][i1], rots[j][i2]));
                }
            }
            cout << res;
        }
        cout << endl;
    }


    return true;
}

signed main(){
    while(solve());
    return false;
}
accuracy: 1
time_ms: 1430
memory_kb: 3428
final_rank: 10

code_snippet: #include<bits/stdc++.h>

using namespace std;

class Vector{
  public:
    int x;
    int y;
    int z;
    Vector():x(0),y(0),z(0){}
    Vector(int x,int y,int z):x(x),y(y),z(z){}

    Vector rotate(char c){
      if(c == '^'){
        return Vector(x,-z,y);
      }
      if(c == 'v'){
        return Vector(x,z,-y);
      }
      if(c == '>'){
        return Vector(y,-x,z);
      }
      if(c == '<'){
        return Vector(-y,x,z);
      }
      exit(1);
    }

    bool operator==(Vector other){
      return array<int,3>{x,y,z} == array<int,3>{other.x,other.y,other.z};
    }

    bool operator!=(Vector other){
      return not (*this == other);
    }
};

class Dice{
  public:
    array<Vector,6> data;
    Dice(){}
    Dice(array<Vector,6> data){
      for(int i=0;i<6;++i){
        this->data[i] = data[i];
      }
    }
    Dice changeAt(int p,Vector v){
      array<Vector,6> res = data;
      res[p] = v;
      return Dice(res);
    }

    Dice rotate(char c){
      array<Vector,6> res = data;
      if(c == '^'){
        auto tmp = res[0];
        res[0] = res[3];
        res[3] = res[2];
        res[2] = res[1];
        res[1] = tmp;
      }
      if(c == 'v'){
        auto tmp = res[0];
        res[0] = res[1];
        res[1] = res[2];
        res[2] = res[3];
        res[3] = tmp;
      }
      if(c == '<'){
        auto tmp = res[0];
        res[0] = res[5];
        res[5] = res[2];
        res[2] = res[4];
        res[4] = tmp;
      }
      if(c == '>'){
        auto tmp = res[0];
        res[0] = res[4];
        res[4] = res[2];
        res[2] = res[5];
        res[5] = tmp;
      }
      for(auto &i:res){
        auto x = i.rotate(c);
        i = x;
      }
      return Dice(res);
    }
};

vector<Dice> enumerate(Dice di){
  vector<Dice> rights;
  vector<Dice> res;
  string s1=">>>>^>>>>";
  for(auto i:s1){
    rights.push_back(di);
    Dice tmp = di.rotate(i);
    di = tmp;
  }
  string s2="^^^^";
  for(auto i:rights){
    Dice x = i;
    for(auto j:s2){
      res.push_back(x);
      Dice tmp = x.rotate(j);
      x = tmp;
    }
  }
  return res;
}

Dice create(){
  vector<string> table(5);
  for(auto &i:table)cin >> i;
  int dx[]={1,0,-1,0};
  int dy[]={0,-1,0,1};
  char rots[]={'>','^','<','v'};
  map<char,Vector> vs;
  vs['^'] = Vector(0,0,1);
  vs['v'] = Vector(0,0,-1);
  vs['>'] = Vector(1,0,0);
  vs['<'] = Vector(-1,0,0);
  function<Dice(int,int,int,int,Dice)> rec = [&](int y,int x,int ly,int lx,Dice dice) -> Dice{
    Dice res = dice.changeAt(0,vs[table[y][x]]);
    for(int i=0;i<4;++i){
      int ny = y + dy[i];
      int nx = x + dx[i];
      if(ny < 0 or nx < 0)continue;
      if(5 <= ny or 5 <= nx)continue;
      if(table[ny][nx] == '.')continue;
      if(ny == ly and nx == lx)continue;
      Dice v = rec(ny,nx,y,x,res.rotate(rots[i]));
      res = v.rotate(rots[(i+2)%4]);
    }
    return res;
  };
  for(int i=0;i<5;++i){
    for(int j=0;j<5;++j){
      if(table[i][j] =='.')continue;
      return rec(i,j,-1,-1,Dice());
    }
  }
  exit(1);
}

int niterudo(Dice x,Dice y){
  int res = 0;
  for(int i=0;i<6;++i){
    if(x.data[i] != y.data[i])++res;
  }
  return res;
}

int souido(Dice x,Dice y){
  int res = 10000;
  for(auto xx:enumerate(x)){
    res = min(res,niterudo(xx,y));
  }
  return res;
}

void func(int n){
  vector<Dice> dices(n);
  for(auto &i:dices){
    i = create();
  }
  for(int i=0;i<n;++i){
    for(int j=0;j<n;++j){
      cout << souido(dices[i],dices[j]);
    }
    cout << endl;
  }
}

int main(){
  int n;
  while(cin >> n and n){
    func(n);
  }
}
accuracy: 1
time_ms: 5120
memory_kb: 3480
final_rank: 18

code_snippet: #include <bits/stdc++.h>

#define rep(i, s, n) for (int i = (int)(s); i < (int)(n); i++)
#define rrep(i, s, n) for (int i = (int)(n)-1; i >= (int)(s); i--)
#define all(v) v.begin(), v.end()

using ll = long long;
using ld = long double;
using ull = unsigned long long;

template <typename T> bool chmin(T &a, const T &b) {
    if (a <= b) return false;
    a = b;
    return true;
}
template <typename T> bool chmax(T &a, const T &b) {
    if (a >= b) return false;
    a = b;
    return true;
}

using namespace std;

using ar = array<int,6>;
const string dirs = ">^<v";
const vector<int> dx = {0,-1,0,1}, dy = {1,0,-1,0};
const int ng = 4;

void o(){ cout << "!" << endl; }

struct dice {
    ar a;
    dice () {}
    dice (vector<string> grid){
        auto get = [&](int x, int y){
            if (x < 0 || x >= 5 || y < 0 || y >= 5) return ng;
            rep(i,0,4) if (grid[x][y] == dirs[i]) return i;
            return ng;
        };
        int sx = -1, sy = -1;
        rep(x,0,5) rep(y,0,5) if (get(x,y) != ng) sx = x, sy = y;
        vector<vector<bool>> done(5,vector<bool>(5,false));
        auto dfs = [&](auto dfs, int x, int y) -> void {
            done[x][y] = true;
            rep(k,0,4){
                int nx = x + dx[k], ny = y + dy[k];
                if (get(nx,ny) == ng || done[nx][ny]) continue;
                roll(k);
                a[1] = get(nx,ny);
                dfs(dfs,nx,ny);
                roll((k+2)%4);
            }
        };
        a = {ng,get(sx,sy),ng,ng,ng,ng};
        dfs(dfs,sx,sy);
    }
    int rot(int dir, int times = 1){
        if (dir == ng) return ng;
        return (dir+times)%4;
    }
    void roll_up(){
        a = {a[1],a[2],a[3],a[0],rot(a[4],1),rot(a[5],3)};
    }
    void roll_down(){
        roll_up(); roll_up(); roll_up();
    }
    void roll_left(){
        a = {rot(a[0],3),a[5],rot(a[2],1),rot(a[4],2),a[1],rot(a[3],2)};
    }
    void roll_right(){
        roll_left(); roll_left(); roll_left();
    }
    void roll(int k){
        if (k == 0) roll_left();
        if (k == 1) roll_down();
        if (k == 2) roll_right();
        if (k == 3) roll_up();
    }
    int diff(dice other){
        int ans = 6;
        auto update = [&](){
            int res = 0;
            rep(i,0,6) if (a[i] != other.a[i]) res++;
            chmin(ans,res);
        };
        rep(i,0,4){
            rep(j,0,4){
                update();
                roll_left();
            }
            roll_up();
        }
        roll_left(); roll_up();
        rep(j,0,4){
            update();
            roll_left();
        }
        roll_down(); roll_right(); roll_right(); roll_up();
        rep(j,0,4){
            update();
            roll_left();
        }
        return ans;
    }
    void print(){
        rep(i,0,6) cout << a[i] << " \n"[i == 5];
    }
};

void solve(int n){
    vector<dice> a(n);
    rep(i,0,n){
        vector<string> b(5);
        rep(j,0,5) cin >> b[j];
        a[i] = dice(b); //a[i].print();
    }
    rep(i,0,n){
        string ans = "";
        rep(j,0,n) ans += to_string(a[i].diff(a[j]));
        cout << ans << endl;
    }
}

int main(){
    while (true){
        int n; cin >> n;
        if (n == 0) break;
        solve(n);
    }
}
accuracy: 1
time_ms: 310
memory_kb: 3408
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
void chmin(int& a, int b) { if(a > b) a = b; }

const string arrow = "^>v<";
int to_i(char c) {
    for(int i = 0; ; i++) if(arrow[i] == c) return i;
}
int cw(int x) {
    return (x + 1) % 4;
}
int ud(int x) {
    return (x + 2) % 4;
}
int ccw(int x) {
    return (x + 3) % 4;
}
struct Dice {
    /*
     0
    415
     2
     3
     */
    int arr[6];
    Dice roll_up() const {
        /*
         1
   ccw(4)2cw(5)
         3
         0
         */
        return {arr[1], arr[2], arr[3], arr[0], ccw(arr[4]), cw(arr[5])};
    }
    Dice roll_down() const {
        return roll_up().roll_up().roll_up();
    }
    Dice roll_right() const {
        /*
         ccw(0)
    ud(3)4    1
         cw(2)
         ud(5)
         */
        return {ccw(arr[0]), arr[4], cw(arr[2]), ud(arr[5]), ud(arr[3]), arr[1]};
    }
    Dice roll_left() const {
        return roll_right().roll_right().roll_right();
    }
};
Dice input_dice() {
    char s[5][6];
    for(auto& c : s) cin >> c;
    auto at = [&](int x, int y) {
        if(x < 0 || y < 0 || x >= 5 || y >= 5) return '.';
        return s[x][y];
    };
    auto [sx, sy] = [&]{
        for(int x = 0; x < 5; x++) for(int y = 0; y < 5; y++) if(at(x, y) != '.') return pair{x, y};
        assert(false);
    }();
    auto dfs = [&](int x, int y, Dice d, auto dfs) -> Dice {
        assert(at(x, y) != '.');
        d.arr[1] = to_i(at(x, y));
        s[x][y] = '.';
        if(at(x - 1, y) != '.') d = dfs(x - 1, y, d.roll_up(), dfs).roll_down();
        if(at(x + 1, y) != '.') d = dfs(x + 1, y, d.roll_down(), dfs).roll_up();
        if(at(x, y - 1) != '.') d = dfs(x, y - 1, d.roll_left(), dfs).roll_right();
        if(at(x, y + 1) != '.') d = dfs(x, y + 1, d.roll_right(), dfs).roll_left();
        return d;
    };
    return dfs(sx, sy, Dice{}, dfs);
}
int dist(Dice a, Dice b) {
    int cnt = 0;
    for(int i = 0; i < 6; i++) cnt += a.arr[i] != b.arr[i];
    return cnt;
}
int min_dist(Dice a, Dice b) {
    int min = INT_MAX;
    auto roll = [&]{
        for(int i = 0; i < 4; i++) {
            chmin(min, dist(a, b));
            a = a.roll_right();
        }
    };
    for(int i = 0; i < 4; i++) {
        roll();
        a = a.roll_up();
    }
    a = a.roll_right();
    for(int i = 0; i < 4; i++) {
        roll();
        a = a.roll_up();
    }
    return min;
}
void solve() {
    int N;
    cin >> N;
    if(N == 0) exit(0);
    vector<Dice> dice(N);
    for(auto& d : dice) d = input_dice();
    for(int i = 0; i < N; i++) for(int j = 0; j < N; j++) {
        cout << min_dist(dice[i], dice[j]);
        if(j + 1 == N) cout << '\n';
    }
}
int main() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    while(1) solve();
}
accuracy: 1
time_ms: 300
memory_kb: 3492
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;

int dx[4]={1,0,-1,0};
int dy[4]={0,-1,0,1};
vector<array<int,4>>dv={{2,1,4,3},{5,4,0,2},{5,1,0,3},{5,2,0,4},{5,3,0,1},{4,1,2,3}};
vector<array<int,4>>dvd={{0,1,2,3},{1,0,3,0},{0,0,0,0},{3,0,1,0},{2,0,2,0},{2,3,0,1}};
map<char,int>c2d={{'^',2},{'>',3},{'v',0},{'<',1}};

struct ArrowDie{
  array<int,6>Ar;
  ArrowDie(vector<vector<char>>& S){
    for(int i=0;i<5;i++){
      for(int j=0;j<5;j++){
        if(S[i][j]=='.')continue;
        queue<array<int,2>>bfs;
        bfs.push({i,j});
        vector<vector<short>>dist(5,vector<short>(5,100)),idx(5,vector<short>(5,-1));
        vector<vector<short>>dire(5,vector<short>(5,6));
        dist[i][j]=0;
        dire[i][j]=0;
        idx[i][j]=0;
        Ar[0]=(-dire[i][j]+4+c2d[S[i][j]])%4;
        while(bfs.size()){
          int h=bfs.front()[0],w=bfs.front()[1];
          bfs.pop();
          for(int k=0;k<4;k++){
            int k2=(k+dire[h][w])%4;
            if(h+dx[k2]>=0&&h+dx[k2]<5&&w+dy[k2]>=0&&w+dy[k2]<5&&dist[h+dx[k2]][w+dy[k2]]>dist[h][w]+1&&S[h+dx[k2]][w+dy[k2]]!='.'){
              dist[h+dx[k2]][w+dy[k2]]=dist[h][w]+1;
              bfs.push({h+dx[k2],w+dy[k2]});
              idx[h+dx[k2]][w+dy[k2]]=dv[idx[h][w]][k];
              dire[h+dx[k2]][w+dy[k2]]=(dire[h][w]+dvd[idx[h][w]][k])%4;
              Ar[idx[h+dx[k2]][w+dy[k2]]]=(c2d[S[h+dx[k2]][w+dy[k2]]]+4-dire[h+dx[k2]][w+dy[k2]])%4;
            }
          }
        }
        return;
      }
    }
  }
  void print(){
    for(int i=0;i<6;i++){
      cout<<Ar[i]<<' ';
    }
    cout<<endl;
  }
  void roll1(){
    int t=Ar[4];
    Ar[4]=Ar[3],Ar[3]=Ar[2],Ar[2]=Ar[1],Ar[1]=t,Ar[5]=(Ar[5]+1)%4,Ar[0]=(Ar[0]+3)%4;
  }
  void roll2(){
    int t=Ar[0];
    Ar[0]=Ar[2],Ar[2]=Ar[5],Ar[5]=(Ar[4]+2)%4,Ar[4]=(t+2)%4,Ar[1]=(Ar[1]+3)%4,Ar[3]=(Ar[3]+1)%4;
  }
  int operator==(ArrowDie A){
    int ret=0;
    for(int i=0;i<6;i++){
      if(A.Ar[i]==Ar[i])ret+=1;
    }
    return ret;
  }
};

int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int N;
  while(cin>>N,N!=0){
    vector<ArrowDie>Dice;
    for(int i=0;i<N;i++){
      vector S(5,vector(5,'/'));
      for(int j=0;j<5;j++){
        for(int k=0;k<5;k++){
          cin>>S[j][k];
        }
      }
      Dice.push_back(ArrowDie(S));
    }
    for(int i=0;i<N;i++){
      for(int j=0;j<N;j++){
        int t=0;
        for(int k=0;k<4;k++){
          for(int l=0;l<4;l++){
            Dice[i].roll1();
            t=max(t,Dice[i]==Dice[j]);
          }
          Dice[i].roll2();
        }
        Dice[i].roll1();
        Dice[i].roll2();
        for(int k=0;k<4;k++){
          Dice[i].roll1();
          t=max(t,Dice[i]==Dice[j]);
        }
        Dice[i].roll2();Dice[i].roll2();Dice[i].roll2();
        Dice[i].roll1();Dice[i].roll1();
        Dice[i].roll2();
        for(int k=0;k<4;k++){
          Dice[i].roll1();
          t=max(t,Dice[i]==Dice[j]);
        }
        cout<<6-t;
      }
      cout<<'\n';
    }
  }
}
accuracy: 1
time_ms: 240
memory_kb: 3384
final_rank: 1

code_snippet: //type " $ g++ test.cpp -I . "
#include <bits/stdc++.h>
//#include <atcoder/modint>
//using namespace atcoder;
using namespace std;
#define reps(i,s,n) for(int i = s; i < n; i++)
#define rep(i,n) reps(i,0,n)
#define Rreps(i,n,e) for(int i = n - 1; i >= e; --i)
#define Rrep(i,n) Rreps(i,n,0)
#define ALL(a) a.begin(), a.end()

using ll = long long;
using vec = vector<ll>;
using mat = vector<vec>;

ll N,M,H,W,Q,K,A,B;
string S;
using P = pair<ll, ll>;
using tp = tuple<ll, ll, ll>;
const ll INF = (1LL<<60);

template<class T> bool chmin(T &a, const T b){
    if(a > b) {a = b; return true;}
    else return false;
}
template<class T> bool chmax(T &a, const T b){
    if(a < b) {a = b; return true;}
    else return false;
}
template<class T> void my_printv(std::vector<T> v,bool endline = true){
    if(!v.empty()){
        for(std::size_t i{}; i<v.size()-1; ++i) std::cout<<v[i]<<" ";
        std::cout<<v.back();
    }
    if(endline) std::cout<<std::endl;
}

//using mint = modint998244353;
//using vm = vector<mint>;

struct Dice{
    int ii, jj, nxtord;
    int l, r, u, d, f, b;
    vector<int> val;

    void vtoi(){
        l = val[0]; r = val[1];
        f = val[2]; b = val[3];
        u = val[4]; d = val[5];
    }

    void itov(){
        val = {l, r, f, b, u, d};
    }

    void init(vector<int> v){
        rep(i, 6) val[i] = v[i];
        vtoi();
    }

    Dice(vector<int> v = {}) 
    : val(6), ii(0), jj(0), l(0), r(0), f(0), b(0), u(0), d(0), nxtord(0){
        if(v.size() == 6) init(v);
    }
     
    bool operator<(const Dice &dice) const{
        rep(i, 6){
            if(val[i] < dice.val[i]) return true;
            if(val[i] > dice.val[i]) return false;
        }
        return false;
    }

    bool operator==(const Dice &dice) const{
        return !((*this) < dice || dice < (*this));
    }

    bool same(const Dice &dice) const{
        Dice mine(*this);
        rep(_, 4){
            rep(__, 4){
                if(dice == mine) return true;
                mine.RollE();
            }
            mine.RollL();
        }
        mine.RollN();
        rep(_, 2){
            rep(__, 4){
                if(dice == mine) return true;
                mine.RollE();
            }
            mine.RollN(); mine.RollN();
        }
        return false;
    }

    void RollN(){
        int temp = u;
        u = f; f = d; d = b; b = temp;
        (r += 3) &= 3;
        (l += 1) &= 3;
        itov();
    }

    void RollE(){
        int temp = u;
        u = l; l = d; d = r; r = temp;
        (f += 3) &= 3;
        (b += 1) &= 3;
        d ^= 2;
        u ^= 2;
        itov();
    }

    void RollS(){RollN(); RollN(); RollN(); }
    void RollW(){RollE(); RollE(); RollE(); }
    void RollL(){RollN(); RollE(); RollS(); }
    void RollR(){RollS(); RollE(); RollN(); }

    void roll(int di, int dj){
        ii += di; jj += dj;
        if(di == 0){
            dj == 1 ? RollE() : RollW();
        }else{
            di == 1 ? RollS() : RollN();
        }
    }

    void print(){
        cout<<"dice\n";
        cout<<l<<' '<<r<<' '<<f<<' '<<b<<' '<<u<<' '<<d<<endl;
        rep(i, 6) cout<<val[i]<<" \n"[i == 5];
    }

    int diff(const Dice &dice) const{
        int res = 0;
        //rep(i, 6) if(val[i] != dice.val[i]) ++res;
        if(l != dice.l) ++res;
        if(r != dice.r) ++res;
        if(f != dice.f) ++res;
        if(b != dice.b) ++res;
        if(u != dice.u) ++res;
        if(d != dice.d) ++res;
        return res;
    }

    int diff_all(const Dice &dice) const{
        int res = 6;
        
        Dice mine(*this);
        rep(lp1, 4){
            rep(lp2, 4){
                chmin(res, mine.diff(dice));
                mine.RollE();
            }
            mine.RollL();
        }
        mine.RollN();
        rep(lp1, 2){
            rep(lp2, 4){
                chmin(res, mine.diff(dice));
                mine.RollE();
            }
            mine.RollN(); mine.RollN();
        }
        return res;
    }
};

const vector<int> di = {-1, 0, 1, 0};
const vector<int> dj = {0, -1, 0, 1};

int main(){
    while(cin>>N, N){
        vector<vector<string>> g(N, vector<string>(5));
        vector<Dice> dices;
        for(vector<string> &paper : g) {
            rep(j, 5) cin>>paper[j];
            map<char, int> cost = {{'v', 2}, {'<', 1}, {'^', 0}, {'>', 3}};
            auto G = paper;
            Dice tmp;
            auto dfs = [&](auto &&self, int i, int j) -> void{
                tmp.u = cost[G[i][j]];
                tmp.itov();
                G[i][j] = '.';
                rep(k, 4){
                    int ni = i + di[k], nj = j + dj[k];
                    if(ni >= 0 && ni < 5 && nj >= 0 && nj < 5 && G[ni][nj] != '.'){
                        tmp.roll(-di[k], -dj[k]);
                        self(self, ni, nj);
                        tmp.roll(di[k], dj[k]);
                    }
                }
            };
            rep(i, 5) rep(j, 5){
                if(G[i][j] != '.') {
                    dfs(dfs, i, j);
                    break;
                }
            }
            //tmp.print();
            dices.push_back(tmp);
        }
        rep(i, N) {
            rep(j, N) cout<<dices[i].diff_all(dices[j]);
            cout<<endl;
        }
        
    }
}
accuracy: 1
time_ms: 650
memory_kb: 3416
final_rank: 3

code_snippet: #ifdef LOCAL
#define debug(_) cerr << #_ << ": " << (_) << '\n'
#define _GLIBCXX_DEBUG
#else
#define debug(_) (void(0))
#endif  // LOCAL

#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const string UDFBLR_s = "UDFBLR";

int idx(char face_ch) {
    int ret = UDFBLR_s.find(face_ch);
    assert(ret != UDFBLR_s.npos);
    return ret;
}

vector<vector<int>> face_lists(6, vector<int>(4));
vector<string> raw_face_lists = {"BRFL", "FRBL", "URDL",
                                 "DRUL", "UFDB", "UBDF"};

map<string, int> raw_dict = {{"UB", 0},  {"BD", 0},  {"DF", 0},  {"FU", 0},
                             {"UR", -1}, {"RD", -1}, {"DL", -1}, {"LU", -1},
                             {"LF", 0},  {"FR", 0},  {"RB", 2},  {"LB", 2}};
map<pair<int, int>, int> nridx_dicts;

const string dirs = "^>v<";
vector<pair<int, int>> didjs = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};

struct ArrowDice {
    vector<int> UDFBLR;
    ArrowDice(vector<string> strs) {
        UDFBLR.resize(6);
        vector<vector<pair<int, int>>> label(
            5, vector<pair<int, int>>(5, {-1, -1}));
        int si, sj;
        for (si = 0; si < 5; si++) {
            for (sj = 0; sj < 5; sj++) {
                if (strs[si][sj] != '.') {
                    break;
                }
            }
            if (sj != 5) {
                break;
            }
        }
        label[si][sj] = {0, 0};
        stack<pair<int, int>> st;
        st.push({si, sj});
        // cerr << si << ' ' << sj << endl;
        while (!st.empty()) {
            auto [i, j] = st.top();
            st.pop();
            auto [fidx, fdir] = label[i][j];
            for (int rd = 0; rd < 4; rd++) {
                int d = fdir + rd;
                d %= 4;
                auto [di, dj] = didjs[d];
                int ni = i + di;
                int nj = j + dj;
                if (0 <= ni && ni < 5 && 0 <= nj && nj < 5 &&
                    strs[ni][nj] != '.' && label[ni][nj] == make_pair(-1, -1)) {
                    int nfidx = face_lists[fidx][rd];
                    int nfdir = (nridx_dicts[{fidx, nfidx}] + fdir) % 4;
                    label[ni][nj] = {nfidx, nfdir};
                    st.push({ni, nj});
                }
            }
        }
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                if (label[i][j] != make_pair(-1, -1)) {
                    auto [fidx, fdir] = label[i][j];
                    int act_dir = dirs.find(strs[i][j]);
                    UDFBLR[fidx] = (act_dir - fdir + 4) % 4;
                }
            }
        }
        
    }

    void F_rot() {
        int U, D, F, B, L, R;
        U = UDFBLR[0];
        D = UDFBLR[1];
        F = UDFBLR[2];
        B = UDFBLR[3];
        L = UDFBLR[4];
        R = UDFBLR[5];
        UDFBLR = {(L + 1) % 4, (R + 1) % 4, (F + 1) % 4,
                  (B + 3) % 4, (D + 1) % 4, (U + 1) % 4};
    }

    void U_rot() {
        int U, D, F, B, L, R;
        U = UDFBLR[0];
        D = UDFBLR[1];
        F = UDFBLR[2];
        B = UDFBLR[3];
        L = UDFBLR[4];
        R = UDFBLR[5];
        UDFBLR = {(U + 1) % 4, (D + 3) % 4, R, (L + 2) % 4, F, (B + 2) % 4};
    }
};

int diff(ArrowDice dice1, ArrowDice dice2) {
    int count = 0;
    for (int i = 0; i < 6; i++) {
        if (dice1.UDFBLR[i] != dice2.UDFBLR[i]) {
            count++;
        }
    }
    return count;
}

int all_diff(ArrowDice dice1, ArrowDice dice2) {
    int ret = 9;
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            ret = min(ret, diff(dice1, dice2));
            dice1.U_rot();
        }
        dice1.F_rot();
    }
    dice1.U_rot();
    dice1.F_rot();
    for (int i = 0; i < 4; i++) {
        ret = min(ret, diff(dice1, dice2));
        dice1.U_rot();
    }
    dice1.F_rot();
    dice1.F_rot();
    for (int i = 0; i < 4; i++) {
        ret = min(ret, diff(dice1, dice2));
        dice1.U_rot();
    }
    return ret;
}

void solve() {
    int N;
    cin >> N;
    if (N == 0) {
        exit(0);
    }
    vector<ArrowDice> dices;
    for (int i = 0; i < N; i++) {
        vector<string> tmp(5);
        for (int j = 0; j < 5; j++) {
            cin >> tmp[j];
        }

        dices.push_back(ArrowDice(tmp));
    }

    vector<vector<int>> answer(N, vector<int>(N));
    for (int i = 0; i < N; i++) {
        for (int j = i + 1; j < N; j++) {
            answer[i][j] = all_diff(dices[i], dices[j]);
            answer[j][i] = answer[i][j];
        }
    }
    for (auto &&row : answer) {
        for (auto &&e : row) {
            cout << e;
        }
        cout << '\n';
    }
}

int main() {
    for (int i = 0; i < 6; i++) {
        for (int j = 0; j < 4; j++) {
            face_lists[i][j] = idx(raw_face_lists[i][j]);
        }
    }
    for (auto &&[key, val] : raw_dict) {
        int from_ = idx(key[0]);
        int to = idx(key[1]);
        nridx_dicts[{from_, to}] = (4 + val) % 4;
        nridx_dicts[{to, from_}] = (4 - val) % 4;
    }

    while (true) {
        solve();
    }

    return 0;
}
accuracy: 1
time_ms: 770
memory_kb: 3516
final_rank: 11