Problem:
Dice Stamp
サイコロスタンプ
あなたは地元の縁日で，今までに見たことがないゲームの出店を発見した．
N
個の6面サイコロを，ボード上に落として転がすゲームだ．
より正確には，
N
個のボタンが
N
個のサイコロに1対1に紐付いており，ボタンを押すことで対応したサイコロがボードに落ちる．
ボタンを好きなように
N
回押し，サイコロを
N
回落として転がすことで得点を得るゲームである．
ゲームのより詳細なルールを説明しよう．
ゲームで使用する
N
個のサイコロはすべて各辺の長さが1の立方体であり，ボードは長さが1の正方形のマスに区切られた十分に広い平面である．
ゲーム開始前，ボードの各マスにはすべて0が書かれている．
各サイコロの各面には整数が書かれている．これは1から6までとは限らないし，サイコロごとに違う数が書かれていることもある．
ゲームで用いる筐体には
N
個のボタンが付いており，
N
個のサイコロと1対1に紐付いている．
いずれかのボタンを押すと，対応したサイコロが機械から排出されてボードに落ち，何度か回転する．
回転の途中，サイコロの下面は必ずボードのいずれかのマスにぴったりと重なる．
下面がマスに触れる度，そのマスに書かれていた数が，サイコロの下面に書かれた数で上書きされる．
これは落下により初めてボードに触れたときも含む．
回転が止まった後，サイコロはボードから取り除かれ，元の排出装置へと戻される．
ボタンを
N
回押した後，ボードに書かれた数の和が最終得点となる．
同じボタンを複数回押すことはできるが，1つ前に排出したサイコロの回転が終わり，排出装置に戻るまで次のボタンを押すことはできない．
さて，出店のおっちゃんはサイコロの排出の仕方はランダムだと主張しているが，注意深いあなたは，他の客が遊ぶ様子を観察することで，同じボタンを押した時の挙動がそれまでのボタンの押し方に依らず完全に同一であることに気付いた．
より具体的には，
i
番目のボタンを押したときの挙動は以下のように決定的である．
i
番目のサイコロが排出される．
このサイコロは内部で決められたマスに決められた向きで落下する．この向きは必ず，マスの正方形と下面の正方形とがぴったりと重なる向きである．
サイコロは前後左右4方向いずれかに回転することを繰り返す．回転回数やそれぞれの回転の方向も，内部で決められている．
決められた回転が終了すると，サイコロはボードから取り除かれ，排出装置に戻される．
ここで，便宜上3次元空間を考え，マスの辺に平行な向きにそれぞれ
x
軸と
y
軸をとり，サイコロ上面が向く方向を
z
軸正方向とする. この時，サイコロの回転は
x
,
y
軸の正，負方向の4通りであり，それぞれ下図のようになる．ただし，図中の記号は後述の入力形式に対応している．
決定的に動くとはなんて詐欺だ，と憤りを感じたものの，あなたは
N
回のボタンの押し方によって最終得点を変えられることに気が付いた．
あなたは入念な観察により各サイコロの各面に書かれた数や落とされる初期位置・向き・その後の回転の仕方に至るまで完全な情報を揃えた．
集めた情報に基づいて，最善のボタンの押し方で得られるこのゲームの最高得点を求めよ．
Input
入力は40個以下のデータセットからなる．各データセットは以下の形式で表される．
N
1番目のサイコロの情報
...
N
番目のサイコロの情報
入力の最初の行は，サイコロの個数を表す1つの整数
N
からなる．1 ≤
N
≤ 15 と仮定してよい．
以降，
N
個のサイコロの情報が続く．
それぞれのサイコロの情報は，以下の形式で表される．
x
y
l
r
f
b
d
u
rot
1行目は2つの整数
x
,
y
からなり，排出されたときにサイコロが落とされるマスの中心の座標 (
x
,
y
) を表す．-1,000 ≤
x
,
y
≤ 1,000 と仮定してよい．
2行目は6つの整数
l
,
r
,
f
,
b
,
d
,
u
からなり，各面に書かれた数を表す．
l
,
r
,
f
,
b
,
d
,
u
はそれぞれ，落とされたときに
x
軸負方向，
x
軸正方向，
y
軸負方向，
y
軸正方向，
z
軸負方向，
z
軸正方向を向いている面に書かれた数である．1 ≤
l
,
r
,
f
,
b
,
d
,
u
≤ 100 と仮定してよい．
3行目は回転の仕方を表す文字列
rot
からなる．
rot
は '
L
', '
R
', '
F
', '
B
' のみからなる文字列であり，1文字以上，30文字以下である．
rot の j 番目の文字は j 回目の回転の方向を表しており，文字が '
L
', '
R
', '
F
', '
B
' のときそれぞれ，
x
軸負方向，
x
軸正方向，
y
軸負方向，
y
軸正方向に回転することを示す．
入力の終わりは，1つのゼロを含む1行で示される．
Output
各データセットについて，
N
回のボタンの押し方を工夫することで得られる最高得点を1行で出力せよ．
各出力行はこの数値以外の文字を含んではならない．
Sample Input
1
0 0
1 2 3 4 5 6
RRRRBBBBLLLLFFFF
2
0 0
1 1 1 1 1 1
RRR
2 2
100 100 100 100 100 100
FFF
1
1000 -1000
1 2 3 4 5 6
LFRB
4
-3 -4
1 2 3 4 5 6
BBBBBBBB
4 -3
11 12 13 14 15 16
LLLLLLLL
3 4
21 22 23 24 25 26
FFFFFFFF
-4 3
31 32 33 34 35 36
RRRRRRRR
3
-2 -2
9 3 1 1 1 1
RRRRBLLLBRRBLB
0 -3
2 5 2 5 2 1
BBLBBRBB
3 0
10 7 2 10 1 5
LLFLLBLL
0
Output for Sample Input
64
403
10
647
96

Submitted solutions:

code_snippet: #include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
int dx[4] = {1, 0, 0, -1};
int dy[4] = {0, 1, -1, 0};
//l r f b d u
//0 1 2 3 4 5
int go[4][6] = {
    {5, 4, 2, 3, 0, 1},
    {0, 1, 5, 4, 2, 3},
    {0, 1, 4, 5, 3, 2},
    {4, 5, 2, 3, 1, 0}
};
const int N(65555);
const int LOG(16);
int x[LOG], y[LOG];
char st[555];
int a[6], b[6], tp[555], lg2[N];
vector<pair<pair<int, int>,int> > vec[LOG];
int cnf[LOG][LOG], totcnf[N][LOG], ic[N][LOG], ans[N];
int main() {
    tp['R'] = 0;
    tp['B'] = 1;
    tp['F'] = 2;
    tp['L'] = 3;
    int n;
    for(;;) {
        scanf("%d", &n);
        if(!n) {
            break;
        }
        for(int i(0); i < n; i++) {
            scanf("%d%d", &x[i], &y[i]);
            for(int j(0); j < 6; j++) {
                scanf("%d", &a[j]);
            }
            scanf("%s", st);
            int len(strlen(st));
            vec[i].clear();
            for(int j(0); j <= len; j++) {
                //printf("%d %d %d %d\n", i, x[i], y[i], a[4]);
                vec[i].push_back(make_pair(make_pair(x[i], y[i]), a[4]));
                if(j != len) {
                    for(int k(0); k < 6; k++) {
                        b[go[tp[st[j]]][k]] = a[k];
                    }
                    memcpy(a, b, sizeof(b));
                    x[i] += dx[tp[st[j]]];
                    y[i] += dy[tp[st[j]]];
                }
            }
            for(int j(0); j + 1 < (int)vec[i].size(); j++) {
                bool flag(false);
                for(int k(j + 1); k < (int)vec[i].size(); k++) {
                    if(vec[i][j].first == vec[i][k].first) {
                        flag = true;
                        break;
                    }
                }
                if(flag) {
                    vec[i].erase(vec[i].begin() + j);
                    j--;
                }
            }
            for(int j(0); j < i; j++) {
                cnf[j][i] = 0;
                cnf[i][j] = 0;
                for(int k(0); k < (int)vec[i].size(); k++) {
                    for(int l(0); l < (int)vec[j].size(); l++) {
                        if(vec[i][k].first == vec[j][l].first) {
                            cnf[j][i] |= 1 << k;
                            cnf[i][j] |= 1 << l;
                        }
                    }
                }
                //printf("cnf[%d][%d] = %d\n", i, j, cnf[i][j]);
            }
        }
        for(int i(0); i < n; i++) {
            lg2[1 << i] = i;
        }
        for(int msk(0); msk < (1 << n); msk++) {
            for(int i(0); i < n; i++) {
                if((msk & (1 << i)) == 0) {
                    ic[msk][i] = 0;
                    totcnf[msk][i] = msk == 0 ? 0 : totcnf[msk - (msk & -msk)][i] | cnf[lg2[msk & -msk]][i];
                    for(int j(0); j < (int)vec[i].size(); j++) {
                        ic[msk][i] += (totcnf[msk][i] & (1 << j)) ? 0 : vec[i][j].second;
                    }
                    //printf("ic[%d][%d] = %d\n", msk, i, ic[msk][i]);
                }
            }
        }
        memset(ans, 0, sizeof(ans));
        for(int msk(0); msk < (1 << n); msk++) {
            for(int i(0); i < n; i++) {
                if((msk & (1 << i)) == 0) {
                    ans[msk | (1 << i)] = max(ans[msk | (1 << i)], ans[msk] + ic[msk][i]);
                }
            }
        }
        printf("%d\n", ans[(1 << n) - 1]);
    }
}
accuracy: 1
time_ms: 30
memory_kb: 11776
final_rank: 4

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

// #ifndef ONLINE_JUDGE
// #define _GLIBCXX_DEBUG // 配列外参照のエラー
// #endif

// スタンダードライブラリ
#include <bits/stdc++.h>
using namespace std;

// 型関連
using ll = long long;
using lint = long long;
using pll = pair<ll, ll>;
using plll = tuple<ll, ll, ll>;
using pii = pair<int, int>;
using piii = tuple<ll, ll, ll>;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vvvi = vector<vector<vector<int>>>;
using vvvvi = vector<vector<vector<vector<int>>>>;
using vl = vector<ll>;
using vvl = vector<vector<ll>>;
using vvvl = vector<vector<vector<ll>>>;
using vvvvl = vector<vector<vector<vector<ll>>>>;

template <class T> using prique = priority_queue<T>;
template <class T> void chmin(T &a, T b) {
    if (a > b)
        a = b;
}
template <class T> void chmax(T &a, T b) {
    if (a < b)
        a = b;
}

#define all(v) v.begin(), v.end()

// 型定数
constexpr ll mod = 998244353;
constexpr ll MOD = 1000000007;
int INF32 = 2e9;
ll INF64 = 9e18;
#define endl '\n';

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

/////////////////////////// print関連
template <typename T> void print(vector<T> A);
void print();
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail);
void print(string S);
template <typename T> void print(vector<vector<T>> &F);

inline void Yes(bool f);

/*
U: 上面
F: 正面（前側面）
R: 右側面
B: 後ろ側面
L: 左側面
D: 下面

ダイスの各面が持つ何かしらの値で初期化を行う。
*/
template <typename T> struct Dice {
    T U, F, R, B, L, D;
    int x, y;
    Dice(T U, T F, T R, T B, T L, T D, int x = 0, int y = 0)
        : U(U), F(F), R(R), B(B), L(L), D(D), x(x), y(y) {}

    /*
d: 倒れる方向
0: 前に倒れる(Fが下になる) 
1: 右に倒れる(Rが下になる) 
2: 後ろに倒れる(Bが下になる) 
3: 左に倒れる(Lが下になる) 
x,yの方向は問題によって変えてください
*/
    void Rotation(int d) {
        T nU = U, nF = F, nR = R, nB = B, nL = L, nD = D, nx = x, ny = y;
        if (d == 0) {
            nF = U, nD = F, nB = D, nU = B, ny--;
        } else if (d == 1) {
            nR = U, nD = R, nL = D, nU = L, nx++;
        } else if (d == 2) {
            nF = D, nU = F, nB = U, nD = B, ny++;
        } else {
            nL = U, nD = L, nR = D, nU = R, nx--;
        }
        U = nU, F = nF, R = nR, B = nB, L = nL, D = nD, x = nx, y = ny;
    }

    void Rotation(char d) {
        switch (d) {
        case 'L':
            Rotation(3);
            break;
        case 'R':
            Rotation(1);
            break;
        case 'F':
            Rotation(0);
            break;
        case 'B':
            Rotation(2);
            break;
        }
    }
};

///////////////////ここから//////////////////////


template<class T> size_t HashCombine(const size_t seed,const T &v){
    return seed^(std::hash<T>()(v)+0x9e3779b9+(seed<<6)+(seed>>2));
}
/* pair用 */
template<class T,class S> struct std::hash<std::pair<T,S>>{
    size_t operator()(const std::pair<T,S> &keyval) const noexcept {
        return HashCombine(std::hash<T>()(keyval.first), keyval.second);
    }
};


unordered_map<pii, int> Dice_map() {
    int x, y;
    cin >> x >> y;
    int l, r, f, b, d, u;
    cin >> l >> r >> f >> b >> d >> u;
    Dice<int> D(u, f, r, b, l, d, x, y);
    string S;
    cin >> S;

    unordered_map<pii, int> ret;
    ret[{x,y}] = d;
    for (int i = 0; i < S.size(); i++) {
        D.Rotation(S[i]);
        ret[{D.x, D.y}] = D.D;
        //print(D.x,D.y);
    }
    return ret;
}

