#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
//#define NDEBUG
#include <cassert>
using namespace std;


// N:0 E:1 S:2 W:3
const int dx[] = {0,1,0,-1};
const int dy[] = {-1,0,1,0};

typedef pair<int,int> pii;
#define y first
#define x second

int H, W;
vector<string> stage;
string pg;
vector<int> jmp;

bool visit[60][60][1100][4];
int dir;
pii robo;

int ans;

bool valid_range(int h, int w) {
	return 0 <= h && h < H && 0 <= w && w < W;
}

void update(int & pc, int nex_pc) {
	// cout << robo.y << " " << robo.x << " " << pc << " " << dir << endl;
	assert(pc != nex_pc);
	if(visit[robo.y][robo.x][pc][dir]) {
		cout << -1 << endl;
		exit(0);
	}
	visit[robo.y][robo.x][pc][dir] = true;
	pc = nex_pc;
}

bool check(int & pc) {
	bool res, inv;
	inv = false;
	if(pg[pc] == '~') {
		inv = true;
		update(pc, pc+1);
	}
	int nx, ny;
	ny = robo.y + dy[dir];
	nx = robo.x + dx[dir];
	switch(pg[pc]){
		case 'C' :
			res = stage[ny][nx] == '#'; break;
		case 'N' :
			res = dir == 0; break;
		case 'E' :
			res = dir == 1; break;
		case 'S' :
			res = dir == 2; break;
		case 'W' :
			res = dir == 3; break;
		case 'T' :
			res = true; break;
		default :
			assert(0);
	}
	if(inv)
		return !res;
	return res;
}

bool solve(int & pc) {
	int res = 0;
	while(pc < pg.size() && pg[pc] != ']' && pg[pc] != '}') {
		if(stage[robo.y][robo.x] == 'g')
			return true;
		if(pg[pc] == '[') {
			bool flg;
			int tmp;
			tmp = jmp[pc];
			update(pc,pc+1);
			flg = check(pc);
			if(flg) {
				update(pc,pc+1);
				if(solve(pc))
					return true;
				assert(pc == tmp);
				update(pc, pc+1);
			}
			else {
				update(pc,tmp+1);
			}
		}
		else if (pg[pc] == '{') {
			int tmp = jmp[pc];
			bool flg = true;
			update(pc,pc+1);
			while(check(pc)) {
				update(pc,pc+1);
				if(solve(pc))
					return true;
				update(pc, jmp[pc]);
				update(pc, pc+1);
			}
			update(pc,tmp+1);
		}
		else {
			int nx, ny;
			nx = robo.x; ny = robo.y;
			switch(pg[pc]) {
				case '^' :
					ny = robo.y + dy[dir];
					nx = robo.x + dx[dir];
					ans++;
					break;
				case 'v' :
					ny = robo.y + dy[dir+2&3];
					nx = robo.x + dx[dir+2&3];
					ans++;
					break;
				case '<' :
					dir = dir-1 +4 & 3;
					ans++;
					break;
				case '>' :
					dir = dir+1 +4 & 3;
					ans++;
					break;
				default  : assert(0);
			}
			if(valid_range(ny, nx) && stage[ny][nx] != '#') {
				robo.y = ny;
				robo.x = nx;
			}
			update(pc,pc+1);
		}
	}
	if(stage[robo.y][robo.x] == 'g')
		return true;
	return false;
}

int main() {
	cin >> H >> W;
	stage.resize(H);
	for(int i = 0; i < H; i++) cin >> stage[i];
	cin >> pg;

	for(int i = 0; i < H; i++) {
		for(int j = 0; j < W; j++) {
			if(stage[i][j] == 's') {
				robo.y = i;
				robo.x = j;
				stage[i][j] = '.';
			}
		}
	}
	jmp.resize(pg.size());
	stack<int> stk;
	for(int i = 0; i < pg.size(); i++) {
		if(pg[i] == '[' || pg[i] == '{') {
			stk.push(i);
		}
		else if(pg[i] == ']' || pg[i] == '}') {
			int tmp;
			tmp = stk.top(); stk.pop();
			jmp[i] = tmp;
			jmp[tmp] = i;
		}
	}

	int tmp;
	bool res;
	tmp = 0;
	res = solve(tmp);
	if(res)
		cout << ans << endl;
	else
		cout << -1 << endl;
}