#include<bits/stdc++.h>

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

using namespace std;

#define N 0
#define E 1
#define S 2
#define W 3

int h,w,olen,back[1001];
char c[51][51];
string opr;
bool visited[50][50][4][1001];
bool p_visited[50][50][4][1001];
bool opr_visited[50][50][4][1001];
int dx[] = {+0,+1,+0,-1};
int dy[] = {-1,+0,+1,+0};

inline bool judge(int x,int y,int dir,char condition) {
  if( condition == 'T' ) return true;
  if( condition == 'N' ) return dir == N;
  if( condition == 'E' ) return dir == E;
  if( condition == 'S' ) return dir == S;
  if( condition == 'W' ) return dir == W;
  if( condition == 'C' ) {
    int nx = x + dx[dir], ny = y + dy[dir];
    assert( 0 <= nx && nx < w );
    assert( 0 <= ny && ny < h );
    return c[ny][nx] == '#';
  }
  assert(false);
}

bool fix(int &x,int &y,int &dir,int &pointer) {
  if( opr[pointer] == ']' ) {
    ++pointer;
    return true;
  } else if( opr[pointer] == '}' ) {
    pointer = back[pointer];
    return true;
  } else if( opr[pointer] == '[' || opr[pointer] == '{' ) {
    bool res = judge(x,y,dir,opr[pointer+1+(opr[pointer+1]=='~')]);
    if( opr[pointer+1] == '~' ) res = !res;
    if( res ) {
      pointer = pointer + 2 + ( opr[pointer+1] == '~' );
    } else {
      pointer = back[pointer] + 1;
    }
    return true;
  }
  return false;
}

void compute() {
  olen = (int)opr.size();
  memset(back,-1,sizeof back);
  {
    deque<int> if_deq, while_deq;
    rep(i,olen) {
      if( opr[i] == '[' ) if_deq.push_back(i);
      else if( opr[i] == '{' ) while_deq.push_back(i);
      else if( opr[i] == ']' ) { back[i] = if_deq.back(); back[if_deq.back()] = i; if_deq.pop_back(); }
      else if( opr[i] == '}' ) { back[i] = while_deq.back(); back[while_deq.back()] = i; while_deq.pop_back(); }
    }
  }
  
  int x,y=-1,dir = 0, gx, gy=-1;
  rep(i,h) rep(j,w) {
    if( c[i][j] == 's' ) {
      x = j, y = i;
      c[i][j] = '.';
    }
    if( c[i][j] == 'g' ) {
      gx = j, gy = i;
      c[i][j] = '.';
    }
  }

  assert(  y != -1 );
  assert( gy != -1 );

  int cnt = 0, pointer = 0;

  while(1) {
    int px = x, py = y, pdir = dir, ppointer = pointer;
    while(fix(x,y,dir,pointer)) {
      if( opr_visited[x][y][dir][pointer] && !p_visited[px][py][pdir][ppointer] ) goto Loop;
      opr_visited[x][y][dir][pointer] = true;
    }
    p_visited[px][py][pdir][ppointer] = true;


    
    if( x == gx && y == gy ) {
      cout << cnt << endl;
      return;
    }

    if( pointer >= olen ) break;

    if( visited[y][x][dir][pointer] ) break;
    visited[y][x][dir][pointer] = true;    
    
    if( opr[pointer] == '^' ) {
      int nx = x + dx[dir], ny = y + dy[dir];
      if( c[ny][nx] != '#' ) x = nx, y = ny;
    } else if( opr[pointer] == 'v' ) {
      int nx = x + dx[(dir+2)%4], ny = y + dy[(dir+2)%4];
      if( c[ny][nx] != '#' ) x = nx, y = ny;
    } else if( opr[pointer] == '<' ) {
      ( dir += 3 ) %= 4;
    } else if( opr[pointer] == '>' ) {
      ( dir += 1 ) %= 4;
    } else {
      assert(false);
    }
    ++pointer,++cnt;
  }
 Loop:;
  puts("-1");
}

int main() {
  cin >> h >> w;
  rep(i,h) {
    string tmp;
    cin >> tmp;
    rep(j,w) c[i][j] = tmp[j];
  }
  cin.ignore();
  getline(cin,opr);
  compute();
  return 0;
}

Measured memory_bytes: 30100