Problem:
盤面上にロボットと壁，ゴールが設置されており， ロボットの行動パターンを記述したプログラムが与えられる．
与えられるプログラムは以下のEBNF で表される．
プログラム:= {文};
文:= if 文|while 文|動作文;
if 文:= "[", 条件, プログラム, "]";
while 文:= "{", 条件, プログラム, "}";

動作文:= "^"|"v"|"<"|">";
条件:= ["~"], "N"|"E"|"S"|"W"|"C"|"T";
「プログラム」は0個以上の「文」からなり，1つ以上の文が存在する場合は 1 つ目の文から順番に1 つずつ文が実行される．「文」は「動作文」，「if 文」，「while 文」のいずれかである．「動作文」は"
^
", "
v
","
<
","
>
" のいずれかであり，それぞれ以下の動作が実行される．
"
^
": 前進
"
v
": 後退
"
<
": 左に90 度回転
"
>
": 右に90 度回転
「if 文」は "
[
"，「条件」，「プログラム」，"
]
" を順番に並べたもので，以下の手順で実行される．
「条件」の内容が真かどうか判定する
判定が真なら「プログラム」の内容を実行し，このif 文の処理を終了する
判定が偽ならこのif 文の処理を終了する
「while 文」は "
{
"，「条件」，「プログラム」，"
}
" を順番に並べたもので，以下の手順で実行される．
「条件」の内容が真かどうか判定する
判定が真なら「プログラム」の内容を実行し，1 に戻る
判定が偽なら，この while 文の処理を終了する
「条件」は "
N
", "
E
", "
S
", "
W
", "
C
", "
T
" のいずれかであり，先頭には"
~
" をつけることができる．それぞれの記述は以下の真偽値を表す．
先頭に "
~
" が付いている場合は真偽値が逆転
N
: 北を向いているならば真，そうでなければ偽
E
: 東を向いているならば真，そうでなければ偽
S
: 南を向いているならば真，そうでなければ偽
W
: 西を向いているならば真，そうでなければ偽
C
: 目の前に壁があるならば真，そうでなければ偽
T
: 常に真
ロボットは最初，北を向いているものとする．ロボットは壁を通ることができず，何もないマスのみを移動できる．もし，プログラムが壁の上を通るような動作を実行しようとした場合，ロボットは移動せずその場にとどまる．最後に，ロボットはゴールに到達した時，実行途中のプログラムが残っていたとしてもすべて中断して動作を停止する．
このとき，ロボットがゴールにたどり着くまでにどのぐらい時間がかかるのか知りたい．ロボットは条件判定やプログラムの読み込みに関しては非常に高速に実行できるので実際の動作時間を決定するのは「動作文」のみである．そこで，このロボットがゴールに辿り着くまでに「動作文」を何回実行するかを教えてほしい．
なお，壁の上を通るような動作を実行しようとして，実際には「動作文」の動作が行われなかった場合にも「動作文」は実行されたものとみなす．
Input
入力は以下の形式で与えられる．
H
W
a
1,1
a
1,2
. . . a
1,W
a
2,1
a
2,2
. . . a
2,W
: : :
a
H,1
a
H,2
. . . a
H,W
s
H
は盤面の高さ，
W
は盤面の幅を表す．
次に盤面を真上から見た状態が与えられる．この盤面は上，下，左，右がそれぞれ北，南，西，東に対応する．各マスの状態を表す
a
i,j
は以下のいずれかの文字である．
"
s
" : ロボット（ロボットの初期位置．このマスには壁がないことが保証されている）
"
g
" : ゴール
"
#
" : 壁（ロボットは壁の上を移動することはできない）
"
.
" : 何もないマス
s
にはロボットに与えられるプログラムが文字列として入力される．
Constraints
1 ≤
H,W
≤ 50
1 ≤
s
の文字数 ≤ 1,000
a
i,j
は"
.
", "
#
", "
s
", "
g
" のいずれか
"
s
", "
g
" はそれぞれ 1 回しか登場しない
i = 1
または
i = H
または
j = 1
または
j = W
ならば
a
i,j
= "
#
"（盤面の外周は壁で囲まれていることが保証されている）
s
として与えられるプログラムは構文的に正しい
Output
たどり着ける場合は"到達するまでに実行した「動作文」の数" を，たどりつけない場合は "-1" を出力せよ．なお，壁の上を通るような動作を実行しようとして，実際には「動作文」の動作が行われなかった場合にも「動作文」が実行されたものとみなす点に注意せよ（入力例1）．
Sample Input 1
5 3
###
#g#
#.#
#s#
###
^<^<vv
Output for the Sample Input 1
5
Sample Input 2
5 7
#######
#.#g..#
#.###.#
#s....#
#######
{T{~C^}<}
Output for the Sample Input 2
17
Sample Input 3
5 7
#######
#.#g..#
#.###.#
#s....#
#######
{T{~C^}>}
Output for the Sample Input 3
-1

Submitted solutions:

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...);
}

/**
 * @brief template
 */

struct UnionFind{
    vector<int> par; int n;
    UnionFind(){}
    UnionFind(int _n):par(_n,-1),n(_n){}
    int root(int x){return par[x]<0?x:par[x]=root(par[x]);}
    bool same(int x,int y){return root(x)==root(y);}
    int size(int x){return -par[root(x)];}
    bool unite(int x,int y){
        x=root(x),y=root(y); if(x==y)return false;
        if(size(x)>size(y))swap(x,y);
        par[y]+=par[x]; par[x]=y; n--; return true;
    }
};

/**
 * @brief Union Find
 */

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

int main() {
    int N, M, K;
    cin >> N >> M;
    vector B(N,vector<bool>(M));
    int SX, SY, GX, GY;
    rep(i,0,N) {
        string s;
        cin >> s;
        rep(j,0,M) {
            if (s[j] == '#') B[i][j] = false;
            else B[i][j] = true;
            if (s[j] == 's') SX = i, SY = j;
            if (s[j] == 'g') GX = i, GY = j;
        }
    }
    string S;
    cin >> S;
    K = S.size();
    vector<int> Left(K,-1), Right(K,-1);
    stack<int> st;
    rep(i,0,K) {
        if (S[i] == '[' || S[i] == '{') st.push(i);
        if (S[i] == ']' || S[i] == '}') Left[i] = st.top(), Right[Left[i]] = i, st.pop();
    }
    vector DP(N,vector(M,vector(4,vector<int>(K+1,inf))));
    int X = SX, Y = SY, dir = 0, ind = 0, D = 0;
    auto judge = [&](char C) -> bool {
        if (C == 'T') return true;
        if (C == 'C') return !B[X+dx[dir]][Y+dy[dir]];
        if (C == 'N') return dir==0;
        if (C == 'W') return dir==1;
        if (C == 'S') return dir==2;
        if (C == 'E') return dir==3;
        return true;
    };
    while(1) {
        if (DP[X][Y][dir][ind] != inf) break;
        DP[X][Y][dir][ind] = D;
        if (ind == K) break;
        if (X == GX && Y == GY) break;
        if (S[ind] == '[' || S[ind] == '{') {
            bool J;
            if (S[ind+1] == '~') {
                J = !judge(S[ind+2]);
            }
            else {
                J = judge(S[ind+1]);
            }
            if (J) {
                if (S[ind+1]=='~') ind+=3;
                else ind+=2;
            }
            else {
                ind=Right[ind]+1;
            }
        }
        else if (S[ind] == ']') {
            ind++;
        }
        else if (S[ind] == '}') {
            ind = Left[ind];
        }
        else if (S[ind] == '^') {
            if (B[X+dx[dir]][Y+dy[dir]]) X += dx[dir], Y += dy[dir];
            D++;
            ind++;
        }
        else if (S[ind] == 'v') {
            if (B[X-dx[dir]][Y-dy[dir]]) X -= dx[dir], Y -= dy[dir];
            D++;
            ind++;
        }
        else if (S[ind] == '<') {
            dir = (dir+1) % 4;
            D++;
            ind++;
        }
        else if (S[ind] == '>') {
            dir = (dir+3) % 4;
            D++;
            ind++;
        }
    }
    int ANS = inf;
    rep(i,0,4) {
        rep(j,0,K+1) chmin(ANS,DP[GX][GY][i][j]);
    }
    cout << (ANS == inf ? -1 : ANS) << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 43500
final_rank: 4

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 H, W;
vector<string> a;
string s;
int i, n;
int x, y, d, gx, gy;
// 北, 東, 南, 西
int dx[] = {-1,  0, +1,  0};
int dy[] = { 0, +1,  0, -1};

int cnt = 0;



vector<vector<vector<bool>>> vis;
vector<vector<vector<int>>> cnter;

void program();
void if_bun();
void while_bun();
void dousa_bun();
bool joken();
void watch();

void watch() {
    assert(0 <= x and x < H);
    assert(0 <= y and y < W);
    assert(0 <= d and d < 4);
    cnter[x][y][d]++;
    if(1'000'000 <= cnter[x][y][d]) exit(print(-1));
}

bool no_dousa = false;

void program() {
    watch();
    while(i < n) {
        if(s[i] == '[') if_bun();
        else if(s[i] == '{') while_bun();
        else if(set<char>{'^', 'v', '<', '>'}.count(s[i])) dousa_bun();
        else if(s[i] == '}') { i++; return; }
        else if(s[i] == ']') { i++; return; }
        else return;
    }
}

void if_bun() {
    watch();
    assert(s[i] == '['); i++;
    if(joken()) { program(); if(s[i] == ']') i++; }
    else {
        no_dousa = true;
        program(); if(s[i] == ']') i++;
        no_dousa = false;
    }
}

void while_bun() {
    watch();
    assert(s[i] == '{'); i++;
    int j = i;
    while(joken()) { watch(); program(); i = j; }
    no_dousa = true;
    program();
    no_dousa = false;
}

void dousa_bun() {
    watch();
    if(no_dousa) { i++; return; }
    if(s[i] == '^') {
        int nx = x + dx[d], ny = y + dy[d];
        if(0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] != '#') {
            tie(x, y, d) = make_tuple(nx, ny, d);
        } else {
            tie(x, y, d) = make_tuple(x, y, d);
        }
    } else if(s[i] == 'v') {
        int nx = x - dx[d], ny = y - dy[d];
        if(0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] != '#') {
            tie(x, y, d) = make_tuple(nx, ny, d);
        } else {
            tie(x, y, d) = make_tuple(x, y, d);
        }
    } else if(s[i] == '<') {
        tie(x, y, d) = make_tuple(x, y, (d - 1 + 4) % 4);
    } else if(s[i] == '>') {
        tie(x, y, d) = make_tuple(x, y, (d + 1) % 4);
    }
    i++;
    cnt++;
    if(make_pair(x, y) == make_pair(gx, gy)) exit(print(cnt));
}

bool joken() {
    watch();
    if(no_dousa) {
        if(s[i] == '~') i += 2;
        else i += 1;
        return false;
    }
    if(s[i] == '~') {
        if(s[i + 1] == 'N') { i += 2; return !(d == 0); }
        if(s[i + 1] == 'E') { i += 2; return !(d == 1); }
        if(s[i + 1] == 'S') { i += 2; return !(d == 2); }
        if(s[i + 1] == 'W') { i += 2; return !(d == 3); }
        if(s[i + 1] == 'C') { i += 2;
            int nx = x + dx[d], ny = y + dy[d];
            return !(0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] == '#');
        }
        if(s[i + 1] == 'T') { i += 2; return false; }
    } else {
        if(s[i] == 'N') { i += 1; return (d == 0); }
        if(s[i] == 'E') { i += 1; return (d == 1); }
        if(s[i] == 'S') { i += 1; return (d == 2); }
        if(s[i] == 'W') { i += 1; return (d == 3); }
        if(s[i] == 'C') { i += 1;
            int nx = x + dx[d], ny = y + dy[d];
            return (0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] == '#');
        }
        if(s[i] == 'T') { i += 1; return true; }
    }

    assert(0);
}

int main() {
    H = in(), W = in();
    a = in(H);
    cin >> s;
    n = s.size();
    for(int xx : rep(H)) for(int yy : rep(W)) {
        if(a[xx][yy] == 's') tie( x,  y) = make_pair(xx, yy), a[xx][yy] = '.';
        if(a[xx][yy] == 'g') tie(gx, gy) = make_pair(xx, yy), a[xx][yy] = '.';
    }
    d = 0;
    vis = vector(H, vector(W, vector(4, false)));
    cnter = vector(H, vector(W, vector(4, 0)));

    while(vis[x][y][d] == false) {
        vis[x][y][d] = true;
        i = 0;
        program();
        debug(x);
        debug(y);
        debug(d);
        watch();
    }

    return print(-1);
}
accuracy: 0.11392405063291139
time_ms: 270
memory_kb: 3704
final_rank: 17

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

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

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

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

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

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

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

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

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

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


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

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

namespace std {

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

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

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

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

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

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

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

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

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

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

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

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

using f64 = long double;

} // namespace macro

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

int H, W;
vector<string> a;
string s;
int i, n;
int x, y, d, gx, gy;
// 北, 東, 南, 西
int dx[] = {-1,  0, +1,  0};
int dy[] = { 0, +1,  0, -1};

int cnt = 0;



vector<vector<vector<bool>>> vis;
vector<vector<vector<int>>> cnter;

void program();
void if_bun();
void while_bun();
void dousa_bun();
bool joken();
void watch();

void watch() {
    cnter[x][y][d]++;
    if(1'000'000 <= cnter[x][y][d]) exit(print(-1));
}

bool no_dousa = false;

void program() {
    watch();
    while(i < n) {
        if(s[i] == '[') if_bun();
        else if(s[i] == '{') while_bun();
        else if(set<char>{'^', 'v', '<', '>'}.count(s[i])) dousa_bun();
        else if(s[i] == '}') { i++; return; }
        else if(s[i] == ']') { i++; return; }
        else return;
    }
}

void if_bun() {
    watch();
    assert(s[i] == '['); i++;
    if(joken()) { program(); if(s[i] == ']') i++; }
    else {
        no_dousa = true;
        program(); if(s[i] == ']') i++;
        no_dousa = false;
    }
}

void while_bun() {
    watch();
    assert(s[i] == '{'); i++;
    int j = i;
    while(joken()) { watch(); program(); i = j; }
    no_dousa = true;
    program();
    no_dousa = false;
}

void dousa_bun() {
    watch();
    if(no_dousa) { i++; return; }
    if(s[i] == '^') {
        int nx = x + dx[d], ny = y + dy[d];
        if(0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] != '#') {
            tie(x, y, d) = make_tuple(nx, ny, d);
        } else {
            tie(x, y, d) = make_tuple(x, y, d);
        }
    } else if(s[i] == 'v') {
        int nx = x - dx[d], ny = y - dy[d];
        if(0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] != '#') {
            tie(x, y, d) = make_tuple(nx, ny, d);
        } else {
            tie(x, y, d) = make_tuple(nx, ny, d);
        }
    } else if(s[i] == '<') {
        tie(x, y, d) = make_tuple(x, y, (d - 1 + 4) % 4);
    } else if(s[i] == '>') {
        tie(x, y, d) = make_tuple(x, y, (d + 1) % 4);
    }
    i++;
    cnt++;
    if(make_pair(x, y) == make_pair(gx, gy)) exit(print(cnt));
}

bool joken() {
    watch();
    if(no_dousa) {
        if(s[i] == '~') i += 2;
        else i += 1;
        return false;
    }
    if(s[i] == '~') {
        if(s[i + 1] == 'N') { i += 2; return !(d == 0); }
        if(s[i + 1] == 'E') { i += 2; return !(d == 1); }
        if(s[i + 1] == 'S') { i += 2; return !(d == 2); }
        if(s[i + 1] == 'W') { i += 2; return !(d == 3); }
        if(s[i + 1] == 'C') { i += 2;
            int nx = x + dx[d], ny = y + dy[d];
            return !(0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] == '#');
        }
        if(s[i + 1] == 'T') { i += 2; return false; }
    } else {
        if(s[i] == 'N') { i += 1; return (d == 0); }
        if(s[i] == 'E') { i += 1; return (d == 1); }
        if(s[i] == 'S') { i += 1; return (d == 2); }
        if(s[i] == 'W') { i += 1; return (d == 3); }
        if(s[i] == 'C') { i += 1;
            int nx = x + dx[d], ny = y + dy[d];
            return (0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] == '#');
        }
        if(s[i] == 'T') { i += 1; return true; }
    }

    assert(0);
}

int main() {
    H = in(), W = in();
    a = in(H);
    cin >> s;
    s += '$';
    n = s.size();
    for(int xx : rep(H)) for(int yy : rep(W)) {
        if(a[xx][yy] == 's') tie( x,  y) = make_pair(xx, yy), a[xx][yy] = '.';
        if(a[xx][yy] == 'g') tie(gx, gy) = make_pair(xx, yy), a[xx][yy] = '.';
    }
    d = 0;
    vis = vector(H, vector(W, vector(4, false)));
    cnter = vector(H, vector(W, vector(4, 0)));

    while(vis[x][y][d] == false) {
        vis[x][y][d] = true;
        i = 0;
        program();
        debug(x);
        debug(y);
        debug(d);
        watch();
    }

    return print(-1);
}
accuracy: 0.05063291139240506
time_ms: 270
memory_kb: 3460
final_rank: 19

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 H, W;
vector<string> a;
string s;
int i, n;
int x, y, d, gx, gy;
// 北, 東, 南, 西
int dx[] = {-1,  0, +1,  0};
int dy[] = { 0, +1,  0, -1};

int cnt = 0, step = 0;



vector<vector<vector<bool>>> vis;

void program();
void if_bun();
void while_bun();
void dousa_bun();
bool joken();
void watch();

void watch() {
    step++;
    if(1'000'0000 <= step) exit(print(-1));
}

bool no_dousa = false;

void program() {
    watch();
    while(i < n) {
        if(s[i] == '[') if_bun();
        else if(s[i] == '{') while_bun();
        else if(set<char>{'^', 'v', '<', '>'}.count(s[i])) dousa_bun();
        else if(s[i] == '}') { i++; return; }
        else if(s[i] == ']') { i++; return; }
        else return;
    }
}

void if_bun() {
    watch();
    assert(s[i] == '['); i++;
    if(joken()) { program(); if(s[i] == ']') i++; }
    else {
        no_dousa = true;
        program(); if(s[i] == ']') i++;
        no_dousa = false;
    }
}