bool solve() {
    int N;
    cin >> N;
    if (N == 0) {
        return false;
    }
    vector<unordered_map<pii, int>> VM;
    for (int i = 0; i < N; i++) {
        VM.push_back(Dice_map());
    }
    vector<unordered_map<pii, int>> stamped(1 << N); //集合Sによってスタンプされた座標を持つ
    vector<int> dp(1<<N);  //集合Sでスタンプされたときの最大値
    for (int S = 0; S < (1 << N); S++) {
        for (int v = 0; v < N; v++) {
            if (S & (1 << v)) {
                continue;
            }
            unordered_map<pii, int> nex_map = stamped[S];
            int w=dp[S];
            for (auto [key, val] : VM[v]) {
                if (nex_map.count(key)) {
                    continue;
                }
                nex_map[key] = val;
                w+=val;
            }
            chmax(dp[S + (1 << v)], w);
            swap(stamped[S+(1<<v)],nex_map);
        }
    }
    print(dp[(1<<N)-1]);

    return true;
}

int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    while (solve())
        ;
}

////////////////////print/////////////////////////
// 1次元ベクトルを出力する
template <typename T> void print(vector<T> A) {
    if (A.size() == 0) {
        return;
    }
    for (size_t i = 0; i < A.size() - 1; i++) {
        cout << A[i] << ' ';
    }
    cout << A[A.size() - 1] << endl;
    return;
}

// 2次元ベクトルを出力する
template <typename T> void print(vector<vector<T>> &F) {
    for (size_t i = 0; i < F.size(); i++) {
        for (size_t j = 0; j < F[i].size(); j++) {
            cout << F[i][j];
            if (j < F[i].size() - 1) {
                cout << ' ';
            }
        }
        cout << endl;
    }
}

// 空白行を出力するprint
void print() { cout << endl; }

// 数値・文字列を空白区切りで出力する. print(a,b)など
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    cout << head;
    if (sizeof...(tail) != 0)
        cout << " ";
    print(forward<Tail>(tail)...);
}

void print(string S) { cout << S << endl; }

//////////////出力関連

inline void Yes(bool f) {
    if (f) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;
    }
}
accuracy: 1
time_ms: 7200
memory_kb: 215464
final_rank: 18

code_snippet: #ifndef ONLINE_JUDGE
#define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>
using namespace std;
#include <atcoder/all>
using namespace atcoder;
// #include <boost/rational.hpp>
// using namespace boost;
// using rat = rational<long long int>;
using mint = modint998244353;
// using mint = modint1000000007;
// using mint = mint;
using ll = long long;
using ld = long double;
using ull = uint64_t;
using pll = pair<ll, ll>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vpll = vector<pll>;
using vvpll = vector<vpll>;
using vm = vector<mint>;
using vvm = vector<vm>;
using vvvm = vector<vvm>;
using vstr = vector<string>;
#define v(T) vector<T>
#define vv(T) vector<vector<T>>
#define vvv(T) vector<vector<vector<T>>>
#define vvvv(T) vector<vector<vector<vector<T>>>>

istream &operator>>(istream &is, mint &a){ll tmp; is >> tmp; a = tmp; return is;}
ostream &operator<<(ostream &os, const mint &a){ os << a.val(); return os; }
string to_string(const __int128_t &a) { if (a == 0) return "0"; string s = ""; __int128_t num = a; bool is_negative = false; if (num < 0) { is_negative = true; num = -num; } while (num > 0) { s += '0' + (num % 10); num /= 10; } if (is_negative) s += '-'; reverse(s.begin(), s.end()); return s; }
istream &operator>>(istream &is, __int128_t &a){ string s; is >> s; a = 0; for(char c : s) { if(isdigit(c)) {a = a*10 + (c - '0'); }  } if(s[0]=='-'){ a *= -1; } return is; }
ostream &operator<<(ostream &os, const __int128_t &a){ os << to_string(a); return os; }
template<class T, class U> istream &operator>>(istream &is, pair<T, U> &p) { is >> p.first >> p.second; return is; }
template<class T, class U> ostream &operator<<(ostream &os, const pair<T, U> &p) { os << p.first << " " << p.second; return os; }
template<class T> istream &operator>>(istream &is, vector<T> &vec){ for(T &e : vec){is >> e;} return is; }
template<class T> ostream &operator<<(ostream &os, const vector<T> &vec) { for(int i = 0; i < (int)vec.size(); i++) { os << vec[i] << (i + 1 != (int)vec.size() ? " " : ""); } return os; }

template <class... T> constexpr auto min (T... a) { return min(initializer_list<common_type_t<T...>>{a...}); }
template <class... T> constexpr auto max (T... a) { return max(initializer_list<common_type_t<T...>>{a...}); }
template<class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
template<class T> T opmin(T x, T y) { return min(x, y); }
template<class T> T einf() { return numeric_limits<T>::max(); }
template<class T> T opmax(T x, T y) { return max(x, y); }
template<class T> T eminf() { return numeric_limits<T>::min(); }
template<class T> T opsum(T x, T y) { return x + y; }
template<class T> T ezero() { return (T)0; }
// #define maxseg(T) segtree<T, [](T x, T y){return max(x, y);}, [](){return (T)(-(1LL << 60));}>
// #define minseg(T) segtree<T, [](T x, T y){return min(x, y);}, [](){return (T)((1LL << 60));}>
// #define sumseg(T) segtree<T, [](T x, T y){return x + y;}, [](){return (T)(0);}>
template<class T> using minseg = segtree<T, opmin<T>, einf<T>>;
template<class T> using maxseg = segtree<T, opmax<T>, eminf<T>>;
template<class T> using sumseg = segtree<T, opsum<T>, ezero<T>>;
// template<class T> struct v : vector<T> { using vector<T> :: vector; };
// template<class T> struct vv : vector<v<T>> { using vector<v<T>> :: vector; };
// template<class T> struct vvv : vector<vv<T>> { using vector<vv<T>> :: vector; };
template<class T> inline bool chmin(T& a, T b) {if(a > b){a = b; return true;} else {return false;}};
template<class T> inline bool chmax(T& a, T b) {if(a < b){a = b; return true;} else {return false;}};
#define rep(i,n) for(ll i = 0; i < (ll)(n); i++)
#define repr(i,n) for(ll i = (ll)(n) - 1; i >= 0; i--)
#define REP(i, l, r) for(ll i = (ll)l; i <= (ll)(r); i++)
#define REPR(i, l, r) for(ll i = (ll)r; i >= (ll)(l); i--)
const ll inf = (1 << 30);
const ll INF = (1LL << 60);
const vector<pair<ll, ll>> DIJ = {{1, 0}, {0, -1}, {-1, 0}, {0, 1}};
void out(){cout<<'\n';}
template<class T, class... Ts> void out(const T& a, const Ts&... b){ cout<<a; (cout<<... << (cout << ' ', b)); cout << '\n';}
void outf(){cout<<endl;}
template<class T, class... Ts> void outf(const T& a, const Ts&... b){ cout<<a; (cout<<... << (cout << ' ', b)); cout << endl;}
template<class T, class U> void outp(pair<T, U> a){ out((a).first, (a).second); }
template<class T, class U> void outpf(pair<T, U> a){ outf((a).first, (a).second); }
template<class T> void outv(T a){rep(i, (a).size()){ cout << (a)[i] << " "; } cout << endl;}
template<class T> void outvL(T a){rep(i, (a).size()){out((a)[i]);} cout << flush; }
// template<class T> void outvv(T a){rep(i, a.size()){ rep(j, a.at(i).size()){cout << a.at(i).at(j) << " "; } cout << endl; }}
// template<class T> void outvp(T a){rep(i, a.size()){ out2(a.at(i).first, a.at(i).second); }}
void setpre(int a){cout << fixed << setprecision(a);}
#define outN out("No")
#define outY out("Yes")
#define outYN(flag) out(flag ? "Yes" : "No")
#define dame(...) {outf(__VA_ARGS__);return 0;}

template<class T> void read(vector<T>& vec){ for(int i = 0; i < (int)vec.size(); i++) { cin >> vec[i]; } }
template<class... T> void read(T&... a){(cin >> ... >> a);}
#define readll(...) ll __VA_ARGS__; read(__VA_ARGS__)
#define readvll(a, n) vector<ll> a(n); read(a)
#define readvt(type, a, n) vector<type> a(n); read(a)
#define readvll2(a, b, n) vector<ll> a(n), b(n); for(int lopi = 0; lopi < (int)(n); lopi++) cin >> (a)[lopi] >> (b)[lopi]
#define readvll3(a, b, c, n) vector<ll> a(n), b(n), c(n); for(int lopi = 0; lopi < (int)(n); lopi++) cin >> (a)[lopi] >> (b)[lopi] >> (c)[lopi]
#define readstr(...) string __VA_ARGS__; read(__VA_ARGS__)
#define readundirG(G, N, M) G = vvll(N); rep(lopi, M) {ll a, b; cin >> a >> b; G[a-1].push_back(b-1); G[b-1].push_back(a-1);}
#define readdirG(G, N, M) G = vvll(N); rep(lopi, M) {ll a, b; cin >> a >> b; G[a-1].push_back(b-1);}
#define readundirwghG(G, N, M) G = vv(pll)(N); rep(lopi, M) {ll a, b, c; cin >> a >> b >> c; G[a-1].emplace_back(b-1,c); G[b-1].emplace_back(a-1, c);}
#define readdirwghG (G, N, M) G = vv(pll)(N); rep(lopi, M) {ll a, b, c; cin >> a >> b >> c; G[a-1].emplace_back(b-1, c);}

#define All(a) (a).begin(), (a).end()
template<class T> inline void sortr(T& a){ sort((a).rbegin(), (a).rend()); }
template<class T> inline vector<int> argsort(T V, bool rev = false){vector<int> res(V.size()); iota(res.begin(), res.end(), 0); sort(res.begin(), res.end(), [&](int x, int y){if(!rev){return V[x] < V[y];}else{return V[x] > V[y];}}); return res;}
template<class T, class U> inline void sort_by_idx(T& V, vector<U>& I){assert(V.size() == I.size()); T tmpv = V; for(int loopi = 0; loopi < (int)I.size(); loopi++){V[loopi] = tmpv[I.at(loopi)];}}
template<class T, class U> inline void sortp(vector<T>& v1, vector<U>& v2, bool rev1 = false, int rev2 = false){assert(v1.size() == v2.size()); vector<int> I(v1.size()); iota(I.begin(), I.end(), 0); sort(I.begin(), I.end(), [&](const int x, const int y){if(v1[x] != v1[y]){return (bool)(rev1 ^ (v1[x] < v1[y]));}else{if(v2[x]==v2[y]){return false;} return (bool)(rev2 ^ (v2[x] < v2[y]));}}); sort_by_idx(v1, I); sort_by_idx(v2, I);}
template<class T> T POW(T x, ll n) {T ret = 1; while(n > 0){if(n & 1) ret *= x; x *= x; n >>= 1;} return ret;}
ll powll(ll x, ll n){ll ret = 1; while(n > 0){if(n & 1) ret *= x; x *= x; n >>= 1;} return ret;}
inline ll divceil(ll x, ll y) { if(x >= 0) {return(x / y + (ll)(x % y != 0)); } else { return -((-x) / y); } }
inline ll divfloor(ll x, ll y) { if(x >= 0) { return x/y; } else { return -((-x)/y + (ll)((-x) % y != 0)); } }
inline bool inLR(ll x, ll L, ll R){ return (L <= x && x < R); }
inline bool inRect(ll pos_x, ll pos_y, ll rect_H, ll rect_W, ll rect_h = 0, ll rect_w = 0){ return (rect_h <= pos_x && pos_x < rect_H && rect_w <= pos_y && pos_y < rect_W); }

template<class T> vector<T> &operator++(vector<T> &v) {for(auto &e : v){e++;} return v;}
template<class T> vector<T> operator++(vector<T> &v, signed) {auto res=v; for(auto &e : v){e++;} return res;}
template<class T> vector<T> &operator--(vector<T> &v) {for(auto &e : v){e--;} return v;}
template<class T> vector<T> operator--(vector<T> &v, signed) {auto res=v; for(auto &e : v){e--;} return res;}
template<class T> vector<T> operator+(const vector<T> &x, const vector<T> &y) { assert(x.size() == y.size()); vector<T> ret(x.size()); for(int i = 0; i < (int)x.size(); i++) {ret[i] = x[i] + y[i];} return ret; }
template<class T> vector<T> operator-(const vector<T> &x, const vector<T> &y) { assert(x.size() == y.size()); vector<T> ret(x.size()); for(int i = 0; i < (int)x.size(); i++) {ret[i] = x[i] - y[i];} return ret; } 

template<class T, class U> pair<T, U> operator+(const pair<T, U> &x, const pair<T, U> &y) { return make_pair(x.first + y.first, x.second + y.second); }
template<class T, class U> pair<T, U> operator-(const pair<T, U> &x, const pair<T, U> &y) { return make_pair(x.first - y.first, x.second - y.second); }
template<class T, class U> void operator+=(pair<T, U> &x, pair<T, U> &y) { x = x + y; }
template<class T, class U> void operator-=(pair<T, U> &x, pair<T, U> &y) { x = x - y; }

template<class T> size_t HashCombine(const size_t seed,const T &v){ return seed^(std::hash<T>()(v)+0x9e3779b9+(seed<<6)+(seed>>2)); }
template<class T,class S> struct std::hash<std::pair<T,S>>{ size_t operator()(const std::pair<T,S> &keyval) const noexcept { return HashCombine(std::hash<T>()(keyval.first), keyval.second); } };
template<class T> struct std::hash<std::vector<T>>{ size_t operator()(const std::vector<T> &keyval) const noexcept { size_t s=0; for (auto&& v: keyval) s=HashCombine(s,v); return s; } };
template<int N> struct HashTupleCore{ template<class Tuple> size_t operator()(const Tuple &keyval) const noexcept{ size_t s=HashTupleCore<N-1>()(keyval); return HashCombine(s,std::get<N-1>(keyval)); } };
template <> struct HashTupleCore<0>{ template<class Tuple> size_t operator()(const Tuple &keyval) const noexcept{ return 0; } };
template<class... Args> struct std::hash<std::tuple<Args...>>{ size_t operator()(const tuple<Args...> &keyval) const noexcept { return HashTupleCore<tuple_size<tuple<Args...>>::value>()(keyval); } };

