Problem:
Icpcan Alphabet
Figure D-1 A picture of two expressions engraved on a stone wall.
Research on the civilization of old kingdom of Icpca has been carried out at the Investigation Center for Prehistoric Civilization (ICPC).
Their recent excavation found two expressions engraved on a stone wall at the ruins of Icpca.
The expressions are composed of
n
distinct Icpca letters
a
1
, ...,
a
n
, symbols corresponding to inequality signs ('<' and '>') and parentheses ('
(
' and '
)
').
In what follows, they are represented by capital Roman letters and ordinary symbols for description ease.
Expressions conform to the following grammar rules with the start symbol
E
.
E ::= F | '(' E '<' E ')' | '(' E '>' E ')'
  F ::= a
1
| a
2
| ... | a
n
Analyses unifying multifarious knowledge on the old kingdom and its civilization revealed the following evaluation rules.
A total order relation is defined on the set of letters
a
1
, ...,
a
n
.
When an expression consists only of a single letter, the value of the expression is that very letter.
For two expressions
P
and
Q
with values
a
i
and
a
j
, respectively, the value of the expression
(
P
<
Q
)
is one of the letters
a
i
or
a
j
that precedes in the total order. If the two letters are the same, the value is that letter.
Similarly, for two expressions
P
and
Q
with values
a
i
and
a
j
, respectively, the value of the expression
(
P
>
Q
)
is one of the letters
a
i
or
a
j
that comes later in the total order. If the two letters are the same, the value is that letter.
It was also found that the values of the two expressions discovered must be equal.
How many different total orders, among
n
! possible total orders,
make the values of the two expressions equal?
Input
The input consists of multiple datasets, each in the following format.
n
a
1
a
2
...
a
n
S
T
Each dataset consists of four lines.
The first line contains
n
(1 ≤
n
≤ 16), the number of different capital Roman letters corresponding to Icpcan characters.
The second line contains
n
distinct capital Roman letters without any spaces.
The third and the fourth lines contain two discovered expressions
S
and
T
, respectively.
Both
S
and
T
conform to the grammar given above and neither of them has more than 100 characters.
The end of the input is indicated by a line containing a zero.
The number of datasets does not exceed 50.
Output
For each dataset, output a single line containing the number of different total orders making the values of the two expressions equal.
Sample Input
3
CIP
((I<C)>(P<C))
(P>C)
2
AB
(A<B)
(A>B)
3
ANY
((A<N)<Y)
((N<Y)<((A<A)<N))
6
ANSWER
A
((E>(A>((E<W)>(N<S))))>(A<W))
0
Output for the Sample Input
1
0
6
300

Submitted solutions:

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

using namespace std;
using ll = long long;

// clang-format off

int n;
string a;
string S, T;

char val(const string& P, int& r, char tchar, int mask) {
    ++r;
    if (P[r-1]==tchar) return 1;
    int idx=P[r-1]-'A';
    if ((mask>>idx)&1) {
        return 2; // greater other char
    } else {
        return 0; // smaller
    }
}

char expr(const string& P, int& r, char tchar, int mask) {
    if (P[r] == '(') {
        ++r; // (
        int c1 = expr(P, r, tchar, mask);
        char op = P[r];
        ++r; // < or >
        int c2 = expr(P, r, tchar, mask);
        ++r; // )
        assert(op=='<'||op=='>');
        if (op == '<') {
            return min(c1, c2);
        } else {
            return max(c1, c2);
        }
    } else {
        int v = val(P, r, tchar, mask);
        return v;
    }
}

int main(void) {
    
    while (cin>>n, n>0) {
        cin>>a>>S>>T;

        ll ans = 0;
        vector<ll> fact(n+1,1);
        for(int i=0;i<n;++i) fact[i+1]=fact[i]*(i+1);
        for(int i=0;i<n;++i) {
            for(int s=0; s<(1L<<n); ++s) {
                if ((s>>i)&1) continue;
                int mask=0;
                for (int j=0;j<n;++j) if ((s>>j)&1) mask|=1L<<(a[j]-'A');
                int r1=0, r2=0;
                int e1=expr(S, r1, a[i], mask);
                int e2=expr(T, r2, a[i], mask);
                if (e1 == 1 && e2 == 1) {
                    int l=popcount<unsigned int>(s);
                    int r=n-1-l;
                    ans+=fact[l]*fact[r];
                }
            }
        }
        cout << ans <<endl;
    }

}
accuracy: 1
time_ms: 2140
memory_kb: 3456
final_rank: 13

code_snippet: #line 1 "library/Template/template.hpp"
#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, typename S = T> S SUM(const vector<T> &a) {
    return accumulate(ALL(a), S(0));
}
template <typename S, typename T = S> S POW(S a, T b) {
    S ret = 1, base = a;
    for (;;) {
        if (b & 1)
            ret *= base;
        b >>= 1;
        if (b == 0)
            break;
        base *= base;
    }
    return ret;
}
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 debug 1
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define debug 0
#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...);
}
#line 2 "library/Utility/fastio.hpp"
#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
 */
#line 2 "library/Utility/random.hpp"

namespace Random {
mt19937_64 randgen(chrono::steady_clock::now().time_since_epoch().count());
using u64 = unsigned long long;
u64 get() {
    return randgen();
}
template <typename T> T get(T L) { // [0,L]
    return get() % (L + 1);
}
template <typename T> T get(T L, T R) { // [L,R]
    return get(R - L) + L;
}
double uniform() {
    return double(get(1000000000)) / 1000000000;
}
string str(int n) {
    string ret;
    rep(i, 0, n) ret += get('a', 'z');
    return ret;
}
template <typename Iter> void shuffle(Iter first, Iter last) {
    if (first == last)
        return;
    int len = 1;
    for (auto it = first + 1; it != last; it++) {
        len++;
        int j = get(0, len - 1);
        if (j != len - 1)
            iter_swap(it, first + j);
    }
}
template <typename T> vector<T> select(int n, T L, T R) { // [L,R]
    if (n * 2 >= R - L + 1) {
        vector<T> ret(R - L + 1);
        iota(ALL(ret), L);
        shuffle(ALL(ret));
        ret.resize(n);
        return ret;
    } else {
        unordered_set<T> used;
        vector<T> ret;
        while (SZ(used) < n) {
            T x = get(L, R);
            if (!used.count(x)) {
                used.insert(x);
                ret.push_back(x);
            }
        }
        return ret;
    }
}

void relabel(int n, vector<pair<int, int>> &es) {
    shuffle(ALL(es));
    vector<int> ord(n);
    iota(ALL(ord), 0);
    shuffle(ALL(ord));
    for (auto &[u, v] : es)
        u = ord[u], v = ord[v];
}
template <bool directed, bool multi, bool self>
vector<pair<int, int>> genGraph(int n, int m) {
    vector<pair<int, int>> cand, es;
    rep(u, 0, n) rep(v, 0, n) {
        if (!self and u == v)
            continue;
        if (!directed and u > v)
            continue;
        cand.push_back({u, v});
    }
    if (m == -1)
        m = get(SZ(cand));
    // chmin(m, SZ(cand));
    vector<int> ord;
    if (multi)
        rep(_, 0, m) ord.push_back(get(SZ(cand) - 1));
    else {
        ord = select(m, 0, SZ(cand) - 1);
    }
    for (auto &i : ord)
        es.push_back(cand[i]);
    relabel(n, es);
    return es;
}
vector<pair<int, int>> genTree(int n) {
    vector<pair<int, int>> es;
    rep(i, 1, n) es.push_back({get(i - 1), i});
    relabel(n, es);
    return es;
}
}; // namespace Random

/**
 * @brief Random
 */
#line 4 "sol.cpp"

int main() {
    for (;;) {
        int n;
        read(n);
        if (n == 0)
            break;
        string var, S, T;
        read(var, S, T);

        if (n == 1) {
            print(1);
            continue;
        }
        sort(ALL(var));
        ll ret = 0;
        rep(x, 0, n) {
            string rem;
            rep(j, 0, n) if (x != j) rem += var[j];
            rep(mask, 0, 1 << (n - 1)) {
                string zen, kou;
                rep(i, 0, n - 1) {
                    if (mask >> i & 1)
                        zen += rem[i];
                    else
                        kou += rem[i];
                }
                // 0:zen,1:s[x],2:kou
                auto dfs = [&](auto &dfs, int &i, string &s) -> int {
                    if (s[i] != '(') {
                        int ret = -1;
                        if (zen.find(s[i]) != string::npos)
                            ret = 0;
                        else if (s[i] == var[x])
                            ret = 1;
                        else
                            ret = 2;
                        i++;
                        return ret;
                    }

                    i++; // (
                    int X = dfs(dfs, i, s);
                    char c = s[i];
                    i++;
                    int Y = dfs(dfs, i, s);
                    i++; // )

                    int ret;
                    if (c == '<')
                        ret = min(X, Y);
                    else
                        ret = max(X, Y);
                    // show(s, i, ret);
                    return ret;
                };
                int init = 0;
                int X = dfs(dfs, init, S);
                init = 0;
                int Y = dfs(dfs, init, T);
                // show(X, Y, var[x], zen, kou);
                if (X == 1 and Y == 1) {
                    ll add = 1;
                    rep(x, 1, SZ(zen) + 1) add *= x;
                    rep(x, 1, SZ(kou) + 1) add *= x;
                    ret += add;
                }
            }
        }
        print(ret);
    }
    return 0;
}
accuracy: 1
time_ms: 2890
memory_kb: 3420
final_rank: 15