void while_bun() {
    watch();
    assert(s[i] == '{'); i++;
    int j = i;
    while(joken()) { watch(); program(); i = j; }
    no_dousa = true;
    program();
    no_dousa = false;
}

void dousa_bun() {
    watch();
    if(no_dousa) { i++; return; }
    if(s[i] == '^') {
        int nx = x + dx[d], ny = y + dy[d];
        if(0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] != '#') {
            tie(x, y, d) = make_tuple(nx, ny, d);
        } else {
            tie(x, y, d) = make_tuple(x, y, d);
        }
    } else if(s[i] == 'v') {
        int nx = x - dx[d], ny = y - dy[d];
        if(0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] != '#') {
            tie(x, y, d) = make_tuple(nx, ny, d);
        } else {
            tie(x, y, d) = make_tuple(nx, ny, d);
        }
    } else if(s[i] == '<') {
        tie(x, y, d) = make_tuple(x, y, (d - 1 + 4) % 4);
    } else if(s[i] == '>') {
        tie(x, y, d) = make_tuple(x, y, (d + 1) % 4);
    }
    i++;
    cnt++;
    if(make_pair(x, y) == make_pair(gx, gy)) exit(print(cnt));
}

bool joken() {
    watch();
    if(no_dousa) {
        if(s[i] == '~') i += 2;
        else i += 1;
        return false;
    }
    if(s[i] == '~') {
        if(s[i + 1] == 'N') { i += 2; return !(d == 0); }
        if(s[i + 1] == 'E') { i += 2; return !(d == 1); }
        if(s[i + 1] == 'S') { i += 2; return !(d == 2); }
        if(s[i + 1] == 'W') { i += 2; return !(d == 3); }
        if(s[i + 1] == 'C') { i += 2;
            int nx = x + dx[d], ny = y + dy[d];
            return !(0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] == '#');
        }
        if(s[i + 1] == 'T') { i += 2; return false; }
    } else {
        if(s[i] == 'N') { i += 1; return (d == 0); }
        if(s[i] == 'E') { i += 1; return (d == 1); }
        if(s[i] == 'S') { i += 1; return (d == 2); }
        if(s[i] == 'W') { i += 1; return (d == 3); }
        if(s[i] == 'C') { i += 1;
            int nx = x + dx[d], ny = y + dy[d];
            return (0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] == '#');
        }
        if(s[i] == 'T') { i += 1; return true; }
    }

    assert(0);
}


int main() {
    H = in(), W = in();
    a = in(H);
    cin >> s;
    s += '$';
    n = s.size();
    for(int xx : rep(H)) for(int yy : rep(W)) {
        if(a[xx][yy] == 's') tie( x,  y) = make_pair(xx, yy), a[xx][yy] = '.';
        if(a[xx][yy] == 'g') tie(gx, gy) = make_pair(xx, yy), a[xx][yy] = '.';
    }
    d = 0;
    vis = vector(H, vector(W, vector(4, false)));

    while(vis[x][y][d] == false) {
        vis[x][y][d] = true;
        i = 0;
        program();
        debug(x);
        debug(y);
        debug(d);
        watch();
    }

    return print(-1);
}
accuracy: 0.11392405063291139
time_ms: 440
memory_kb: 3648
final_rank: 18

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 H, W;
vector<string> a;
string s;
int i, n;
int x, y, d, gx, gy;
// 北, 東, 南, 西
int dx[] = {-1,  0, +1,  0};
int dy[] = { 0, +1,  0, -1};

int cnt = 0, step = 0;



vector<vector<vector<bool>>> vis;

void program();
void if_bun();
void while_bun();
void dousa_bun();
bool joken();
void watch();

void watch() {
    step++;
    if(1'000'000 <= step) exit(print(-1));
}

bool no_dousa = false;

void program() {
    watch();
    while(i < n) {
        if(s[i] == '[') if_bun();
        else if(s[i] == '{') while_bun();
        else if(set<char>{'^', 'v', '<', '>'}.count(s[i])) dousa_bun();
        else if(s[i] == '}') { i++; return; }
        else if(s[i] == ']') { i++; return; }
        else return;
    }
}

void if_bun() {
    watch();
    assert(s[i] == '['); i++;
    if(joken()) { program(); if(s[i] == ']') i++; }
    else {
        no_dousa = true;
        program(); if(s[i] == ']') i++;
        no_dousa = false;
    }
}

void while_bun() {
    watch();
    assert(s[i] == '{'); i++;
    int j = i;
    while(joken()) { program(); i = j; }
    no_dousa = true;
    program();
    no_dousa = false;
}

void dousa_bun() {
    if(no_dousa) { i++; return; }
    if(s[i] == '^') {
        int nx = x + dx[d], ny = y + dy[d];
        if(0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] != '#') {
            tie(x, y, d) = make_tuple(nx, ny, d);
        } else {
            tie(x, y, d) = make_tuple(x, y, d);
        }
    } else if(s[i] == 'v') {
        int nx = x - dx[d], ny = y - dy[d];
        if(0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] != '#') {
            tie(x, y, d) = make_tuple(nx, ny, d);
        } else {
            tie(x, y, d) = make_tuple(nx, ny, d);
        }
    } else if(s[i] == '<') {
        tie(x, y, d) = make_tuple(x, y, (d - 1 + 4) % 4);
    } else if(s[i] == '>') {
        tie(x, y, d) = make_tuple(x, y, (d + 1) % 4);
    }
    i++;
    cnt++;
    watch();
    if(make_pair(x, y) == make_pair(gx, gy)) exit(print(cnt));
}

bool joken() {
    watch();
    if(no_dousa) {
        if(s[i] == '~') i += 2;
        else i += 1;
        return false;
    }
    if(s[i] == '~') {
        if(s[i + 1] == 'N') { i += 2; return !(d == 0); }
        if(s[i + 1] == 'E') { i += 2; return !(d == 1); }
        if(s[i + 1] == 'S') { i += 2; return !(d == 2); }
        if(s[i + 1] == 'W') { i += 2; return !(d == 3); }
        if(s[i + 1] == 'C') { i += 2;
            int nx = x + dx[d], ny = y + dy[d];
            return !(0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] == '#');
        }
        if(s[i + 1] == 'T') { i += 2; return false; }
    } else {
        if(s[i] == 'N') { i += 1; return (d == 0); }
        if(s[i] == 'E') { i += 1; return (d == 1); }
        if(s[i] == 'S') { i += 1; return (d == 2); }
        if(s[i] == 'W') { i += 1; return (d == 3); }
        if(s[i] == 'C') { i += 1;
            int nx = x + dx[d], ny = y + dy[d];
            return (0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] == '#');
        }
        if(s[i] == 'T') { i += 1; return true; }
    }

    assert(0);
}


int main() {
    H = in(), W = in();
    a = in(H);
    cin >> s;
    n = s.size();
    for(int xx : rep(H)) for(int yy : rep(W)) {
        if(a[xx][yy] == 's') tie( x,  y) = make_pair(xx, yy), a[xx][yy] = '.';
        if(a[xx][yy] == 'g') tie(gx, gy) = make_pair(xx, yy), a[xx][yy] = '.';
    }
    d = 0;
    vis = vector(H, vector(W, vector(4, false)));

    while(vis[x][y][d] == false) {
        vis[x][y][d] = true;
        i = 0;
        program();
        debug(x);
        debug(y);
        debug(d);
    }

    return print(-1);
}
accuracy: 0.11392405063291139
time_ms: 70
memory_kb: 3644
final_rank: 16

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 H, W;
vector<string> a;
string s;
int i, n;
int x, y, d, gx, gy;
// 北, 東, 南, 西
int dx[] = {-1,  0, +1,  0};
int dy[] = { 0, +1,  0, -1};

int cnt = 0, step = 0;

vector<vector<vector<bool>>> vis;

void program();
void if_bun();
void while_bun();
void dousa_bun();
bool joken();

bool no_dousa = false;

void program() {
    while(i < n) {
        if(s[i] == '[') if_bun();
        else if(s[i] == '{') while_bun();
        else if(set<char>{'^', 'v', '<', '>'}.count(s[i])) dousa_bun();
        else if(s[i] == '}') { i++; return; }
        else if(s[i] == ']') { i++; return; }
        else {
            exit(print(s[i]));
        }
    }
}

void if_bun() {
    assert(s[i] == '['); i++;
    if(joken()) { program(); assert(s[i] == ']'); i++; }
    else {
        no_dousa = true;
        program(); assert(s[i] == ']'); i++;
        no_dousa = false;
    }
}

void while_bun() {
    assert(s[i] == '{'); i++;
    int j = i;
    while(joken()) { program(); i = j; }
    no_dousa = true;
    program();
    no_dousa = false;
}

void dousa_bun() {
    if(no_dousa) { i++; return; }
    if(s[i] == '^') {
        int nx = x + dx[d], ny = y + dy[d];
        if(0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] != '#') {
            tie(x, y, d) = make_tuple(nx, ny, d);
        } else {
            tie(x, y, d) = make_tuple(x, y, d);
        }
    } else if(s[i] == 'v') {
        int nx = x - dx[d], ny = y - dy[d];
        if(0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] != '#') {
            tie(x, y, d) = make_tuple(nx, ny, d);
        } else {
            tie(x, y, d) = make_tuple(nx, ny, d);
        }
    } else if(s[i] == '<') {
        tie(x, y, d) = make_tuple(x, y, (d - 1 + 4) % 4);
    } else if(s[i] == '>') {
        tie(x, y, d) = make_tuple(x, y, (d + 1) % 4);
    }
    i++;
    cnt++;
    step++;
    if(1'000'000 <= step) exit(print(-1));
    if(make_pair(x, y) == make_pair(gx, gy)) exit(print(cnt));
}

bool joken() {
    if(no_dousa) {
        if(s[i] == '~') i += 2;
        else i += 1;
        return false;
    }
    if(s[i] == '~') {
        if(s[i + 1] == 'N') { i += 2; return !(d == 0); }
        if(s[i + 1] == 'E') { i += 2; return !(d == 1); }
        if(s[i + 1] == 'S') { i += 2; return !(d == 2); }
        if(s[i + 1] == 'W') { i += 2; return !(d == 3); }
        if(s[i + 1] == 'C') { i += 2;
            int nx = x + dx[d], ny = y + dy[d];
            return !(0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] == '#');
        }
        if(s[i + 1] == 'T') { i += 2; return false; }
    } else {
        if(s[i] == 'N') { i += 1; return (d == 0); }
        if(s[i] == 'E') { i += 1; return (d == 1); }
        if(s[i] == 'S') { i += 1; return (d == 2); }
        if(s[i] == 'W') { i += 1; return (d == 3); }
        if(s[i] == 'C') { i += 1;
            int nx = x + dx[d], ny = y + dy[d];
            return (0 <= nx and nx < H and 0 <= ny and ny < W and a[nx][ny] == '#');
        }
        if(s[i] == 'T') { i += 1; return true; }
    }

    assert(0);
}


int main() {
    H = in(), W = in();
    a = in(H);
    cin >> s;
    n = s.size();
    for(int xx : rep(H)) for(int yy : rep(W)) {
        if(a[xx][yy] == 's') tie( x,  y) = make_pair(xx, yy), a[xx][yy] = '.';
        if(a[xx][yy] == 'g') tie(gx, gy) = make_pair(xx, yy), a[xx][yy] = '.';
    }
    d = 0;
    vis = vector(H, vector(W, vector(4, false)));

    while(vis[x][y][d] == false) {
        vis[x][y][d] = true;
        i = 0;
        program();
        debug(x);
        debug(y);
        debug(d);
    }

    return print(-1);
}
accuracy: 0.0379746835443038
time_ms: 270
memory_kb: 3388
final_rank: 20

code_snippet: #include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

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

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

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

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

#define debug(...)                                                     \
    std::cerr << "LINE: " << __LINE__ << " [" << #__VA_ARGS__ << "]:", \
        debug_out(__VA_ARGS__)

void debug_out() {
    std::cerr << std::endl;
}

template <typename Head, typename... Tail> void debug_out(Head h, Tail... t) {
    std::cerr << " " << h;
    if (sizeof...(t) > 0) std::cerr << ",";
    debug_out(t...);
}

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

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

typedef std::string::const_iterator State;

bool expect(State &begin, char expected) {
    return *begin == expected;
}

void consume(State &begin, char expected) {
    assert(*begin == expected);
    begin++;
}

bool isdigit(char c) {
    return '0' <= c && c <= '9';
}

bool isAlpha(char c) {
    return 'A' <= c && c <= 'Z';
}

bool isalpha(char c) {
    return 'a' <= c && c <= 'z';
}

struct Node {
    int type;
    int end;
    int move = -1;
    int cond;
    bool is_not = false;
};

void program(State &);
void stmt(State &);
std::pair<int, bool> condition(State &);

std::vector<Node> prog;

void program(State &begin) {
    while (expect(begin, '[') || expect(begin, '{') || expect(begin, '^') ||
           expect(begin, 'v') || expect(begin, '<') || expect(begin, '>')) {
        stmt(begin);
    }
}

void stmt(State &begin) {
    int idx = prog.size();
    prog.emplace_back(Node());
    if (expect(begin, '[')) {
        prog[idx].type = 0;
        consume(begin, '[');
        auto [cond, is_not] = condition(begin);
        prog[idx].cond = cond;
        prog[idx].is_not = is_not;
        program(begin);
        consume(begin, ']');
        prog[idx].end = prog.size();
        prog.emplace_back(Node());
        prog.back().type = 3;
        prog.back().end = idx;
    } else if (expect(begin, '{')) {
        prog[idx].type = 1;
        consume(begin, '{');
        auto [cond, is_not] = condition(begin);
        prog[idx].cond = cond;
        prog[idx].is_not = is_not;
        program(begin);
        consume(begin, '}');
        prog[idx].end = prog.size();
        prog.emplace_back(Node());
        prog.back().type = 4;
        prog.back().end = idx;
    } else {
        prog[idx].type = 2;
        std::string s = "^v><";
        rep(i, 0, 4) {
            if (expect(begin, s[i])) {
                consume(begin, s[i]);
                prog[idx].move = i;
                break;
            }
        }
        assert(prog[idx].move >= 0);
    }
}

std::pair<int, bool> condition(State &begin) {
    bool is_not = false;
    if (expect(begin, '~')) {
        consume(begin, '~');
        is_not = true;
    }
    std::string s = "NESWCT";
    rep(i, 0, 6) {
        if (expect(begin, s[i])) {
            consume(begin, s[i]);
            return {i, is_not};
        }
    }
    assert(0);
}

int main() {
    int h, w;
    std::cin >> h >> w;
    std::vector<std::string> a(h);
    rep(i, 0, h) std::cin >> a[i];
    std::string s;
    std::cin >> s;
    s += ';';
    State begin = s.begin();
    program(begin);
    consume(begin, ';');
    int sy = -1, sx = -1, gy = -1, gx = -1;
    rep(i, 0, h) rep(j, 0, w) {
        if (a[i][j] == 's') {
            sy = i;
            sx = j;
        }
        if (a[i][j] == 'g') {
            gy = i;
            gx = j;
        }
    }
    int sz = prog.size();
    std::set<std::tuple<int,int,int,int>> set;
    int y = sy, x = sx;
    int idx = 0, d = 0;
    std::vector<int> dy = {-1, 0, 1, 0};
    std::vector<int> dx = {0, 1, 0, -1};
    int cnt = 0;
    auto check = [&](const Node &node) -> bool {
        assert(node.type == 0 || node.type == 1);
        int cond = node.cond;
        if (cond < 4) {
            return cond == d;
        } else if (cond == 4) {
            int ny = y + dy[d];
            int nx = x + dx[d];
            return 0 <= ny && ny < h && 0 <= nx && nx < w && a[ny][nx] == '#';
        } else {
            return true;
        }
    };

    while (idx < sz && set.find({y,x,idx,d}) == set.end()) {
        set.insert({y, x, idx, d});
        if (y == gy && x == gx) break;
        if (prog[idx].type == 0 || prog[idx].type == 1) {
            bool is_ok = check(prog[idx]);
            if (prog[idx].is_not) is_ok = !is_ok;
            if (is_ok)
                idx++;
            else
                idx = prog[idx].end + 1;
        } else if (prog[idx].type == 2) {
            if (prog[idx].move == 0) {
                int ny = y + dy[d];
                int nx = x + dx[d];
                if (0 <= ny && ny < h && 0 <= nx && nx < w &&
                    a[ny][nx] != '#') {
                    y = ny;
                    x = nx;
                }
            } else if (prog[idx].move == 1) {
                int ny = y + dy[d ^ 2];
                int nx = x + dx[d ^ 2];
                if (0 <= ny && ny < h && 0 <= nx && nx < w &&
                    a[ny][nx] != '#') {
                    y = ny;
                    x = nx;
                }
            } else if (prog[idx].move == 2) {
                d = (d + 1) % 4;
            } else {
                assert(prog[idx].move == 3);
                d = (d - 1 + 4) % 4;
            }
            cnt++;
            idx++;
        } else if (prog[idx].type == 3) {
            idx++;
        } else {
            assert(prog[idx].type == 4);
            idx = prog[idx].end;
        }
    }
    if (y == gy && x == gx) {
        std::cout << cnt << '\n';
    } else {
        std::cout << "-1\n";
    }
}
accuracy: 1
time_ms: 210
memory_kb: 79584
final_rank: 8

code_snippet: #include <iostream>
#include <string>
#include <vector>
using namespace std;

int H, W, sx, sy, gx, gy;
char c[59][59];
string Program;
int Parentheses[1009];
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