struct dice
{
    ll x, y;
    ll l, r, f, b, d, u;
    string rot;
    map<pll, ll> pos;
    void read()
    {
        cin >> x >> y >> l >> r >> f >> b >> d >> u;
        cin >> rot;
    }

    // x--
    void rotl()
    {
        ll tmp = d;
        d = l;
        l = u;
        u = r;
        r = tmp;
        x--;
    }

    // x++
    void rotr()
    {
        ll tmp = d;
        d = r;
        r = u;
        u = l;
        l = tmp;
        x++;
    }

    // y--;
    void rotf()
    {
        ll tmp = d;
        d = f;
        f = u;
        u = b;
        b = tmp;
        y--;
    }

    // y++
    void rotb()
    {
        ll tmp = d;
        d = b;
        b = u;
        u = f;
        f = tmp;
        y++;
    }

    void calc_pos()
    {
        pos[{x, y}] = d;
        for(auto c : rot)
        {
            if(c == 'L')
            {
                rotl();
            }
            else if(c == 'R')
            {
                rotr();
            }
            else if(c == 'F')
            {
                rotf();
            }
            else
            {
                rotb();
            }
            pos[{x, y}] = d;
        }
    }
};

int main()
{
    std::cin.tie(nullptr), std::ios_base::sync_with_stdio(false);
    while(true)
    {
        readll(N);
        if(!N) break;
        vector<dice> D(N);
        rep(i, N) D[i].read();
        rep(i, N) D[i].calc_pos();
        vll dp(1LL << N, 0);
        rep(bit, 1LL << N)
        {
            vll cand;
            set<pll> used;
            rep(i, N)
            {
                if((bit >> i) & 1)
                {
                    for(auto [xy, d] : D[i].pos)
                    {
                        used.insert(xy);
                    }
                }
                else cand.emplace_back(i);
            }
            for(auto i : cand)
            {
                ll nxt = dp[bit];
                for(auto [xy, d] : D[i].pos)
                {
                    if(used.count(xy)) continue;
                    nxt += d;
                }
                chmax(dp[bit | (1LL << i)], nxt);
            }
        }
        outf(dp[(1LL << N) - 1]);
    }
}
accuracy: 1
time_ms: 4110
memory_kb: 4036
final_rank: 15

code_snippet: # include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
const double pi = acos(-1);
template<class T>constexpr T inf() { return ::std::numeric_limits<T>::max(); }
template<class T>constexpr T hinf() { return inf<T>() / 2; }
template <typename T_char>T_char TL(T_char cX) { return tolower(cX); }
template <typename T_char>T_char TU(T_char cX) { return toupper(cX); }
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; }
int popcnt(unsigned long long n) { int cnt = 0; for (int i = 0; i < 64; i++)if ((n >> i) & 1)cnt++; return cnt; }
int d_sum(ll n) { int ret = 0; while (n > 0) { ret += n % 10; n /= 10; }return ret; }
int d_cnt(ll n) { int ret = 0; while (n > 0) { ret++; n /= 10; }return ret; }
ll gcd(ll a, ll b) { if (b == 0)return a; return gcd(b, a%b); };
ll lcm(ll a, ll b) { ll g = gcd(a, b); return a / g*b; };
ll MOD(ll x, ll m){return (x%m+m)%m; }
ll FLOOR(ll x, ll m) {ll r = (x%m+m)%m; return (x-r)/m; }
template<class T> using dijk = priority_queue<T, vector<T>, greater<T>>;
# define all(qpqpq)           (qpqpq).begin(),(qpqpq).end()
# define UNIQUE(wpwpw)        (wpwpw).erase(unique(all((wpwpw))),(wpwpw).end())
# define LOWER(epepe)         transform(all((epepe)),(epepe).begin(),TL<char>)
# define UPPER(rprpr)         transform(all((rprpr)),(rprpr).begin(),TU<char>)
# define rep(i,upupu)         for(ll i = 0, i##_len = (upupu);(i) < (i##_len);(i)++)
# define reps(i,opopo)        for(ll i = 1, i##_len = (opopo);(i) <= (i##_len);(i)++)
# define len(x)                ((ll)(x).size())
# define bit(n)               (1LL << (n))
# define pb push_back
# define eb emplace_back
# define exists(c, e)         ((c).find(e) != (c).end())

struct INIT{
	INIT(){
		std::ios::sync_with_stdio(false);
		std::cin.tie(0);
		cout << fixed << setprecision(20);
	}
}INIT;

namespace mmrz {
	void solve();
}

int main(){
	mmrz::solve();
}
#define debug(...) (static_cast<void>(0))

using namespace mmrz;

using vll=vector<ll>;
using vvll = vector<vector<ll>>;
using ull = unsigned long long;
using lll = __int128;
#define per(i,n) for(ll i=n-1;i>=0;--i)
#define rep2(i,a,n) for (ll i=a;i<n;++i)
#define per2(i,a,n) for (ll i=a;i>=n;--i)

// [BEGIN] template の include

int SOLVE(){
	int n; cin >> n;
	if(n==0) return 1;
	map<pair<int,int>, int> dice_idx;
	vector<map<pair<int,int>, ll>> write_numbers(n);
	int x, y;
	vector<int> dice(6);
	string route;

	rep(i,n) {
		cin >> x >> y;
		rep(j,6) cin >> dice[j];
		cin >> route;
		// tyakuti
		dice_idx[{x,y}] = dice_idx[{x,y}] | (1<<i);
		write_numbers[i][{x,y}] = dice[4];
		for(char c: route) {
			vector nxt = dice;
			if(c=='L') {
				x -= 1;
				nxt[0] = dice[5];
				nxt[1] = dice[4];
				nxt[4] = dice[0];
				nxt[5] = dice[1];
			} else if(c=='R') {
				x += 1;
				nxt[0] = dice[4];
				nxt[1] = dice[5];
				nxt[4] = dice[1];
				nxt[5] = dice[0];
			} else if(c=='F') {
				y -= 1;
				nxt[2] = dice[5];
				nxt[3] = dice[4];
				nxt[4] = dice[2];
				nxt[5] = dice[3];
			} else {
				y += 1;
				nxt[2] = dice[4];
				nxt[3] = dice[5];
				nxt[4] = dice[3];
				nxt[5] = dice[2];
			}
			dice = nxt;
			dice_idx[{x,y}] = dice_idx[{x,y}] | (1<<i);
			write_numbers[i][{x,y}] = dice[4];
		}
	}

	vll dp(1<<n, -1);
	dp[0] = 0;
	rep(i, 1<<n) {
		rep(j,n) {
			if(((i>>j)&1)==1) continue;
			int nxt = i | (1<<j);
			ll adr = 0;
			for(auto [xy, val]: write_numbers[j]) {
				auto [xx,yy] = xy;
				if((dice_idx[{xx,yy}] & nxt) == dice_idx[{xx,yy}]) adr += val;
			}
			chmax(dp[nxt], dp[i] + adr);
		}
	}
	cout << dp[(1<<n)-1] << '\n';
	return 0;
}

void mmrz::solve(){
	while(!SOLVE());
}
accuracy: 1
time_ms: 590
memory_kb: 3848
final_rank: 6

code_snippet: //#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i,n) for (ll i=0;i<(ll)n;i++)
#define rrep(i,n) for (ll i=n-1;i>=(ll)0;i--)
#define loop(i,m,n) for(ll i=m;i<=(ll)n;i++)
#define rloop(i,m,n) for(ll i=m;i>=(ll)n;i--)
#define vl vector<long long>
#define vvl vector<vector<long long>>
#define vdbg(a) rep(ii,a.size()){cout<<a[ii]<<" ";}cout<<endl;
#define vvdbg(a) rep(ii,a.size()){rep(jj,a[ii].size()){cout<<a[ii][jj]<<" ";}cout<<endl;}
#define setdbg(a) for(const auto & ii:a){cout<<ii<<" ";}cout<<endl;
#define YES cout<<"Yes"<<endl;return 0;
#define NO cout<<"No"<<endl;return 0;
#define inf 4000000000000000000LL
#define mod 998244353LL
//#define mod 1000000007LL
random_device rnd;// 非決定的な乱数生成器
mt19937 mt(rnd());// メルセンヌ・ツイスタの32ビット版、引数は初期シード


//#include<boost/multiprecision/cpp_int.hpp>
//#define bbi boost::multiprecision::cpp_int

//#include<atcoder/lazysegtree>

//√の値が整数かを調べる
bool isSqrt(ll n) {
	if (n < 0) return false;
	ll sqrtN = static_cast<ll>(sqrt(n));
	return sqrtN * sqrtN == n;
}

//整数同士の累乗の計算をする。
ll power(ll A, ll B) {
	ll result = 1;
	for (ll i=0;i<B;i++){
		result *= A;
	}
	return result;
}

//素因数分解
vector<ll> makePrime(ll n){
	vector<ll> factors;
	while (n % 2 == 0) {
		factors.push_back(2);
		n /= 2;
	}
	for (ll i=3; i*i<=n;i+=2) {
		while (n%i == 0) {
			factors.push_back(i);
			n /= i;
		}
	}
	if (n > 2) {
		factors.push_back(n);
	}
	return factors;
}

//map形式で、nを素因数分解した値を返す
map<ll,ll> makeMapPrime(ll n){
	map<ll,ll> factors;
	while (n % 2 == 0) {
		factors[2]++;
		n /= 2;
	}
	for (ll i=3; i*i<=n;i+=2) {
		while (n%i == 0) {
			factors[i]++;
			n /= i;
		}
	}
	if (n > 2) {
		factors[n]++;
	}
	return factors;
}

// nのk乗をmodで割った余りを計算
ll power_mod(ll n, ll k){
	long long result = 1;
	while (k > 0){
		if ((k&1) ==1)result=(result*n)%mod;
		n=n*n%mod;
		k >>= 1;
	}
	return result;
}

//mod mにおけるaの逆元を計算
ll modinv(ll a, ll m) {
	ll b = m, u = 1, v = 0;
	while (b) {
		ll t = a / b;
		a -= t * b; swap(a, b);
		u -= t * v; swap(u, v);
	}
	u %= m; 
	if (u < 0) u += m;
	return u;
}

//場合の数 nCr を求める
ll ncr(ll n,ll r) {
	if(n<r)return 0;
	vvl dp(n+1,vl(r+1));
	rep (i,n+1)dp[i][0] = 1;
	rep (i,r+1)dp[i][i] = 1;
	loop (i,1,n){
		loop (j,1,min((ll)i-1,r)) {
			//nCr= n-1Cr-1 + n-1Cr
			dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
		}
	}
	return dp[n][r];
}

//受け取った文字列を、第2引数が0なら全て小文字に、1なら大文字に変換する関数
string cnvString(const string &str, int mode) {
	string result = str;
	if (mode == 0) {
		// 小文字に変換
		for (char &c : result) {
			c = tolower(c);
		}
	} else if (mode == 1) {
		// 大文字に変換
		for (char &c : result) {
			c = toupper(c);
		}
	}
	return result;
}

//第一引数で受け取った数を、第二引数で受け取った数の進数と見做して、第三引数の進数へ変換する。
string cnvBase(const string &str, ll from_base, ll to_base) {
	ll num = 0;
	//小文字があったら大文字に変換
	string num_str=cnvString(str,1);
	// 数値を10進数に変換
	for (char digit : num_str) {
		num = num * from_base + (isdigit(digit) ? digit - '0' : digit - 'A' + 10);
	}
	string result;
	// 数値を目的の基数に変換
	while (num > 0) {
		ll remainder = num % to_base;
		result.push_back(remainder < 10 ? remainder + '0' : remainder - 10 + 'A');
		num /= to_base;
	}
	// 結果を逆順にして返す
	reverse(result.begin(), result.end());
	return result.empty() ? "0" : result;
}

//底がaの対数xを計算。ただし小数点は繰り上げ。
ll logax(ll a, ll x){
	if(x<=1)return 0;
	ll result = 1;
	ll power = 1;
	while (power < (x+a-1) / a){
		power *= a;
		result++;
	}
	return result;
}

//第一引数を第二引数で割った余りを計算、割る数はint範囲
ll bigmd(const string &num, int md) {
	ll ans = 0;
	ll SIZ = 9; //9桁のチャンク
	ll base = 1000000000;//SIZ個の0
	rep(i,(num.size()-1)/SIZ+1){
		ll chunk = 0;
		ll l = i*SIZ;
		ll r = min((ll)num.size(),l+SIZ);
		if(r!=num.size()){
			ans = (ans*base+stoll(num.substr(l,r-l)))%md;
		}else{
			rep(i,r-l)ans*=10;
			ans=(ans+stoll(num.substr(l,r-l)))%md;
		}
	}
	return ans;
}

//受け取った2次元文字の外側に、文字pをコーティングする。
vector<string> pad(vector<string> &s,char p){
	ll h=s.size();
	ll w=s[0].size();
	vector<string> res(h+2,string(w+2,p));
	rep(i,h)rep(j,w)res[i+1][j+1]=s[i][j];
	return res;
}

//ax+by=cの整数解を得る ただし、cはgcd(a,b)の倍数でない場合、0,0になる
pair<ll,ll> ex_euclid(ll a,ll b,ll c){
	if(a<0||b<0||c<0){
		pair<ll,ll>ans=ex_euclid(abs(a),abs(b),abs(c));
		if(a<0)ans.first*=-1;
		if(b<0)ans.second*=-1;
		if(c<0)ans.first*=-1,ans.second*=-1;
		return ans;
	}
	if(c!=1){
		ll d=gcd(a,b);
		if(c%d!=0)return make_pair(0,0);
		pair<ll,ll>ans = ex_euclid(a/d,b/d,1);
		ans.first*=c/d;
		ans.second*=c/d;
		return ans;
	}
	if(a<b){
		pair<ll,ll>ans=ex_euclid(b,a,c);
		swap(ans.first,ans.second);
		return ans;
	}
	if(a==1&&b==0)return make_pair(1,0);
	else if(b==0) return make_pair(0,0);
	ll x,y;
	tie(x,y)=ex_euclid(b,a%b,c);
	pair<ll,ll> ans=make_pair(y,x-(a/b)*y);
	return ans;
}