code_snippet: #pragma region Macros
#include <bits/stdc++.h>
using namespace std;
using lint = long long;
using ull = unsigned long long;
using ld = long double;
using int128 = __int128_t;
#define all(x) (x).begin(), (x).end()
#define EPS 1e-8
#define uniqv(v) v.erase(unique(all(v)), v.end())
#define OVERLOAD_REP(_1, _2, _3, name, ...) name
#define REP1(i, n) for (auto i = std::decay_t<decltype(n)>{}; (i) != (n); ++(i))
#define REP2(i, l, r) for (auto i = (l); (i) != (r); ++(i))
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP2, REP1)(__VA_ARGS__)
#define log(x) cout << x << endl
#define logfixed(x) cout << fixed << setprecision(10) << x << endl;
#define logy(bool)         \
  if (bool) {              \
    cout << "Yes" << endl; \
  } else {                 \
    cout << "No" << endl;  \
  }

ostream &operator<<(ostream &dest, __int128_t value) {
  ostream::sentry s(dest);
  if (s) {
    __uint128_t tmp = value < 0 ? -value : value;
    char buffer[128];
    char *d = end(buffer);
    do {
      --d;
      *d = "0123456789"[tmp % 10];
      tmp /= 10;
    } while (tmp != 0);
    if (value < 0) {
      --d;
      *d = '-';
    }
    int len = end(buffer) - d;
    if (dest.rdbuf()->sputn(d, len) != len) {
      dest.setstate(ios_base::badbit);
    }
  }
  return dest;
}

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

template <typename T>
ostream &operator<<(ostream &os, const set<T> &set_var) {
  for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
    os << *itr;
    ++itr;
    if (itr != set_var.end()) os << " ";
    itr--;
  }
  return os;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
  for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
    os << itr->first << " -> " << itr->second << "\n";
  }
  return os;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &pair_var) {
  os << "(" << pair_var.first << ", " << pair_var.second << ")";
  return os;
}

void out() { cout << '\n'; }
template <class T, class... Ts>
void out(const T &a, const Ts &...b) {
  cout << a;
  (cout << ... << (cout << ' ', b));
  cout << '\n';
}

template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (T &in : v) is >> in;
  return is;
}

inline void in(void) { return; }
template <typename First, typename... Rest>
void in(First &first, Rest &...rest) {
  cin >> first;
  in(rest...);
  return;
}

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

vector<lint> dx8 = {1, 1, 0, -1, -1, -1, 0, 1};
vector<lint> dy8 = {0, 1, 1, 1, 0, -1, -1, -1};
vector<lint> dx4 = {1, 0, -1, 0};
vector<lint> dy4 = {0, 1, 0, -1};

#pragma endregion

char solve(string s, const vector<int> &o) {
  stack<char> st;
  int siz = s.size();

  rep(i, siz) {
    char c = s[i];
    if (c == ')') {
      char a, b;
      char op;
      b = st.top();
      st.pop();
      op = st.top();
      st.pop();
      a = st.top();
      st.pop();
      st.pop();

      int aid = a - 'A';
      int bid = b - 'A';
      char res;

      if (op == '<') {
        if (o[aid] < o[bid]) {
          res = a;
        } else {
          res = b;
        }
      } else {
        if (o[aid] < o[bid]) {
          res = b;
        } else {
          res = a;
        }
      }

      st.push(res);
    } else {
      st.push(c);
    }
  }
  return st.top();
}

int main() {
  cin.tie(0)->sync_with_stdio(0);
  int n;

  vector<long long> fac(100);

  fac[0] = 1;
  fac[1] = 1;
  for (lint i = 2; i < 30; i++) {
    fac[i] = fac[i - 1] * i;
  }

  while (1) {
    in(n);
    if (n == 0) break;

    vector<char> cv(26);
    string a;
    in(a);
    sort(all(a));
    char cur = 'A';

    rep(i, a.size()) {
      cv[a[i] - 'A'] = cur;
      cur++;
    }

    string s, t;
    in(s, t);

    rep(i, s.size()) {
      if ('A' <= s[i] and s[i] <= 'Z') {
        s[i] = cv[s[i] - 'A'];
      }
    }
    rep(i, t.size()) {
      if ('A' <= t[i] and t[i] <= 'Z') {
        t[i] = cv[t[i] - 'A'];
      }
    }

    rep(i, a.size()) {
      a[i] = cv[a[i] - 'A'];
    }

    vector<int> ord(n, -2);
    lint ans = 0;
    for (auto c : a) {
      ord[c - 'A'] = 0;
      int cur = c - 'A';
      rep(bit, 1 << n) {
        int cnt_0 = 0, cnt_1 = 0;

        rep(i, n) {
          if (i == cur) {
            continue;
          }
          if (bit & (1 << i)) {
            ord[i] = 1;
            cnt_1++;
          } else {
            ord[i] = -1;
            cnt_0++;
          }
        }
        char res_s = solve(s, ord);
        char res_t = solve(t, ord);
        if (res_s == c and res_t == c) {
          ans += fac[cnt_0] * fac[cnt_1];
        }
      }
    }
    out(ans / 2);
  }
}
accuracy: 1
time_ms: 3800
memory_kb: 3456
final_rank: 18

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

char EVAL(char lf, char op, char rg) {
    if(op == '<') {
        if(lf == '-' || rg == '-') return '-';
        if(lf == '0' || rg == '0') return '0';
        if(lf == '+' || rg == '+') return '+';
    }else {
        if(lf == '+' || rg == '+') return '+';
        if(lf == '0' || rg == '0') return '0';
        if(lf == '-' || rg == '-') return '-';
    }
    return '*';
}

char EXPR(string &S, int &i) {
    if(S[i] == '(') {
        i += 1;
        char lf = EXPR(S, i);
        char op = S[i];
        i += 1;
        char rg = EXPR(S, i);
        i += 1;
        return EVAL(lf, op, rg);
    }else {
        char ret = S[i];
        i += 1;
        return ret;
    }
}

string FORMAT(string S, string A, string X) {
    for(char &c : S) {
        if(isupper(c)) {
            c = X[find(A.begin(), A.end(), c) - A.begin()];
        }
    }
    return S;
}

bool solve() {
    int N;
    cin >> N;
    if(N == 0) return false;
    string A, S, T;
    cin >> A >> S >> T;
    string X(N, '*');
    vector<string> v;
    auto dfs = [&](auto dfs, int i, int j) -> void {
        if(i == N) {
            // cout << X << endl;
            v.push_back(X);
        }else {
            X[i] = '-';
            dfs(dfs, i + 1, j);
            X[i] = '+';
            dfs(dfs, i + 1, j);
            if(j == 0) {
                X[i] = '0';
                dfs(dfs, i + 1, j + 1);
            }
        }
    };
    dfs(dfs, 0, 0);
    long long ans = 0;
    for(string x : v) {
        int i = 0, j = 0;
        string s = FORMAT(S, A, x);
        string t = FORMAT(T, A, x);
        if(EXPR(s, i) == '0' && EXPR(t, j) == '0') {
            long long f = 1;
            int cn = count(x.begin(), x.end(), '-');
            int cp = count(x.begin(), x.end(), '+');
            for(int k = 1; k <= cn; k++) f *= k;
            for(int k = 1; k <= cp; k++) f *= k;
            ans += f;
        }
    }
    cout << ans << endl;
    return true;
}

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

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

struct dat {
    int L, R;
    char C;
};

vector<dat> make_tree(const string &S) {
    vector<dat> T;
    auto rec = [&] (auto rec, int &i) -> int {
        int p = T.size();
        T.push_back({-1, -1, '?'});
        if (S[i] != '(' && S[i] != ')') {
            T[p] = dat{-1, -1, S[i]};
        } else {
            int l = rec(rec, ++i);
            assert(S[i] == '<' || S[i] == '>');
            char c = S[i];
            int r = rec(rec, ++i);
            T[p] = dat{l, r, c};
        }
        i++;
        return p;
    };
    int i = 0;
    rec(rec, i);
    return T;
}