int main() {
	// Input
	cin >> H >> W;
	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			cin >> c[i][j];
			if (c[i][j] == 's') { sx = i; sy = j; c[i][j] = '.'; }
			if (c[i][j] == 'g') { gx = i; gy = j; c[i][j] = '.'; }
		}
	}
	cin >> Program;
	
	// Find Parentheses
	vector<int> vec;
	for (int i = 0; i < (int)Program.size(); i++) {
		if (Program[i] == '{' || Program[i] == '[') {
			vec.push_back(i);
		}
		if (Program[i] == '}' || Program[i] == ']') {
			int idx1 = vec[vec.size() - 1];
			int idx2 = i;
			Parentheses[idx1] = idx2;
			Parentheses[idx2] = idx1;
			vec.pop_back();
		}
	}
	
	// Simulation
	int current_x = sx;
	int current_y = sy;
	int current_dir = 2;
	int current_pc = 0;
	int current_time = 0;
	int current_loop = 0;
	while (current_loop < 5 * H * W * (int)Program.size() && current_pc < (int)Program.size()) {
		current_loop += 1;
		char Letter = Program[current_pc];
		if (current_x == gx && current_y == gy) {
			cout << current_time << endl;
			return 0;
		}
		
		// Case 1: Rotate
		if (Letter == '>' || Letter == '<' || Letter == '^' || Letter == 'v') {
			current_time += 1;
			if (Program[current_pc] == '>') current_dir = (current_dir + 3) % 4;
			if (Program[current_pc] == '<') current_dir = (current_dir + 1) % 4;
			if (Program[current_pc] == '^') {
				int next_x = current_x + dx[current_dir];
				int next_y = current_y + dy[current_dir];
				if (c[next_x][next_y] != '#') {
					current_x = next_x;
					current_y = next_y;
				}
			}
			if (Program[current_pc] == 'v') {
				int next_x = current_x - dx[current_dir];
				int next_y = current_y - dy[current_dir];
				if (c[next_x][next_y] != '#') {
					current_x = next_x;
					current_y = next_y;
				}
			}
			current_pc += 1;
		}
		
		// Case 2: If/While Begin
		if (Letter == '[' || Letter == '{') {
			char cond = Program[current_pc + 1];
			bool inversed = false;
			if (cond == '~') {
				cond = Program[current_pc + 2];
				inversed = true;
			}
			
			// Check if condition is true or not
			bool flag = false;
			if (cond == 'N' && current_dir == 2) flag = true;
			if (cond == 'E' && current_dir == 1) flag = true;
			if (cond == 'S' && current_dir == 0) flag = true;
			if (cond == 'W' && current_dir == 3) flag = true;
			if (cond == 'C' && c[current_x+dx[current_dir]][current_y+dy[current_dir]] == '#') flag = true;
			if (cond == 'T') flag = true;
			if (inversed == true) flag ^= true;
			
			// A fork in the road
			if (flag == true) {
				if (Program[current_pc+1] != '~') current_pc += 2;
				else current_pc += 3;
			}
			else {
				current_pc = Parentheses[current_pc] + 1;
			}
		}
		
		// Case 3: While End
		if (Letter == ']') current_pc += 1;
		if (Letter == '}') current_pc = Parentheses[current_pc];
	}
	
	// :( Case
	cout << "-1" << endl;
	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3500
final_rank: 2

code_snippet: //#define _GLIBCXX_DEBUG

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