//オイラーのトーシェント関数。N以下のNと互いに素な物の数を返す。
ll euler(ll n){
	unordered_map<ll,ll> factors;
	ll tmp=n;
	while (tmp % 2 == 0) {
		factors[2]++;
		tmp /= 2;
	}
	for (ll i=3; i*i<=tmp;i+=2) {
		while (tmp%i == 0) {
			factors[i]++;
			tmp/= i;
		}
	}
	if (tmp > 2)factors[tmp]++;
	ll ans=1;
	for(const auto & val:factors){
		ans*=power(val.first,val.second-1)*(val.first-1);
	}
	return ans;
}

// Union-Find
struct UnionFind {
	vector<int> par, siz;
	UnionFind(int n) : par(n, -1) , siz(n, 1) { }
	// 根を求める
	int root(int x) {
		if (par[x] == -1) return x;
		else return par[x] = root(par[x]);
	}
	// x と y が同じグループに属するかどうか (根が一致するかどうか)
	bool issame(int x, int y) {
		return root(x) == root(y);
	}
	// x を含むグループと y を含むグループとを併合する
	bool unite(int x, int y) {
		x = root(x), y = root(y);
		if (x == y) return false;
		if (siz[x] < siz[y]) swap(x, y);
		par[y] = x;
		siz[x] += siz[y];
		return true;
	}
	// x を含むグループのサイズ
	int size(int x) {
		return siz[root(x)];
	}
};

//重み付きUF
struct PotentialUnionFind {
	ll n;
	vl par, siz, pot;
	PotentialUnionFind(ll N) : par(N,-1) , siz(N,1) , pot(N,0){n=N;}
	// 根を求める
	ll root(ll x) {
		if (par[x] == -1) return x;
		ll tmp = root(par[x]);
		pot[x] += pot[par[x]];
		par[x] = tmp;
		return par[x];
	}
	// x と y が同じグループに属するかどうか (根が一致するかどうか)
	bool issame(ll x, ll y) {
		return root(x) == root(y);
	}
	//x よりいくつ大きい所に y があるか。根が一致しない場合は"0"
	ll potential(ll x,ll y){
		if(root(x) != root(y)) return 0;
		else return pot[y]-pot[x];
	}
	//x より w だけ大きい状態として y を併合。
	bool unite(ll x, ll y, ll w) {
		ll rx = root(x),ry = root(y);
		if (rx == ry) return false;
		w += pot[x]-pot[y];
		if (siz[rx] < siz[ry]) swap(rx, ry),w*=-1;
		par[ry] = rx;
		siz[rx] += siz[ry];
		siz[ry] = 0;
		pot[ry] = w;
		return true;
	}
	// x を含むグループのサイズ
	ll size(ll x) {
		return siz[root(x)];
	}
	//小さい順にUnionFindグラフを調整、O(n log n)
	void regulation(){
		vvl r(n);
		rep(i,n)r[root(i)].push_back(i);
		rep(i,n){
			if(r[i].size()==0)continue;
			ll mn = i;
			rep(j,r[i].size())if(pot[mn]>pot[r[i][j]])mn=r[i][j];
			siz[mn]=siz[i];
			siz[i]=0;
			ll tmp = pot[mn];
			rep(j,r[i].size()){
				pot[r[i][j]]-=tmp;
				par[r[i][j]] = mn;
			}
			par[mn]=-1;
		}
	}
	void debug(){
		rep(i,n)cout<<setw(4)<<left<<par[i]<<" ";
		cout<<endl;
		rep(i,n)cout<<setw(4)<<left<<pot[i]<<" ";
		cout<<endl;
	}
};

//分離可能UnionFind、経路圧縮をしない。
struct CuttingFind{
	vector<int> par, siz;
	CuttingFind(int n) : par(n, -1) , siz(n, 1) { }
	// 根を求める
	int root(int x) {
		if (par[x] == -1) return x;
		else return root(par[x]);
	}
	// x と y が同じグループに属するかどうか (根が一致するかどうか)
	bool issame(int x, int y) {
		return root(x) == root(y);
	}
	//根x と 根y のグループを併合する(お互い根ではない時、falseで何もしない)
	bool unite(int x, int y) {
		if (issame(x,y) || par[x] != -1 || par[y] != -1) {
			cout<<"error"<<endl;
			return false;
		}
		if (siz[x] < siz[y]) swap(x, y);
		par[y] = x;
		siz[x] += siz[y];
		return true;
	}
	//根の側から、その直系の子供を分離する。片方が根でもう片方が直系の子でなければならない。
	bool separate(int x,int y){
		if(par[y]==-1)swap(x,y);
		if(par[y]!=x||par[x]!=-1){
			cout<<"error2"<<endl;
			return false;
		}
		siz[x] -= siz[y];
		par[y]=-1;
		return true;
	}
	// x を含むグループのサイズを求める
	int size(int x) {
		return siz[root(x)];
	}
};
//セグ木,乗せる値の型が必要
template<typename T>
struct SegTree{
	ll size;
	ll tall;
	vector<T> data;
	function<T(T,T)> p;
	//セグ木に乗せる値の初期値をa配列にし、putの関数をセグ木に乗せる、dをデフォルト値に。
	SegTree(vector<T> a,function<T(T,T)> put,T d) : data(power(2,logax(2,a.size())+1)) {
		size = data.size()/2;
		tall=logax(2,size)+1;
		p=put;
		ll tmp=size;
		data = vector<T>(size*2,d);
		while(tmp!=0){
			if(tmp==size)rep(i,a.size())data[tmp+i]=a[i];
			else rep(i,tmp) data[tmp+i]=p(data[2*(tmp+i)],data[2*(tmp+i)+1]);
			tmp/=2;
		}
	}
	//更新、t番目の値をxにする。
	void update(ll t,T x){
		t+=size;
		while(t!=0){
			if(t>=size)data[t]=x;
			else data[t]=p(data[2*t],data[2*t+1]);
			t/=2;
		}
	}
	//取得、l~r区間内の評価値を取得する。
	T get(ll l,ll r){
		//lとrが範囲外なら範囲内に正す
		l=max(0LL,l);
		r=min(r,size-1);
		r++;
		T ans=data[0];
		ll pos=l+size;
		ll wid=1;
		//出来る限り上に上げきる。
		while(l+(wid*2)<=r){
			while(l%(wid*2)==0&&l+(wid*2)<=r)pos/=2,wid*=2;
			ans=p(ans,data[pos]);
			pos++;
			l+=wid;
		}
		//上げ終わったので今度は下げる
		while(l!=r){
			while(l+wid>r)pos*=2,wid/=2;
			ans=p(ans,data[pos]);
			pos++;
			l+=wid;
		}
		return ans;
	}
	//セグ木デバッグ用、丸ごと出力
	void print(){
		rep(i,size)cout<<setw(7)<<left<<i;
		cout<<endl;
		ll pos=size;
		rep(i,tall){
			rep(j,size){
				if(j%power(2,i)==0)cout<<setw(7)<<left<<data[pos],pos++;
				else cout<<"       ";
			}
			pos/=4;
			cout<<endl;
		}
	}
};

//グリッド問題等用
vl dx={1,0,-1,0};
vl dy={0,1,0,-1};

ll solve(){
	ll n;
	cin>>n;
	if(n==0){return 1;}

	map<pair<ll,ll>,ll> bit;
	vector<map<pair<ll,ll>,ll>> g(n);
	
	rep(i,n){
		ll x,y;
		vl dice(6);
		cin>>x>>y;
		rep(j,6)cin>>dice[j];
		string rot;
		cin>>rot;

		map<pair<ll,ll>,ll> tmp;
		tmp[{x,y}]=dice[4];
		rep(j,rot.size()){
			if(rot[j]=='L'){
				vl aft(6);
				vl move={4,5,2,3,1,0};
				rep(k,6)aft[move[k]]=dice[k];
				dice=aft;
				x--;
			}
			if(rot[j]=='R'){
				vl aft(6);
				vl move={5,4,2,3,0,1};
				rep(k,6)aft[move[k]]=dice[k];
				dice=aft;
				x++;
			}
			if(rot[j]=='F'){
				vl aft(6);
				vl move={0,1,4,5,3,2};
				rep(k,6)aft[move[k]]=dice[k];
				dice=aft;
				y--;
			}
			if(rot[j]=='B'){
				vl aft(6);
				vl move={0,1,5,4,2,3};
				rep(k,6)aft[move[k]]=dice[k];
				dice=aft;
				y++;
			}
			tmp[{x,y}]=dice[4];
		}
		for(const auto &val:tmp){
			bit[val.first]+=(1LL<<i);
		}
		g[i]=tmp;
	}

	vl dp((1LL<<n),0);
	rep(b,(1LL<<n)){
		rep(i,n){
			if(b&(1LL<<i))continue;
			ll next=b+(1LL<<i);
			ll plus=0;
			for(const auto & val:g[i]){
				if((bit[val.first]&next)==bit[val.first]){
					plus+=val.second;
				}
			}
			dp[next]=max(dp[next],dp[b]+plus);
		}
	}
	cout<<dp[(1LL<<n)-1]<<endl;
	return 0;
}

//メイン
int main(){
	while(solve()==0);
	return 0;
}
accuracy: 1
time_ms: 560
memory_kb: 3960
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(a) (a).begin(), (a).end()
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rrep(i, n) for (int i = (int)(n); i >= 0; i--)
#define range(i, l, r) for (int i = (int)(l); i < (int)(r); i++)
using ll = long long;

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    os << "[";
    for (int i = 0; i < v.size(); i++) {
        os << v[i] << (i == (v.size() - 1) ? "" : ", ");
    }
    os << "]";
    return os;
}

template <typename T>
ostream& operator<<(ostream& os, const set<T>& s) {
    os << "{";
    for (auto v : s) {
        os << v << ", ";
    }
    os << "}";
    return os;
}

template <typename T1, typename T2>
ostream& operator<<(ostream& os, const pair<T1, T2> p) {
    os << "{" << p.first << ", " << p.second << "}";
    return os;
}

struct Dice {
    vector<int> num;
};
using pii = pair<int, int>;

void move(Dice* d, char dir) {
    if (dir == 'B') {
        int tmp = d->num[0];
        d->num[0] = d->num[3];
        d->num[3] = d->num[5];
        d->num[5] = d->num[2];
        d->num[2] = tmp;
    } else if (dir == 'F') {
        int tmp = d->num[0];
        d->num[0] = d->num[2];
        d->num[2] = d->num[5];
        d->num[5] = d->num[3];
        d->num[3] = tmp;
    } else if (dir == 'R') {
        int tmp = d->num[1];
        d->num[1] = d->num[2];
        d->num[2] = d->num[4];
        d->num[4] = d->num[3];
        d->num[3] = tmp;
    } else {
        int tmp = d->num[1];
        d->num[1] = d->num[3];
        d->num[3] = d->num[4];
        d->num[4] = d->num[2];
        d->num[2] = tmp;
    }
}

int movex(int x, char dir) {
    if (dir == 'R') {
        x++;
    } else if (dir == 'L') {
        x--;
    }
    return x;
}

int movey(int y, char dir) {
    if (dir == 'B') {
        y++;
    } else if (dir == 'F') {
        y--;
    }
    return y;
}

int main() {
    while (true) {
        int n;
        cin >> n;
        if (n == 0) break;
        vector<Dice> dice(n);
        vector<map<pii, int>> pos(n);

        rep(i, n) {
            int x, y;
            cin >> x >> y;
            int l, r, f, b, d, u;
            cin >> l >> r >> f >> b >> d >> u;
            Dice di;
            di.num = {f, r, u, d, l, b};
            pos[i][{x, y}] = di.num[3];

            string rot;
            cin >> rot;
            for (auto c : rot) {
                move(&di, c);
                x = movex(x, c);
                y = movey(y, c);
                pos[i][{x, y}] = di.num[3];
            }
        }

        vector<set<pii>> ng(1 << n);
        rep(i, 1 << n) {
            rep(j, n) if ((1 << j) & i) {
                for (auto k : pos[j]) {
                    ng[i].insert(k.first);
                }
            }
        }

        vector<int> dp(1 << n);
        rep(i, 1 << n) {
            rep(j, n) {
                if (i & (1 << j)) continue;
                int tmp = dp[i];
                for (auto [k, v] : pos[j]) {
                    if (ng[i].find(k) == ng[i].end()) {
                        tmp += v;
                    }
                }
                dp[i | (1 << j)] = max(dp[i | (1 << j)], tmp);
            }
        }

        cout << dp[(1 << n) - 1] << endl;
    }
}
accuracy: 1
time_ms: 3230
memory_kb: 234988
final_rank: 17

code_snippet: // AOJ #2703
// Dice Stamp 2025.2.11

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

void cycleFour(int &first, int &second, int &third, int &fourth) {
    int t = first;
    first = second, second = third, third = fourth, fourth = t;
}