bool solve() {
    int N;
    cin >> N;
    if (N == 0) return false;
    string A, S, T;
    cin >> A >> S >> T;
    vector<long long> fac(N + 1, 1);
    for (int i = 1; i <= N; i++) fac[i] = i * fac[i - 1];
    auto treeS = make_tree(S);
    auto treeT = make_tree(T);
    long long ans = 0;
    vector<int> val(256, 0);
    auto f = [&] (auto f, const vector<dat> &T, int u) -> int {
        char c = T[u].C;
        if (c != '<' && c != '>') return val[c];
        auto l = f(f, T, T[u].L), r = f(f, T, T[u].R);
        return c == '<' ? min(l, r) : max(l, r);
    };
    for (int k = 0; k < N; k++) {
        for (int i = 0; i < 1 << N; i++) {
            int l = 0, r = 0;
            for (int j = 0; j < N; j++) {
                if (j == k) {
                    val[A[j]] = 0;
                } else if (i >> j & 1) {
                    val[A[j]] = -1;
                    l++;
                } else {
                    val[A[j]] = 1;
                    r++;
                }
            }
            if (f(f, treeS, 0) == 0 && f(f, treeT, 0) == 0) {
                ans += fac[l] * fac[r];
            }
        }
    }
    cout << ans / 2 << '\n';
    return true;
}

int main() {
    while (solve()) {}
}
accuracy: 1
time_ms: 1370
memory_kb: 3584
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define rrep(i,start,end) for (ll i = start;i >= (ll)(end);i--)
#define repn(i,end) for(ll i = 0; i <= (ll)(end); i++)
#define reps(i,start,end) for(ll i = start; i < (ll)(end); i++)
#define repsn(i,start,end) for(ll i = start; i <= (ll)(end); i++)
#define each(p,a) for(auto &p:a)
typedef vector<ll> vll;
typedef vector<pair<ll ,ll>> vpll;
typedef vector<vector<ll>> vvll;
typedef set<ll> sll;
typedef map<ll , ll> mpll;
typedef pair<ll ,ll> pll;
typedef tuple<ll , ll , ll> tpl3;
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define Str(...) string __VA_ARGS__; input(__VA_ARGS__)
#define Ch(...) char __VA_ARGS__; input(__VA_ARGS__)
#define all(a)  (a).begin(),(a).end()
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define sz(x) (ll)x.size()
// << std::fixed << std::setprecision(10)
const ll INF = 1LL << 60;
const ld EPS = 1e-9;
 
ll lceil(ll a,ll b){if(a%b==0){return a/b;}if(a>=0){return (a/b)+1;}else{return -((-a)/b);}}
ll lfloor(ll a,ll b){if(a%b==0){return a/b;}if(a>=0){return (a/b);}else{return -((-a)/b)-1;}}
inline ll positive_mod(ll a,ll m){return (a % m + m)%m;}
inline ll popcnt(ull a){ return __builtin_popcountll(a);}
//0indexed
inline ll topbit(ll a){assert(a != 0);return 63 - __builtin_clzll(a);}
inline ll smlbit(ll a){assert(a != 0);return __builtin_ctzll(a);}
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<typename T> std::istream &operator>>(std::istream&is,std::vector<T>&v){for(T &in:v){is>>in;}return is;}
template<typename T> std::ostream &operator<<(std::ostream&os,const std::vector<T>&v){for(auto it=std::begin(v);it!=std::end(v);){os<<*it<<((++it)!=std::end(v)?" ":"");}return os;}
template<typename T1, typename T2>std::ostream &operator<< (std::ostream &os, std::pair<T1,T2> p){os << "{" << p.first << "," << p.second << "}";return os;}
template<class... T>void input(T&... a){(cin >> ... >> a);}
void print(){cout << endl;}
template<class T, class... Ts>void print(const T& a, const Ts&... b){cout << a;((cout << ' ' << b), ...);cout << endl;}
template<class T> void pspace(const T& a){ cout << a << ' ';}
void perr(){cerr << endl;}
template<class T, class... Ts>void perr(const T& a, const Ts&... b){cerr << a;((cerr << ' ' << b), ...);cerr << endl;}
void yes(bool i = true){ return print(i?"yes":"no"); }
void Yes(bool i = true){ return print(i?"Yes":"No"); }
void YES(bool i = true){ return print(i?"YES":"NO"); }
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;}
//grid探索用
vector<ll> _ta = {0,0,1,-1,1,1,-1,-1};
vector<ll> _yo = {1,-1,0,0,1,-1,1,-1};
bool isin(ll now_i,ll now_j,ll h,ll w){return (0<=now_i && now_i < h && 0 <= now_j && now_j < w);}
  
ll lpow(ll x,ll n){ll ans = 1;while(n >0){if(n & 1)ans *= x;x *= x;n >>= 1;}return ans;}
ll Modlpow(ll x,ll n,ll m){ll ans = 1;ll a = x%m;while(n >0){if(n & 1){ans *= a;ans%= m;}a *= a;a %= m;n >>= 1;}return ans;} 
const ll MOD9 = 998244353LL;
const ll MOD10 = 1000000007LL;


typedef string::const_iterator State;

class ParseError {};

ll expression(State &begin);
map<char,ll> cmp;
struct node{
	char ch; // charがいいときもある
	vector<ll> to;
};

vector<node>nodes;

//四則演算の式を構文解析し評価結果を返す。
ll expression(State &begin){
  if(isupper(*begin)){
    ll ret = nodes.size();
    nodes.push_back({*begin,{}});
    begin++;
    return ret;
  }
  // (
  assert(*begin == '(');
  begin++;
  ll before = expression(begin);
  ll ret = sz(nodes);
  nodes.push_back({*begin,{}});
  begin++;
  ll after = expression(begin);

  nodes[ret].to.push_back(before);
  nodes[ret].to.push_back(after);
  nodes[before].to.push_back(ret);
  nodes[after].to.push_back(ret);

  assert(*begin == ')');
  begin++;

  return ret;
}


void solve(ll n){
  Str(s);
  cmp.clear();
  rep(i,n){
    cmp[s[i]] = i;
  }

  auto retable = [&](string &t) -> vvll {
    nodes.clear();
    State begin = t.begin();
    ll root = expression(begin);

    //各文字がトップになるときの
    vector<vector<ll>> able(n);
    rep(z,n){
      vector<vector<ll>> dp(sz(nodes),vll(1<<n));// -1 s[z] より小さいのが上がってきた、0:同じ,1:大きい
      vector<ll> found(sz(nodes),0);//n頂点
      auto dfs = [&](auto dfs, ll v)->void{
        found[v] = 1;
        if(isupper(nodes[v].ch)){
          if(nodes[v].ch == s[z]){
            rep(i,1 << n){
              dp[v][i] = 0;
            }
          }else{
            ll id = cmp[nodes[v].ch];
            rep(i,1 << n){
              if(i >> id &1){
                dp[v][i] = 1;
              }else{
                dp[v][i] = -1;
              }
            }
          }
          return ;
        }
        //gでグラフを受け取っている
        vll vs;
        for(auto &p:nodes[v].to){
          if(found[p] == 0){
            vs.push_back(p);
            dfs(dfs,p);
          }
        }
        //更新
        if(nodes[v].ch == '<'){
          //小さいほうが残る
          rep(i,1 << n){
            dp[v][i] = min(dp[vs[0]][i],dp[vs[1]][i]);
          }
        }else{
          rep(i,1 << n){
            dp[v][i] = max(dp[vs[0]][i],dp[vs[1]][i]);
          }
        }
      };
      dfs(dfs,root);
      rep(i,1 << n){
        if(dp[root][i] == 0){
          able[z].push_back(i);
        }
      }
    }
    return able;
  };
  Str(t);
  vvll ablet = retable(t);

  Str(u);
  vvll ableu_tmp = retable(u);
  //後ろはsetにする
  vector<set<ll>> ableu(n);
  rep(i,n){
    each(p,ableu_tmp[i]){
      ableu[i].insert(p);
    }
  }
  ll ans = 0;
  vll kai(n+1);
  kai[0] = 1;
  repsn(i,1,n){
    kai[i] = kai[i-1]*i;
  }

  rep(i,n){
    each(p,ablet[i]){
      if((p >> i & 1)&&ableu[i].contains(p)){
        //
        ll ucnt = popcnt(p);
        ll dcnt = n - ucnt;
        ucnt--;
        ans += kai[ucnt] * kai[dcnt]; 
      }
    }
  }
  cout << ans << endl;

}


int main(){
  ios::sync_with_stdio(false);cin.tie(nullptr);
  while(true){
    LL(n);
    if(n == 0)break;
    solve(n);
  }
}
accuracy: 1
time_ms: 3110
memory_kb: 31620
final_rank: 19

code_snippet: #include <bits/stdc++.h>
# pragma GCC target("avx2")
# pragma GCC optimize("O3")
# pragma GCC optimize("unroll-loops")
using namespace std;
using ll = long long;
#define rep(i, n) for (ll i=0; i<(n); i++)
template<typename T> bool chmin(T &a, T b) { if (a > b) {a = b; return true;} return false; }
template<typename T> bool chmax(T &a, T b) { if (a < b) {a = b; return true;} return false; }
const ll INFL = (1LL << 61);