#define endl '\n'
#define lfs cout<<fixed<<setprecision(10)
#define ALL(a)  (a).begin(),(a).end()
#define ALLR(a)  (a).rbegin(),(a).rend()
#define UNIQUE(a) (a).erase(unique((a).begin(),(a).end()),(a).end())
#define spa << " " <<
#define fi first
#define se second
#define MP make_pair
#define MT make_tuple
#define PB push_back
#define EB emplace_back
#define rep(i,n,m) for(ll i = (n); i < (ll)(m); i++)
#define rrep(i,n,m) for(ll i = (ll)(m) - 1; i >= (ll)(n); i--)
using ll = long long;
using ld = long double;
const ll MOD1 = 1e9+7;
const ll MOD9 = 998244353;
const ll INF = 1e18;
using P = pair<ll, ll>;
template<typename T> using PQ = priority_queue<T>;
template<typename T> using QP = priority_queue<T,vector<T>,greater<T>>;
template<typename T1, typename T2>bool chmin(T1 &a,T2 b){if(a>b){a=b;return true;}else return false;}
template<typename T1, typename T2>bool chmax(T1 &a,T2 b){if(a<b){a=b;return true;}else return false;}
ll median(ll a,ll b, ll c){return a+b+c-max({a,b,c})-min({a,b,c});}
void ans1(bool x){if(x) cout<<"Yes"<<endl;else cout<<"No"<<endl;}
void ans2(bool x){if(x) cout<<"YES"<<endl;else cout<<"NO"<<endl;}
void ans3(bool x){if(x) cout<<"Yay!"<<endl;else cout<<":("<<endl;}
template<typename T1,typename T2>void ans(bool x,T1 y,T2 z){if(x)cout<<y<<endl;else cout<<z<<endl;}  
template<typename T1,typename T2,typename T3>void anss(T1 x,T2 y,T3 z){ans(x!=y,x,z);};  
template<typename T>void debug(const T &v,ll h,ll w,string sv=" "){for(ll i=0;i<h;i++){cout<<v[i][0];for(ll j=1;j<w;j++)cout<<sv<<v[i][j];cout<<endl;}};
template<typename T>void debug(const T &v,ll n,string sv=" "){if(n!=0)cout<<v[0];for(ll i=1;i<n;i++)cout<<sv<<v[i];cout<<endl;};
template<typename T>void debug(const vector<T>&v){debug(v,v.size());}
template<typename T>void debug(const vector<vector<T>>&v){for(auto &vv:v)debug(vv,vv.size());}
template<typename T>void debug(stack<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(queue<T> st){while(!st.empty()){cout<<st.front()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(deque<T> st){while(!st.empty()){cout<<st.front()<<" ";st.pop_front();}cout<<endl;}
template<typename T>void debug(PQ<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(QP<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(const set<T>&v){for(auto z:v)cout<<z<<" ";cout<<endl;}
template<typename T>void debug(const multiset<T>&v){for(auto z:v)cout<<z<<" ";cout<<endl;}
template<typename T,size_t size>void debug(const array<T, size> &a){for(auto z:a)cout<<z<<" ";cout<<endl;}
template<typename T,typename V>void debug(const map<T,V>&v){for(auto z:v)cout<<"["<<z.first<<"]="<<z.second<<",";cout<<endl;}
template<typename T>vector<vector<T>>vec(ll x, ll y, T w){vector<vector<T>>v(x,vector<T>(y,w));return v;}
ll gcd(ll x,ll y){ll r;while(y!=0&&(r=x%y)!=0){x=y;y=r;}return y==0?x:y;}
//vector<ll>dx={1,-1,0,0,1,1,-1,-1};vector<ll>dy={0,0,1,-1,1,-1,1,-1};
template<typename T>vector<T> make_v(size_t a,T b){return vector<T>(a,b);}
template<typename... Ts>auto make_v(size_t a,Ts... ts){return vector<decltype(make_v(ts...))>(a,make_v(ts...));}
template<typename T1, typename T2>ostream &operator<<(ostream &os, const pair<T1, T2>&p){return os << p.first << " " << p.second;}
template<typename T>ostream &operator<<(ostream &os, const vector<T> &v){for(auto &z:v)os << z << " ";cout<<"|"; return os;}
template<typename T>void rearrange(vector<int>&ord, vector<T>&v){
  auto tmp = v;
  for(int i=0;i<tmp.size();i++)v[i] = tmp[ord[i]];
}
template<typename Head, typename... Tail>void rearrange(vector<int>&ord,Head&& head, Tail&&... tail){
  rearrange(ord, head);
  rearrange(ord, tail...);
}
template<typename T> vector<int> ascend(const vector<T>&v){
  vector<int>ord(v.size());iota(ord.begin(),ord.end(),0);
  sort(ord.begin(),ord.end(),[&](int i,int j){return v[i]<v[j];});
  return ord;
}
template<typename T> vector<int> descend(const vector<T>&v){
  vector<int>ord(v.size());iota(ord.begin(),ord.end(),0);
  sort(ord.begin(),ord.end(),[&](int i,int j){return v[i]>v[j];});
  return ord;
}
template<typename T> vector<T> inv_perm(const vector<T>&ord){
  vector<T>inv(ord.size());
  for(int i=0;i<ord.size();i++)inv[ord[i]] = i;
  return inv;
}
ll FLOOR(ll n,ll div){assert(div>0);return n>=0?n/div:(n-div+1)/div;}
ll CEIL(ll n,ll div){assert(div>0);return n>=0?(n+div-1)/div:n/div;}
ll digitsum(ll n){ll ret=0;while(n){ret+=n%10;n/=10;}return ret;}
ll modulo(ll n,ll d){return (n%d+d)%d;};
template<typename T>T min(const vector<T>&v){return *min_element(v.begin(),v.end());}
template<typename T>T max(const vector<T>&v){return *max_element(v.begin(),v.end());}
template<typename T>T acc(const vector<T>&v){return accumulate(v.begin(),v.end(),T(0));};
template<typename T>T reverse(const T &v){return T(v.rbegin(),v.rend());};
//mt19937 mt(chrono::steady_clock::now().time_since_epoch().count());
int popcount(ll x){return __builtin_popcountll(x);};
int poplow(ll x){return __builtin_ctzll(x);};
int pophigh(ll x){return 63 - __builtin_clzll(x);};
template<typename T>T poll(queue<T> &q){auto ret=q.front();q.pop();return ret;};
template<typename T>T poll(priority_queue<T> &q){auto ret=q.top();q.pop();return ret;};
template<typename T>T poll(QP<T> &q){auto ret=q.top();q.pop();return ret;};
template<typename T>T poll(stack<T> &s){auto ret=s.top();s.pop();return ret;};
ll MULT(ll x,ll y){if(LLONG_MAX/x<=y)return LLONG_MAX;return x*y;}
ll POW2(ll x, ll k){ll ret=1,mul=x;while(k){if(mul==LLONG_MAX)return LLONG_MAX;if(k&1)ret=MULT(ret,mul);mul=MULT(mul,mul);k>>=1;}return ret;}
ll POW(ll x, ll k){ll ret=1;for(int i=0;i<k;i++){if(LLONG_MAX/x<=ret)return LLONG_MAX;ret*=x;}return ret;}
template< typename T = int >
struct edge {
  int to;
  T cost;
  int id;
  edge():id(-1){};
  edge(int to, T cost = 1, int id = -1):to(to), cost(cost), id(id){}
  operator int() const { return to; }
};

template<typename T>
using Graph = vector<vector<edge<T>>>;
template<typename T>
Graph<T>revgraph(const Graph<T> &g){
  Graph<T>ret(g.size());
  for(int i=0;i<g.size();i++){
    for(auto e:g[i]){
      int to = e.to;
      e.to = i;
      ret[to].push_back(e);
    }
  }
  return ret;
}
template<typename T>
Graph<T> readGraph(int n,int m,int indexed=1,bool directed=false,bool weighted=false){
  Graph<T> ret(n);
  for(int es = 0; es < m; es++){
    int u,v;
    T w=1;
    cin>>u>>v;u-=indexed,v-=indexed;
    if(weighted)cin>>w;
    ret[u].emplace_back(v,w,es);
    if(!directed)ret[v].emplace_back(u,w,es);
  }
  return ret;
}
template<typename T>
Graph<T> readParent(int n,int indexed=1,bool directed=true){
  Graph<T>ret(n);
  for(int i=1;i<n;i++){
    int p;cin>>p;
    p-=indexed;
    ret[p].emplace_back(i);
    if(!directed)ret[i].emplace_back(p);
  }
  return ret;
}

template <typename F>
class
#if defined(__has_cpp_attribute) && __has_cpp_attribute(nodiscard)
  [[nodiscard]]
#endif  // defined(__has_cpp_attribute) && __has_cpp_attribute(nodiscard)
FixPoint final : private F
{
public:
  template <typename G>
  explicit constexpr FixPoint(G&& g) noexcept
    : F{std::forward<G>(g)}
    {}

  template <typename... Args>
  constexpr decltype(auto)
  operator()(Args&&... args) const
#if !defined(__GNUC__) || defined(__clang__) || __GNUC__ >= 9
  noexcept(noexcept(F::operator()(std::declval<FixPoint>(), std::declval<Args>()...)))
#endif  // !defined(__GNUC__) || defined(__clang__) || __GNUC__ >= 9
  {
    return F::operator()(*this, std::forward<Args>(args)...);
  }
};  // class FixPoint


#if defined(__cpp_deduction_guides)
template <typename F>
FixPoint(F&&)
  -> FixPoint<std::decay_t<F>>;
#endif  // defined(__cpp_deduction_guides)


namespace
{
  template <typename F>
#if !defined(__has_cpp_attribute) || !__has_cpp_attribute(nodiscard)
#  if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 4)
  __attribute__((warn_unused_result))
#  elif defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_Check_return_)
  _Check_return_
#  endif  // defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#endif  // !defined(__has_cpp_attribute) || !__has_cpp_attribute(nodiscard)
  inline constexpr decltype(auto)
  makeFixPoint(F&& f) noexcept
{
  return FixPoint<std::decay_t<F>>{std::forward<std::decay_t<F>>(f)};
}
}  // namespace

int H, W;
vector<string> a;
string s;
int passed_time = 0;

vector<int> jump;

int dy[] = {-1, 0, 1, 0};
int dx[] = {0, 1, 0, -1};
string dir = "NESW";

using State = tuple<int, int, int, int>; // y, x, dir, cursor
set<State> st;
State now;

void action() {
  auto &[y, x, d, c] = now;
//  if (st.find(now) != st.end()) {
//    cout << -1 << endl;
//    exit(0);
//  }
//  st.insert(now);
  passed_time++;

  char mv = s[c++];
  if (mv == '^') {
    int ny = y + dy[d], nx = x + dx[d];
    if (a[ny][nx] != '#') {
      y = ny; x = nx;
    }
  } else if (mv == 'v') {
    int ny = y - dy[d], nx = x - dx[d];
    if (a[ny][nx] != '#') {
      y = ny; x = nx;
    }
  } else if (mv == '>') {
    d = (d + 1) % 4;
  } else if (mv == '<') {
    d = (d - 1 + 4) % 4;
  } else {
    assert(1);
  }

  if (a[y][x] == 'g') {
    cout << passed_time << endl;
    exit(0);
  }
}

bool condition() {
  auto &[y, x, d, c] = now;
//  cout << " in cond --- :" << y << " " << x << " " << dir[d] << " " << c << ": " << s.substr(c) << endl;
  bool inv = false;
  if (st.find(now) != st.end()) {
    cout << -1 << endl;
    exit(0);
  }
  st.insert(now);

  if (s[c] == '~') {
    c++; inv = true;
  }
  char p = s[c++];
  if (dir.find(p) != string::npos) {
    return inv ^ (dir.find(p) == d);
  } else if (p == 'C') {
    int ny = y + dy[d], nx = x + dx[d];
    return inv ^ (a[ny][nx] == '#');
  } else if (p == 'T') {
    return !inv;
  } else {
    assert(1);
  }
  return false;
}

void program();

void if_state() {
  auto &[y, x, d, c] = now;
  assert(s[c++] == '[');

  bool cond = condition();
  if (cond) {
    program();
  } else {
    c = jump[jump[c - 1]];
  }

  assert(s[c++] == ']');
}

void while_state() {
  auto &[y, x, d, c] = now;
  assert(s[c++] == '{');

  while (1) {
    bool cond = condition();
    if (cond) {
      program();
      c = jump[c] + 1;
    } else {
      c = jump[jump[c - 1]];
      break;
    }
  }

//  cout << y << " " << x << " " << dir[d] << " " << c << ": " << s[c] << endl;
  assert(s[c++] == '}');
}

void program() {
  auto &[y, x, d, c] = now;
//  cout << y << " " << x << " " << dir[d] << " " << c << ": " << s.substr(c) << endl;
  while (c < s.size() && s[c] != ']' && s[c] != '}') {
    if (s[c] == '[') {
      if_state();
    } else if (s[c] == '{') {
      while_state();
    } else {
      action();
    }
  }
}

int main() {
  cin >> H >> W; a.resize(H);
  rep(i, 0, H) cin >> a[i];

  cin >> s;
  jump.resize(s.size(), -1);

  stack<int> open;
  rep(i, 0, s.size()) {
    if (s[i] == '[' || s[i] == '{') {
      open.push(i);
    } else if (s[i] == ']' || s[i] == '}') {
      int idx = open.top(); open.pop();
      jump[idx] = i;
      jump[i] = idx;
    } else {
      if (open.size()) {
        jump[i] = open.top();
      }
    }
  }

  rep(i, 0, H) {
    rep(j, 0, W) {
      if (a[i][j] == 's') {
        now = State(i, j, 0, 0);
      }
    }
  }

  program();
  cout << -1 << endl;
}
accuracy: 1
time_ms: 130
memory_kb: 49404
final_rank: 6

code_snippet: //#define _GLIBCXX_DEBUG

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

#define endl '\n'
#define lfs cout<<fixed<<setprecision(10)
#define ALL(a)  (a).begin(),(a).end()
#define ALLR(a)  (a).rbegin(),(a).rend()
#define UNIQUE(a) (a).erase(unique((a).begin(),(a).end()),(a).end())
#define spa << " " <<
#define fi first
#define se second
#define MP make_pair
#define MT make_tuple
#define PB push_back
#define EB emplace_back
#define rep(i,n,m) for(ll i = (n); i < (ll)(m); i++)
#define rrep(i,n,m) for(ll i = (ll)(m) - 1; i >= (ll)(n); i--)
using ll = long long;
using ld = long double;
const ll MOD1 = 1e9+7;
const ll MOD9 = 998244353;
const ll INF = 1e18;
using P = pair<ll, ll>;
template<typename T> using PQ = priority_queue<T>;
template<typename T> using QP = priority_queue<T,vector<T>,greater<T>>;
template<typename T1, typename T2>bool chmin(T1 &a,T2 b){if(a>b){a=b;return true;}else return false;}
template<typename T1, typename T2>bool chmax(T1 &a,T2 b){if(a<b){a=b;return true;}else return false;}
ll median(ll a,ll b, ll c){return a+b+c-max({a,b,c})-min({a,b,c});}
void ans1(bool x){if(x) cout<<"Yes"<<endl;else cout<<"No"<<endl;}
void ans2(bool x){if(x) cout<<"YES"<<endl;else cout<<"NO"<<endl;}
void ans3(bool x){if(x) cout<<"Yay!"<<endl;else cout<<":("<<endl;}
template<typename T1,typename T2>void ans(bool x,T1 y,T2 z){if(x)cout<<y<<endl;else cout<<z<<endl;}  
template<typename T1,typename T2,typename T3>void anss(T1 x,T2 y,T3 z){ans(x!=y,x,z);};  
template<typename T>void debug(const T &v,ll h,ll w,string sv=" "){for(ll i=0;i<h;i++){cout<<v[i][0];for(ll j=1;j<w;j++)cout<<sv<<v[i][j];cout<<endl;}};
template<typename T>void debug(const T &v,ll n,string sv=" "){if(n!=0)cout<<v[0];for(ll i=1;i<n;i++)cout<<sv<<v[i];cout<<endl;};
template<typename T>void debug(const vector<T>&v){debug(v,v.size());}
template<typename T>void debug(const vector<vector<T>>&v){for(auto &vv:v)debug(vv,vv.size());}
template<typename T>void debug(stack<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(queue<T> st){while(!st.empty()){cout<<st.front()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(deque<T> st){while(!st.empty()){cout<<st.front()<<" ";st.pop_front();}cout<<endl;}
template<typename T>void debug(PQ<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(QP<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(const set<T>&v){for(auto z:v)cout<<z<<" ";cout<<endl;}
template<typename T>void debug(const multiset<T>&v){for(auto z:v)cout<<z<<" ";cout<<endl;}
template<typename T,size_t size>void debug(const array<T, size> &a){for(auto z:a)cout<<z<<" ";cout<<endl;}
template<typename T,typename V>void debug(const map<T,V>&v){for(auto z:v)cout<<"["<<z.first<<"]="<<z.second<<",";cout<<endl;}
template<typename T>vector<vector<T>>vec(ll x, ll y, T w){vector<vector<T>>v(x,vector<T>(y,w));return v;}
ll gcd(ll x,ll y){ll r;while(y!=0&&(r=x%y)!=0){x=y;y=r;}return y==0?x:y;}
//vector<ll>dx={1,-1,0,0,1,1,-1,-1};vector<ll>dy={0,0,1,-1,1,-1,1,-1};
template<typename T>vector<T> make_v(size_t a,T b){return vector<T>(a,b);}
template<typename... Ts>auto make_v(size_t a,Ts... ts){return vector<decltype(make_v(ts...))>(a,make_v(ts...));}
template<typename T1, typename T2>ostream &operator<<(ostream &os, const pair<T1, T2>&p){return os << p.first << " " << p.second;}
template<typename T>ostream &operator<<(ostream &os, const vector<T> &v){for(auto &z:v)os << z << " ";cout<<"|"; return os;}
template<typename T>void rearrange(vector<int>&ord, vector<T>&v){
  auto tmp = v;
  for(int i=0;i<tmp.size();i++)v[i] = tmp[ord[i]];
}
template<typename Head, typename... Tail>void rearrange(vector<int>&ord,Head&& head, Tail&&... tail){
  rearrange(ord, head);
  rearrange(ord, tail...);
}
template<typename T> vector<int> ascend(const vector<T>&v){
  vector<int>ord(v.size());iota(ord.begin(),ord.end(),0);
  sort(ord.begin(),ord.end(),[&](int i,int j){return v[i]<v[j];});
  return ord;
}
template<typename T> vector<int> descend(const vector<T>&v){
  vector<int>ord(v.size());iota(ord.begin(),ord.end(),0);
  sort(ord.begin(),ord.end(),[&](int i,int j){return v[i]>v[j];});
  return ord;
}
template<typename T> vector<T> inv_perm(const vector<T>&ord){
  vector<T>inv(ord.size());
  for(int i=0;i<ord.size();i++)inv[ord[i]] = i;
  return inv;
}
ll FLOOR(ll n,ll div){assert(div>0);return n>=0?n/div:(n-div+1)/div;}
ll CEIL(ll n,ll div){assert(div>0);return n>=0?(n+div-1)/div:n/div;}
ll digitsum(ll n){ll ret=0;while(n){ret+=n%10;n/=10;}return ret;}
ll modulo(ll n,ll d){return (n%d+d)%d;};
template<typename T>T min(const vector<T>&v){return *min_element(v.begin(),v.end());}
template<typename T>T max(const vector<T>&v){return *max_element(v.begin(),v.end());}
template<typename T>T acc(const vector<T>&v){return accumulate(v.begin(),v.end(),T(0));};
template<typename T>T reverse(const T &v){return T(v.rbegin(),v.rend());};
//mt19937 mt(chrono::steady_clock::now().time_since_epoch().count());
int popcount(ll x){return __builtin_popcountll(x);};
int poplow(ll x){return __builtin_ctzll(x);};
int pophigh(ll x){return 63 - __builtin_clzll(x);};
template<typename T>T poll(queue<T> &q){auto ret=q.front();q.pop();return ret;};
template<typename T>T poll(priority_queue<T> &q){auto ret=q.top();q.pop();return ret;};
template<typename T>T poll(QP<T> &q){auto ret=q.top();q.pop();return ret;};
template<typename T>T poll(stack<T> &s){auto ret=s.top();s.pop();return ret;};
ll MULT(ll x,ll y){if(LLONG_MAX/x<=y)return LLONG_MAX;return x*y;}
ll POW2(ll x, ll k){ll ret=1,mul=x;while(k){if(mul==LLONG_MAX)return LLONG_MAX;if(k&1)ret=MULT(ret,mul);mul=MULT(mul,mul);k>>=1;}return ret;}
ll POW(ll x, ll k){ll ret=1;for(int i=0;i<k;i++){if(LLONG_MAX/x<=ret)return LLONG_MAX;ret*=x;}return ret;}
template< typename T = int >
struct edge {
  int to;
  T cost;
  int id;
  edge():id(-1){};
  edge(int to, T cost = 1, int id = -1):to(to), cost(cost), id(id){}
  operator int() const { return to; }
};

template<typename T>
using Graph = vector<vector<edge<T>>>;
template<typename T>
Graph<T>revgraph(const Graph<T> &g){
  Graph<T>ret(g.size());
  for(int i=0;i<g.size();i++){
    for(auto e:g[i]){
      int to = e.to;
      e.to = i;
      ret[to].push_back(e);
    }
  }
  return ret;
}
template<typename T>
Graph<T> readGraph(int n,int m,int indexed=1,bool directed=false,bool weighted=false){
  Graph<T> ret(n);
  for(int es = 0; es < m; es++){
    int u,v;
    T w=1;
    cin>>u>>v;u-=indexed,v-=indexed;
    if(weighted)cin>>w;
    ret[u].emplace_back(v,w,es);
    if(!directed)ret[v].emplace_back(u,w,es);
  }
  return ret;
}
template<typename T>
Graph<T> readParent(int n,int indexed=1,bool directed=true){
  Graph<T>ret(n);
  for(int i=1;i<n;i++){
    int p;cin>>p;
    p-=indexed;
    ret[p].emplace_back(i);
    if(!directed)ret[i].emplace_back(p);
  }
  return ret;
}

template <typename F>
class
#if defined(__has_cpp_attribute) && __has_cpp_attribute(nodiscard)
  [[nodiscard]]
#endif  // defined(__has_cpp_attribute) && __has_cpp_attribute(nodiscard)
FixPoint final : private F
{
public:
  template <typename G>
  explicit constexpr FixPoint(G&& g) noexcept
    : F{std::forward<G>(g)}
    {}

  template <typename... Args>
  constexpr decltype(auto)
  operator()(Args&&... args) const
#if !defined(__GNUC__) || defined(__clang__) || __GNUC__ >= 9
  noexcept(noexcept(F::operator()(std::declval<FixPoint>(), std::declval<Args>()...)))
#endif  // !defined(__GNUC__) || defined(__clang__) || __GNUC__ >= 9
  {
    return F::operator()(*this, std::forward<Args>(args)...);
  }
};  // class FixPoint


#if defined(__cpp_deduction_guides)
template <typename F>
FixPoint(F&&)
  -> FixPoint<std::decay_t<F>>;
#endif  // defined(__cpp_deduction_guides)


namespace
{
  template <typename F>
#if !defined(__has_cpp_attribute) || !__has_cpp_attribute(nodiscard)
#  if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 4)
  __attribute__((warn_unused_result))
#  elif defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_Check_return_)
  _Check_return_
#  endif  // defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#endif  // !defined(__has_cpp_attribute) || !__has_cpp_attribute(nodiscard)
  inline constexpr decltype(auto)
  makeFixPoint(F&& f) noexcept
{
  return FixPoint<std::decay_t<F>>{std::forward<std::decay_t<F>>(f)};
}
}  // namespace

int H, W;
vector<string> a;
string s;
int passed_time = 0;

vector<int> jump;

int dy[] = {-1, 0, 1, 0};
int dx[] = {0, 1, 0, -1};
string dir = "NESW";

using State = tuple<int, int, int, int>; // y, x, dir, cursor
set<State> st;
State now;

void action() {
  auto &[y, x, d, c] = now;
//  if (st.find(now) != st.end()) {
//    cout << -1 << endl;
//    exit(0);
//  }
//  st.insert(now);
  passed_time++;

  char mv = s[c++];
  if (mv == '^') {
    int ny = y + dy[d], nx = x + dx[d];
    if (a[ny][nx] != '#') {
      y = ny; x = nx;
    }
  } else if (mv == 'v') {
    int ny = y - dy[d], nx = x - dx[d];
    if (a[ny][nx] != '#') {
      y = ny; x = nx;
    }
  } else if (mv == '>') {
    d = (d + 1) % 4;
  } else if (mv == '<') {
    d = (d - 1 + 4) % 4;
  } else {
    assert(1);
  }

  if (a[y][x] == 'g') {
    cout << passed_time << endl;
    exit(0);
  }
}

bool condition() {
  auto &[y, x, d, c] = now;
//  cout << " in cond --- :" << y << " " << x << " " << dir[d] << " " << c << ": " << s.substr(c) << endl;
  bool inv = false;
  if (st.find(now) != st.end()) {
    cout << -1 << endl;
    exit(0);
  }
  st.insert(now);

  if (s[c] == '~') {
    c++; inv = true;
  }
  char p = s[c++];
  if (dir.find(p) != string::npos) {
    return inv ^ (dir.find(p) == d);
  } else if (p == 'C') {
    int ny = y + dy[d], nx = x + dx[d];
    return inv ^ (a[ny][nx] == '#');
  } else if (p == 'T') {
    return !inv;
  } else {
    assert(1);
  }
  return false;
}

void program();

void if_state() {
  auto &[y, x, d, c] = now;
  assert(s[c++] == '[');

  bool cond = condition();
  if (cond) {
    program();
  } else {
    c = jump[jump[c]];
  }

  assert(s[c++] == ']');
}

void while_state() {
  auto &[y, x, d, c] = now;
  assert(s[c++] == '{');

  while (1) {
    bool cond = condition();
    if (cond) {
      program();
      c = jump[c] + 1;
    } else {
      c = jump[jump[c - 1]];
      break;
    }
  }

//  cout << y << " " << x << " " << dir[d] << " " << c << ": " << s[c] << endl;
  assert(s[c++] == '}');
}

void program() {
  auto &[y, x, d, c] = now;
//  cout << y << " " << x << " " << dir[d] << " " << c << ": " << s.substr(c) << endl;
  while (c < s.size() && s[c] != ']' && s[c] != '}') {
    if (s[c] == '[') {
      if_state();
    } else if (s[c] == '{') {
      while_state();
    } else {
      action();
    }
  }
}

int main() {
  cin >> H >> W; a.resize(H);
  rep(i, 0, H) cin >> a[i];

  cin >> s;
  jump.resize(s.size(), -1);

  stack<int> open;
  rep(i, 0, s.size()) {
    if (s[i] == '[' || s[i] == '{') {
      open.push(i);
    } else if (s[i] == ']' || s[i] == '}') {
      int idx = open.top(); open.pop();
      jump[idx] = i;
      jump[i] = idx;
    } else {
      if (open.size()) {
        jump[i] = open.top();
      }
    }
  }

  rep(i, 0, H) {
    rep(j, 0, W) {
      if (a[i][j] == 's') {
        now = State(i, j, 0, 0);
      }
    }
  }

  program();
  cout << -1 << endl;
}
accuracy: 0.45569620253164556
time_ms: 130
memory_kb: 49580
final_rank: 11

code_snippet: //#define _GLIBCXX_DEBUG

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

#define endl '\n'
#define lfs cout<<fixed<<setprecision(10)
#define ALL(a)  (a).begin(),(a).end()
#define ALLR(a)  (a).rbegin(),(a).rend()
#define UNIQUE(a) (a).erase(unique((a).begin(),(a).end()),(a).end())
#define spa << " " <<
#define fi first
#define se second
#define MP make_pair
#define MT make_tuple
#define PB push_back
#define EB emplace_back
#define rep(i,n,m) for(ll i = (n); i < (ll)(m); i++)
#define rrep(i,n,m) for(ll i = (ll)(m) - 1; i >= (ll)(n); i--)
using ll = long long;
using ld = long double;
const ll MOD1 = 1e9+7;
const ll MOD9 = 998244353;
const ll INF = 1e18;
using P = pair<ll, ll>;
template<typename T> using PQ = priority_queue<T>;
template<typename T> using QP = priority_queue<T,vector<T>,greater<T>>;
template<typename T1, typename T2>bool chmin(T1 &a,T2 b){if(a>b){a=b;return true;}else return false;}
template<typename T1, typename T2>bool chmax(T1 &a,T2 b){if(a<b){a=b;return true;}else return false;}
ll median(ll a,ll b, ll c){return a+b+c-max({a,b,c})-min({a,b,c});}
void ans1(bool x){if(x) cout<<"Yes"<<endl;else cout<<"No"<<endl;}
void ans2(bool x){if(x) cout<<"YES"<<endl;else cout<<"NO"<<endl;}
void ans3(bool x){if(x) cout<<"Yay!"<<endl;else cout<<":("<<endl;}
template<typename T1,typename T2>void ans(bool x,T1 y,T2 z){if(x)cout<<y<<endl;else cout<<z<<endl;}  
template<typename T1,typename T2,typename T3>void anss(T1 x,T2 y,T3 z){ans(x!=y,x,z);};  
template<typename T>void debug(const T &v,ll h,ll w,string sv=" "){for(ll i=0;i<h;i++){cout<<v[i][0];for(ll j=1;j<w;j++)cout<<sv<<v[i][j];cout<<endl;}};
template<typename T>void debug(const T &v,ll n,string sv=" "){if(n!=0)cout<<v[0];for(ll i=1;i<n;i++)cout<<sv<<v[i];cout<<endl;};
template<typename T>void debug(const vector<T>&v){debug(v,v.size());}
template<typename T>void debug(const vector<vector<T>>&v){for(auto &vv:v)debug(vv,vv.size());}
template<typename T>void debug(stack<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(queue<T> st){while(!st.empty()){cout<<st.front()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(deque<T> st){while(!st.empty()){cout<<st.front()<<" ";st.pop_front();}cout<<endl;}
template<typename T>void debug(PQ<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(QP<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(const set<T>&v){for(auto z:v)cout<<z<<" ";cout<<endl;}
template<typename T>void debug(const multiset<T>&v){for(auto z:v)cout<<z<<" ";cout<<endl;}
template<typename T,size_t size>void debug(const array<T, size> &a){for(auto z:a)cout<<z<<" ";cout<<endl;}
template<typename T,typename V>void debug(const map<T,V>&v){for(auto z:v)cout<<"["<<z.first<<"]="<<z.second<<",";cout<<endl;}
template<typename T>vector<vector<T>>vec(ll x, ll y, T w){vector<vector<T>>v(x,vector<T>(y,w));return v;}
ll gcd(ll x,ll y){ll r;while(y!=0&&(r=x%y)!=0){x=y;y=r;}return y==0?x:y;}
//vector<ll>dx={1,-1,0,0,1,1,-1,-1};vector<ll>dy={0,0,1,-1,1,-1,1,-1};
template<typename T>vector<T> make_v(size_t a,T b){return vector<T>(a,b);}
template<typename... Ts>auto make_v(size_t a,Ts... ts){return vector<decltype(make_v(ts...))>(a,make_v(ts...));}
template<typename T1, typename T2>ostream &operator<<(ostream &os, const pair<T1, T2>&p){return os << p.first << " " << p.second;}
template<typename T>ostream &operator<<(ostream &os, const vector<T> &v){for(auto &z:v)os << z << " ";cout<<"|"; return os;}
template<typename T>void rearrange(vector<int>&ord, vector<T>&v){
  auto tmp = v;
  for(int i=0;i<tmp.size();i++)v[i] = tmp[ord[i]];
}
template<typename Head, typename... Tail>void rearrange(vector<int>&ord,Head&& head, Tail&&... tail){
  rearrange(ord, head);
  rearrange(ord, tail...);
}
template<typename T> vector<int> ascend(const vector<T>&v){
  vector<int>ord(v.size());iota(ord.begin(),ord.end(),0);
  sort(ord.begin(),ord.end(),[&](int i,int j){return v[i]<v[j];});
  return ord;
}
template<typename T> vector<int> descend(const vector<T>&v){
  vector<int>ord(v.size());iota(ord.begin(),ord.end(),0);
  sort(ord.begin(),ord.end(),[&](int i,int j){return v[i]>v[j];});
  return ord;
}
template<typename T> vector<T> inv_perm(const vector<T>&ord){
  vector<T>inv(ord.size());
  for(int i=0;i<ord.size();i++)inv[ord[i]] = i;
  return inv;
}
ll FLOOR(ll n,ll div){assert(div>0);return n>=0?n/div:(n-div+1)/div;}
ll CEIL(ll n,ll div){assert(div>0);return n>=0?(n+div-1)/div:n/div;}
ll digitsum(ll n){ll ret=0;while(n){ret+=n%10;n/=10;}return ret;}
ll modulo(ll n,ll d){return (n%d+d)%d;};
template<typename T>T min(const vector<T>&v){return *min_element(v.begin(),v.end());}
template<typename T>T max(const vector<T>&v){return *max_element(v.begin(),v.end());}
template<typename T>T acc(const vector<T>&v){return accumulate(v.begin(),v.end(),T(0));};
template<typename T>T reverse(const T &v){return T(v.rbegin(),v.rend());};
//mt19937 mt(chrono::steady_clock::now().time_since_epoch().count());
int popcount(ll x){return __builtin_popcountll(x);};
int poplow(ll x){return __builtin_ctzll(x);};
int pophigh(ll x){return 63 - __builtin_clzll(x);};
template<typename T>T poll(queue<T> &q){auto ret=q.front();q.pop();return ret;};
template<typename T>T poll(priority_queue<T> &q){auto ret=q.top();q.pop();return ret;};
template<typename T>T poll(QP<T> &q){auto ret=q.top();q.pop();return ret;};
template<typename T>T poll(stack<T> &s){auto ret=s.top();s.pop();return ret;};
ll MULT(ll x,ll y){if(LLONG_MAX/x<=y)return LLONG_MAX;return x*y;}
ll POW2(ll x, ll k){ll ret=1,mul=x;while(k){if(mul==LLONG_MAX)return LLONG_MAX;if(k&1)ret=MULT(ret,mul);mul=MULT(mul,mul);k>>=1;}return ret;}
ll POW(ll x, ll k){ll ret=1;for(int i=0;i<k;i++){if(LLONG_MAX/x<=ret)return LLONG_MAX;ret*=x;}return ret;}
template< typename T = int >
struct edge {
  int to;
  T cost;
  int id;
  edge():id(-1){};
  edge(int to, T cost = 1, int id = -1):to(to), cost(cost), id(id){}
  operator int() const { return to; }
};

template<typename T>
using Graph = vector<vector<edge<T>>>;
template<typename T>
Graph<T>revgraph(const Graph<T> &g){
  Graph<T>ret(g.size());
  for(int i=0;i<g.size();i++){
    for(auto e:g[i]){
      int to = e.to;
      e.to = i;
      ret[to].push_back(e);
    }
  }
  return ret;
}
template<typename T>
Graph<T> readGraph(int n,int m,int indexed=1,bool directed=false,bool weighted=false){
  Graph<T> ret(n);
  for(int es = 0; es < m; es++){
    int u,v;
    T w=1;
    cin>>u>>v;u-=indexed,v-=indexed;
    if(weighted)cin>>w;
    ret[u].emplace_back(v,w,es);
    if(!directed)ret[v].emplace_back(u,w,es);
  }
  return ret;
}
template<typename T>
Graph<T> readParent(int n,int indexed=1,bool directed=true){
  Graph<T>ret(n);
  for(int i=1;i<n;i++){
    int p;cin>>p;
    p-=indexed;
    ret[p].emplace_back(i);
    if(!directed)ret[i].emplace_back(p);
  }
  return ret;
}

template <typename F>
class
#if defined(__has_cpp_attribute) && __has_cpp_attribute(nodiscard)
  [[nodiscard]]
#endif  // defined(__has_cpp_attribute) && __has_cpp_attribute(nodiscard)
FixPoint final : private F
{
public:
  template <typename G>
  explicit constexpr FixPoint(G&& g) noexcept
    : F{std::forward<G>(g)}
    {}

  template <typename... Args>
  constexpr decltype(auto)
  operator()(Args&&... args) const
#if !defined(__GNUC__) || defined(__clang__) || __GNUC__ >= 9
  noexcept(noexcept(F::operator()(std::declval<FixPoint>(), std::declval<Args>()...)))
#endif  // !defined(__GNUC__) || defined(__clang__) || __GNUC__ >= 9
  {
    return F::operator()(*this, std::forward<Args>(args)...);
  }
};  // class FixPoint


#if defined(__cpp_deduction_guides)
template <typename F>
FixPoint(F&&)
  -> FixPoint<std::decay_t<F>>;
#endif  // defined(__cpp_deduction_guides)


namespace
{
  template <typename F>
#if !defined(__has_cpp_attribute) || !__has_cpp_attribute(nodiscard)
#  if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 4)
  __attribute__((warn_unused_result))
#  elif defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_Check_return_)
  _Check_return_
#  endif  // defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#endif  // !defined(__has_cpp_attribute) || !__has_cpp_attribute(nodiscard)
  inline constexpr decltype(auto)
  makeFixPoint(F&& f) noexcept
{
  return FixPoint<std::decay_t<F>>{std::forward<std::decay_t<F>>(f)};
}
}  // namespace

int H, W;
vector<string> a;
string s;
int passed_time = 0;

vector<int> jump;

int dy[] = {-1, 0, 1, 0};
int dx[] = {0, 1, 0, -1};
string dir = "NESW";

using State = tuple<int, int, int, int>; // y, x, dir, cursor
set<State> st;
State now;

void action() {
  auto &[y, x, d, c] = now;
//  if (st.find(now) != st.end()) {
//    cout << -1 << endl;
//    exit(0);
//  }
//  st.insert(now);
  if (a[y][x] == 'g') {
    cout << passed_time << endl;
    exit(0);
  }
  passed_time++;

  char mv = s[c++];
  if (mv == '^') {
    int ny = y + dy[d], nx = x + dx[d];
    if (a[ny][nx] != '#') {
      y = ny; x = nx;
    }
  } else if (mv == 'v') {
    int ny = y - dy[d], nx = x - dx[d];
    if (a[ny][nx] != '#') {
      y = ny; x = nx;
    }
  } else if (mv == '>') {
    d = (d + 1) % 4;
  } else if (mv == '<') {
    d = (d - 1 + 4) % 4;
  } else {
    assert(1);
  }
}

bool condition() {
  auto &[y, x, d, c] = now;
//  cout << " in cond --- :" << y << " " << x << " " << dir[d] << " " << c << ": " << s[c] << endl;
  bool inv = false;
  if (st.find(now) != st.end()) {
    cout << -1 << endl;
    exit(0);
  }
  st.insert(now);

  if (s[c] == '~') {
    c++; inv = true;
  }
  char p = s[c++];
  if (dir.find(p) != string::npos) {
    return inv ^ (dir.find(p) == d);
  } else if (p == 'C') {
    int ny = y + dy[d], nx = x + dx[d];
    return inv ^ (a[ny][nx] == '#');
  } else if (p == 'T') {
    return !inv;
  } else {
    assert(1);
  }
  return false;
}

void program();

void if_state() {
  auto &[y, x, d, c] = now;
  assert(s[c++] == '[');

  bool cond = condition();
  if (cond) {
    program();
  } else {
    c = jump[jump[c]];
  }

  assert(s[c++] == ']');
}

void while_state() {
  auto &[y, x, d, c] = now;
  assert(s[c++] == '{');

  while (1) {
    bool cond = condition();
    if (cond) {
      program();
      c = jump[c] + 1;
    } else {
      c = jump[jump[c - 1]];
      break;
    }
  }

//  cout << y << " " << x << " " << dir[d] << " " << c << ": " << s[c] << endl;
  assert(s[c++] == '}');
}

void program() {
  auto &[y, x, d, c] = now;
//  cout << y << " " << x << " " << dir[d] << " " << c << ": " << s[c] << endl;
  while (c < s.size() && s[c] != ']' && s[c] != '}') {
    if (s[c] == '[') {
      if_state();
    } else if (s[c] == '{') {
      while_state();
    } else {
      action();
    }
  }
}

int main() {
  cin >> H >> W; a.resize(H);
  rep(i, 0, H) cin >> a[i];

  cin >> s;
  jump.resize(s.size(), -1);

  stack<int> open;
  rep(i, 0, s.size()) {
    if (s[i] == '[' || s[i] == '{') {
      open.push(i);
    } else if (s[i] == ']' || s[i] == '}') {
      int idx = open.top(); open.pop();
      jump[idx] = i;
      jump[i] = idx;
    } else {
      if (open.size()) {
        jump[i] = open.top();
      }
    }
  }

  rep(i, 0, H) {
    rep(j, 0, W) {
      if (a[i][j] == 's') {
        now = State(i, j, 0, 0);
      }
    }
  }

  program();
  cout << -1 << endl;
}
accuracy: 0.17721518987341772
time_ms: 140
memory_kb: 49476
final_rank: 15

code_snippet: #include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <climits>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <memory>
#include <numeric>
#include <optional>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

/* macro */

#define rep(i, a, n) for (int i = (int)(a); i < (int)(n); i++)
#define rrep(i, a, n) for (int i = ((int)(n - 1)); i >= (int)(a); i--)
#define Rep(i, a, n) for (i64 i = (i64)(a); i < (i64)(n); i++)
#define RRep(i, a, n) for (i64 i = ((i64)(n - i64(1))); i >= (i64)(a); i--)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define Bit(n) (1LL << (n))

/* macro end */

/* template */

namespace ebi {

#ifdef LOCAL
#define debug(...)                                                      \
    std::cerr << "LINE: " << __LINE__ << "  [" << #__VA_ARGS__ << "]:", \
        debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif

void debug_out() { std::cerr << std::endl; }

template <typename Head, typename... Tail>
void debug_out(Head h, Tail... t) {
    std::cerr << " " << h;
    if (sizeof...(t) > 0) std::cout << " :";
    debug_out(t...);
}

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

template <typename T1, typename T2>
std::istream &operator>>(std::istream &os, std::pair<T1, T2> &pa) {
    return os >> pa.first >> pa.second;
}

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

template <typename T>
std::istream &operator>>(std::istream &os, std::vector<T> &vec) {
    for (T &e : vec) std::cin >> e;
    return os;
}

template <typename T>
std::ostream &operator<<(std::ostream &os, const std::optional<T> &opt) {
    if (opt) {
        os << opt.value();
    } else {
        os << "invalid value";
    }
    return os;
}

using std::size_t;
using i32 = std::int32_t;
using u32 = std::uint32_t;
using i64 = std::int64_t;
using u64 = std::uint64_t;

template <class T, T init>
auto make_vector(int n) {
    return std::vector<T>(n, init);
}

template <class T, T init, typename Head, typename... Tail>
auto make_vector(Head n, Tail... ts) {
    return std::vector(n, make_vector<T, init>(ts...));
}

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

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

template <class T>
T pow(T x, i64 n) {
    T res = 1;
    while (n > 0) {
        if (n & 1) res = res * x;
        x = x * x;
        n >>= 1;
    }
    return res;
}

template <class T>
T mod_pow(T x, i64 n, i64 mod) {
    T res = 1;
    while (n > 0) {
        if (n & 1) res = (res * x) % mod;
        x = (x * x) % mod;
        n >>= 1;
    }
    return res;
}

template <class T>
T scan() {
    T val;
    std::cin >> val;
    return val;
}

template <class T>
struct Edge {
    int to;
    T cost;
    Edge(int _to, T _cost = 1) : to(_to), cost(_cost) {}
};

template <class T>
struct Graph : std::vector<std::vector<Edge<T>>> {
    using std::vector<std::vector<Edge<T>>>::vector;
    void add_edge(int u, int v, T w, bool directed = false) {
        (*this)[u].emplace_back(v, w);
        if (directed) return;
        (*this)[v].emplace_back(u, w);
    }
};

struct graph : std::vector<std::vector<int>> {
    using std::vector<std::vector<int>>::vector;
    void add_edge(int u, int v, bool directed = false) {
        (*this)[u].emplace_back(v);
        if (directed) return;
        (*this)[v].emplace_back(u);
    }
};

constexpr i64 LNF = std::numeric_limits<i64>::max() / 4;

constexpr int INF = std::numeric_limits<int>::max() / 2;

// const std::vector<int> dy = {1, 0, -1, 0, 1, 1, -1, -1};
// const std::vector<int> dx = {0, 1, 0, -1, 1, -1, 1, -1};

const std::vector<int> dy = {-1, 0, 1, 0};
const std::vector<int> dx = {0, 1, 0, -1};

}  // namespace ebi

/*
    reference: https://gist.github.com/draftcode/1357281
*/

namespace ebi {

typedef std::string::const_iterator State;
class ParseError {};

bool expect(State &begin, char expected) {
    if (*begin == expected) {
        return true;
    } else {
        return false;
    }
}

// beginがexpectedを指していたらbeginを一つ進める。
void consume(State &begin, char expected) {
    if (*begin == expected) {
        begin++;
    } else {
        std::cerr << "Expected '" << expected << "' but got '" << *begin << "'"
                  << std::endl;
        std::cerr << "Rest string is '";
        while (*begin) {
            std::cerr << *begin++;
        }
        std::cerr << "'" << std::endl;
        throw ParseError();
    }
}

bool isdigit(char c) { return '0' <= c && c <= '9'; }

bool isAlpha(char c) { return 'A' <= c && c <= 'Z'; }

bool isalpha(char c) { return 'a' <= c && c <= 'z'; }

}  // namespace ebi

namespace ebi {

enum Type { MOVE, IF, WHILE, WHILEEND, END };

struct Node {
    Type type;
    int condition;
    int next;
    Node(Type t, int c, int nxt) : type(t), condition(c), next(nxt) {}
};

std::vector<Node> program;

void Program(State &);
void Sentence(State &);
void If(State &);
void While(State &);
void Move(State &);
void Condition(State &);

void Program(State &begin) {
    while (!expect(begin, ';')) Sentence(begin);
    program.emplace_back(END, -1, -1);
}

void Sentence(State &begin) {
    if (expect(begin, '['))
        If(begin);
    else if (expect(begin, '{'))
        While(begin);
    else
        Move(begin);
    return;
}

void If(State &begin) {
    consume(begin, '[');
    int idx = program.size();
    program.emplace_back(IF, -1, -1);
    Condition(begin);
    while (!expect(begin, ']')) {
        Sentence(begin);
    }
    consume(begin, ']');
    program[idx].next = program.size();
}

void While(State &begin) {
    consume(begin, '{');
    int idx = program.size();
    program.emplace_back(WHILE, -1, -1);
    Condition(begin);
    while (!expect(begin, '}')) {
        Sentence(begin);
    }
    consume(begin, '}');
    program.emplace_back(WHILEEND, -1, idx);
    program[idx].next = program.size();
}

void Move(State &begin) {
    int move = 0;
    if (expect(begin, '^')) {
        consume(begin, '^');
    } else if (expect(begin, 'v')) {
        consume(begin, 'v');
        move = 1;
    } else if (expect(begin, '<')) {
        consume(begin, '<');
        move = 2;
    } else if (expect(begin, '>')) {
        consume(begin, '>');
        move = 3;
    } else {
        assert(0);
    }
    program.emplace_back(MOVE, -1, move);
}

void Condition(State &begin) {
    int condition = 0;
    if (expect(begin, '~')) {
        consume(begin, '~');
        condition |= 1 << 3;
    }
    if (expect(begin, 'N')) {
        consume(begin, 'N');
    } else if (expect(begin, 'E')) {
        consume(begin, 'E');
        condition |= 1;
    } else if (expect(begin, 'S')) {
        consume(begin, 'S');
        condition |= 2;
    } else if (expect(begin, 'W')) {
        consume(begin, 'W');
        condition |= 3;
    } else if (expect(begin, 'C')) {
        consume(begin, 'C');
        condition |= 4;
    } else if (expect(begin, 'T')) {
        consume(begin, 'T');
        condition |= 5;
    } else {
        assert(0);
    }
    program.back().condition = condition;
}

int dp[50][50][1010][4];

void main_() {
    int h, w;
    std::cin >> h >> w;
    std::vector<std::string> a(h);
    std::cin >> a;
    int sy = -1, sx = -1, gy = -1, gx = -1;
    rep(i, 0, h) rep(j, 0, w) {
        if (a[i][j] == 's') {
            sy = i;
            sx = j;
        } else if (a[i][j] == 'g') {
            gy = i;
            gx = j;
        }
    }
    std::string s;
    std::cin >> s;
    s += ';';
    State begin = s.begin();
    Program(begin);
    int sz = program.size();
    {
        rep(i,0,h) rep(j,0,w) rep(k,0,sz) rep(l,0,4) dp[i][j][k][l] = INF;
    }
    std::queue<std::tuple<int, int, int, int>> que;
    auto can_move = [&](int y, int x, int move) -> bool {
        int ny = y + dy[move];
        int nx = x + dx[move];
        if (0 <= ny && ny < h && 0 <= nx && nx < w && a[ny][nx] != '#') {
            return true;
        }
        return false;
    };

    auto iscondition = [&](int y, int x, int direction, int condition) -> bool {
        bool flag = true;
        if ((condition >> 3) & 1) {
            condition ^= 1 << 3;
            flag = false;
        }
        if (condition < 4) {
            return flag == (condition == direction);
        } else if (condition == 4) {
            return flag == (!can_move(y, x, direction));
        } else if (condition == 5) {
            return flag;
        } else
            assert(0);
    };
    auto next_move = [&](int y, int x, int idx, int direction) -> int {
        std::set<int> set;
        set.insert(idx);
        while (program[idx].type != MOVE) {
            if (program[idx].type == WHILEEND) {
                idx = program[idx].next;
            } else if (program[idx].type == WHILE || program[idx].type == IF) {
                if (iscondition(y, x, direction, program[idx].condition)) {
                    idx++;
                } else {
                    idx = program[idx].next;
                }
            } else if (program[idx].type == END) {
                assert(idx == sz - 1);
                return sz - 1;
            } else
                assert(0);
            if(set.find(idx) == set.end()) {
                set.insert(idx);
            }
            else return sz - 1;
        }
        return idx;
    };
    {
        int idx = next_move(sy, sx, 0, 0);
        if (idx != sz - 1) {
            que.push({sy, sx, idx, 0});
            dp[sy][sx][idx][0] = 0;
        }
    }
    while (!que.empty()) {
        auto [y, x, idx, direction] = que.front();
        que.pop();
        assert(program[idx].type == MOVE);
        int move = program[idx].next;
        int ret = dp[y][x][idx][direction];
        if (move == 0) {
            if (can_move(y, x, direction)) {
                y += dy[direction];
                x += dx[direction];
            }
        } else if (move == 1) {
            int i = (direction + 2) % 4;
            if (can_move(y, x, i)) {
                y += dy[i];
                x += dx[i];
            }
        } else if (move == 2) {
            direction = (direction + 3) % 4;
        } else if (move == 3) {
            direction = (direction + 1) % 4;
        } else
            assert(0);
        idx = next_move(y, x, ++idx, direction);
        if (ret + 1 < dp[y][x][idx][direction]) {
            dp[y][x][idx][direction] = ret + 1;
            if (idx == sz - 1) continue;
            que.push({y, x, idx, direction});
        }
    }
    int ans = INF;
    rep(i, 0, sz) rep(j, 0, 4) chmin(ans, dp[gy][gx][i][j]);
    if (ans == INF) ans = -1;
    std::cout << ans << '\n';
}

}  // namespace ebi

int main() {
    std::cout << std::fixed << std::setprecision(15);
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);
    int t = 1;
    // std::cin >> t;
    while (t--) {
        ebi::main_();
    }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 42936
final_rank: 5

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

#ifdef _MSC_VER
#  include <intrin.h>
#else
#  include <x86intrin.h>
#endif

#include <limits>
#include <type_traits>

namespace suisen {
// ! utility
template <typename ...Types>
using constraints_t = std::enable_if_t<std::conjunction_v<Types...>, std::nullptr_t>;
template <bool cond_v, typename Then, typename OrElse>
constexpr decltype(auto) constexpr_if(Then&& then, OrElse&& or_else) {
    if constexpr (cond_v) {
        return std::forward<Then>(then);
    } else {
        return std::forward<OrElse>(or_else);
    }
}

// ! function
template <typename ReturnType, typename Callable, typename ...Args>
using is_same_as_invoke_result = std::is_same<std::invoke_result_t<Callable, Args...>, ReturnType>;
template <typename F, typename T>
using is_uni_op = is_same_as_invoke_result<T, F, T>;
template <typename F, typename T>
using is_bin_op = is_same_as_invoke_result<T, F, T, T>;

template <typename Comparator, typename T>
using is_comparator = std::is_same<std::invoke_result_t<Comparator, T, T>, bool>;

// ! integral
template <typename T, typename = constraints_t<std::is_integral<T>>>
constexpr int bit_num = std::numeric_limits<std::make_unsigned_t<T>>::digits;
template <typename T, unsigned int n>
struct is_nbit { static constexpr bool value = bit_num<T> == n; };
template <typename T, unsigned int n>
static constexpr bool is_nbit_v = is_nbit<T, n>::value;

// ?
template <typename T>
struct safely_multipliable {};
template <>
struct safely_multipliable<int> { using type = long long; };
template <>
struct safely_multipliable<long long> { using type = __int128_t; };
template <>
struct safely_multipliable<unsigned int> { using type = unsigned long long; };
template <>
struct safely_multipliable<unsigned long int> { using type = __uint128_t; };
template <>
struct safely_multipliable<unsigned long long> { using type = __uint128_t; };
template <>
struct safely_multipliable<float> { using type = float; };
template <>
struct safely_multipliable<double> { using type = double; };
template <>
struct safely_multipliable<long double> { using type = long double; };
template <typename T>
using safely_multipliable_t = typename safely_multipliable<T>::type;

template <typename T, typename = void>
struct rec_value_type {
    using type = T;
};
template <typename T>
struct rec_value_type<T, std::void_t<typename T::value_type>> {
    using type = typename rec_value_type<typename T::value_type>::type;
};
template <typename T>
using rec_value_type_t = typename rec_value_type<T>::type;

} // namespace suisen

// ! type aliases
using i128 = __int128_t;
using u128 = __uint128_t;

template <typename T>
using pq_greater = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <typename T, typename U>
using umap = std::unordered_map<T, U>;

// ! macros (capital: internal macro)
#define OVERLOAD2(_1,_2,name,...) name
#define OVERLOAD3(_1,_2,_3,name,...) name
#define OVERLOAD4(_1,_2,_3,_4,name,...) name

#define REP4(i,l,r,s)  for(std::remove_reference_t<std::remove_const_t<decltype(r)>>i=(l);i<(r);i+=(s))
#define REP3(i,l,r)    REP4(i,l,r,1)
#define REP2(i,n)      REP3(i,0,n)
#define REPINF3(i,l,s) for(std::remove_reference_t<std::remove_const_t<decltype(l)>>i=(l);;i+=(s))
#define REPINF2(i,l)   REPINF3(i,l,1)
#define REPINF1(i)     REPINF2(i,0)
#define RREP4(i,l,r,s) for(std::remove_reference_t<std::remove_const_t<decltype(r)>>i=(l)+fld((r)-(l)-1,s)*(s);i>=(l);i-=(s))
#define RREP3(i,l,r)   RREP4(i,l,r,1)
#define RREP2(i,n)     RREP3(i,0,n)

#define rep(...)    OVERLOAD4(__VA_ARGS__, REP4   , REP3   , REP2   )(__VA_ARGS__)
#define rrep(...)   OVERLOAD4(__VA_ARGS__, RREP4  , RREP3  , RREP2  )(__VA_ARGS__)
#define repinf(...) OVERLOAD3(__VA_ARGS__, REPINF3, REPINF2, REPINF1)(__VA_ARGS__)

#define CAT_I(a, b) a##b
#define CAT(a, b) CAT_I(a, b)
#define UNIQVAR(tag) CAT(tag, __LINE__)
#define loop(n) for (std::remove_reference_t<std::remove_const_t<decltype(n)>> UNIQVAR(loop_variable) = n; UNIQVAR(loop_variable) --> 0;)

#define all(iterable) std::begin(iterable), std::end(iterable)
#define input(type, ...) type __VA_ARGS__; read(__VA_ARGS__)

#ifdef LOCAL
#  define debug(...) debug_internal(#__VA_ARGS__, __VA_ARGS__)

template <class T, class... Args>
void debug_internal(const char* s, T&& first, Args&&... args) {
    constexpr const char* prefix = "[\033[32mDEBUG\033[m] ";
    constexpr const char* open_brakets = sizeof...(args) == 0 ? "" : "(";
    constexpr const char* close_brakets = sizeof...(args) == 0 ? "" : ")";
    std::cerr << prefix << open_brakets << s << close_brakets << ": " << open_brakets << std::forward<T>(first);
    ((std::cerr << ", " << std::forward<Args>(args)), ...);
    std::cerr << close_brakets << "\n";
}

#else
#  define debug(...) void(0)
#endif

// ! I/O utilities

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

// pair
template <typename T, typename U>
std::ostream& operator<<(std::ostream& out, const std::pair<T, U>& a) {
    return out << a.first << ' ' << a.second;
}
// tuple
template <unsigned int N = 0, typename ...Args>
std::ostream& operator<<(std::ostream& out, const std::tuple<Args...>& a) {
    if constexpr (N >= std::tuple_size_v<std::tuple<Args...>>) {
        return out;
    } else {
        out << std::get<N>(a);
        if constexpr (N + 1 < std::tuple_size_v<std::tuple<Args...>>) {
            out << ' ';
        }
        return operator<<<N + 1>(out, a);
    }
}
// vector
template <typename T>
std::ostream& operator<<(std::ostream& out, const std::vector<T>& a) {
    for (auto it = a.begin(); it != a.end();) {
        out << *it;
        if (++it != a.end()) out << ' ';
    }
    return out;
}
// array
template <typename T, size_t N>
std::ostream& operator<<(std::ostream& out, const std::array<T, N>& a) {
    for (auto it = a.begin(); it != a.end();) {
        out << *it;
        if (++it != a.end()) out << ' ';
    }
    return out;
}
inline void print() { std::cout << '\n'; }
template <typename Head, typename... Tail>
inline void print(const Head& head, const Tail &...tails) {
    std::cout << head;
    if (sizeof...(tails)) std::cout << ' ';
    print(tails...);
}
template <typename Iterable>
auto print_all(const Iterable& v, std::string sep = " ", std::string end = "\n") -> decltype(std::cout << *v.begin(), void()) {
    for (auto it = v.begin(); it != v.end();) {
        std::cout << *it;
        if (++it != v.end()) std::cout << sep;
    }
    std::cout << end;
}

__int128_t parse_i128(std::string& s) {
    __int128_t ret = 0;
    for (int i = 0; i < int(s.size()); i++) if ('0' <= s[i] and s[i] <= '9') ret = 10 * ret + s[i] - '0';
    if (s[0] == '-') ret = -ret;
    return ret;
}
__uint128_t parse_u128(std::string& s) {
    __uint128_t ret = 0;
    for (int i = 0; i < int(s.size()); i++) if ('0' <= s[i] and s[i] <= '9') ret = 10 * ret + s[i] - '0';
    return ret;
}
// __int128_t
std::istream& operator>>(std::istream& in, __int128_t& v) {
    std::string s;
    in >> s;
    v = parse_i128(s);
    return in;
}
// __uint128_t
std::istream& operator>>(std::istream& in, __uint128_t& v) {
    std::string s;
    in >> s;
    v = parse_u128(s);
    return in;
}
// pair
template <typename T, typename U>
std::istream& operator>>(std::istream& in, std::pair<T, U>& a) {
    return in >> a.first >> a.second;
}
// tuple
template <unsigned int N = 0, typename ...Args>
std::istream& operator>>(std::istream& in, std::tuple<Args...>& a) {
    if constexpr (N >= std::tuple_size_v<std::tuple<Args...>>) {
        return in;
    } else {
        return operator>><N + 1>(in >> std::get<N>(a), a);
    }
}
// vector
template <typename T>
std::istream& operator>>(std::istream& in, std::vector<T>& a) {
    for (auto it = a.begin(); it != a.end(); ++it) in >> *it;
    return in;
}
// array
template <typename T, size_t N>
std::istream& operator>>(std::istream& in, std::array<T, N>& a) {
    for (auto it = a.begin(); it != a.end(); ++it) in >> *it;
    return in;
}
template <typename ...Args>
void read(Args &...args) {
    (std::cin >> ... >> args);
}

// ! integral utilities

// Returns pow(-1, n)
template <typename T>
constexpr inline int pow_m1(T n) {
    return -(n & 1) | 1;
}
// Returns pow(-1, n)
template <>
constexpr inline int pow_m1<bool>(bool n) {
    return -int(n) | 1;
}

// Returns floor(x / y)
template <typename T>
constexpr inline T fld(const T x, const T y) {
    return (x ^ y) >= 0 ? x / y : (x - (y + pow_m1(y >= 0))) / y;
}
template <typename T>
constexpr inline T cld(const T x, const T y) {
    return (x ^ y) <= 0 ? x / y : (x + (y + pow_m1(y >= 0))) / y;
}

template <typename T, suisen::constraints_t<suisen::is_nbit<T, 16>> = nullptr>
__attribute__((target("popcnt"))) constexpr inline int popcount(const T x) { return _mm_popcnt_u32(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
__attribute__((target("popcnt"))) constexpr inline int popcount(const T x) { return _mm_popcnt_u32(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
__attribute__((target("popcnt"))) constexpr inline int popcount(const T x) { return _mm_popcnt_u64(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 16>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clz(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clz(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clzll(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 16>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctz(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctz(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctzll(x) : suisen::bit_num<T>; }
template <typename T>
constexpr inline int floor_log2(const T x) { return suisen::bit_num<T> -1 - count_lz(x); }
template <typename T>
constexpr inline int ceil_log2(const T x) { return floor_log2(x) + ((x & -x) != x); }
template <typename T>
constexpr inline int kth_bit(const T x, const unsigned int k) { return (x >> k) & 1; }
template <typename T>
constexpr inline int parity(const T x) { return popcount(x) & 1; }

// ! container

template <typename T, typename Comparator, suisen::constraints_t<suisen::is_comparator<Comparator, T>> = nullptr>
auto priqueue_comp(const Comparator comparator) {
    return std::priority_queue<T, std::vector<T>, Comparator>(comparator);
}

template <typename Iterable>
auto isize(const Iterable& iterable) -> decltype(int(iterable.size())) {
    return iterable.size();
}

template <typename T, typename Gen, suisen::constraints_t<suisen::is_same_as_invoke_result<T, Gen, int>> = nullptr>
auto generate_vector(int n, Gen generator) {
    std::vector<T> v(n);
    for (int i = 0; i < n; ++i) v[i] = generator(i);
    return v;
}
template <typename T>
auto generate_range_vector(T l, T r) {
    return generate_vector(r - l, [l](int i) { return l + i; });
}
template <typename T>
auto generate_range_vector(T n) {
    return generate_range_vector(0, n);
}

template <typename T>
void sort_unique_erase(std::vector<T>& a) {
    std::sort(a.begin(), a.end());
    a.erase(std::unique(a.begin(), a.end()), a.end());
}

template <typename InputIterator, typename BiConsumer>
auto foreach_adjacent_values(InputIterator first, InputIterator last, BiConsumer f) -> decltype(f(*first++, *last), void()) {
    if (first != last) for (auto itr = first, itl = itr++; itr != last; itl = itr++) f(*itl, *itr);
}
template <typename Container, typename BiConsumer>
auto foreach_adjacent_values(Container c, BiConsumer f) -> decltype(c.begin(), c.end(), void()) {
    foreach_adjacent_values(c.begin(), c.end(), f);
}

// ! other utilities

// x <- min(x, y). returns true iff `x` has chenged.
template <typename T>
inline bool chmin(T& x, const T& y) {
    if (y >= x) return false;
    x = y;
    return true;
}
// x <- max(x, y). returns true iff `x` has chenged.
template <typename T>
inline bool chmax(T& x, const T& y) {
    if (y <= x) return false;
    x = y;
    return true;
}

template <typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
std::string bin(T val, int bit_num = -1) {
    std::string res;
    if (bit_num >= 0) {
        for (int bit = bit_num; bit-- > 0;) res += '0' + ((val >> bit) & 1);
    } else {
        for (; val; val >>= 1) res += '0' + (val & 1);
        std::reverse(res.begin(), res.end());
    }
    return res;
}

template <typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
std::vector<T> digits_low_to_high(T val, T base = 10) {
    std::vector<T> res;
    for (; val; val /= base) res.push_back(val % base);
    if (res.empty()) res.push_back(T{ 0 });
    return res;
}
template <typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
std::vector<T> digits_high_to_low(T val, T base = 10) {
    auto res = digits_low_to_high(val, base);
    std::reverse(res.begin(), res.end());
    return res;
}

template <typename T>
std::string join(const std::vector<T>& v, const std::string& sep, const std::string& end) {
    std::ostringstream ss;
    for (auto it = v.begin(); it != v.end();) {
        ss << *it;
        if (++it != v.end()) ss << sep;
    }
    ss << end;
    return ss.str();
}

namespace suisen {}
using namespace suisen;
using namespace std;

struct io_setup {
    io_setup(int precision = 20) {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(precision);
    }
} io_setup_{};

// ! code from here

constexpr int dx4[4] = { -1, 0, 1, 0 };
constexpr int dy4[4] = { 0, 1, 0, -1 };

constexpr int N = 0, E = 1, S = 2, W = 3;
constexpr char SUCC = '^', BACK = 'v', ROTR = '>', ROTL = '<';
constexpr char NEG = '~';

tuple<int, int, int> operate(char c, int x, int y, int d) {
    if (c == ROTR) {
        return { x, y, (d + 1) & 3 };
    } else if (c == ROTL) {
        return { x, y, (d + 3) & 3 };
    } else if (c == SUCC) {
        return { x + dx4[d], y + dy4[d], d };
    } else if (c == BACK) {
        return { x + dx4[d ^ 2], y + dy4[d ^ 2], d };
    } else {
        assert(false);
    }
}

int main() {
    input(int, h, w);
    int sx = -1, sy = -1, tx = -1, ty = -1;
    vector wall(h, vector<int8_t>(w, false));
    rep(i, h) {
        input(string, s);
        rep(j, w) {
            wall[i][j] = s[j] == '#';
            if (s[j] == 's') {
                sx = i, sy = j;
            } else if (s[j] == 'g') {
                tx = i, ty = j;
            }
        }
    }

    input(string, instruction);
    const int len = instruction.size();
    vector<int> brace(len, -1);
    {
        vector<int> st;
        rep(i, len) {
            if (instruction[i] == '{' or instruction[i] == '[') {
                st.push_back(i);
            } else if (instruction[i] == '}' or instruction[i] == ']') {
                int j = st.back();
                brace[i] = j;
                brace[j] = i;
                st.pop_back();
            }
        }
    }

    vector vis(4, vector(h, vector<set<int>>(w)));

    int x = sx, y = sy, d = N;

    int cnt = 0;
    auto dfs = [&](auto dfs, int i) -> void {
        if (vis[d][x][y].count(i)) {
            print(-1);
            exit(0);
        }
        if (x == tx and y == ty) {
            print(cnt);
            exit(0);
        }
        if (i == len) {
            print(-1);
            exit(0);
        }
        vis[d][x][y].insert(i);

        if (instruction[i] == '[') {
            bool neg = instruction[i + 1] == NEG;
            int ni = i + neg;
            if (instruction[ni + 1] == 'N') {
                if (neg xor (d == N)) {
                    dfs(dfs, ni + 2);
                } else {
                    dfs(dfs, brace[i] + 1);
                }
            } else if (instruction[ni + 1] == 'E') {
                if (neg xor (d == E)) {
                    dfs(dfs, ni + 2);
                } else {
                    dfs(dfs, brace[i] + 1);
                }
            } else if (instruction[ni + 1] == 'S') {
                if (neg xor (d == S)) {
                    dfs(dfs, ni + 2);
                } else {
                    dfs(dfs, brace[i] + 1);
                }
            } else if (instruction[ni + 1] == 'W') {
                if (neg xor (d == W)) {
                    dfs(dfs, ni + 2);
                } else {
                    dfs(dfs, brace[i] + 1);
                }
            } else if (instruction[ni + 1] == 'C') {
                if (neg xor wall[x + dx4[d]][y + dy4[d]]) {
                    dfs(dfs, ni + 2);
                } else {
                    dfs(dfs, brace[i] + 1);
                }
            } else if (instruction[ni + 1] == 'T') {
                if (neg xor true) {
                    dfs(dfs, ni + 2);
                } else {
                    dfs(dfs, brace[i] + 1);
                }
            } else {
                assert(false);
            }
        } else if (instruction[i] == ']') {
            dfs(dfs, i + 1);
        } else if (instruction[i] == '{') {
            while (true) {
                bool neg = instruction[i + 1] == NEG;
                int ni = i + neg;
                if (instruction[ni + 1] == 'N') {
                    if (neg xor (d == N)) {
                        dfs(dfs, ni + 2);
                    } else {
                        dfs(dfs, brace[i] + 1);
                        break;
                    }
                } else if (instruction[ni + 1] == 'E') {
                    if (neg xor (d == E)) {
                        dfs(dfs, ni + 2);
                    } else {
                        dfs(dfs, brace[i] + 1);
                        break;
                    }
                } else if (instruction[ni + 1] == 'S') {
                    if (neg xor (d == S)) {
                        dfs(dfs, ni + 2);
                    } else {
                        dfs(dfs, brace[i] + 1);
                        break;
                    }
                } else if (instruction[ni + 1] == 'W') {
                    if (neg xor (d == W)) {
                        dfs(dfs, ni + 2);
                    } else {
                        dfs(dfs, brace[i] + 1);
                        break;
                    }
                } else if (instruction[ni + 1] == 'C') {
                    if (neg xor wall[x + dx4[d]][y + dy4[d]]) {
                        dfs(dfs, ni + 2);
                    } else {
                        dfs(dfs, brace[i] + 1);
                        break;
                    }
                } else if (instruction[ni + 1] == 'T') {
                    if (neg xor true) {
                        dfs(dfs, ni + 2);
                    } else {
                        dfs(dfs, brace[i] + 1);
                        break;
                    }
                } else {
                    assert(false);
                }
            }
        } else if (instruction[i] == '}') {
            return;
        } else {
            char op = instruction[i];
            auto [nx, ny, nd] = operate(op, x, y, d);
            ++cnt;
            if (not wall[nx][ny]) x = nx, y = ny, d = nd;
            dfs(dfs, i + 1);
        }
    };
    dfs(dfs, 0);
    return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 60912
final_rank: 7

code_snippet: #line 1 "b.cpp"
/*	author:  Kite_kuma
	created: 2022.06.01 17:05:51 */

#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>

template <class T0, class T1, class T2>
inline bool in_range(T0 x, T1 lef, T2 rig) {
	return ((lef <= x) && (x < rig));
}

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

void Yes(bool flag = true) { std::cout << (flag ? "Yes" : "No") << '\n'; }
void YES(bool flag = true) { std::cout << (flag ? "YES" : "NO") << '\n'; }

template <class T>
void drop(T answer) {
	std::cout << answer << '\n';
	exit(0);
}

template <class T>
void vout(std::vector<T> const &v, bool vertically = 0) {
	if(vertically) {
		for(auto const &a : v) {
			std::cout << a << '\n';
		}
		return;
	}
	for(auto it = v.begin(); it != v.end(); it++) {
		std::cout << (*it);
		if(it != v.end() - 1) {
			std::cout << ' ';
		}
	}
	std::cout << '\n';
	return;
}

inline void print() { std::cout << '\n'; }
template <class T>
inline void print(const T &x) {
	std::cout << x << '\n';
	return;
}
template <typename Head, typename... Tail>
void print(const Head &H, const Tail &... T) {
	std::cout << H << " ";
	print(T...);
}

template <class T>
void add(std::vector<T> &v, T value) {
	for(auto &a : v) a += value;
	return;
}

template <class T>
T greatest_lower_multiple(T x, T d) {
	if(d == 0) return 0;
	if(d < 0) d *= -1;
	T y = x % d;
	if(y < 0) y += d;
	return x - y;
}

template <class T>
T least_upper_multiple(T x, T d) {
	return -greatest_lower_multiple(-x, d);
}

// ceil(a / b);
template <class T>
T dup(T a, T b) {
	assert(b);
	if(b < 0) {
		a *= -1;
		b *= -1;
	}
	return least_upper_multiple(a, b) / b;
}

long long pow_ll(long long a, long long n) {
	assert(n >= 0LL);
	if(n == 0) return 1LL;
	if(a == 0) return 0LL;
	if(a == 1) return 1LL;
	if(a == -1) return (n & 1LL) ? -1LL : 1LL;
	long long res = 1;
	while(n > 1LL) {
		if(n & 1LL) res *= a;
		a *= a;
		n >>= 1;
	}
	return res * a;
}

long long modpow(long long a, long long n, long long mod) {	 // a^n mod
	assert(n >= 0 && mod);
	if(mod == 1) return 0LL;
	long long res = 1;
	a %= mod;
	while(n > 0) {
		if(n & 1) res = res * a % mod;
		a = a * a % mod;
		n >>= 1;
	}
	return res < 0 ? res + mod : res;
}

// return x which satisfies a * x % mod == gcd(a, mod)
// not (mod | a)
long long modinv(long long a, const long long mod) {
	long long b = mod, u = 1, v = 0;
	while(b) {
		long long t = a / b;
		a -= t * b;
		std::swap(a, b);
		u -= t * v;
		std::swap(u, v);
	}
	u %= mod;
	if(u < 0) u += mod;
	return u;
}

template <class T>
int lb(const std::vector<T> &a, const T x) {
	return (int)std::distance(a.begin(), std::lower_bound(a.begin(), a.end(), x));
}
template <class T>
int ub(const std::vector<T> &a, const T x) {
	return (int)std::distance(a.begin(), std::upper_bound(a.begin(), a.end(), x));
}
template <class T>
void unq_sort(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<int> press(const std::vector<T> &a) {
	std::vector<T> vec = a;
	unq_sort(vec);
	std::vector<int> ret;
	for(const auto &v : a) ret.push_back(lb(vec, v));
	return ret;
}
#line 1 "SPJ-Library/template/header.hpp"
#include <bits/stdc++.h>
#line 2 "SPJ-Library/template/io.hpp"

#line 4 "SPJ-Library/template/io.hpp"

#line 8 "SPJ-Library/template/debug.hpp"

#line 3 "SPJ-Library/template/constants.hpp"

constexpr int inf = 1000'000'000;
constexpr long long INF = 1'000'000'000'000'000'000LL;
constexpr int mod_1000000007 = 1000000007;
constexpr int mod_998244353 = 998244353;
const long double pi = acosl(-1.);
constexpr int dx[8] = {0, -1, 0, 1, 1, -1, -1, 1};
constexpr int dy[8] = {1, 0, -1, 0, 1, 1, -1, -1};
#line 10 "SPJ-Library/template/debug.hpp"

namespace viewer {

template <typename T, typename U>
void view(const std::pair<T, U> &p);

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p);

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p);

void view(const long long &e);

void view(const int &e);

template <typename T>
void view(const T &e);

template <typename T>
void view(const std::set<T> &s);

template <typename T>
void view(const std::unordered_set<T> &s);

template <typename T>
void view(const std::multiset<T> &s);

template <typename T>
void view(const std::unordered_multiset<T> &s);

template <typename T>
void view(const std::vector<T> &v);

template <typename T, std::size_t ary_size>
void view(const std::array<T, ary_size> &v);

template <typename T>
void view(const std::vector<std::vector<T>> &vv);

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v);

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v);

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v);

template <typename map_type>
void view_map_container(const map_type &m);

template <typename T, typename U>
void view(const std::map<T, U> &m);

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m);

template <typename container_type>
void view_container(const container_type &c, bool vertically = false) {
	typename container_type::const_iterator begin = c.begin();
	const typename container_type::const_iterator end = c.end();
	if(vertically) {
		std::cerr << "{\n";
		while(begin != end) {
			std::cerr << '\t';
			view(*(begin++));
			if(begin != end) std::cerr << ',';
			std::cerr << '\n';
		}
		std::cerr << '}';
		return;
	}
	std::cerr << "{ ";
	while(begin != end) {
		view(*(begin++));
		if(begin != end) std::cerr << ',';
		std::cerr << ' ';
	}
	std::cerr << '}';
}

template <typename T, typename U>
void view(const std::pair<T, U> &p) {
	std::cerr << '(';
	view(p.first);
	std::cerr << ", ";
	view(p.second);
	std::cerr << ')';
}

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p) {
	std::cerr << '(';
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ')';
}

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p) {
	std::cerr << '(';
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ", ";
	view(std::get<3>(p));
	std::cerr << ')';
}

void view(const long long &e) {
	if(e == INF)
		std::cerr << "INF";
	else if(e == -INF)
		std::cerr << "-INF";
	else
		std::cerr << e;
}

void view(const int &e) {
	if(e == inf)
		std::cerr << "inf";
	else if(e == -inf)
		std::cerr << "-inf";
	else
		std::cerr << e;
}

template <typename T>
void view(const T &e) {
	std::cerr << e;
}

template <typename T>
void view(const std::set<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::unordered_set<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::multiset<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::unordered_multiset<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::vector<T> &v) {
	view_container(v);
}

template <typename T, std::size_t ary_size>
void view(const std::array<T, ary_size> &v) {
	view_container(v);
}

template <typename T>
void view(const std::vector<std::vector<T>> &vv) {
	view_container(vv, true);
}

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v) {
	view_container(v, true);
}

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v) {
	view_container(v, true);
}

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v) {
	view_container(v, true);
}

template <typename map_type>
void view_map_container(const map_type &m) {
	std::cerr << "{\n";
	for(typename map_type::const_iterator it = m.begin(); it != m.end(); it++) {
		std::cerr << "\t[";
		view(it->first);
		std::cerr << "] : ";
		view(it->second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::map<T, U> &m) {
	view_map_container(m);
}

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m) {
	view_map_container(m);
}

}  // namespace viewer

// when compiling : g++ foo.cpp -DLOCAL
#ifdef LOCAL
void debug_out() {}
template <typename T>
void debug_out(const T &x) {
	viewer::view(x);
}
template <typename Head, typename... Tail>
void debug_out(const Head &H, const Tail &... T) {
	viewer::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "]\n";                                       \
	} while(0)
#else
#define debug(...) (void(0))
#endif
#line 2 "SPJ-Library/template/scanner.hpp"

#line 6 "SPJ-Library/template/scanner.hpp"

namespace scanner {
template <class T>
void scan(T &a) {
	std::cin >> a;
}

template <class T, class L>
void scan(std::pair<T, L> &p) {
	scan(p.first);
	scan(p.second);
}

template <class T0, class T1, class T2>
void scan(std::tuple<T0, T1, T2> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	scan(t0);
	scan(t1);
	scan(t2);
	p = std::make_tuple(t0, t1, t2);
}

template <class T0, class T1, class T2, class T3>
void scan(std::tuple<T0, T1, T2, T3> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	T3 t3;
	scan(t0);
	scan(t1);
	scan(t2);
	scan(t3);
	p = std::make_tuple(t0, t1, t2, t3);
}

template <class T>
void scan(std::vector<T> &a) {
	for(auto &i : a) scan(i);
}

void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner

#define VEC(type, name, size) \
	vector<type> name(size);  \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                     \
	vector<vector<type>> name(h, vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)        \
	string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHR(...)      \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DBL(...)        \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define TPL3(type0, type1, type2, name)   \
	std::tuple<type0, type1, type2> name; \
	scanner::INPUT(name);
#define TPL4(type0, type1, type2, type3, name)   \
	std::tuple<type0, type1, type2, type3> name; \
	scanner::INPUT(name);

template <typename T1, typename T2>
std::istream &operator>>(std::istream &is, std::pair<T1, T2> &p) {
	is >> p.first >> p.second;
	return is;
}

template <typename T1, typename T2>
std::ostream &std::operator<<(std::ostream &os, const std::pair<T1, T2> &p) {
	os << p.first << ' ' << p.second;
	return os;
}
template <class T>
std::ostream &std::operator<<(std::ostream &os, const std::vector<T> &v) {
	for(typename std::vector<T>::const_iterator it = v.begin(); it != v.end(); it++) {
		if(it != v.begin()) std::cerr << ' ';
		os << *it;
	}
	return os;
}

struct fast_io {
	fast_io() {
		std::ios::sync_with_stdio(false);
		std::cin.tie(nullptr);
		std::cout << std::fixed << std::setprecision(15);
		srand((unsigned)time(NULL));
	}
} fast_io_;
#line 2 "SPJ-Library/template/macros.hpp"

#define foa(s, v) for(auto &s : v)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pcnt(n) __builtin_popcountll((long long)n)

#define REPname(a, b, c, d, e, ...) e
#define rep(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int Counter_in_rep_macro = 0; Counter_in_rep_macro < (x); ++Counter_in_rep_macro)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))
#define DREPname(a, b, c, d, e, ...) e
#define drep(...) DREPname(__VA_ARGS__, DREP3, DREP2, DREP1)(__VA_ARGS__)
#define DREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define DREP2(i, l, r) for(int i = (r)-1; i >= (l); --i)
#define DREP3(i, l, r, c) for(int i = (r)-1; i >= (l); i -= (c))

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = std::vector<int>;
using vvi = std::vector<std::vector<int>>;
using vvvi = std::vector<std::vector<std::vector<int>>>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
template <class T = ll>
using V = std::vector<T>;
template <class T = ll>
using VV = V<V<T>>;
template <class T = ll>
using VVV = V<V<V<T>>>;
template <class T = ll>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <class T = ll>
using pqdn = std::priority_queue<T>;

using namespace std;
using ll = long long;

vector<vector<int>> grid;  // 1: wall   0: passable
int h, w;

string direction_string = "ENWS";
int x, y, gx, gy;

vector<int> otherbraket;
vvvi history;

struct parser {
	int counter;
	std::string s;
	std::string::iterator it;
	int dir;
	parser(std::string str) : s(str) { initialize(); }

	void initialize() {
		it = s.begin();
		counter = 0;
		dir = 1;
	}

	ll operation(const ll &lef, const ll &rig, const char &op) {
		switch(op) {
			case '+': {
				return lef + rig;
			}
			case '-': {
				return lef - rig;
			}
			case '*': {
				return lef * rig;
			}
			case '/': {
				return lef / rig;
			}
			default: {
				assert(false);
			}
		}
	}

	bool match(const char &c) { return it != s.end() && *it == c; }

	bool match(const std::string &str) {
		if(s.end() - it < str.size()) return false;
		return std::equal(str.begin(), str.end(), it);
	}

	void consume(const char &c) {
		if(match(c)) {
			it++;
			return;
		}
		std::cerr << "---------------------\nParse error\nWhole string:\n\t" << s << "\n\t";
		int place = int(it - s.begin());
		while(place--) std::cerr << ' ';
		std::cerr << "^\nAssumed character:\n\t" << c << "\n---------------------\n";
		exit(0);
	}

	void consume(const std::string &str) {
		if(match(str)) {
			for(int i = 0; i < int(str.size()); i++) it++;
			return;
		}
		std::cerr << "---------------------\nParse error\nWhole string:\n\t" << s << "\n\t";
		int place = int(it - s.begin());
		while(place--) std::cerr << ' ';
		std::cerr << "^\nAssumed string:\n\t" << str << "\n---------------------\n";
		exit(0);
	}

	bool ended() { return it == s.end() || *it == ']' || *it == '}'; }

	// true if reached goal
	bool program() {
		while(!ended()) {
			if(state()) return true;
		}
		return false;
	}

	bool check_history() {
		int p = int(it - s.begin());
		debug(p, dir, x, y);
		int &tmp = history[p * 4 + dir][x][y];
		if(tmp) {
			counter = -1;
			return true;
		}
		tmp = 1;
		return false;
	}

	bool state() {
		if(*it == '{') {
			if(whilestate()) return true;
		} else if(*it == '[') {
			if(ifstate()) return true;
		} else {
			if(movestate()) return true;
		}
		return check_history();
	}

	bool ifstate() {
		consume('[');
		int right = otherbraket[it - s.begin()];
		if(!condition()) {
			it = s.begin() + (right + 1);
			return false;
		}
		if(program()) return true;
		consume(']');
		return false;
	}

	bool whilestate() {
		const auto it_save = it;
		int right = otherbraket[it - s.begin()];
		consume('{');
		debug(it - s.begin(), 'w', right);
		if(!condition()) {
			it = s.begin() + (right + 1);
			return false;
		}
		if(program()) return true;
		consume('}');
		it = it_save;
		debug("hoge");
		if(check_history()) return true;
		debug("passed");
		return whilestate();
	}

	bool movestate() {
		debug(dir, x, y, it - s.begin(), *it, dx[dir], dy[dir]);
		counter++;
		switch(*it++) {
			case '<': {
				dir++;
				dir %= 4;
				return false;
				break;
			}
			case '>': {
				dir = (dir + 3) % 4;
				return false;
				break;
			}

			case '^': {
				int ax, ay;
				tie(ax, ay) = front();
				if(grid[ax][ay]) return false;
				x = ax;
				y = ay;
				return x == gx && y == gy;
			}

			case 'v': {
				int ax, ay;
				tie(ax, ay) = back();
				if(grid[ax][ay]) return false;
				x = ax;
				y = ay;
				return x == gx && y == gy;
			}

			default: {
				assert(false);
			}
		}
	}

	pair<int, int> front() { return make_pair(x + dx[dir], y + dy[dir]); }
	pair<int, int> back() { return make_pair(x - dx[dir], y - dy[dir]); }

	bool condition() {
		if(*it == '~') {
			it++;
			return !condition();
		}
		if(*it == 'T') {
			it++;
			return true;
		}
		if(*it == 'C') {
			it++;
			int w, z;
			tie(w, z) = front();
			return (grid[w][z] == 1);
		}
		if(!(*it == 'N' || *it == 'E' || *it == 'W' || *it == 'S')) {
			debug(*it);
			debug(it - s.begin());
			debug(s);
		}
		assert(*it == 'N' || *it == 'E' || *it == 'W' || *it == 'S');
		return direction_string[dir] == *it++;
	}
};
#line 7 "a.cpp"

int solve() {
	grid.resize(h);
	rep(xx, h) {
		vi &v = grid[xx];
		v.assign(w, 0);
		string str;
		cin >> str;
		rep(i, w) {
			if(str[i] == '#')
				v[i] = 1;
			else if(str[i] == 's') {
				x = xx;
				y = i;
			} else if(str[i] == 'g') {
				gx = xx;
				gy = i;
			}
		}
	}
	string command;
	cin >> command;
	parser ps(command);
	stack<int> st;
	otherbraket.assign(int(command.size()), -1);
	rep(i, int(command.size())) {
		char c = command[i];
		if(command[i] == '[' || c == '{') {
			st.push(i);
		} else if(c == ']' || c == '}') {
			otherbraket[st.top()] = i;
			st.pop();
		}
	}
	history.resize((int(command.size()) + 1) * 4);
	foa(v, history) {
		v.resize(h);
		foa(c, v) { c.assign(w, 0); }
	}

	debug(grid);
	debug(command);

	if(!ps.program()) {
		debug("ended");
		return -1;
	}
	return ps.counter;
}

int main() {
	while(cin >> h >> w && h && w) {
		cout << solve() << '\n';
	}
	return 0;
}
accuracy: 0.5822784810126582
time_ms: 30
memory_kb: 48756
final_rank: 10

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

using namespace std;

class Parser{
    string S;
    int pos = 0;
    vector<string> A;
    vector<array<int, 2>> DD = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    int dir = 0;
    vector<vector<vector<vector<bool>>>> visited;
    public:
    int h, w;
    int cnt = 0;
    Parser(string S, vector<string> A) : S(S), A(A){
        visited = vector(A.size(), vector(A[0].size(), vector(4, vector(S.size(), false))));
        for (int i = 0; i < A.size(); i++){
            for (int j = 0; j < A[0].size(); j++){
                if (A[i][j] == 's'){
                    this->A[i][j] = '.';
                    h = i;
                    w = j;
                }
            }
        }
    }

    char peek(){
        return pos < S.size() ? S[pos] : 'a';
    }

    void skip_spaces(){
        while (peek() == ' ')
            pos++;
    }

    void next(string S){
        for (const auto &s: S){
            assert(peek() == s);
            pos++;
        }
    }

    void program(bool is_exec){
        while (pos < S.size() and peek() != ']' and peek() != '}'){
            if (peek() == '[')
                if_statement(is_exec);
            else if (peek() == '{')
                while_statement(is_exec);
            else
                move_statement(is_exec);
        }
    }

    void if_statement(bool is_exec){
        next("[");
        bool cond = condition();
        program(is_exec & cond);
        next("]");
    }

    void while_statement(bool is_exec){
        next("{");
        int p = pos;
        while (true){
            bool cond = condition();
            if (is_exec and cond){
                if (visited[h][w][dir][pos])
                    cnt = -1;
                else
                    visited[h][w][dir][pos] = true;
            }
            program(is_exec & cond);
            if (cnt != -1 and A[h][w] != 'g' and is_exec & cond){
                pos = p;
                continue;
            }
            next("}");
            break;
        }
    }

    bool condition(){
        bool is_not = false;
        if (peek() == '~'){
            is_not = true;
            pos++;
        }

        char c = peek();
        pos++;
        bool res = false;
        if (c == 'N')
            res = dir == 0;
        else if (c == 'E')
            res = dir == 1;
        else if (c == 'S')
            res = dir == 2;
        else if (c == 'W')
            res = dir == 3;
        else if (c == 'C'){
            int nh = h + DD[dir][0];
            int nw = w + DD[dir][1];
            res = !is_floor(nh, nw);
        } else if (c == 'T')
            res = true;
        else
            assert(false);

        return res ^ is_not;
    }

    bool is_floor(int i, int j){
        return A[i][j] == '.' or A[i][j] == 'g';
    }

    void move(char c){
        if (A[h][w] == 'g')
            return;
        if (cnt == -1)
            return;
        cnt++;
        if (c == '^'){
            auto nh = h + DD[dir][0];
            auto nw = w + DD[dir][1];
            if (is_floor(nh, nw)){
                h = nh;
                w = nw;
            }
        } else if (c == 'v'){
            auto nh = h - DD[dir][0];
            auto nw = w - DD[dir][1];
            if (is_floor(nh, nw)){
                h = nh;
                w = nw;
            }
        } else if (c == '<'){
            dir = (dir + 3) % 4;
        } else if (c == '>'){
            dir = (dir + 1) % 4;
        } else {
            assert(false);
        }
    }

    void move_statement(bool is_exec){
        assert(peek() == '^' or peek() == 'v' or peek() == '<' or peek() == '>');
        if (is_exec)
            move(peek());
        pos++;
    }

    int number(){
        int res = 0;
        while (isdigit(peek())){
            res = res * 10 + peek() - '0';
            pos++;
        }
        return res;
    }
};

int main(){
    int h, w;
    cin >> h >> w;
    vector<string> A(h);
    for (auto &a: A)
        cin >> a;
    string S;
    cin >> S;
    Parser parser(S, A);
    parser.program(true);
    cout << (A[parser.h][parser.w] == 'g' ? parser.cnt : -1)<< endl;
}
accuracy: 1
time_ms: 10
memory_kb: 5156
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int H, W;
    cin>>H>>W;
    vector<string> a(H);
    for (auto& x : a) cin >> x;
    string s;
    cin >> s;
    vector<int> di = {-1, 0, 1, 0};
    vector<int> dj = {0, -1, 0, 1};
    map<char, int> dir;
    dir['N'] = 0;
    dir['W'] = 1;
    dir['S'] = 2;
    dir['E'] = 3;
    int si, sj;
    rep(i, 0, H) rep(j, 0, W) if (a[i][j] == 's') si = i, sj = j;
    int i = si, j = sj, d = dir['H'], cnt = 0, ans = -100, k = 0;
    set<tuple<int, int, int, int>> states;

    vector<int> right(s.size());
    stack<int> st;
    rep(i, 0, s.size()) {
        if (s[i] == '[' || s[i] == '{') st.push(i);
        if (s[i] == ']' || s[i] == '}') right[st.top()] = i, st.pop();
    }

    auto dfs = [&](auto& dfs) -> void {
        if (states.count({i, j, d, k})) {
            ans = -1;
            return;
        }
        states.insert({i, j, d, k});
        if (k == s.size()) return;
        if (s[k] == ']' || s[k] == '}') {
            ++k;
            return;
        }
        if (s[k] == '[' || s[k] == '{') {
            int tmp = k;
            ++k;
            bool neg = false, cond;
            if (s[k] == '~') {
                neg = true;
                ++k;
            }
            if (s[k] == 'T') {
                cond = true;
            } else if (s[k] == 'C') {
                int ni = i + di[d], nj = j + dj[d];
                cond = a[ni][nj] == '#';
            } else {
                cond = d == dir[s[k]];
            }
            ++k;
            cond ^= neg;
            if (cond) {
                dfs(dfs);
                if (ans != -100) return;
                if (s[tmp] == '{') k = tmp;
            } else {
                k = right[tmp]+1;
            }
        } else {
            ++cnt;
            if (s[k] == '<') {
                d = (d + 1) % 4;
            } else if (s[k] == '>') {
                d = (d + 3) % 4;
            } else {
                int nd = d;
                if (s[k] == 'v') nd = (nd + 2) % 4;
                int ni = i + di[nd], nj = j + dj[nd];
                if (a[ni][nj] != '#') {
                    i = ni;
                    j = nj;
                }
                if (a[i][j] == 'g') {
                    ans = cnt;
                    return;
                }
            }
            ++k;
        }
        dfs(dfs);
    };

    dfs(dfs);
    if (ans == -100) ans = -1;
    cout << ans << endl;
}
accuracy: 1
time_ms: 240
memory_kb: 79768
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int H, W;
    cin>>H>>W;
    vector<string> a(H);
    for (auto& x : a) cin >> x;
    string s;
    cin >> s;
    vector<int> di = {-1, 0, 1, 0};
    vector<int> dj = {0, -1, 0, 1};
    map<char, int> dir;
    dir['N'] = 0;
    dir['W'] = 1;
    dir['S'] = 2;
    dir['E'] = 3;
    int si, sj;
    rep(i, 0, H) rep(j, 0, W) if (a[i][j] == 's') si = i, sj = j;
    int i = si, j = sj, d = dir['H'], cnt = 0, ans = -1, k = 0;
    set<tuple<int, int, int, int>> states;

    vector<int> right(s.size());
    stack<int> st;
    rep(i, 0, s.size()) {
        if (s[i] == '[' || s[i] == '{') st.push(i);
        if (s[i] == ']' || s[i] == '}') right[st.top()] = i, st.pop();
    }

    auto dfs = [&](auto& dfs) -> void {
        if (states.count({i, j, d, k})) return;
        states.insert({i, j, d, k});
        if (k == s.size()) return;
        if (s[k] == ']' || s[k] == '}') {
            ++k;
            return;
        }
        if (s[k] == '[' || s[k] == '{') {
            int tmp = k;
            ++k;
            bool neg = false, cond;
            if (s[k] == '~') {
                neg = true;
                ++k;
            }
            if (s[k] == 'T') {
                cond = true;
            } else if (s[k] == 'C') {
                int ni = i + di[d], nj = j + dj[d];
                cond = a[ni][nj] == '#';
            } else {
                cond = d == dir[s[k]];
            }
            ++k;
            cond ^= neg;
            if (cond) {
                dfs(dfs);
                if (ans != -1) return;
                if (s[tmp] == '{') k = tmp;
            } else {
                k = right[tmp]+1;
            }
        } else {
            ++cnt;
            if (s[k] == '<') {
                d = (d + 1) % 4;
            } else if (s[k] == '>') {
                d = (d + 3) % 4;
            } else {
                int nd = d;
                if (s[k] == 'v') nd = (nd + 2) % 4;
                int ni = i + di[nd], nj = j + dj[nd];
                if (a[ni][nj] != '#') {
                    i = ni;
                    j = nj;
                }
                if (a[i][j] == 'g') {
                    ans = cnt;
                    return;
                }
            }
            ++k;
        }
        dfs(dfs);
    };

    dfs(dfs);
    cout << ans << endl;
}
accuracy: 0.3037974683544304
time_ms: 120
memory_kb: 50952
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int H, W;
    cin>>H>>W;
    vector<string> a(H);
    for (auto& x : a) cin >> x;
    string s;
    cin >> s;
    vector<int> di = {-1, 0, 1, 0};
    vector<int> dj = {0, -1, 0, 1};
    map<char, int> dir;
    dir['N'] = 0;
    dir['W'] = 1;
    dir['S'] = 2;
    dir['E'] = 3;
    int si, sj;
    rep(i, 0, H) rep(j, 0, W) if (a[i][j] == 's') si = i, sj = j;
    int i = si, j = sj, d = dir['H'], cnt = 0, ans = -1, k = 0;
    set<tuple<int, int, int, int>> states;

    vector<int> right(s.size());
    stack<int> st;
    rep(i, 0, s.size()) {
        if (s[i] == '[' || s[i] == '{') st.push(i);
        if (s[i] == ']' || s[i] == '}') right[st.top()] = i, st.pop();
    }

    auto dfs = [&](auto& dfs) -> void {
        if (states.count({i, j, d, k})) return;
        states.insert({i, j, d, k});
        if (k == s.size()) return;
        if (s[k] == ']' || s[k] == '}') {
            ++k;
            return;
        }
        if (s[k] == '[' || s[k] == '{') {
            int tmp = k;
            ++k;
            bool neg = false, cond;
            if (s[k] == '~') {
                neg = true;
                ++k;
            }
            if (s[k] == 'T') {
                cond = true;
            } else if (s[k] == 'C') {
                int ni = i + di[d], nj = j + dj[d];
                cond = a[ni][nj] == '#';
            } else {
                cond = d == dir[s[k]];
            }
            ++k;
            cond ^= neg;
            if (cond) {
                dfs(dfs);
                if (ans != -1) return;
                k = tmp;
            } else {
                k = right[tmp]+1;
            }
        } else {
            ++cnt;
            if (s[k] == '<') {
                d = (d + 1) % 4;
            } else if (s[k] == '>') {
                d = (d + 3) % 4;
            } else {
                int nd = d;
                if (s[k] == 'v') nd = (nd + 2) % 4;
                int ni = i + di[nd], nj = j + dj[nd];
                if (a[ni][nj] != '#') {
                    i = ni;
                    j = nj;
                }
                if (a[i][j] == 'g') {
                    ans = cnt;
                    return;
                }
            }
            ++k;
        }
        dfs(dfs);
    };

    dfs(dfs);
    cout << ans << endl;
}
accuracy: 0.17721518987341772
time_ms: 120
memory_kb: 50904
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define INF 1LL << 60
#define rep(i, n) for (int i = 0; i < (n); ++i)

int clamp(int x, int l, int r) { return max(l, min(x, r)); }

int main() {
    int h, w;
    cin >> h >> w;

    string a[h];
    rep(i, h) cin >> a[i];

    string prog;
    cin >> prog;

    map<pair<pair<int, int>, pair<int, int>>, int> mp;
    vector<int> st;
    int p = 0, dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1}, x, y, r = 0, ct = 0;

    rep(i, h) rep(j, w) if (a[i][j] == 's') x = i, y = j;

    while (p < prog.size()) {
        if (prog[p] == '^') {
            int nx = clamp(x + dx[r], 0, h - 1);
            int ny = clamp(y + dy[r], 0, w - 1);
            if (a[nx][ny] != '#') x = nx, y = ny;
            if (a[x][y] == 'g') {
                cout << ct + 1 << endl;
                return 0;
            }
            p++, ct++;
        } else if (prog[p] == 'v') {
            int nx = clamp(x - dx[r], 0, h - 1);
            int ny = clamp(y - dy[r], 0, w - 1);
            if (a[nx][ny] != '#') x = nx, y = ny;
            if (a[x][y] == 'g') {
                cout << ct + 1 << endl;
                return 0;
            }
            p++, ct++;
        } else if (prog[p] == '<') {
            r = (r + 3) % 4;
            p++, ct++;
        } else if (prog[p] == '>') {
            r = (r + 1) % 4;
            p++, ct++;
        } else if (prog[p] == '[') {
            int n = 0, c = 0, nest = 1;
            if (prog[++p] == '~') n = 1, p++;
            switch (prog[p]) {
                case 'T': c = 1; break;
                case 'N': c = r == 0; break;
                case 'E': c = r == 1; break;
                case 'S': c = r == 2; break;
                case 'W': c = r == 3; break;
                case 'C': {
                    int nx = clamp(x + dx[r], 0, h - 1);
                    int ny = clamp(y + dy[r], 0, w - 1);
                    c = (x == nx && y == ny) || a[nx][ny] == '#';
                    break;
                }
                default: break;
            }
            if (!n ^ c) {
                while (nest) {
                    p++;
                    if (prog[p] == '[') nest++;
                    else if (prog[p] == ']')
                        nest--;
                }
            }
            p++;
        } else if (prog[p] == '{') {
            st.push_back(p);

            int n = 0, c = 0, nest = 1;
            if (prog[++p] == '~') n = 1, p++;
            switch (prog[p]) {
                case 'T': c = 1; break;
                case 'N': c = r == 0; break;
                case 'E': c = r == 1; break;
                case 'S': c = r == 2; break;
                case 'W': c = r == 3; break;
                case 'C': {
                    int nx = clamp(x + dx[r], 0, h - 1);
                    int ny = clamp(y + dy[r], 0, w - 1);
                    c = (x == nx && y == ny) || a[nx][ny] == '#';
                    break;
                }
                default: break;
            }
            if (!n ^ c) {
                while (nest) {
                    p++;
                    if (prog[p] == '{') nest++;
                    else if (prog[p] == '}')
                        nest--;
                }
                st.pop_back();
            } else {
                mp[{{x, y}, {r, p}}]++;
                if (mp[{{x, y}, {r, p}}] > 100) {
                    cout << -1 << endl;
                    return 0;
                }
            }
            p++;
        } else if (prog[p] == '}') {
            p = st.back();
            st.pop_back();
        } else {
            p++;
        }
    }
    cout << -1 << endl;
}
accuracy: 1
time_ms: 60
memory_kb: 5012
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define INF 1LL << 60
#define rep(i, n) for (int i = 0; i < (n); ++i)

int clamp(int x, int l, int r) { return max(l, min(x, r)); }

int main() {
    int h, w;
    cin >> h >> w;

    string a[h];
    rep(i, h) cin >> a[i];

    string prog;
    cin >> prog;

    map<pair<pair<int, int>, pair<int, int>>, int> mp;
    vector<int> st;
    int p = 0, dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1}, x, y, r = 0, ct = 0;

    rep(i, h) rep(j, w) if (a[i][j] == 's') x = i, y = j;

    while (p < prog.size()) {
        if (prog[p] == '^') {
            int nx = clamp(x + dx[r], 0, h - 1);
            int ny = clamp(y + dy[r], 0, w - 1);
            if (a[nx][ny] != '#') x = nx, y = ny;
            if (a[x][y] == 'g') {
                cout << ct + 1 << endl;
                return 0;
            }
            p++, ct++;
        } else if (prog[p] == 'v') {
            int nx = clamp(x - dx[r], 0, h - 1);
            int ny = clamp(y - dy[r], 0, w - 1);
            if (a[nx][ny] != '#') x = nx, y = ny;
            if (a[x][y] == 'g') {
                cout << ct + 1 << endl;
                return 0;
            }
            p++, ct++;
        } else if (prog[p] == '<') {
            r = (r + 3) % 4;
            p++, ct++;
        } else if (prog[p] == '>') {
            r = (r + 1) % 4;
            p++, ct++;
        } else if (prog[p] == '[') {
            int n = 0, c = 0, nest = 1;
            if (prog[p] == '~') n = 1, p++;
            switch (prog[p]) {
                case 'T': c = 1; break;
                case 'N': c = r == 0; break;
                case 'E': c = r == 1; break;
                case 'S': c = r == 2; break;
                case 'W': c = r == 3; break;
                case 'C': {
                    int nx = clamp(x + dx[r], 0, h - 1);
                    int ny = clamp(y + dy[r], 0, w - 1);
                    c = (x == nx && y == ny) || a[nx][ny] == '#';
                    break;
                }
                default: break;
            }
            if (!n ^ c) {
                while (nest) {
                    p++;
                    if (prog[p] == '[') nest++;
                    else if (prog[p] == ']')
                        nest--;
                }
            }
            p++;
        } else if (prog[p] == '{') {
            st.push_back(p);

            int n = 0, c = 0, nest = 1;
            if (prog[++p] == '~') n = 1, p++;
            switch (prog[p]) {
                case 'T': c = 1; break;
                case 'N': c = r == 0; break;
                case 'E': c = r == 1; break;
                case 'S': c = r == 2; break;
                case 'W': c = r == 3; break;
                case 'C': {
                    int nx = clamp(x + dx[r], 0, h - 1);
                    int ny = clamp(y + dy[r], 0, w - 1);
                    c = (x == nx && y == ny) || a[nx][ny] == '#';
                    break;
                }
                default: break;
            }
            if (!n ^ c) {
                while (nest) {
                    p++;
                    if (prog[p] == '{') nest++;
                    else if (prog[p] == '}')
                        nest--;
                }
                st.pop_back();
            } else {
                mp[{{x, y}, {r, p}}]++;
                if (mp[{{x, y}, {r, p}}] > 100) {
                    cout << -1 << endl;
                    return 0;
                }
            }
            p++;
        } else if (prog[p] == '}') {
            p = st.back();
            st.pop_back();
        } else {
            p++;
        }
    }
    cout << -1 << endl;
}
accuracy: 0.17721518987341772
time_ms: 50
memory_kb: 6308
final_rank: 13