int main() {
    std::ios::sync_with_stdio(0);
    cin.tie(0);

    while (true) {
        int N;
        cin >> N;
        if (N == 0) break;

        vector< map< pair<int,int>, int > > dmap(N);
        vector< pair<int,int> > coor;

        for (int i = 0; i < N; ++i) {
            int posX, posY;
            cin >> posX >> posY;
            int left, right, front, back, bottom, top;
            cin >> left >> right >> front >> back >> bottom >> top;
            string seq;
            cin >> seq;

            dmap[i].clear();
            dmap[i][make_pair(posX, posY)] = bottom;
            coor.push_back(make_pair(posX, posY));

            for (char move : seq) {
                if (move == 'L') {
                    posX--;
                    cycleFour(top, right, bottom, left);
                } else if (move == 'R') {
                    posX++;
                    cycleFour(top, left, bottom, right);
                } else if (move == 'F') {
                    posY--;
                    cycleFour(top, back, bottom, front);
                } else if (move == 'B') {
                    posY++;
                    cycleFour(top, front, bottom, back);
                }
                dmap[i][make_pair(posX, posY)] = bottom;
                coor.push_back(make_pair(posX, posY));
            }
        }

        sort(coor.begin(), coor.end());
        coor.erase(unique(coor.begin(), coor.end()), coor.end());

        vector<int> cellDiceMask(coor.size(), 0);
        vector< vector< pair<int,int> > > clist(N);
        for (int i = 0; i < N; ++i) {
            clist[i].clear();
            for (const auto &entry : dmap[i]) {
                pair<int,int> coordinate = entry.first;
                int stampValue = entry.second;
                int j = lower_bound(coor.begin(), coor.end(), coordinate) - coor.begin();
                clist[i].push_back(make_pair(j, stampValue));
                cellDiceMask[j] |= (1 << i);
            }
        }

        int tot = 1 << N;
        vector<int> dp(tot, 0);
        dp[tot - 1] = 0;

        for (int k = tot - 1; k >= 0; --k) {
            int bestScoreForCurrentMask = 0;
            for (int i = 0; i < N; ++i) {
                if ((k & (1 << i)) == 0) {
                    int nextMask = k | (1 << i);
                    int scoreIfUsingThisDice = dp[nextMask];
                    for (const auto &stampInfo : clist[i]) {
                        int j = stampInfo.first;
                        int stampValue = stampInfo.second;
                        if ((cellDiceMask[j] & k) == 0)
                            scoreIfUsingThisDice += stampValue;
                    }
                    if (scoreIfUsingThisDice > bestScoreForCurrentMask)
                        bestScoreForCurrentMask = scoreIfUsingThisDice;
                }
            }
            dp[k] = bestScoreForCurrentMask;
        }
        cout << dp[0] << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3560
final_rank: 1

code_snippet: // AOJ #2703
// Dice Stamp 2025.2.11

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

void cycleFour(int &first, int &second, int &third, int &fourth) {
    int temp = first;
    first = second;
    second = third;
    third = fourth;
    fourth = temp;
}

int main() {
    std::ios::sync_with_stdio(0);
    cin.tie(0);

    while (true) {
        int N;
        cin >> N;
        if (N == 0) break;

        vector< map< pair<int,int>, int > > dmap(N);
        vector< pair<int,int> > coor;

        for (int i = 0; i < N; ++i) {
            int posX, posY;
            cin >> posX >> posY;
            int leftFace, rightFace, frontFace, backFace, bottomFace, topFace;
            cin >> leftFace >> rightFace >> frontFace >> backFace >> bottomFace >> topFace;
            string moveSequence;
            cin >> moveSequence;

            dmap[i].clear();
            dmap[i][make_pair(posX, posY)] = bottomFace;
            coor.push_back(make_pair(posX, posY));

            for (char move : moveSequence) {
                if (move == 'L') {
                    posX -= 1;
                    cycleFour(topFace, rightFace, bottomFace, leftFace);
                } else if (move == 'R') {
                    posX += 1;
                    cycleFour(topFace, leftFace, bottomFace, rightFace);
                } else if (move == 'F') {
                    posY -= 1;
                    cycleFour(topFace, backFace, bottomFace, frontFace);
                } else if (move == 'B') {
                    posY += 1;
                    cycleFour(topFace, frontFace, bottomFace, backFace);
                }
                dmap[i][make_pair(posX, posY)] = bottomFace;
                coor.push_back(make_pair(posX, posY));
            }
        }

        sort(coor.begin(), coor.end());
        coor.erase(unique(coor.begin(), coor.end()), coor.end());

        vector<int> cellDiceMask(coor.size(), 0);
        vector< vector< pair<int,int> > > clist(N);
        for (int i = 0; i < N; ++i) {
            clist[i].clear();
            for (const auto &entry : dmap[i]) {
                pair<int,int> coordinate = entry.first;
                int stampValue = entry.second;
                int j = lower_bound(coor.begin(), coor.end(), coordinate) - coor.begin();
                clist[i].push_back(make_pair(j, stampValue));
                cellDiceMask[j] |= (1 << i);
            }
        }

        int tot = 1 << N;
        vector<int> dp(tot, 0);
        dp[tot - 1] = 0;

        for (int k = tot - 1; k >= 0; --k) {
            int bestScoreForCurrentMask = 0;
            for (int i = 0; i < N; ++i) {
                if ((k & (1 << i)) == 0) {
                    int nextMask = k | (1 << i);
                    int scoreIfUsingThisDice = dp[nextMask];
                    for (const auto &stampInfo : clist[i]) {
                        int j = stampInfo.first;
                        int stampValue = stampInfo.second;
                        if ((cellDiceMask[j] & k) == 0)
                            scoreIfUsingThisDice += stampValue;
                    }
                    if (scoreIfUsingThisDice > bestScoreForCurrentMask)
                        bestScoreForCurrentMask = scoreIfUsingThisDice;
                }
            }
            dp[k] = bestScoreForCurrentMask;
        }
        cout << dp[0] << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3564
final_rank: 2

code_snippet: // AOJ #2703
// Dice Stamp 2025.2.11

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

struct DieState {
    int top, bottom, left, right, front, back;
};
 
DieState rollLeft(const DieState &s) {
    DieState ns;
    ns.top    = s.right;
    ns.bottom = s.left;
    ns.left   = s.top;
    ns.right  = s.bottom;
    ns.front  = s.front;
    ns.back   = s.back;
    return ns;
}
 
DieState rollRight(const DieState &s) {
    DieState ns;
    ns.top    = s.left;
    ns.bottom = s.right;
    ns.left   = s.bottom;
    ns.right  = s.top;
    ns.front  = s.front;
    ns.back   = s.back;
    return ns;
}
 
DieState rollForward(const DieState &s) {
    DieState ns;
    ns.top    = s.back;
    ns.bottom = s.front;
    ns.front  = s.top;
    ns.back   = s.bottom;
    ns.left   = s.left;
    ns.right  = s.right;
    return ns;
}
 
DieState rollBackward(const DieState &s) {
    DieState ns;
    ns.top    = s.front;
    ns.bottom = s.back;
    ns.front  = s.bottom;
    ns.back   = s.top;
    ns.left   = s.left;
    ns.right  = s.right;
    return ns;
}
 
struct PairHash {
    size_t operator()(const pair<int,int>& p) const {
        return ((size_t)p.first * 13131ULL) ^ ((size_t)p.second);
    }
};
 
 
struct State {
    vector<int> config;
    int sum;
};
 
bool dominates(const State &A, const State &B) {
    int n = A.config.size();
    for (int i = 0; i < n; i++) {
        if(A.config[i] < B.config[i])
            return false;
    }
    return true;
}
 
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
 
    while(true){
        int N;
        cin >> N;
        if(N == 0) break;
 
        vector<unordered_map<pair<int,int>, int, PairHash>> dieStamps(N);
 
        for (int i = 0; i < N; i++){
            int startX, startY;
            cin >> startX >> startY;
            int l, r, f, b, d, u;
            cin >> l >> r >> f >> b >> d >> u;
            string rot;
            cin >> rot;
 
            DieState state;
            state.top    = u;
            state.bottom = d;
            state.left   = l;
            state.right  = r;
            state.front  = f;
            state.back   = b;
 
            int curX = startX, curY = startY;
 
            unordered_map<pair<int,int>, int, PairHash> stamps;
            stamps[{curX, curY}] = state.bottom;
 
            for (char c : rot) {
                if (c == 'L'){
                    curX -= 1;
                    state = rollLeft(state);
                } else if (c == 'R'){
                    curX += 1;
                    state = rollRight(state);
                } else if (c == 'F'){
                    curY -= 1;
                    state = rollForward(state);
                } else if (c == 'B'){
                    curY += 1;
                    state = rollBackward(state);
                }
                stamps[{curX, curY}] = state.bottom;
            }
 
            dieStamps[i] = move(stamps);
        }
 
        unordered_map<pair<int,int>, int, PairHash> cellIndex;
        vector<pair<int,int>> cells;
        for (int i = 0; i < N; i++){
            for (auto &entry : dieStamps[i]){
                pair<int,int> cell = entry.first;
                if(cellIndex.find(cell) == cellIndex.end()){
                    int idx = cells.size();
                    cells.push_back(cell);
                    cellIndex[cell] = idx;
                }
            }
        }
        int M = cells.size();
 
        vector<vector<int>> dieVal(N, vector<int>(M, 0));
        for (int i = 0; i < N; i++){
            for (auto &entry : dieStamps[i]){
                pair<int,int> cell = entry.first;
                int j = cellIndex[cell];
                dieVal[i][j] = entry.second;
            }
        }
 
 
        int totStates = 1 << N;
        vector< vector<State> > dp(totStates);
 
        State init;
        init.config.assign(M, 0);
        init.sum = 0;
        dp[0].push_back(init);
 
        for (int mask = 0; mask < totStates; mask++){
            if(dp[mask].empty()) continue;
 
            for (int i = 0; i < N; i++){
                if(mask & (1 << i)) continue;
                int nmask = mask | (1 << i);
 
                for (auto &st : dp[mask]) {
                    State ns;
                    ns.config = st.config;
                    int add = 0;
                    for (int j = 0; j < M; j++){
                        int newVal = (dieVal[i][j] > 0 ? dieVal[i][j] : ns.config[j]);
                        add += (newVal - ns.config[j]);
                        ns.config[j] = newVal;
                    }
                    ns.sum = st.sum + add;
 
                    bool dominated = false;
                    vector<int> toRemove;
                    for (int k = 0; k < dp[nmask].size(); k++){
                        if (dominates(dp[nmask][k], ns)) { 
                            dominated = true; 
                            break;
                        }
                        if (dominates(ns, dp[nmask][k])) {
                            toRemove.push_back(k);
                        }
                    }
                    if(dominated) continue;
                    for (int idx = toRemove.size()-1; idx >= 0; idx--){
                        int rem = toRemove[idx];
                        dp[nmask].erase(dp[nmask].begin() + rem);
                    }
                    dp[nmask].push_back(ns);
                }
            }
        }
        int ans = 0;
        for (int mask = 0; mask < totStates; mask++){
            for (auto &st : dp[mask]) ans = max(ans, st.sum);
        }
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 610
memory_kb: 44616
final_rank: 12

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
 */

template <unsigned mod = 1000000007> struct fp {
    unsigned v;
    static constexpr int get_mod() {
        return mod;
    }
    constexpr unsigned inv() const {
        assert(v != 0);
        int x = v, y = mod, p = 1, q = 0, t = 0, tmp = 0;
        while (y > 0) {
            t = x / y;
            x -= t * y, p -= t * q;
            tmp = x, x = y, y = tmp;
            tmp = p, p = q, q = tmp;
        }
        if (p < 0)
            p += mod;
        return p;
    }
    constexpr fp(ll x = 0) : v(x >= 0 ? x % mod : (mod - (-x) % mod) % mod) {}
    fp operator-() const {
        return fp() - *this;
    }
    fp pow(ull t) {
        fp res = 1, b = *this;
        while (t) {
            if (t & 1)
                res *= b;
            b *= b;
            t >>= 1;
        }
        return res;
    }
    fp &operator+=(const fp &x) {
        if ((v += x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator-=(const fp &x) {
        if ((v += mod - x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator*=(const fp &x) {
        v = ull(v) * x.v % mod;
        return *this;
    }
    fp &operator/=(const fp &x) {
        v = ull(v) * x.inv() % mod;
        return *this;
    }
    fp operator+(const fp &x) const {
        return fp(*this) += x;
    }
    fp operator-(const fp &x) const {
        return fp(*this) -= x;
    }
    fp operator*(const fp &x) const {
        return fp(*this) *= x;
    }
    fp operator/(const fp &x) const {
        return fp(*this) /= x;
    }
    bool operator==(const fp &x) const {
        return v == x.v;
    }
    bool operator!=(const fp &x) const {
        return v != x.v;
    }
    friend istream &operator>>(istream &is, fp &x) {
        return is >> x.v;
    }
    friend ostream &operator<<(ostream &os, const fp &x) {
        return os << x.v;
    }
};

template <unsigned mod> void rd(fp<mod> &x) {
    fastio::rd(x.v);
}
template <unsigned mod> void wt(fp<mod> x) {
    fastio::wt(x.v);
}

template <typename T> T Inv(ll n) {
    static const int md = T::get_mod();
    static vector<T> buf({0, 1});
    assert(n > 0);
    n %= md;
    while (SZ(buf) <= n) {
        int k = SZ(buf), q = (md + k - 1) / k;
        buf.push_back(buf[k * q - md] * q);
    }
    return buf[n];
}

template <typename T> T Fact(ll n, bool inv = 0) {
    static const int md = T::get_mod();
    static vector<T> buf({1, 1}), ibuf({1, 1});
    assert(n >= 0 and n < md);
    while (SZ(buf) <= n) {
        buf.push_back(buf.back() * SZ(buf));
        ibuf.push_back(ibuf.back() * Inv<T>(SZ(ibuf)));
    }
    return inv ? ibuf[n] : buf[n];
}

template <typename T> T nPr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nCr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(r, inv ^ 1) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nHr(int n, int r, bool inv = 0) {
    return nCr<T>(n + r - 1, r, inv);
}

/**
 * @brief Modint
 */

struct Dice {
    int l, r, f, b, d, u;
    int x, y;
    Dice(int _l, int _r, int _f, int _b, int _d, int _u, int _x = 30, int _y = 30) {
        l = _l, r = _r, f = _f, b = _b, d = _d, u = _u, x = _x, y = _y;
    }
};

Dice L(Dice D) {
    Dice ND = D;
    ND.x--;
    ND.l = D.u, ND.u = D.r, ND.r = D.d, ND.d = D.l;
    return ND;
}

Dice R(Dice D) {
    Dice ND = D;
    ND.x++;
    ND.r = D.u, ND.u = D.l, ND.l = D.d, ND.d = D.r;
    return ND;
}

Dice F(Dice D) {
    Dice ND = D;
    ND.y--;
    ND.f = D.u, ND.u = D.b, ND.b = D.d, ND.d = D.f;
    return ND;
}

Dice B(Dice D) {
    Dice ND = D;
    ND.y++;
    ND.b = D.u, ND.u = D.f, ND.f = D.d, ND.d = D.b;
    return ND;
}

int main() {
while(1) {
    int N;
    cin >> N;
    if (N == 0) return 0;
    vector<vector<pair<pair<int,int>,int>>> V(N);
    map<pair<int,int>,int> mp;
    rep(i,0,N) {
        vector<vector<int>> Grid(61,vector<int>(61,-1));
        int _x, _y, _l, _r, _f, _b, _d, _u;
        cin >> _x >> _y >> _l >> _r >> _f >> _b >> _d >> _u;
        Dice D(_l, _r, _f, _b, _d, _u);
        Grid[D.x][D.y] = D.d;
        string S;
        cin >> S;
        for (char C : S) {
            if (C == 'L') D = L(D);
            if (C == 'R') D = R(D);
            if (C == 'F') D = F(D);
            if (C == 'B') D = B(D);
            Grid[D.x][D.y] = D.d;
        }
        rep(j,0,61) {
            rep(k,0,61) {
                if (Grid[j][k] > 0) {
                    int nx = j - 30 + _x, ny = k - 30 + _y;
                    V[i].push_back({{nx,ny},Grid[j][k]});
                    mp[{nx,ny}] |= (1<<i);
                }
            }
        }
    }
    vector<int> DP(1<<N, -inf);
    DP[0] = 0;
    rep(i,0,1<<N) {
        rep(j,0,N) {
            if ((i & (1<<j)) == 0) {
                int Cur = DP[i];
                for (pair<pair<int,int>,int> P : V[j]) {
                    if ((mp[P.first] & i) == 0) Cur += P.second;
                }
                chmax(DP[i | (1<<j)], Cur);
            }
        }
    }
    cout << DP[(1<<N)-1] << endl;
}
}
accuracy: 1
time_ms: 210
memory_kb: 3424
final_rank: 3

code_snippet: #line 1 "main.cpp"
#include<bits/stdc++.h>
using namespace std;

#line 1 "/mnt/c/Users/hope_/ComPro/Libraries/Library/other/Dice.hpp"
// 面と変数の対応付けは Dice Stamp (https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2703) における
// (l, r, f, b, d, u) から (xn, xp, yn, yp, zn, zp) に置き換えたものとする。
// 面の値（Label）のみを保持。一致判定などにおいて向きは非考慮。
// Verified Link1: Dice Stamp (https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2703)

struct Dice{
    static constexpr int arr[7][7] = {
        {0,0,0,0,0,0,0},
        {0,0,4,2,5,3,0},
        {0,3,0,6,1,0,4},
        {0,5,1,0,0,6,2},
        {0,2,6,0,0,1,5},
        {0,4,0,1,6,0,3},
        {0,0,3,5,2,4,0}
    };
    int xnL, xpL, ynL, ypL, znL, zpL; // labels
    int xco, yco, zco; // x, y, z coordinate (for rolling the dice)

    Dice() : xnL(2), xpL(5), ynL(3), ypL(4), znL(6), zpL(1), xco(0), yco(0), zco(0) {}
    
    Dice(int xn, int xp, int yn, int yp, int zn, int zp, int xco = 0, int yco = 0, int zco = 0) :
    xnL(xn), xpL(xp), ynL(yn), ypL(yp), znL(zn), zpL(zp), xco(xco), yco(yco), zco(zco) {}

    // after initialization, make normal dice (set -1 to unknown label)
    void makeNormalDice(int xn, int xp, int yn, int yp, int zn, int zp){
        if(xn == -1 && xp != -1){ xn = 7 - xp; }
        if(xp == -1 && xn != -1){ xp = 7 - xn; }
        if(yn == -1 && yp != -1){ yn = 7 - yp; }
        if(yp == -1 && yn != -1){ yp = 7 - yn; }
        if(zn == -1 && zp != -1){ zn = 7 - zp; }
        if(zp == -1 && zn != -1){ zp = 7 - zn; }
        if(xn == -1){
            assert(xp == -1 && yn != -1 && zn != -1);
            xn = arr[zp][yp];
            xp = arr[zp][yn];
        }
        if(yn == -1){
            assert(yp == -1 && xn != -1 && zn != -1);
            yn = arr[zp][xn];
            yp = arr[zp][xp];
        }
        if(zn == -1){
            assert(zp == -1 && xn != -1 && yn != -1);
            zn = arr[yp][xp];
            zp = arr[yp][xn];
        }
        xnL = xn, xpL = xp;
        ynL = yn, ypL = yp;
        znL = zn, zpL = zp;
    }

    // shift 4 params to left.
    // (a, b, c, d) -> (b, c, d, a)
    void shift(int& a, int& b, int& c, int& d){
        int tmp = a;
        a = b, b = c, c = d, d = tmp;
    }

    void rotXY(bool clockwise = false){
        if(clockwise) shift(xpL, ypL, xnL, ynL);
        else shift(xpL, ynL, xnL, ypL);
    }
    void rotYZ(bool clockwise = false){
        if(clockwise) shift(ypL, zpL, ynL, znL);
        else shift(ypL, znL, ynL, zpL);
    }
    void rotXZ(bool clockwise = false){
        if(clockwise) shift(xpL, zpL, xnL, znL);
        else shift(xpL, znL, xnL, zpL);
    }

    // roll dice
    void rotB(){ rotYZ(true); yco++; }
    void rotF(){ rotYZ(false);  yco--; }
    void rotR(){ rotXZ(true); xco++; }
    void rotL(){ rotXZ(false);  xco--; }

    friend ostream& operator<<(ostream& os, const Dice& dice){
        os << "(xnL, xpL, ynL, ypL, znL, zpL) = (";
        os << dice.xnL << ", " << dice.xpL << ", ";
        os << dice.ynL << ", " << dice.ypL << ", ";
        os << dice.znL << ", " << dice.zpL << ")\n"; 
        os << "(x, y, z) = (" << dice.xco << ", " << dice.yco << ", " << dice.zco << ")\n"; 
        return os;
    }
};
#line 5 "main.cpp"

int main(){
    while(1){
        int N; cin >> N;
        if(N == 0) break;
        vector<Dice> dices(N);
        vector<string> mov(N);

        const int MAX_N = 2070;
        const int OFFSET = 1035;
        for(int i = 0; i < N; i++){
            int x, y; cin >> x >> y;
            int l, r, f, b, d, u; cin >> l >> r >> f >> b >> d >> u;
            cin >> mov[i];
            x += OFFSET, y += OFFSET;
            dices[i] = Dice(l, r, f, b, d, u, x, y);
        }

        int M = (1 << N);
        const int INF = 1e9;
        vector<int> dp(M, -INF);
        dp[0] = 0;
        vector<vector<bool>> used(MAX_N, vector<bool>(MAX_N));
        vector<vector<int>> vals(MAX_N, vector<int>(MAX_N));

        for(int u = 0; u < M - 1; u++){
            // set "used"
            for(int j = 0; j < N; j++){
                if(u & (1 << j)){
                    Dice di = dices[j];
                    used[di.yco][di.xco] = true;
                    for(char c : mov[j]){
                        if(c == 'B') di.rotB();
                        if(c == 'F') di.rotF();
                        if(c == 'R') di.rotR();
                        if(c == 'L') di.rotL();
                        used[di.yco][di.xco] = true;
                    }
                }
            }
            // calc score
            for(int j = 0; j < N; j++){
                if(!(u & (1 << j))){
                    int val = 0;
                    Dice di = dices[j];
                    if(!used[di.yco][di.xco]) vals[di.yco][di.xco] = di.znL;
                    for(char c : mov[j]){
                        if(c == 'B') di.rotB();
                        if(c == 'F') di.rotF();
                        if(c == 'R') di.rotR();
                        if(c == 'L') di.rotL();
                        if(!used[di.yco][di.xco]) vals[di.yco][di.xco] = di.znL;
                        // if(N == 1) cout << di.znL << " ";
                    }
                    // cout << endl;
                    di = dices[j];

                    val += vals[di.yco][di.xco];
                    vals[di.yco][di.xco] = 0;
                    for(char c : mov[j]){
                        if(c == 'B') di.rotB();
                        if(c == 'F') di.rotF();
                        if(c == 'R') di.rotR();
                        if(c == 'L') di.rotL();
                        val += vals[di.yco][di.xco];
                        // if(N == 1) cout << vals[di.yco][di.xco] << " ";
                        vals[di.yco][di.xco] = 0;
                    }
                    // cerr << "!" << val << endl;
                    dp[u | (1 << j)] = max(dp[u | (1 << j)], dp[u] + val);
                }
            }
            // init "used"
            for(int j = 0; j < N; j++){
                if(u & (1 << j)){
                    Dice di = dices[j];
                    used[di.yco][di.xco] = false;
                    for(char c : mov[j]){
                        if(c == 'B') di.rotB();
                        if(c == 'F') di.rotF();
                        if(c == 'R') di.rotR();
                        if(c == 'L') di.rotL();
                        used[di.yco][di.xco] = false;
                    }
                }
            }
        }

        cout << dp[M - 1] << endl;
    }
}
accuracy: 1
time_ms: 460
memory_kb: 20572
final_rank: 7

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

using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vd = vector<double>;
using vvd = vector<vd>;
using vvvd = vector<vvd>;
#define all(A) A.begin(),A.end()
#define ALL(A) A.begin(),A.end()
#define rep(i, n) for (int i = 0; i < (int) (n); i++)
template<class T>
bool chmax(T& p, T q) {
    if (p < q) {
        p = q; return 1;
    }
    return 0;
};
template<class T>
bool chmin(T& p, T q) {
    if (p > q) {
        p = q; return 1;
    }
    return 0;
};

struct dice{
    ll l,r,f,b,d,u;

    void input(){
        cin>>l>>r>>f>>b>>d>>u;
    }

    void roll(char C){
        if(C=='R'){
            ll p=u;
            u=l;
            l=d;
            d=r;
            r=p;
        }
        if(C=='L')rep(i,3)roll('R');
        if(C=='F'){
            ll p=u;
            u=b;
            b=d;
            d=f;
            f=p;
        }
        if(C=='B')rep(i,3)roll('F');
    }
};
void mov(ll &x,ll &y,char C){
    if(C=='R')x++;
    if(C=='L')x--;
    if(C=='F')y--;
    if(C=='B')y++;
}

void solve(ll N) {
    vector<dice> D(N);
    vll X(N),Y(N);
    vector<string> S(N);
    rep(i,N){
        cin>>X[i]>>Y[i];
        D[i].input();
        cin>>S[i];
    }
    vector<ll> DP(1<<N,-1e18);
    DP[0]=0;
    rep(bit,1<<N){
        set<pair<ll,ll>> SS;
        rep(i,N){
            if(bit&(1<<i)){
                ll x=X[i];
                ll y=Y[i];
                SS.insert({x,y});
                for(auto s:S[i]){
                    mov(x,y,s);
                    SS.insert({x,y});
                }
            }
        }
        rep(i,N){
            if(bit&(1<<i))continue;
            dice ND=D[i];
            ll x=X[i];
            ll y=Y[i];
            map<pair<ll,ll>,ll> MP;
            MP[{x,y}]=ND.d;
            for(auto s:S[i]){
                mov(x,y,s);
                ND.roll(s);
                MP[{x,y}]=ND.d;
            }
            ll res=0;
            for(auto m:MP){
                if(!SS.count(m.first))res+=m.second;
            }
            chmax(DP[bit+(1<<i)],DP[bit]+res);
        }
    }
    cout<<DP[(1<<N)-1]<<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: 4920
memory_kb: 3684
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;
struct dice {
    int x_neg, x_pos, y_neg, y_pos, z_neg, z_pos;
    dice() : dice(0, 0, 0, 0, 0, 0) {}
    dice(int x1, int x2, int y1, int y2, int z1, int z2) : 
    x_neg(x1), x_pos(x2), y_neg(y1), y_pos(y2), z_neg(z1), z_pos(z2) {}
    void rotate(char C) {
        if (C == 'L') {
            int tmp = x_pos;
            x_pos = z_neg;
            z_neg = x_neg;
            x_neg = z_pos;
            z_pos = tmp;
        }
        if (C == 'R') {
            int tmp = x_pos;
            x_pos = z_pos;
            z_pos = x_neg;
            x_neg = z_neg;
            z_neg = tmp;
        }
        if (C == 'F') {
            int tmp = y_pos;
            y_pos = z_neg;
            z_neg = y_neg;
            y_neg = z_pos;
            z_pos = tmp;
        }
        if (C == 'B') {
            int tmp = y_pos;
            y_pos = z_pos;
            z_pos = y_neg;
            y_neg = z_neg;
            z_neg = tmp;
        }
    }
};
int X[15],Y[15],dp[1<<15];
dice D[15];
string rot[15];
unordered_set<int>used[1 << 15];
int add(int S, int p) {
    int x = X[p], y = Y[p];
    unordered_map<int, int> memo;
    dice d = D[p];
    int res = 0;
    for (char c : rot[p]) {
        res -= memo[x * 4000 + y];
        if (used[S].find(x * 4000 + y) == used[S].end()) {
            res += memo[x * 4000 + y] = d.z_neg;
        }
        d.rotate(c);
        if (c == 'L') x--;
        if (c == 'R') x++;
        if (c == 'F') y--;
        if (c == 'B') y++;
    }
    for (auto[key, val] : memo) used[S | (1 << p)].insert(key);
    return res;
}
bool solve() {
    int N;
    cin >> N;
    if (N == 0) return 0;
    for (int i = 0; i < N; i++) {
        cin >> X[i] >> Y[i];
        X[i] += 2000, Y[i] += 2000;
        int x1, x2, y1, y2, z1, z2;
        cin >> x1 >> x2 >> y1 >> y2 >> z1 >> z2;
        D[i] = dice(x1, x2, y1, y2, z1, z2);
        cin >> rot[i];
        rot[i].push_back('$');
    }
    for (int i = 0; i < (1 << N); i++) {
        dp[i] = 0;
        used[i].clear();
    }
    for (int i = 0; i < (1 << N); i++) {
        for (int j = 0; j < N; j++) {
            if (i >> j & 1) continue;
            int k = i | (1 << j);
            for (int xy : used[i]) used[k].insert(xy);
            dp[k] = max(dp[k], dp[i] + add(i, j));
        }
    }
    cout << dp[(1 << N) -1] << endl;
    return 1;
}
int main() {
    while (solve()) {}
}
accuracy: 1
time_ms: 7240
memory_kb: 216940
final_rank: 19

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

bool solve(){
  int N, x, y;
  cin >> N;
  if(N==0) return 0;
  vector<int> dp(1<<N, 0);
  vector<vector<int>> dice_num(N, vector<int>(6));
  vector<string> dice_ord(N);
  vector<pair<int, int>> place(N);
  vector<unordered_set<int>> used(1<<N);
  for(int i=0;i<N;i++){
    cin >> x >> y;
    x += 1050;
    y += 1050;
    place[i] = make_pair(x, y);
    for(int j=0;j<6;j++){
      cin >> dice_num[i][j];
    }
    cin >> dice_ord[i];
    dice_ord[i].push_back('S');
  }

  auto score = [&](int S, int d) -> int{
    int ret = 0;
    auto [x, y] = place[d];
    vector<int> dice(6);
    for(int i=0;i<6;i++){
      dice[i] = dice_num[d][i];
    }
    unordered_map<int, int> count;
    for(char s: dice_ord[d]){
      ret -= count[x*3000+y];
      if(used[S].count(x*3000+y)==0){
        ret += dice[4];
        count[x*3000+y] = dice[4];
      }
      used[S|(1<<d)].insert(x*3000+y);
      if(s=='R'){
        dice = {dice[4], dice[5], dice[2], dice[3], dice[1], dice[0]};
        x++;
      }else if(s=='L'){
        dice = {dice[5], dice[4], dice[2], dice[3], dice[0], dice[1]};
        x--;
      }else if(s=='B'){
        dice = {dice[0], dice[1], dice[4], dice[5], dice[3], dice[2]};
        y++;
      }else{
        dice = {dice[0], dice[1], dice[5], dice[4], dice[2], dice[3]};
        y--;
      }
    }
    return ret;
  };

  for(int i=0;i<(1<<N);i++){
    for(int j=0;j<N;j++){
      if(!(i&(1<<j))){
        for(auto x: used[i]){
          used[i|(1<<j)].insert(x);
        }
        dp[i|(1<<j)] = max(dp[i|(1<<j)], dp[i]+score(i, j));
      }
    }
  }
  cout << dp[(1<<N)-1] << endl;
  return 1;
}

int main(){
  while(solve());
}
accuracy: 1
time_ms: 7890
memory_kb: 215368
final_rank: 20

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

namespace lib {
using namespace std;

template <typename T = int>
class Dice {
private:
    array<T, 6> data;
    int id_;
public:
    Dice(int id_ = 0) : id_(id_) {
        iota(data.begin(), data.end(), 1);
    }
    Dice(const array<T, 6>& data, int id_ = 0) : data(data), id_(id_) {}

    void rotate_north() {
        T temp = data[5];
        data[5] = data[4];
        data[4] = data[0];
        data[0] = data[1];
        data[1] = temp;
    }
    void rotate_east() {
        T temp = data[5];
        data[5] = data[2];
        data[2] = data[0];
        data[0] = data[3];
        data[3] = temp;
    }
    void rotate_south() {
        T temp = data[5];
        data[5] = data[1];
        data[1] = data[0];
        data[0] = data[4];
        data[4] = temp;
    }
    void rotate_west() {
        T temp = data[5];
        data[5] = data[3];
        data[3] = data[0];
        data[0] = data[2];
        data[2] = temp;
    }

    T top() const {
        return data[0];
    }
    T front() const {
        return data[1];
    }
    T right() const {
        return data[2];
    }
    T left() const {
        return data[3];
    }
    T back() const {
        return data[4];
    }
    T bottom() const {
        return data[5];
    }
    int id( ) const {
        return id_;
    }

    void rotate(const char c) {
        if (c == 'N') {
            rotate_north();
        }
        else if (c == 'E') {
            rotate_east();
        }
        else if (c == 'S') {
            rotate_south();
        }
        else if (c == 'W') {
            rotate_west();
        }
        else {
            assert(false);
        }
    }

    Dice match(T top_value, T front_value) {
        Dice temp = Dice(*this);
        for (int i = 0 ; i < 6 ; i++) {
            for (int j = 0 ; j < 4 ; j++) {
                if (temp.top() == top_value && temp.front() == front_value) {
                    return temp;
                }
                temp.rotate_east();
            }
            if (i & 1) {
                temp.rotate_east();
            }
            else {
                temp.rotate_west();
            }
            temp.rotate_south();
        }
        assert(false);
        return temp;
    }
};

template <typename T>
bool operator==(const Dice<T>& lhs, const Dice<T>& rhs) {
    Dice temp = Dice(lhs);
    for (int i = 0 ; i < 6 ; i++) {
        for (int j = 0 ; j < 4 ; j++) {
            if (temp.top() == rhs.top && temp.bottom() == rhs.bottom() &&
                    temp.front() == rhs.front() && temp.back() == rhs.back() && 
                    temp.right() == rhs.right() && temp.left() == rhs.left()) {
                return true;
            }
            temp.rotate_east();
        }
        if (i & 1) {
            temp.rotate_east();
        }
        else {
            temp.rotate_west();
        }
        temp.rotate_south();
    }
    return false;
}

} // namespace lib

bool solve() {
    int N;
    std::cin >> N;
    if (N == 0) return false;
    using data = std::vector<std::pair<std::pair<int, int>, int>>;
    std::vector<data> D(N);
    for (int i{} ; i < N ; i++) {
        int x, y, l, r, f, b, d, u;
        std::string rot;
        std::cin >> x >> y;
        std::cin >> l >> r >> f >> b >> d >> u;
        std::cin >> rot;
        // std::replace(rot.begin(), rot.end(), 'L', 'E');
        // std::replace(rot.begin(), rot.end(), 'R', 'W');
        // std::replace(rot.begin(), rot.end(), 'F', 'S');
        // std::replace(rot.begin(), rot.end(), 'B', 'N');
        lib::Dice<int> dice{std::array<int, 6>{ u, f, r, l, b, d }};
        data cur;
        // std::cout << x << ' ' << y << ' ' << dice.bottom() << std::endl;
        cur.push_back(std::make_pair(std::make_pair(x, y), dice.bottom()));
        for (auto c : rot) {
            if (c == 'L') {
                x--;
                dice.rotate_west();
            }
            else if (c == 'R') {
                x++;
                dice.rotate_east();
            }
            else if (c == 'F') {
                y--;
                dice.rotate_south();
            }
            else if (c == 'B') {
                y++;
                dice.rotate_north();
            }
            // std::cout << x << ' ' << y << ' ' << dice.bottom() << std::endl;
            cur.push_back(std::make_pair(std::make_pair(x, y), dice.bottom()));
        }
        std::reverse(cur.begin(), cur.end());
        for (int j{} ; j < (int)cur.size() ; j++) {
            bool fn{};
            for (int k{} ; k < j ; k++) {
                fn |= cur[j].first == cur[k].first;
            }
            if (fn) continue;
            D[i].push_back(cur[j]);
        }
        // exit(0);
    }
    std::vector<int> dp((1 << N), -1);
    dp[0] = 0;
    for (int bit{} ; bit < (1 << N) ; bit++) {
        std::set<std::pair<int, int>> set;
        for (int i{} ; i < N ; i++) if (bit & (1 << i)) {
            for (const auto& [p, _] : D[i]) {
                set.insert(p);
            }
        }
        for (int i{} ; i < N ; i++) if (!(bit & (1 << i))) {
            int add{};
            for (const auto& [p, v] : D[i]) {
                if (set.find(p) != set.end()) continue;
                add += v;
            }
            dp[bit | (1 << i)] = std::max(dp[bit | (1 << i)], dp[bit] + add);
        }
    }
    std::cout << dp[(1 << N) - 1] << '\n';
    return true;
}


int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    while (solve()) ;
}
accuracy: 1
time_ms: 1920
memory_kb: 3568
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define rep(i, a, b) for(ll i = a; i < b; ++i)
#define rrep(i, a, b) for(ll i = a; i >= b; --i)
constexpr ll inf = 4e18;
#define roll_swap(x, a, b, c, d) swap(x.a, x.b), swap(x.b, x.c), swap(x.c, x.d);
struct Dice {
    int top, front, right, left, back, bottom;
    Dice(int to = 1, int fr = 2, int ri = 3, int le = 4, int ba = 5, int bo = 6)
        : top(to), front(fr), right(ri), left(le), back(ba), bottom(bo) {}
    void roll_right() {
        roll_swap((*this), top, left, bottom, right);
    }
    void roll_left() {
        roll_swap((*this), top, right, bottom, left);
    }
    void roll_front() {
        roll_swap((*this), top, back, bottom, front);
    }
    void roll_back() {
        roll_swap((*this), top, front, bottom, back);
    }
    void roll(char dir) {
        if(dir == 'F') (*this).roll_front();
        if(dir == 'B') (*this).roll_back();
        if(dir == 'R') (*this).roll_right();
        if(dir == 'L') (*this).roll_left();
    }
};
int main(void) {
    cin.tie(0);
    ios::sync_with_stdio(0);
    while(1) {
        int n;
        cin >> n;
        if(n == 0) break;
        vector<pair<int, int>> p(n);
        vector<Dice> dice(n);
        vector<string> rot(n);
        rep(i, 0, n) {
            cin >> p[i].first >> p[i].second;
            p[i].first += 1100;
            p[i].second += 1100;
            int l, r, f, b, d, u;
            cin >> l >> r >> f >> b >> d >> u;
            dice[i] = Dice(u, f, r, l, b, d);
            cin >> rot[i];
        }
        vector<int> dp(1 << n, -1);
        vector<vector<int>> flag(2200, vector<int>(2200, 0));
        auto dfs = [&](auto& dfs, int mask) -> int {
            if(dp[mask] != -1) return dp[mask];
            if(mask == 0) return 0;
            int res = 0;
            rep(i, 0, n) {
                if(mask & (1 << i)) {
                    int cnt = 0;
                    {
                        Dice d = dice[i];
                        int x = p[i].first, y = p[i].second;
                        map<pair<int, int>, int> mp;
                        if(!flag[x][y]) mp[{x, y}] = d.bottom;
                        rep(j, 0, (int)rot[i].size()) {
                            d.roll(rot[i][j]);
                            if(rot[i][j] == 'F') y--;
                            if(rot[i][j] == 'B') y++;
                            if(rot[i][j] == 'R') x++;
                            if(rot[i][j] == 'L') x--;
                            if(!flag[x][y]) mp[{x, y}] = d.bottom;
                        }
                        for(const auto& it : mp) {
                            cnt += it.second;
                        }
                    }
                    {
                        Dice d = dice[i];
                        int x = p[i].first, y = p[i].second;
                        flag[x][y]++;
                        rep(j, 0, (int)rot[i].size()) {
                            d.roll(rot[i][j]);
                            if(rot[i][j] == 'F') y--;
                            if(rot[i][j] == 'B') y++;
                            if(rot[i][j] == 'R') x++;
                            if(rot[i][j] == 'L') x--;
                            flag[x][y]++;
                        }
                    }
                    res = max(res, cnt + dfs(dfs, mask - (1 << i)));
                    {
                        Dice d = dice[i];
                        int x = p[i].first, y = p[i].second;
                        flag[x][y]--;
                        rep(j, 0, (int)rot[i].size()) {
                            d.roll(rot[i][j]);
                            if(rot[i][j] == 'F') y--;
                            if(rot[i][j] == 'B') y++;
                            if(rot[i][j] == 'R') x++;
                            if(rot[i][j] == 'L') x--;
                            flag[x][y]--;
                        }
                    }
                }
            }
            return dp[mask] = res;
        };
        cout << dfs(dfs, (1 << n) - 1) << '\n';
    }
}
accuracy: 1
time_ms: 1280
memory_kb: 22152
final_rank: 10

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;

} // namespace macro

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

int solve(int N) {
    vector<map<pair<int,int>, int>> A(N);
    for(auto &mp : A) {
        int x = in(), y = in();
        int l = in(), r = in(), f = in(), b = in(), d = in(), u = in();
        string rot = in();

        mp[{x, y}] = d;
        for(char op : rot) {
            if(op == 'L') {
                tie(x, y) = make_pair(x - 1, y);
                tie(l, r, f, b, d, u) = make_tuple(u, d, f, b, l, r);
            }

            if(op == 'R') {
                tie(x, y) = make_pair(x + 1, y);
                tie(l, r, f, b, d, u) = make_tuple(d, u, f, b, r, l);
            }

            if(op == 'F') {
                tie(x, y) = make_pair(x, y - 1);
                tie(l, r, f, b, d, u) = make_tuple(l, r, u, d, f, b);
            }

            if(op == 'B') {
                tie(x, y) = make_pair(x, y + 1);
                tie(l, r, f, b, d, u) = make_tuple(l, r, d, u, b, f);
            }

            mp[{x, y}] = d;
        }
    }

    vector<int> dp(1 << N, 0);
    for(int S : rep(1 << N)) {
        set<pair<int,int>> st;
        for(int i : rep(N)) if(S & (1 << i)) {
            for(auto [point, value] : A[i]) st.insert(point);
        }
        for(int i : rep(N)) if(!(S & (1 << i))) {
            int sum = 0;
            for(auto [point, value] : A[i]) if(!st.count(point)) sum += value;
            chmax(dp[S | (1 << i)], dp[S] + sum);
        }
    }

    return max_of(dp).val;
}

int main() {
    while(true) {
        int N = in();
        if(N == 0) return 0;
        print(solve(N));
    }
}
accuracy: 1
time_ms: 2190
memory_kb: 3464
final_rank: 13

code_snippet: #include <algorithm>
#include <climits>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <vector>

using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
using lint = ll;
using ulint = ull;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
template <class T>
using V = vector<T>;
template <class T>
using VV = V<V<T>>;
#define For(i, a, b) for (int i = int(a); i < int(b); ++i)
#define rep(i, n) For(i, 0, n)
template <class T, class U>
bool chmin(T &a, U &b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T, class U>
bool chmax(T &a, U &b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template <class T>
ostream &operator<<(ostream &os, const V<T> &v) {
    os << "[";
    for (auto d : v) os << d << ", ";
    return os << "]";
}

#include <array>
template <class T>
struct Dice {
    array<T, 6> face;

    Dice(array<T, 6> arr) : face(arr) {}

    static int opposite(int f) {
        if (f <= 1) return f ^ 1;
        return f ^ 6;
    }

    Dice roll_right() {
        array<T, 6> res = face;
        res[0] = face[5];
        res[1] = face[3];
        res[3] = face[0];
        res[5] = face[1];
        return {res};
    }
    Dice roll_left() {
        array<T, 6> res = face;
        res[0] = face[3];
        res[1] = face[5];
        res[3] = face[1];
        res[5] = face[0];
        return {res};
    }

    Dice roll_front() {
        array<T, 6> res = face;
        res[0] = face[4];
        res[1] = face[2];
        res[2] = face[0];
        res[4] = face[1];
        return {res};
    }
    Dice roll_back() {
        array<T, 6> res = face;
        res[0] = face[2];
        res[1] = face[4];
        res[2] = face[1];
        res[4] = face[0];
        return {res};
    }
};
template <class T>
ostream &operator<<(ostream &os, Dice<T> d) {
    os << "  " << d.face[0] << endl;
    os << d.face[5] << " ";
    For(i, 2, 5) os << d.face[i] << " ";
    return os << endl << "  " << d.face[1];
}

int main() {
    while (true) {
        int n;
        cin >> n;
        if (n == 0) break;
        vector<int> x(n), y(n);
        vector<string> s(n);
        vector<Dice<int>> ds;
        rep(i, n) {
            cin >> x[i] >> y[i];
            array<int, 6> a;
            cin >> a[5] >> a[3] >> a[2] >> a[4] >> a[1] >> a[0];
            Dice d(a);
            ds.push_back(d);
            cin >> s[i];
        }

        map<pii, int> mp;
        rep(i, n) {
            int tx = x[i], ty = y[i];
            mp[{tx, ty}] |= 1 << i;
            for (auto c : s[i]) {
                if (c == 'L') {
                    --tx;
                } else if (c == 'R') {
                    ++tx;
                } else if (c == 'B') {
                    ++ty;
                } else {
                    --ty;
                }
                mp[{tx, ty}] |= 1 << i;
            }
        }

        auto check = [&](int S, int i, int tx, int ty) {
            return (mp[{tx, ty}] & S) == 0;
        };

        vector<int> dp(1 << n, -1);
        dp[0] = 0;
        rep(S, 1 << n) {
            rep(i, n) {
                if (S >> i & 1) continue;

                auto d = ds[i];
                map<pii, int> tmap;

                int tx = x[i], ty = y[i];
                tmap[{tx, ty}] = d.face[1];
                for (auto c : s[i]) {
                    if (c == 'L') {
                        --tx;
                        d = d.roll_left();
                    } else if (c == 'R') {
                        ++tx;
                        d = d.roll_right();
                    } else if (c == 'B') {
                        ++ty;
                        d = d.roll_back();
                    } else {
                        --ty;
                        d = d.roll_front();
                    }
                    tmap[{tx, ty}] = d.face[1];
                    // cout << d << endl;
                }
                int tmp = 0;
                for (auto [key, val] : tmap) {
                    auto [tx, ty] = key;
                    if (check(S, i, tx, ty)) {
                        // cout << tx << " " << ty << " " << val << endl;
                        tmp += val;
                    }
                }

                int T = (S | (1 << i));
                dp[T] = max(dp[T], dp[S] + tmp);
            }
        }
        cout << dp[(1 << n) - 1] << endl;
    }
}
accuracy: 1
time_ms: 1430
memory_kb: 3400
final_rank: 8

code_snippet: #include <algorithm>
#include <climits>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <vector>

using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
using lint = ll;
using ulint = ull;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
template <class T>
using V = vector<T>;
template <class T>
using VV = V<V<T>>;
#define For(i, a, b) for (int i = int(a); i < int(b); ++i)
#define rep(i, n) For(i, 0, n)
template <class T, class U>
bool chmin(T &a, U &b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T, class U>
bool chmax(T &a, U &b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template <class T>
ostream &operator<<(ostream &os, const V<T> &v) {
    os << "[";
    for (auto d : v) os << d << ", ";
    return os << "]";
}

#include <array>
template <class T>
struct Dice {
    array<T, 6> face;

    Dice(array<T, 6> arr) : face(arr) {}

    static int opposite(int f) {
        if (f <= 1) return f ^ 1;
        return f ^ 6;
    }

    Dice roll_right() {
        array<T, 6> res = face;
        res[0] = face[5];
        res[1] = face[3];
        res[3] = face[0];
        res[5] = face[1];
        return {res};
    }
    Dice roll_left() {
        array<T, 6> res = face;
        res[0] = face[3];
        res[1] = face[5];
        res[3] = face[1];
        res[5] = face[0];
        return {res};
    }

    Dice roll_front() {
        array<T, 6> res = face;
        res[0] = face[4];
        res[1] = face[2];
        res[2] = face[0];
        res[4] = face[1];
        return {res};
    }
    Dice roll_back() {
        array<T, 6> res = face;
        res[0] = face[2];
        res[1] = face[4];
        res[2] = face[1];
        res[4] = face[0];
        return {res};
    }
};
template <class T>
ostream &operator<<(ostream &os, Dice<T> d) {
    os << "  " << d.face[0] << endl;
    os << d.face[5] << " ";
    For(i, 2, 5) os << d.face[i] << " ";
    return os << endl << "  " << d.face[1];
}

int main() {
    while (true) {
        int n;
        cin >> n;
        if (n == 0) break;
        vector<int> x(n), y(n);
        vector<string> s(n);
        vector<Dice<int>> ds;
        rep(i, n) {
            cin >> x[i] >> y[i];
            array<int, 6> a;
            cin >> a[5] >> a[3] >> a[2] >> a[4] >> a[1] >> a[0];
            Dice d(a);
            ds.push_back(d);
            cin >> s[i];
        }

        map<pii, int> mp;
        rep(i, n) {
            int tx = x[i], ty = y[i];
            mp[{tx, ty}] |= 1 << i;
            for (auto c : s[i]) {
                if (c == 'L') {
                    --tx;
                } else if (c == 'R') {
                    ++tx;
                } else if (c == 'B') {
                    ++ty;
                } else {
                    --ty;
                }
                mp[{tx, ty}] |= 1 << i;
            }
        }

        auto check = [&](int S, int i, int tx, int ty) {
            return (mp[{tx, ty}] & S) == 0;
        };

        vector<int> dp(1 << n, -1);
        dp[0] = 0;
        rep(S, 1 << n) {
            rep(i, n) {
                if (S >> i & 1) continue;

                auto d = ds[i];
                map<pii, int> tmap;

                int tx = x[i], ty = y[i];
                tmap[{tx, ty}] = d.face[1];
                for (auto c : s[i]) {
                    if (c == 'L') {
                        --tx;
                        d = d.roll_left();
                    } else if (c == 'R') {
                        ++tx;
                        d = d.roll_right();
                    } else if (c == 'B') {
                        ++ty;
                        d = d.roll_back();
                    } else {
                        --ty;
                        d = d.roll_front();
                    }
                    tmap[{tx, ty}] = d.face[1];
                    // cout << d << endl;
                }
                int tmp = 0;
                for (auto [key, val] : tmap) {
                    auto [tx, ty] = key;
                    if (check(S, i, tx, ty)) {
                        // cout << tx << " " << ty << " " << val << endl;
                        tmp += val;
                    }
                }

                int T = (S | (1 << i));
                dp[T] = max(dp[T], dp[S] + tmp);
            }
        }
        cout << dp[(1 << n) - 1] << endl;
    }
}
accuracy: 1
time_ms: 1430
memory_kb: 3524
final_rank: 9

code_snippet: # include <bits/stdc++.h>
# define rep(i, n) for (int i = 0; i < int(n); i++)
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
template <class T> bool chmax(T& a, T b) { return a < b && (a = b, true); }

template <class T>
struct Dice {
   static const int Up    = 0;
   static const int Down  = 1;
   static const int Right = 2;
   static const int Left  = 3;
   static const int Fwd   = 4;
   static const int Back  = 5;

   int x, y;
   array<T, 6> f;

   Dice() = default;

   // 上下右左前後
   Dice(int x, int y, array<T, 6> udrlfb) : x(x), y(y), f(udrlfb) {}

   // <summary>
   // id で指定してください。
   //
   // L : 左側に倒す。x 軸負方向
   // R : 右側に倒す。x 軸正方向
   // F : 前側に倒す。y 軸負方向
   // B : 後ろ側に倒す。y 軸正方向
   // </summary>
   // <returns>
   // 倒した結果、底面に書いてあるもの
   // </returns>
   T rotate(int id) {
      switch (id) {
         case Left:
            swap(Up, Right);
            swap(Right, Down);
            swap(Down, Left);
            x--;
            break;
         case Right:
            // swap に関しては、
            // 'L' を 3 回するということにしても良い
            swap(Up, Left);
            swap(Left, Down);
            swap(Down, Right);
            x++;
            break;
         case Fwd:
            swap(Up, Back);
            swap(Back, Down);
            swap(Down,Fwd);
            y--;
            break;
         case Back:
            // swap に関しては、
            // 'F' を 3 回するということにしても良い
            swap(Up, Fwd);
            swap(Fwd, Down);
            swap(Down, Back);
            y++;
            break;
      }
      return f[Down];
   }

   // <summary>
   // id1 の面が tar1 であり、id2 の面が tar2 であるようなサイコロの向きにします。
   //
   // なお、そのような置き方は一意に定まります。
   // </summary>
   void arange(int id1, const T& tar1, int id2, const T& tar2) {
      assert(count(f.begin(), f.end(), tar1) > 0);
      assert(count(f.begin(), f.end(), tar2) > 0);
      while (f[id1] == tar1 && f[id2] == tar2) {
         rotate(rand() % 2 == 0 ? Right : Fwd);
      }
   }

   // <summary>
   // 方向を表す id を指定すると、その面にかかれてあるものを返します。
   //
   // ```
   // dice.get(Dice<int>::Up);
   // dice.get(Dice<int>::Id('U'));
   // ```
   // </summary>
   int get(int id) {
      return f[id];
   }

   // <returns>
   // c が表す方向の id
   // </returns>
   static int Id(char c) {
      switch (c) {
         case 'U': return Up;
         case 'D': return Down;
         case 'R': return Right;
         case 'L': return Left;
         case 'F': return Fwd;
         case 'B': return Back;
      }
      assert(false);
   }

   // <returns>
   // c の面の反対
   // </returns>
   static char Rev(char c) {
      switch (c) {
         case 'U': return 'D';
         case 'D': return 'U';
         case 'R': return 'L';
         case 'L': return 'R';
         case 'F': return 'B';
         case 'B': return 'F';
      }
      assert(false);
   }

   void swap(int i, int j) {
      std::swap(f[i], f[j]);
   }
};

bool stand(int S, int i) {
   return bool(S & (1 << i));
}

int main() {
   while (true) {
      int n;
      cin >> n;
      if (!n) break;

      vector<map<pll, int>> points;
      rep (i, n) {
         int x, y, l, r, f, b, d, u;
         cin >> x >> y;
         cin >> l >> r >> f >> b >> d >> u;
         Dice dice(x, y, array<int, 6>{u, d, r, l, f, b});

         string ops;
         cin >> ops;

         map<pll, int> tmp;
         tmp[{x, y}] = dice.get(Dice<int>::Down);
         for (char op : ops) {
            dice.rotate(Dice<int>::Id(op));
            tmp[{dice.x, dice.y}] = dice.get(Dice<int>::Down);
         }

         points.push_back(tmp);
      }

      vector<ll> dp(1 << n, 0);
      rep (S, 1 << n) {
         set<pll> st;
         rep (i, n) {
            if (stand(S, i)) {
               for (auto [xy, _] : points[i]) {
                  st.insert(xy);
               }
            }
         }

         rep (i, n) {
            if (stand(S, i)) continue;
            ll sum = 0;
            for (auto [xy, p] : points[i]) {
               if (not st.count(xy)) {
                  sum += p;
               }
            }
            assert(S != (S | (1 << i)));
            chmax(dp[S | (1 << i)], dp[S] + sum);
         }
      }

      ll ans = dp[(1 << n) - 1];
      cout << ans << endl;
   }
}
accuracy: 1
time_ms: 2200
memory_kb: 3600
final_rank: 14