int main() {
    vector<ll> fact(17, 1);
    rep(i, 16) fact[i+1] = fact[i] * (i+1);
    while (true) {
        ll n; cin >> n;
        if (n == 0) break;
        string d; cin >> d;
        string s,t; cin >> s >> t;
        // cout << d << " " << s << " " << t << "\n";
        struct node {
            ll val;
            ll l,r;
        };
        vector<ll> pos(26, -1);
        rep(i, n) pos[d[i] - 'A'] = i;
        auto parse_e = [&] (auto self, ll start, const string &s, vector<node> &nodes) -> pair<ll, ll> {
            ll p = nodes.size();
            if ('A' <= s[start] && s[start] <= 'Z') {
                nodes.emplace_back(pos[s[start] - 'A'], -1, -1);
                return {start + 1, p};
            }
            assert(s[start] == '(');
            nodes.emplace_back(0, -1, -1);
            auto [e, pn] = self(self, start + 1, s, nodes);
            nodes[p].l = pn;
            if (s[e] == '<') nodes[p].val = -1;
            else nodes[p].val = -2;
            auto [en, pnn] = self(self, e + 1, s, nodes);
            nodes[p].r = pnn;
            return {en + 1, p};
        };
        vector<node> nodes;
        vector<node> nodet;
        parse_e(parse_e, 0, s, nodes);
        parse_e(parse_e, 0, t, nodet);
        // for (auto node : nodet) {
        //     cout << node.val << " " << node.l << " " << node.r << "\n";
        // }
        // cout << "---\n";
        ll ans = 0;
        rep(i, n) {
            rep(bit, (1LL << n)) {
                // cout << i << " " << bit << "\n";
                if ((bit >> i) & 1) continue;
                auto dfs = [&] (auto self, ll p, const vector<node> &nodes) -> ll {
                    if (nodes[p].l == -1) {
                        ll x = nodes[p].val;
                        if (x == i) return 0;
                        if ((bit >> x) & 1) return -INFL;
                        return INFL;
                    }
                    ll lv = self(self, nodes[p].l, nodes);
                    ll rv = self(self, nodes[p].r, nodes);
                    // cout << "dfs: " << lv << " " << rv << " " << nodes[p].val << "\n";
                    if (nodes[p].val == -1) return min(lv, rv);
                    return max(lv, rv);
                };
                ll sv = dfs(dfs, 0, nodes);
                ll tv = dfs(dfs, 0, nodet);
                if (sv == 0 && tv == 0) {
                    // cout << i << " " << bit << '\n';
                    ll p = __builtin_popcountll(bit);
                    ans += fact[p] * fact[n-1-p];
                }
            }
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 860
memory_kb: 3456
final_rank: 7

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <bitset>
using namespace std;
using ll = long long;
#define rep(i,n) for(ll i=0; i<ll(n); i++)
template<class A, class B> void chmin(A& l, const B& r){ if(r < l) l = r; }

ll solve(int N, string S, string A, string B){
    using Bitset = bitset<65536>;
    vector<Bitset> buf(N);
    rep(i,N) rep(j,1<<N) if(j&(1<<i)) buf[i].set(j);
    auto expr = [&](auto& expr, string &s, ll& p) -> Bitset {
        if(s[p] == '('){
            p++;
            auto fa = expr(expr, s, p);
            char d = s[p++];
            auto fb = expr(expr, s, p);
            p++;
            if(d == '<') return fa & fb; else return fa | fb;
        }
        return buf[S.find(s[p++])];
    };
    auto al_expr = [&](string &s) -> Bitset {
        ll p = 0;
        return expr(expr, s, p);
    };
    auto fA = al_expr(A);
    auto fB = al_expr(B);
    vector<ll> fact(N+1, 1); rep(i,N) fact[i+1] = fact[i] * (i+1);
    ll ans = 0;
    rep(a,N){
        rep(f,1<<N) if(!(f&(1<<a))){
            ll pc = 0; rep(i,N) pc += (f >> i) & 1;
            if(!fA.test(f) && !fB.test(f) && fA.test(f|(1<<a)) && fB.test(f|(1<<a))){
                ans += fact[pc] * fact[N-1-pc];
            }
        }
    }
    return ans;
}

void testcase(){
    ll N; cin >> N; if(N == 0) exit(0);
    string S, A, B; cin >> S >> A >> B;
    ll ans = solve(N, S, A, B);
    cout << ans << "\n";
}

int main(){
    cin.tie(0)->sync_with_stdio(0);
    while(1) testcase();
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 4004
final_rank: 1

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

using ll = long long;
#define rep(i,l,r) for(ll i=l;i<r;i++)
#define all(v) begin(v),end(v)
#define sz(v) ((int)v.size())
void solve(int, string, string, string);
int main(){
    while(1){
        int n;cin >> n;
        
        if(n==0)break;
        string a, s, t;cin >> a >> s >> t;
        solve(n, a, s, t);
    }
}
void solve(int n, string a, string s, string t){
  

  map<char, int> mp;
  rep(i, 0, n) mp[a[i]] = i;
  ll ans = 0;
  vector<ll> fact(n + 1, 1);
  rep(i, 0, n)fact[i+1] = fact[i] * (i + 1);
  rep(x, 0, n) {
    rep(bit, 0, 1 << n) {
      if (bit >> x & 1) continue;
      auto F = [&](string &S, int &i) -> int {
        char X = S[i];
        i++;
        if (mp[X] == x) return 0;
        else if (bit >> mp[X] & 1) return 1;
        else return -1;
      };
    
      auto E = [&](auto self, string &S, int &i) -> int {
        if (S[i] == '(') {
          i++;
          auto l = self(self, S, i);
          char X = S[i];
          i++;
          auto r = self(self, S, i);
          i++;
          if (X == '<') {
            return min(l, r);
          }
          else {
            return max(l, r);
          }
        }
        else {
          return F(S, i);
        }
      };
      int i = 0;
      auto res1 = E(E, s, i);
      // cerr << i << " " ;
      i = 0;

      auto res2 = E(E, t, i);
      // cerr << i << " ";
      int pc = 0;
      // cerr << x << " " << bit << " " << res1 << " " << res2 << endl;

      rep(i, 0, n) if (bit >> i & 1) pc++;
      if (res1 == 0 and res2 == 0) {
        ans += fact[pc] * fact[n-1-pc];
      }
    }
  }
  cout << ans << endl;
}
accuracy: 1
time_ms: 3320
memory_kb: 3456
final_rank: 16

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

using ll = long long;

int parse(const std::string& s, int& pos, int target, int islarge) {
  if (s[pos] == '(') {
    pos++;
    int l = parse(s, pos, target, islarge);
    char op = s[pos++];
    int r = parse(s, pos, target, islarge);
    assert(s[pos++] == ')');
    if (op == '<') {
      return std::min(l, r);
    } else {
      return std::max(l, r);
    }
  } else {
    assert(isalpha(s[pos]));
    int n = s[pos++] - 'A';
    if (n == target) {
      return 0;
    } else {
      return ((1 << n) & islarge) ? 1 : -1;
    }
  }
}

ll factorial(int n) {
  if (n <= 1) return 1;

  ll ans = 1;

  for (int i = 2; i <= n; i++) {
    ans *= i;
  }

  return ans;
}

bool solve() {
  int N;
  std::cin >> N;

  if (N == 0) {
    return false;
  }

  std::string A, S, T;
  std::cin >> A >> S >> T;

  // std::vector<char> A(A2.begin(), A2.end());

  std::sort(A.begin(), A.end());

  for (char& c : S) {
    if (isalpha(c)) {
      c = 'A' + (std::lower_bound(A.begin(), A.end(), c) - A.begin());
    }
  }

  for (char& c : T) {
    if (isalpha(c)) {
      c = 'A' + (std::lower_bound(A.begin(), A.end(), c) - A.begin());
    }
  }

  ll ans = 0;

  // std::cerr << A << '\n';

  for (int i = 0; i < N; i++) {
    int mask = (1 << N) - 1 - (1 << i);
    for (int p = 0; p < (1 << N); p += 1 + (1 << i)) {
      p &= mask;
      int pos = 0;
      int x = parse(S, pos, i, p);
      pos = 0;
      int y = parse(T, pos, i, p);
      if (x == 0 && y == 0) {
        int a = __builtin_popcount(p);
        int b = N - a - 1;
        ans += factorial(a) * factorial(b);

        // std::cerr << A[i] << " " << std::bitset<16>(p) << " " << a << " " <<
        // b << '\n';
      }
    }
  }

  std::cout << ans << '\n';

  return true;
}

int main() {
  while (solve());
}
accuracy: 1
time_ms: 2040
memory_kb: 3584
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (ll i = s; i < (ll)(t); i++)
#define rrep(i, s, t) for(ll i = (ll)(t) - 1; i >= (ll)(s); i--)
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)

#define TT template<typename T>
TT using vec = vector<T>;
template<class T1, class T2> bool chmin(T1 &x, T2 y) { return x > y ? (x = y, true) : false; }
template<class T1, class T2> bool chmax(T1 &x, T2 y) { return x < y ? (x = y, true) : false; }

struct io_setup {
    io_setup() {
        ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        cout << fixed << setprecision(15);
    }
} io_setup;

using sitr = string::iterator;
vector<int> v(20,0);
vector<int> rc(26,-1);
int F(sitr &itr){
    return v[rc[*(itr++)-'A']];
}
int E(sitr &itr){
    if(*itr=='('){
        itr++;
        int l=E(itr);
        char c=*itr;
        assert(c=='<'||c=='>');
        itr++;
        int r=E(itr);
        assert(*itr==')');
        itr++;
        if(c=='<') return max(l,r);
        else return min(l,r);
    }else{
        return F(itr);
    }
    assert(0);
}

int Solve(){
    int n;
    cin>>n;
    if(n==0) return 0;
    string a,s,t;
    cin>>a>>s>>t;
    rep(i,0,n) rc[a[i]-'A']=i;

    ll ans=0;
    vector<ll> fac(20,1);
    rep(i,1,20) fac[i]=fac[i-1]*i;
    for(int st=0;st<n;st++){
        rep(bit,0,1<<(n-1)){
            rep(i,0,st){
                if((bit>>i)&1) v[i]=1;
                else v[i]=-1;
            }
            v[st]=0;
            rep(i,st+1,n){
                if((bit>>(i-1))&1) v[i]=1;
                else v[i]=-1;
            }
            {
                auto itr=s.begin();
                int l=E(itr);
                if(l!=0) continue;
            }
            {
                auto itr=t.begin();
                int r=E(itr);
                if(r!=0) continue;
            }
            int ct=__builtin_popcount(bit);
            ans+=fac[ct]*fac[n-1-ct];
        }
    }
    cout<<ans<<"\n";
    return 1;
}

int main(){
    while(Solve());
}
accuracy: 1
time_ms: 910
memory_kb: 3456
final_rank: 8

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

namespace noya2 {

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p){
    os << p.first << " " << p.second;
    return os;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p){
    is >> p.first >> p.second;
    return is;
}

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

void in() {}
template <typename T, class... U>
void in(T &t, U &...u){
    cin >> t;
    in(u...);
}

void out() { cout << "\n"; }
template <typename T, class... U, char sep = ' '>
void out(const T &t, const U &...u){
    cout << t;
    if (sizeof...(u)) cout << sep;
    out(u...);
}

template<typename T>
void out(const vector<vector<T>> &vv){
    int s = (int)vv.size();
    for (int i = 0; i < s; i++) out(vv[i]);
}

struct IoSetup {
    IoSetup(){
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(15);
        cerr << fixed << setprecision(7);
    }
} iosetup_noya2;

const int iinf = 1'000'000'007;
const long long linf = 2'000'000'000'000'000'000LL;
const long long mod998 =  998244353;
const long long mod107 = 1000000007;
const long double pi = 3.14159265358979323;
const vector<int> dx = {0,1,0,-1,1,1,-1,-1};
const vector<int> dy = {1,0,-1,0,1,-1,-1,1};
const string ALP = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string alp = "abcdefghijklmnopqrstuvwxyz";
const string NUM = "0123456789";

void yes(){ cout << "Yes\n"; }
void no(){ cout << "No\n"; }
void YES(){ cout << "YES\n"; }
void NO(){ cout << "NO\n"; }
void yn(bool t){ t ? yes() : no(); }
void YN(bool t){ t ? YES() : NO(); }


unsigned long long inner_binary_gcd(unsigned long long a, unsigned long long b){
    if (a == 0 || b == 0) return a + b;
    int n = __builtin_ctzll(a); a >>= n;
    int m = __builtin_ctzll(b); b >>= m;
    while (a != b) {
        int mm = __builtin_ctzll(a - b);
        bool f = a > b;
        unsigned long long c = f ? a : b;
        b = f ? b : a;
        a = (c - b) >> mm;
    }
    return a << min(n, m);
}

template<typename T> T gcd_fast(T a, T b){ return static_cast<T>(inner_binary_gcd(abs(a),abs(b))); }

long long sqrt_fast(long long n) {
    if (n <= 0) return 0;
    long long x = sqrt(n);
    while ((x + 1) * (x + 1) <= n) x++;
    while (x * x > n) x--;
    return x;
}

template<typename T> T floor_div(const T n, const T d) {
    assert(d != 0);
    return n / d - static_cast<T>((n ^ d) < 0 && n % d != 0);
}

template<typename T> T ceil_div(const T n, const T d) {
    assert(d != 0);
    return n / d + static_cast<T>((n ^ d) >= 0 && n % d != 0);
}

template<typename T> void uniq(vector<T> &v){
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
}

template <typename T, typename U> inline bool chmin(T &x, U y) { return (y < x) ? (x = y, true) : false; }

template <typename T, typename U> inline bool chmax(T &x, U y) { return (x < y) ? (x = y, true) : false; }

template<typename T> inline bool range(T l, T x, T r){ return l <= x && x < r; }

} // namespace noya2

#define rep(i,n) for (int i = 0; i < (int)(n); i++)
#define repp(i,m,n) for (int i = (m); i < (int)(n); i++)
#define reb(i,n) for (int i = (int)(n-1); i >= 0; i--)
#define all(v) (v).begin(),(v).end()

using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull = unsigned long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using pil = pair<int,ll>;
using pli = pair<ll,int>;

namespace noya2{

/*　~ (. _________ . /)　*/

}

using namespace noya2;

string r;
int itr;

int dfs(){
    assert(itr < ssize(r));
    if (r[itr] != '('){
        int ret = r[itr] - '0';
        itr++;
        return ret;
    }
    assert(r[itr] == '(');
    itr++;
    int lhs = dfs();
    char op = r[itr];
    itr++;
    int rhs = dfs();
    assert(itr < ssize(r));
    assert(r[itr] == ')');
    itr++;
    if (op == '<'){
        return min(lhs,rhs);
    }
    else {
        return max(lhs,rhs);
    }
}

int parse(string s){
    itr = 0;
    r = s;
    int ret = dfs();
    assert(itr == ssize(r));
    return ret;
}

void solve(int n){
    string a; in(a);
    string s, t; in(s,t);
    vector<bool> ok(1<<n);
    vector<char> w(26);
    rep(sub,1<<n){
        rep(i,n){
            w[a[i]-'A'] = NUM[sub >> i & 1];
        }
        string ns = "";
        for (auto c : s){
            if ('A' <= c && c <= 'Z'){
                ns += w[c - 'A'];
            }
            else {
                ns += c;
            }
        }
        string nt = "";
        for (auto c : t){
            if ('A' <= c && c <= 'Z'){
                nt += w[c - 'A'];
            }
            else {
                nt += c;
            }
        }
        ok[sub] = (parse(ns) == parse(nt));
    }
    assert(ok[0]);
    vector<ll> dp(1<<n);
    dp[0] = 1;
    repp(sub,1,1<<n){
        if (!ok[sub]) continue;
        rep(i,n){
            if (sub >> i & 1){
                dp[sub] += dp[sub^(1<<i)];
            }
        }
    }
    // out(ok);
    // out(dp);
    out(dp.back());
}

int main(){
    while (true){
        int n; in(n);
        if (n == 0) break;
        solve(n);
    }
}
accuracy: 1
time_ms: 590
memory_kb: 4204
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;
#define rep(i,a,b) for (int i=(int)(a);i<(int)(b);i++)
#define all(p) p.begin(),p.end()

void solve(int N){
    string S;
    cin >> S;
    const int M = 26;
    vector<int> ind(M, -1);
    rep(i, 0, N) ind[S[i] - 'A'] = i;
    vector dp(2, vector<int>(1 << N));
    using F = bitset<1 << 16>;
    rep(rp, 0, 2){
        string X;
        cin >> X;
        int pos = 0;
        auto f = [&](auto self) -> F {
            if (X[pos] != '('){
                F base;
                rep(i, 0, 1 << N){
                    if (i & (1 << ind[X[pos] - 'A'])) base[i] = true;
                }
                pos++;
                return base;
            }
            pos++;
            auto L = self(self);
            auto a = X[pos++];
            auto R = self(self);
            pos++;
            if (a == '<'){
                L = (L & R);
            }
            else{
                L = (L | R);
            }
            return L;
        };
        auto tmp = f(f);
        rep(i, 0, 1 << N) dp[rp][i] = tmp[i];
    }
    vector<ll> fact(N + 1, 1);
    rep(i, 0, N) fact[i + 1] = fact[i] * (i + 1);
    ll ans = 0;
    rep(i, 0, 1 << N){
        int a = 0;
        rep(j, 0, N) if (i & (1 << j)) a++;
        a--;
        rep(j, 0, N) if (i & (1 << j)){
            if (dp[0][i] & dp[1][i] & !dp[0][i - (1 << j)] & !dp[1][i - (1 << j)]){
                ans += fact[a] * fact[N - 1 - a];
            }
        }
    }
    cout << ans << "\n";
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N;
    while (cin >> N, N) solve(N);
}
accuracy: 1
time_ms: 80
memory_kb: 4420
final_rank: 2

code_snippet: #include <iostream>
#include <vector>

using namespace std;

using ll = long long;

class IcpcanAlphabet {
public:
    explicit IcpcanAlphabet(const int max_n) : fact(max_n + 1), cmp(26) {
        fact[0] = 1;
        for (int i = 1; i <= max_n; ++i) fact[i] = i * fact[i - 1];
    }

    ll GetNumTotalOrderEqualExp(const std::string &A, const std::string &S, const std::string &T) {
        const int N = A.size();
        ll num = 0;
        for (int i = 0; i < N; ++i) { // S と T の値が A_i となる全順序の数を求める
            cmp[index(A[i])] = 0;

            const unsigned int univ = ((1 << N) - 1) ^ (1 << i); // univ = {0, 1, ..., N - 1} / {i}
            unsigned int sub = univ;
            while (true) { // univ の部分集合を全列挙する：部分集合 sub := {x \in univ | x < i} とする
                int num_less = 0;
                for (int j = 0; j < N; ++j) {
                    if (sub >> j & 1) {
                        ++num_less;
                        cmp[index(A[j])] = -1;
                    }
                    else if (i != j) {
                        cmp[index(A[j])] = 1;
                    }
                }

                auto it_s = S.begin(), it_t = T.begin();
                if (Evaluate(it_s) == 0 && Evaluate(it_t) == 0)
                    num += fact[num_less] * fact[N - num_less - 1];

                if (sub == 0)  break; // 部分集合が空の場合も計算できるように
                sub = (sub - 1) & univ;
            }
        }

        return num;
    }

private:
    std::vector<ll> fact;
    // 固定された a \in A に対して a' \in A の cmp の値を a との大小関係で定める
    // a == a' なら cmp[index(a')] = 0
    // a < a'   なら cmp[index(a')] = 1
    // a > a'   なら cmp[index(a')] = -1
    std::vector<int> cmp;

    unsigned index(const char c) const { return static_cast<unsigned>(c - 'A'); }

    int Evaluate(std::string::const_iterator& it) {
        // E ::= F | '(' E '<' E ')' | '(' E '>' E ')'
        if (*it == '(') {
            int lhs = Evaluate(++it);
            char op = *it;
            int rhs = Evaluate(++it);
            ++it; // skip ')'
            return (op == '<') ? std::min(lhs, rhs) : std::max(lhs, rhs);
        }
        else {
            return cmp[index(*it++)];
        }
    }
};

int main() {
    const int MAX_N = 16;
    IcpcanAlphabet solver(MAX_N);

    int n;
    while (std::cin >> n, n) {
        std::string a, s, t;
        std::cin >> a >> s >> t;
        std::cout << solver.GetNumTotalOrderEqualExp(a, s, t) << std::endl;
    }

    return 0;
}
accuracy: 1
time_ms: 640
memory_kb: 3584
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define ALL(v) (v).begin(), (v).end()
using ll = long long;

ll fac[20];

void solve(int N, string &A, string &S, string &T) {
    map<char,int> idx;
    for (int i = 0; i < N; i++) idx[A[i]] = i;
    vector<pair<int,int>> B[2];
    B[0].resize((int)S.size(), make_pair(-1, -1));
    B[1].resize((int)T.size(), make_pair(-1, -1));
    auto make_block = [&](int t) {
        auto X = (t == 0 ? S : T);
        stack<pair<int,int>> st;
        for (int i = 0; i < (int)X.size(); i++) {
            if ('A' <= X[i] && X[i] <= 'Z') {
                B[t][i] = make_pair(i, i);
                continue;
            }
            if (X[i] == ')') {
                int m = st.top().second; st.pop();
                int l = st.top().second; st.pop();
                assert(X[l] == '(' && (X[m] == '<' || X[m] == '>'));
                B[t][l] = make_pair(m, i);
            }
            else {
                st.emplace(X[i], i);
            }
        }
    };
    make_block(0);
    make_block(1);
    ll ans = 0;
    for (auto c : A) {
        for (int bit = 0; bit < (1 << N); bit++) {
            if ((bit >> idx[c]) & 1) continue;
            int pcnt = __builtin_popcount(bit);
            auto calc = [&](int t) {
                auto X = (t == 0 ? S : T);
                auto comp = [&](auto &comp, int l, int m, int r) {
                    if (l == m && m == r) {
                        return (X[l] == c) ? 0 : (((bit >> idx[X[l]]) & 1) ? 1 : -1);
                    }
                    int lhs = comp(comp, l+1, B[t][l+1].first, B[t][l+1].second);
                    int rhs = comp(comp, m+1, B[t][m+1].first, B[t][m+1].second);
                    return (X[m] == '>' ? max(lhs, rhs) : min(lhs, rhs));
                };
                return (comp(comp, 0, B[t][0].first, B[t][0].second) == 0);
            };
            if (calc(0) && calc(1)) {
                ans += fac[pcnt] * fac[N-1-pcnt];
            }
        }
    }
    cout << ans << "\n";
    return;
}

int main() {
    fac[0] = 1;
    for (int i = 1; i < 20; i++) fac[i] = fac[i-1] * i;
    while (true) {
        int N; cin >> N;
        if (N == 0) break;
        string A, S, T;
        cin >> A >> S >> T;
        solve(N, A, S, T);
    }
}
accuracy: 1
time_ms: 1470
memory_kb: 3584
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#ifdef _DEBUG
#define show(x)          \
	cerr << #x << " : "; \
	showVal(x)
template <typename T>
void showVal(const T &a) {
	cerr << a << endl;
}
template <typename T, typename U>
void showVal(const pair<T, U> &a) {
	cerr << a.first << " " << a.second << endl;
}
template <typename T>
void showVal(const vector<T> &a) {
	for (const T &v : a) cerr << v << " ";
	cerr << endl;
}
template <typename T, typename U>
void showVal(const vector<pair<T, U>> &a) {
	cerr << endl;
	for (const pair<T, U> &v : a) cerr << v.first << " " << v.second << endl;
}
template <typename T, typename U>
void showVal(const map<T, U> &a) {
	cerr << endl;
	for (const auto &v : a) cerr << "[" << v.first << "] " << v.second << endl;
}
template <typename T>
void showVal(const vector<vector<T>> &a) {
	cerr << endl;
	for (const vector<T> &v : a) showVal(v);
}
#else
#define show(x)
#endif
int main() {
	vector<ll> fact(17);
	fact[0] = fact[1] = 1;
	for (int i = 1; i < 16; i++) {
		fact[i + 1] = fact[i] * (i + 1);
	}
	while (1) {
		int n;
		cin >> n;
		if (n == 0) break;
		string c;
		string s, t;
		cin >> c >> s >> t;
		unordered_map<char, int> toi;
		for (int i = 0; i < n; i++) {
			toi[c[i]] = i;
		}
		ll ans = 0;

		vector<map<pair<int, int>, int>> tmpmidi(2);

		for (int v = 0; v < 2; v++) {
			stack<pair<int, int>> st;
			int sz = s.size();
			for (int i = 0; i < sz; i++) {
				if (s[i] == '(') {
					st.push({i, 0});
				} else if (s[i] == ')') {
					auto [l, m] = st.top();
					st.pop();
					tmpmidi[v][{l, i}] = m;
				} else if (s[i] == '<' || s[i] == '>') {
					st.top().second = i;
				}
			}
			swap(s, t);
		}

		for (int x = 0; x < n; x++) {
			// show(x);
			// x fixed
			for (int bit = 0; bit < (1 << (n - 1)); bit++) {
				vector<int> mg(n, 1);
				// 0 : < x, 1: = x,  2 : > x
				{
					int cur = 0;
					for (int i = 0; i < n; i++) {
						if (i == x) continue;
						mg[i] = ((bit >> cur) & 1) * 2;
						cur++;
					}
				}
				// show(mg);

				auto cmp = [&](int lhs, int rhs, char op) -> int {
					// show(op);
					if (op == '<') {
						return min(lhs, rhs);
					} else if (op == '>') {
						return max(lhs, rhs);
					} else {
						assert(false);
						return -1;
					}
				};

				vector<int> vals;

				for (int v = 0; v < 2; v++) {
					int sz = s.size();
					// for (auto [p, m] : midi) {
					// 	show(p);
					// 	show(m);
					// }
					auto val = [&](auto self, int l, int r) -> int {
						// value of [l,r)
						if (l + 1 == r) {
							return mg[toi[s[l]]];
						}
						int m = tmpmidi[v][{l, r - 1}];
						// show(m);
						int lhs = self(self, l + 1, m);
						int rhs = self(self, m + 1, r - 1);
						// show(m);
						// show(s[m]);
						return cmp(lhs, rhs, s[m]);
					};
					// show(val(val, 2, 3));
					// show(val(val, 1, 6));
					vals.push_back(val(val, 0, sz));
					swap(s, t);
				}
				if (vals == vector<int>{1, 1}) {
					vector<int> cnt(3);
					for (int i = 0; i < n; i++) {
						cnt[mg[i]]++;
					}
					ans += fact[cnt[0]] * fact[cnt[2]];
				}
			}
		}
		cout << ans << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 3500
memory_kb: 3456
final_rank: 17

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

using namespace std;
using ll = long long;

bool solve() {
    int n; cin >> n;
    if(n == 0) return false;
    string a; cin >> a;
    string s, t; cin >> s >> t;
    auto get_closing = [](const string& s) {
        int l =ssize(s);
        vector<pair<int, int>> ret(l);
        stack<int> stk;
        for(int i = 0; i < l; i++) {
            if(s[i] == '(') stk.push(i);
            else if(s[i] == '<' || s[i] == '>') ret[stk.top()].first = i;
            else if(s[i] == ')') {
                ret[stk.top()].second = i;
                stk.pop();
            }
        }
        return ret;
    };
    auto process = [&](auto&& self, const string& s, const vector<pair<int, int>>& closing, const vector<int>& order, int l, int r) -> int {
        if(s[l] != '(') {
            assert(l+1 == r);
            int f = ranges::find(a, s[l]) - a.begin();
            return order[f];
        }
        int x = self(self, s, closing, order, l+1, closing[l].first);
        int y = self(self, s, closing, order, closing[l].first+1, closing[l].second);
        if(s[closing[l].first] == '<') return min(x, y);
        if(s[closing[l].first] == '>') return max(x, y);
        assert(0);
    };
    vector<ll> factorial(n+1);
    factorial[0] = 1;
    for(int i = 1; i <= n; i++) factorial[i] = factorial[i-1] * i;
    ll ans = 0;
    auto closing_s = get_closing(s);
    auto closing_t = get_closing(t);
    for(int ret = 0; ret < n; ret++) {
        for(int st = 0; st < 1<<n; st++) {
            if(st >> ret & 1) continue;
            vector<int> order(n);
            for(int i = 0; i < n; i++) {
                if(i == ret) continue;
                if(st >> i & 1) order[i] = 1;
                else order[i] = -1;
            }
            if(process(process, s, closing_s, order, 0, ssize(s)) != 0) continue;
            if(process(process, t, closing_t, order, 0, ssize(t)) != 0) continue;
            ans += factorial[ranges::count(order, 1)] * factorial[ranges::count(order, -1)];
        }
    }
    cout << ans << '\n';
    return true;
}

int main() {
    while(solve());
}
accuracy: 1
time_ms: 940
memory_kb: 3584
final_rank: 9

code_snippet: // AOJ #1643 Icpcan Alphabet
// // 2025.5.1

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

string Cins() {
    static char temp[105];
    char *s = temp;
    do *s = gc();
    while (*s++ > ' ');
    *(s-1) = 0;
    string input(temp);
    return input;
}

void Cout(ll n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

const int MAXN = 16;
const int MAXM = MAXN - 1;
const int MAXJ = 1 << MAXM;

vector<ll> fact;

struct Node {
    char op;
    int c[2], p, let;
    ull mask;
    Node():op(0),p(-1),let(-1),mask(0){ c[0]=c[1]=-1; }
};

int parseExpr(const string &s, int &pos, vector<Node> &t, const vector<int> &id){
    if (s[pos]=='(') {
        pos++;
        int L = parseExpr(s,pos,t,id);
        char op = s[pos++];
        int R = parseExpr(s,pos,t,id);
        pos++;
        int u = t.size();
        t.emplace_back();
        t[u].op = op;
        t[u].c[0] = L; t[u].c[1] = R;
        t[L].p = u; t[R].p = u;
        return u;
    } else {
        int idx = id[s[pos++]-'A'];
        int u = t.size();
        t.emplace_back();
        t[u].op = 'L';
        t[u].let = idx;
        t[u].mask = 1ull<<idx;
        return u;
    }
}

void build_mask(vector<Node> &t, int u){
    if (t[u].op == 'L') return;
    build_mask(t,t[u].c[0]);
    build_mask(t,t[u].c[1]);
    t[u].mask = t[t[u].c[0]].mask | t[t[u].c[1]].mask;
}

int main(){
    fact.resize(MAXN+1);
    fact[0]=1;
    for(int i=1;i<=MAXN;i++) fact[i]=fact[i-1]*i;

    while(true){
        int n = Cin();
        if(n == 0) break;
        string s = Cins(), S = Cins(), T = Cins();
        vector<int> id(26,-1);
        for(int i=0;i<n;i++) id[s[i]-'A'] = i;

        vector<Node> a, b;
        int p1 = 0, p2 = 0;
        int r1 = parseExpr(S,p1,a,id);
        int r2 = parseExpr(T,p2,b,id);
        build_mask(a, r1);
        build_mask(b, r2);

        ull Um = a[r1].mask | b[r2].mask;
        vector<int> U;
        for(int i=0;i<n;i++) if(Um>>i & 1) U.push_back(i);
        int Usz = U.size();

        ull globalF = fact[n] / fact[Usz];
        ull total = 0;

        static bitset<MAXJ> pat[MAXM];
        static bitset<MAXJ> LSs[256], EqS[256], GTs[256];
        static bitset<MAXJ> LSt[256], EqT[256], GTt[256];
        static ll w[MAXN+1];
        bitset<MAXJ> dom;

        for(int c: U){
            bool inS=false, inT=false;
            for(auto &nd:a) if(nd.op=='L' && nd.let==c){ inS=true; break; }
            for(auto &nd:b) if(nd.op=='L' && nd.let==c){ inT=true; break; }
            if(!inS||!inT) continue;

            vector<int> U2; U2.reserve(Usz-1);
            for(int y:U) if(y!=c) U2.push_back(y);
            int m = Usz-1, D = 1<<m;
            int id2[MAXN]; fill(begin(id2), end(id2), -1);
            for(int i2=0;i2<m;i2++) id2[U2[i2]] = i2;

            dom.reset();
            for(int j=0;j<D;j++) dom.set(j);

            for(int pos=0;pos<m;pos++){
                pat[pos].reset();
                int step = 1<<(pos+1), half = 1<<pos;
                for(int j0=half;j0<D;j0+=step){
                    int ed = min(j0+half,D);
                    for(int k=j0;k<ed;k++) pat[pos].set(k);
                }
            }

            int sa = a.size();
            for(int i=0;i<sa;i++){
                LSs[i].reset(); EqS[i].reset(); GTs[i].reset();
                if(a[i].op=='L'){
                    if(a[i].let==c) EqS[i]=dom;
                    else {
                        GTs[i]=pat[id2[a[i].let]];
                        LSs[i]=dom ^ GTs[i];
                    }
                } else {
                    int l=a[i].c[0], r=a[i].c[1];
                    if(a[i].op=='<'){
                        LSs[i]=LSs[l]|LSs[r];
                        GTs[i]=GTs[l]&GTs[r];
                        EqS[i]=(EqS[l]&(EqS[r]|GTs[r]))|(EqS[r]&(EqS[l]|GTs[l]));
                    } else {
                        GTs[i]=GTs[l]|GTs[r];
                        LSs[i]=LSs[l]&LSs[r];
                        EqS[i]=(EqS[l]&~GTs[r])|(EqS[r]&~GTs[l]);
                    }
                }
            }

            int sb = b.size();
            for(int i=0;i<sb;i++){
                LSt[i].reset(); EqT[i].reset(); GTt[i].reset();
                if(b[i].op=='L'){
                    if(b[i].let==c) EqT[i]=dom;
                    else {
                        GTt[i]=pat[id2[b[i].let]];
                        LSt[i]=dom ^ GTt[i];
                    }
                } else {
                    int l=b[i].c[0], r=b[i].c[1];
                    if(b[i].op=='<'){
                        LSt[i]=LSt[l]|LSt[r];
                        GTt[i]=GTt[l]&GTt[r];
                        EqT[i]=(EqT[l]&(EqT[r]|GTt[r]))|(EqT[r]&(EqT[l]|GTt[l]));
                    } else {
                        GTt[i]=GTt[l]|GTt[r];
                        LSt[i]=LSt[l]&LSt[r];
                        EqT[i]=(EqT[l]&~GTt[r])|(EqT[r]&~GTt[l]);
                    }
                }
            }

            for(int k=0;k<=m;k++) w[k] = fact[k]*fact[m-k];

            ull sum_c = 0;
            for(int j=0;j<D;j++){
                if(EqS[r1].test(j) && EqT[r2].test(j))
                    sum_c += w[__builtin_popcount((unsigned)j)];
            }
            total += sum_c;
        }
        Cout(total * globalF);
    }
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 8036
final_rank: 4

code_snippet: // AOJ #1643 Icpcan Alphabet
// // 2025.5.1

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

string Cins() {
    static char temp[105];
    char *s = temp;
    do *s = gc();
    while (*s++ > ' ');
    *(s-1) = 0;
    string input(temp);
    return input;
}

void Cout(ll n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

constexpr int MAXN = 16;
constexpr int MAXM = MAXN - 1;
constexpr int MAXJ = 1 << MAXM;

vector<ll> fact;

struct Node {
    char op;
    int c[2], p;
    int let;
    ull mask;
    Node():op(0),p(-1),let(-1),mask(0){ c[0]=c[1]=-1; }
};

int parseExpr(const string &s, int &pos, vector<Node> &t, const vector<int> &id){
    if(s[pos]=='('){
        pos++;
        int L = parseExpr(s,pos,t,id);
        char op = s[pos++];
        int R = parseExpr(s,pos,t,id);
        pos++;
        int u = t.size();
        t.emplace_back();
        t[u].op = op;
        t[u].c[0] = L; t[u].c[1] = R;
        t[L].p = u; t[R].p = u;
        return u;
    } else {
        int idx = id[s[pos++]-'A'];
        int u = t.size();
        t.emplace_back();
        t[u].op = 'L';
        t[u].let = idx;
        t[u].mask = 1ull<<idx;
        return u;
    }
}

void build_mask(vector<Node> &t, int u){
    if(t[u].op != 'L'){
        build_mask(t, t[u].c[0]);
        build_mask(t, t[u].c[1]);
        t[u].mask = t[t[u].c[0]].mask | t[t[u].c[1]].mask;
    }
}

int main(){
    fact.resize(MAXN+1);
    fact[0] = 1;
    for(int i=1;i<=MAXN;i++) fact[i] = fact[i-1]*i;

    while(true){
        int n = Cin();
        if(n == 0) break;
        string chs = Cins(), S = Cins(), T = Cins();
        vector<int> id(26, -1);
        for(int i=0;i<n;i++) id[chs[i]-'A'] = i;

        vector<Node> a, b;
        int p1=0, p2=0;
        int r1 = parseExpr(S, p1, a, id);
        int r2 = parseExpr(T, p2, b, id);
        build_mask(a, r1);
        build_mask(b, r2);

        ull Um = a[r1].mask | b[r2].mask;
        vector<int> U;
        for(int i=0;i<n;i++) if(Um>>i & 1) U.push_back(i);
        int Usz = U.size();

        ll globalF = fact[n] / fact[Usz];
        __int128 total = 0;
        static bitset<MAXJ> LSs[256], EqS[256], GTs[256];
        static bitset<MAXJ> LSt[256], EqT[256], GTt[256];
        static bitset<MAXJ> pat[MAXM];
        bitset<MAXJ> dom;

        for(int c: U){
            bool inS=false, inT=false;
            for(auto &nd: a) if(nd.op=='L' && nd.let==c){ inS=true; break; }
            for(auto &nd: b) if(nd.op=='L' && nd.let==c){ inT=true; break; }
            if(!inS || !inT) continue;

            vector<int> U2; U2.reserve(Usz-1);
            for(int y: U) if(y!=c) U2.push_back(y);
            int m = Usz - 1;
            array<int,MAXN> id2;
            id2.fill(-1);
            for(int i2=0;i2<m;i2++) id2[U2[i2]] = i2;

            int D = 1<<m;
            dom.reset();
            for(int j=0;j<D;j++) dom.set(j);

            for(int pos=0;pos<m;pos++){
                pat[pos].reset();
                int step = 1<<(pos+1);
                int half = 1<<pos;
                for(int j0=half;j0<D;j0+=step){
                    int end = min(j0+half, D);
                    for(int k=j0;k<end;k++) pat[pos].set(k);
                }
            }

            int szA = a.size();
            for(int i=0;i<szA;i++){
                LSs[i].reset();
                EqS[i].reset();
                GTs[i].reset();
                if(a[i].op=='L'){
                    int y = a[i].let;
                    if(y == c) EqS[i] = dom;
                    else {
                        auto &g = GTs[i];
                        g = pat[ id2[y] ];
                        LSs[i] = dom ^ g;
                    }
                } else {
                    int l = a[i].c[0], r = a[i].c[1];
                    if(a[i].op=='<'){
                        LSs[i] = LSs[l] | LSs[r];
                        GTs[i] = GTs[l] & GTs[r];
                        EqS[i] = (EqS[l] & (EqS[r] | GTs[r])) | (EqS[r] & (EqS[l] | GTs[l]));
                    } else {
                        GTs[i] = GTs[l] | GTs[r];
                        LSs[i] = LSs[l] & LSs[r];
                        EqS[i] = (EqS[l] & ~GTs[r]) | (EqS[r] & ~GTs[l]);
                    }
                }
            }

            int szB = b.size();
            for(int i=0;i<szB;i++){
                LSt[i].reset();
                EqT[i].reset();
                GTt[i].reset();
                if(b[i].op=='L'){
                    int y = b[i].let;
                    if(y == c) EqT[i] = dom;
                    else {
                        auto &g = GTt[i];
                        g = pat[ id2[y] ];
                        LSt[i] = dom ^ g;
                    }
                } else {
                    int l = b[i].c[0], r = b[i].c[1];
                    if(b[i].op=='<'){
                        LSt[i] = LSt[l] | LSt[r];
                        GTt[i] = GTt[l] & GTt[r];
                        EqT[i] = (EqT[l] & (EqT[r] | GTt[r])) | (EqT[r] & (EqT[l] | GTt[l]));
                    } else {
                        GTt[i] = GTt[l] | GTt[r];
                        LSt[i] = LSt[l] & LSt[r];
                        EqT[i] = (EqT[l] & ~GTt[r]) | (EqT[r] & ~GTt[l]);
                    }
                }
            }

            static ll w[MAXN+1];
            for(int k=0;k<=m;k++) w[k] = fact[k] * fact[m-k];

            ll sum_c = 0;
            for(int j=0;j<D;j++){
                if(EqS[r1].test(j) && EqT[r2].test(j)){
                    sum_c += w[__builtin_popcount((unsigned)j)];
                }
            }
            total += sum_c;
        }
        ll ans = (ll)(total * globalF);
        Cout(ans);
    }
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 7964
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

char eval(string &s) {
    if((int)s.size() == 1) return s[0];
    auto dfs = [&](auto dfs, int i) -> pair<char, int> {
        char a;
        if(s[i + 1] == '(') {
            auto [c, j] = dfs(dfs, i + 1);
            a = c;
            i = j + 1;
        } else {
            a = s[i + 1];
            i += 2;
        }
        char x = s[i];
        char b;
        if(s[i + 1] == '(') {
            auto [c, j] = dfs(dfs, i + 1);
            b = c;
            i = j + 1;
        } else {
            b = s[i + 1];
            i += 2;
        }
        if(x == '>') return {max(a, b), i};
        return {min(a, b), i};
    };
    return dfs(dfs, 0).first;
}

int mp[256];
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    vector<ll> fac(17, 1);
    for(ll i = 2; i <= 16; i ++) fac[i] = fac[i - 1] * i;
    int n; cin >> n;
    while(n) {
        string cs; cin >> cs;
        string S, T;
        cin >> S >> T;
        ll ans = 0;
        rep(i, n) {
            int cnt = 0;
            rep(j, n) if(i != j) {
                mp[cs[j]] = cnt ++;
            }
            rep(bit, 1 << cnt) {
                string s = "", t = "";
                foa(e, S) {
                    if('A' <= e and e <= 'Z') {
                        if(e == cs[i]) s += '1'; 
                        else if(bit >> mp[e] & 1) s += '0';
                        else s += '2';
                    } else s += e;
                }
                foa(e, T) {
                    if('A' <= e and e <= 'Z') {
                        if(e == cs[i]) t += '1'; 
                        else if(bit >> mp[e] & 1) t += '0';
                        else t += '2';
                    } else t += e;
                }
                char c = eval(s);
                if(c == '1' and c == eval(t)) {
                    int num = __builtin_popcount(bit);
                    ans += fac[num] * fac[cnt - num];
                }
            }
        }
        cout << ans << endl;
        cin >> n;
    }
    return 0;
}
accuracy: 1
time_ms: 2720
memory_kb: 3584
final_rank: 14