#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;

void permute(string s,string temp,vector<string>& v) {
	if(s.empty()) {
		v.push_back(temp);
	} else {
		for(ll i=0;i<s.size();i++) {
			char chosen=s[i];
			s.erase(s.begin()+i);
			permute(s,temp+chosen,v);
			s.insert(s.begin()+i,chosen);
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	//code here;
//	ll t; cin>>t;
//	while(t--) {
		ll n,m; cin>>n>>m;
		ll count=0,stx,sty;
		char ar[n][m];
		for(ll i=0;i<n;i++) for(ll j=0;j<m;j++) {
			cin>>ar[i][j];
			if(ar[i][j]=='S') {
				stx=i;
				sty=j;
			}
		}
		string s1; cin>>s1;
		string s="0123";
		vector<string> v;
		permute(s,"",v);
		for(ll i=0;i<v.size();i++) {
			map<char,char> mp;
			mp[v[i][0]]='L';
			mp[v[i][1]]='R';
			mp[v[i][2]]='U';
			mp[v[i][3]]='D';
			ll x=stx,y=sty;
			for(ll j=0;j<s1.size();j++) {
				if(x>=n || y>=m) break;
				else if(ar[x][y]=='#') break;
				else if(ar[x][y]=='E') {
					count++;
					break;
				}
				if(mp[s1[j]]=='L') x--;
				else if(mp[s1[j]]=='R') x++;
				else if(mp[s1[j]]=='U') y++;
				else if(mp[s1[j]]=='D') y--;
			}
		}
		cout<<count<<endl;
//	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;

void permute(string s,string temp,vector<string>& v) {
	if(s.empty()) {
		v.push_back(temp);
	} else {
		for(ll i=0;i<s.size();i++) {
			char chosen=s[i];
			s.erase(s.begin()+i);
			permute(s,temp+chosen,v);
			s.insert(s.begin()+i,chosen);
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	//code here;
//	ll t; cin>>t;
//	while(t--) {
		ll n,m; cin>>n>>m;
		ll count=0,stx,sty;
		char ar[n][m];
		for(ll i=0;i<n;i++) for(ll j=0;j<m;j++) {
			cin>>ar[i][j];
			if(ar[i][j]=='S') {
				stx=i;
				sty=j;
			}
		}
		string s1; cin>>s1;
		string s="0123";
		vector<string> v;
		permute(s,"",v);
		for(ll i=0;i<v.size();i++) {
			map<char,char> mp;
			mp[v[i][0]]='L';
			mp[v[i][1]]='R';
			mp[v[i][2]]='U';
			mp[v[i][3]]='D';
			ll x=stx,y=sty;
			for(ll j=0;j<s1.size();j++) {
				if(x<0 || x>=n || y<0 || y>=m) break;
				else if(ar[x][y]=='#') break;
				if(mp[s1[j]]=='L') y--;
				else if(mp[s1[j]]=='R') y++;
				else if(mp[s1[j]]=='U') x--;
				else if(mp[s1[j]]=='D') x++;
				if(ar[x][y]=='E') {
					count++;
					break;
				}
			}
		}
		cout<<count<<endl;
//	}
	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <stack>
#include <cstring>
#include <iterator>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <bitset>
#include <chrono>

using namespace std;
typedef long long mt;
//#define mt int
#define rep(a, b, i) for(register mt i = a; i < b; ++i)
#define repe(a, b, i) for(register mt i = a; i <= b; ++i)
#define repd(a, b, i) for(register mt i = a; i > b; --i)
#define repde(a, b, i) for(register mt i = a; i >= b; --i)

#define N 51
#define K 5
#define M (100001)
#define INF 100000000000000007//10000000000000007// 1e16 + 7
#define MOD 1000000007ll  //1000000007//1e9 + 7
#define EPS 1e-9
#define MAX 1000000000000000001
//#pragma comment(linker, "/STACK:200000000")

mt n, m, answ, ln;
char s[N][N], si[N * 2];

pair<mt, mt> b, e;

mt bx[] = { -1, 1, 0, 0 };
mt by[] = { 0, 0,  -1, 1 };

mt dx[4], dy[4];

void test()
{
	mt pos_x = b.first, pos_y = b.second;
	rep(0, ln, i) {
		pos_x += dx[si[i] - '0'];
		pos_y += dy[si[i] - '0'];

		if (pos_x == e.first && pos_y == e.second) {
			++answ;
			return;
		}

		if (pos_x < 0 || pos_x >= n || pos_y < 0 || pos_y >= m || s[pos_x][pos_y] == '#')
			return;
	}
}

int main(void)
{
#ifdef _DEBUG
	freopen("in.txt", "r", stdin);
#endif
	scanf("%lld %lld", &n, &m);
	rep(0, n, i)
		scanf("%s", s[i]);

	rep(0, n, i)
		rep(0, m, j) {
		if (s[i][j] == 'S') b = make_pair(i, j);
		else if (s[i][j] == 'E') e = make_pair(i, j);
	}

	scanf("%s", si);
	ln = strlen(si);

	rep(0, 4, i) {
		rep(0, 4, j) {
			if (i == j)
				continue;
			rep(0, 4, k) {
				if (i == k || k == j)
					continue;
				dx[0] = bx[i];
				dy[0] = by[i];

				dx[1] = bx[j];
				dy[1] = by[j];

				dx[2] = bx[k];
				dy[2] = by[k];

				rep(0, 4, p) {
					if (p == i || p == j || p == k)
						continue;

					dx[3] = bx[p];
					dy[3] = by[p];
					test();
				}
			}
		}
	}
	printf("%lld\n", answ);
	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <stack>
#include <cstring>
#include <iterator>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <bitset>
#include <chrono>

using namespace std;
typedef long long mt;
//#define mt int
#define rep(a, b, i) for(register mt i = a; i < b; ++i)
#define repe(a, b, i) for(register mt i = a; i <= b; ++i)
#define repd(a, b, i) for(register mt i = a; i > b; --i)
#define repde(a, b, i) for(register mt i = a; i >= b; --i)

#define N 51
#define K 5
#define M (100001)
#define INF 100000000000000007//10000000000000007// 1e16 + 7
#define MOD 1000000007ll  //1000000007//1e9 + 7
#define EPS 1e-9
#define MAX 1000000000000000001
//#pragma comment(linker, "/STACK:200000000")

mt n, m, answ, ln;
char s[N][N], si[N * 2];

pair<mt, mt> b, e;

mt bx[] = { -1, 1, 0, 0 };
mt by[] = { 0, 0,  -1, 1 };

mt dx[4], dy[4];

void test()
{
	mt pos_x = b.first, pos_y = b.second;
	rep(0, ln, i) {
		pos_x += dx[si[i] - '0'];
		pos_y += dy[si[i] - '0'];

		if (pos_x == e.first && pos_y == e.second) {
			++answ;
			return;
		}

		if (pos_x < 0 || pos_x >= n || pos_y < 0 || pos_y >= m || s[pos_x][pos_y] == '#')
			return;
	}
}

mt v[4];
void dfs(mt st)
{
	if (st == 4) { test(); return; }
	rep(0, 4, i) {
		bool ok = true;
		rep(0, st, j)
			if (i == v[j])
				ok = false;
		if (ok) {
			v[st] = i;
			dx[st] = bx[i];
			dy[st] = by[i];

			dfs(st + 1);
		}
	}
}

int main(void)
{
#ifdef _DEBUG
	freopen("in.txt", "r", stdin);
#endif
	scanf("%lld %lld", &n, &m);
	rep(0, n, i)
		scanf("%s", s[i]);

	rep(0, n, i)
		rep(0, m, j) {
		if (s[i][j] == 'S') b = make_pair(i, j);
		else if (s[i][j] == 'E') e = make_pair(i, j);
	}

	scanf("%s", si);
	ln = strlen(si);

	dfs(0);
	printf("%lld\n", answ);
	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <stack>
#include <cstring>
#include <iterator>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <bitset>
#include <chrono>

using namespace std;
typedef long long mt;
//#define mt int
#define rep(a, b, i) for(register mt i = a; i < b; ++i)
#define repe(a, b, i) for(register mt i = a; i <= b; ++i)
#define repd(a, b, i) for(register mt i = a; i > b; --i)
#define repde(a, b, i) for(register mt i = a; i >= b; --i)

#define N 51
#define K 5
#define M (100001)
#define INF 100000000000000007//10000000000000007// 1e16 + 7
#define MOD 1000000007ll  //1000000007//1e9 + 7
#define EPS 1e-9
#define MAX 1000000000000000001
//#pragma comment(linker, "/STACK:200000000")

mt n, m, answ, ln;
char s[N][N], si[N * 2];

pair<mt, mt> b, e;

mt bx[] = { -1, 1, 0, 0 };
mt by[] = { 0, 0,  -1, 1 };

mt dx[4], dy[4];

void test()
{
	mt pos_x = b.first, pos_y = b.second;
	rep(0, ln, i) {
		pos_x += dx[si[i] - '0'];
		pos_y += dy[si[i] - '0'];

		if (pos_x == e.first && pos_y == e.second) {
			++answ;
			return;
		}

		if (pos_x < 0 || pos_x >= n || pos_y < 0 || pos_y >= m)
			return;
	}
}

int main(void)
{
#ifdef _DEBUG
	freopen("in.txt", "r", stdin);
#endif
	scanf("%lld %lld", &n, &m);
	rep(0, n, i)
		scanf("%s", s[i]);

	rep(0, n, i)
		rep(0, n, j)
		if (s[i][j] == 'S') b = make_pair(i, j);
		else if (s[i][j] == 'E') e = make_pair(i, j);

	scanf("%s", si);
	ln = strlen(si);

	rep(0, 4, i) {
		rep(0, 4, j) {
			if (i == j)
				continue;
			rep(0, 4, k) {
				if (i == k || k == j)
					continue;
				dx[0] = bx[i];
				dy[0] = by[i];

				dx[1] = bx[j];
				dy[1] = by[j];

				dx[2] = bx[k];
				dy[2] = by[k];

				rep(0, 4, p) {
					if (p == i || p == j || p == k)
						continue;

					dx[3] = bx[p];
					dy[3] = by[p];
					test();
				}
			}
		}
	}
	printf("%lld\n", answ);
	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <stack>
#include <cstring>
#include <iterator>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <bitset>
#include <chrono>

using namespace std;
typedef long long mt;
//#define mt int
#define rep(a, b, i) for(register mt i = a; i < b; ++i)
#define repe(a, b, i) for(register mt i = a; i <= b; ++i)
#define repd(a, b, i) for(register mt i = a; i > b; --i)
#define repde(a, b, i) for(register mt i = a; i >= b; --i)

#define N 51
#define K 5
#define M (100001)
#define INF 100000000000000007//10000000000000007// 1e16 + 7
#define MOD 1000000007ll  //1000000007//1e9 + 7
#define EPS 1e-9
#define MAX 1000000000000000001
//#pragma comment(linker, "/STACK:200000000")

mt n, m, answ, ln;
char s[N][N], si[N * 2];

pair<mt, mt> b, e;

mt bx[] = { -1, 1, 0, 0 };
mt by[] = { 0, 0,  -1, 1 };

mt dx[4], dy[4];

void test()
{
	mt pos_x = b.first, pos_y = b.second;
	rep(0, ln, i) {
		pos_x += dx[si[i] - '0'];
		pos_y += dy[si[i] - '0'];

		if (pos_x == e.first && pos_y == e.second) {
			++answ;
			return;
		}

		if (pos_x < 0 || pos_x >= n || pos_y < 0 || pos_y >= m || s[pos_x][pos_y] == '#')
			return;
	}
}

int main(void)
{
#ifdef _DEBUG
	freopen("in.txt", "r", stdin);
#endif
	scanf("%lld %lld", &n, &m);
	rep(0, n, i)
		scanf("%s", s[i]);

	rep(0, n, i)
		rep(0, n, j)
		if (s[i][j] == 'S') b = make_pair(i, j);
		else if (s[i][j] == 'E') e = make_pair(i, j);

	scanf("%s", si);
	ln = strlen(si);

	rep(0, 4, i) {
		rep(0, 4, j) {
			if (i == j)
				continue;
			rep(0, 4, k) {
				if (i == k || k == j)
					continue;
				dx[0] = bx[i];
				dy[0] = by[i];

				dx[1] = bx[j];
				dy[1] = by[j];

				dx[2] = bx[k];
				dy[2] = by[k];

				rep(0, 4, p) {
					if (p == i || p == j || p == k)
						continue;

					dx[3] = bx[p];
					dy[3] = by[p];
					test();
				}
			}
		}
	}
	printf("%lld\n", answ);
	return 0;
}


#include <bits/stdc++.h>
using namespace std ;
int n , m , answer ;
pair <int , int >	me , sp , ep ;
string maping [100] , s  ;
bool ch ;
pair <bool , bool > check ;
pair <bool , bool > isval ()
{
	if ( me.first == ep.first && me.second == ep.second )	return make_pair ( true , true ) ;
	else if ( me.first < 0 || me.first >= n  || me.second < 0 || me.second >= m || maping [me.first][me.second] == '#' )	return make_pair ( false , false ) ;
	else	return make_pair ( true , false ) ;
}
int main ()
{
	cin >> n >> m ;
	for (int i = 0 ; i < n ; i ++ )
	{
		cin >> s ;
		for (int j = 0 ; j < m ; j ++ )
		{
			maping [i][j] = s[j] ;
			if ( s[j] == 'S' )
			{
                me.first = i ;
				me.second = j ;
				sp = me ;
			}
			else if ( s[j] == 'E' )
			{
				ep.first = i ;
				ep.second = j ;
			}
		}
	}
	cin >> s ;
	for (int i = 0 ; i < 4 ; i ++ )
	{
		for (int j = 0 ; j < 4 ; j ++ )
		{
			if ( j == i )	continue ;
			for (int k = 0 ; k < 4 ; k ++ )
			{
				if ( k == j || k == i )	continue ;
				for (int l = 0 ; l < 4 ; l ++ )
				{
					if ( l == j || l == i || l == k )	continue ;
					ch = false ;
					me = sp ;
					for ( int q = 0 ; q < s.length() ; q ++ )
					{
						if ( s[q] - '0'  == i )		me.first ++ ;
						else if ( s[q] - '0' == j )		me.first -- ;
						else if ( s[q] - '0' == k )		me.second ++ ;
						else	me.second -- ;
						check = isval () ;
						if (  check.first == false && check.second == false )
						{
							ch = false ;
							break ;
						}
						else if ( check .first == true  && check .second == true )
						{
							ch = true ;
							break ;
						}
					}
					if ( ch )
					{
						answer ++;
					}
				}
			}
		}
	}
	cout << answer ;
	return 0 ;
}


#include <bits/stdc++.h>
using namespace std ;
int n , m , answer , q ;
pair <int , int >	me , sp , ep ;
string  s  ;
char maping [110][110] ;
bool ch ;
pair <bool , bool > check ;
pair <bool , bool > isval ()
{
	if ( me.first == ep.first && me.second == ep.second )	return make_pair ( true , true ) ;
	else if ( me.first < 0 || me.first >= n  || me.second < 0 || me.second >= m || maping [me.first][me.second] == '#' )	return make_pair ( false , false ) ;
	else	return make_pair ( true , false ) ;
}
int main ()
{
	cin >> n >> m ;
	for (int i = 0 ; i < n ; i ++ )
	{
		for (int j = 0 ; j < m ; j ++ )
		{
			cin >> maping [i][j] ;
			if ( maping [i][j] == 'S' )
			{
                me.first = i ;
				me.second = j ;
				sp = me ;
			}
			else if ( maping[i][j] == 'E' )
			{
				ep.first = i ;
				ep.second = j ;
			}
		}
	}
	cin >> s ;
	for (int i = 0 ; i < 4 ; i ++ )
	{
		for (int j = 0 ; j < 4 ; j ++ )
		{
			if ( j == i )	continue ;
			for (int k = 0 ; k < 4 ; k ++ )
			{
				if ( k == j || k == i )	continue ;
				for (int l = 0 ; l < 4 ; l ++ )
				{
					if ( l == j || l == i || l == k )	continue ;
					ch = false ;
					me = sp ;
					for ( int q = 0 ; q < s.length() ; q ++ )
					{
						if ( s[q] - '0'  == i )		me.first ++ ;
						else if ( s[q] - '0' == j )		me.first -- ;
						else if ( s[q] - '0' == k )		me.second ++ ;
						else	me.second -- ;
						check = isval () ;
						if (  check.first == false && check.second == false )
						{
							ch = false ;
							break ;
						}
						else if ( check .first == true  && check .second == true )
						{
							ch = true ;
							break ;
						}
					}
					if ( ch )
					{
						answer ++;
					}
				}
			}
		}
	}
	cout << answer ;
	return 0 ;
}


#include <bits/stdc++.h>
using namespace std ;
int n , m , answer ;
pair <int , int >	me , sp , ep ;
string maping [100] , s  ;
bool ch ;
pair <bool , bool > check ;
pair <bool , bool > isval ()
{
	if ( me.first == ep.first && me.second == ep.second )	return make_pair ( true , true ) ;
	else if ( me.first < 0 || me.first >= n  || me.second < 0 || me.second >= m || maping [me.first][me.second] == '#' )	return make_pair ( false , false ) ;
	else	return make_pair ( true , false ) ;
}
int main ()
{
	cin >> n >> m ;
	for (int i = 0 ; i < n ; i ++ )
	{
		cin >> s ;
		if ( s.size() != m )
		{
			cout << "0" ;
			return 0 ;
		}
		for (int j = 0 ; j < m ; j ++ )
		{
			maping [i][j] = s[j] ;
			if ( s[j] == 'S' )
			{
                me.first = i ;
				me.second = j ;
				sp = me ;
			}
			else if ( s[j] == 'E' )
			{
				ep.first = i ;
				ep.second = j ;
			}
		}
	}
	cin >> s ;
	for (int i = 0 ; i < 4 ; i ++ )
	{
		for (int j = 0 ; j < 4 ; j ++ )
		{
			if ( j == i )	continue ;
			for (int k = 0 ; k < 4 ; k ++ )
			{
				if ( k == j || k == i )	continue ;
				for (int l = 0 ; l < 4 ; l ++ )
				{
					if ( l == j || l == i || l == k )	continue ;
					ch = false ;
					me = sp ;
					for ( int q = 0 ; q < s.length() ; q ++ )
					{
						if ( s[q] - '0'  == i )		me.first ++ ;
						else if ( s[q] - '0' == j )		me.first -- ;
						else if ( s[q] - '0' == k )		me.second ++ ;
						else	me.second -- ;
						check = isval () ;
						if (  check.first == false && check.second == false )
						{
							ch = false ;
							break ;
						}
						else if ( check .first == true  && check .second == true )
						{
							ch = true ;
							break ;
						}
					}
					if ( ch )
					{
						answer ++;
					}
				}
			}
		}
	}
	cout << answer ;
	return 0 ;
}


#include <bits/stdc++.h>
using namespace std ;
int n , m , answer ;
pair <int , int >	me , sp , ep ;
string maping [100] , s  ;
bool ch ;
pair <bool , bool > check ;
pair <bool , bool > isval ()
{
	if ( me.first == ep.first && me.second == ep.second )	return make_pair ( true , true ) ;
	else if ( me.first < 0 || me.first >= n  || me.second < 0 || me.second >= m || maping [me.first][me.second] == '#' )	return make_pair ( false , false ) ;
	else	return make_pair ( true , false ) ;
}
int main ()
{
	cin >> n >> m ;
	for (int i = 0 ; i < n ; i ++ )
	{
		cin >> s ;
		for (int j = 0 ; j < s.length() ; j ++ )
		{
			maping [i][j] = s[j] ;
			if ( s[j] == 'S' )
			{
                me.first = i ;
				me.second = j ;
				sp = me ;
			}
			else if ( s[j] == 'E' )
			{
				ep.first = i ;
				ep.second = j ;
			}
		}
	}
	cin >> s ;
	for (int i = 0 ; i < 4 ; i ++ )
	{
		for (int j = 0 ; j < 4 ; j ++ )
		{
			if ( j == i )	continue ;
			for (int k = 0 ; k < 4 ; k ++ )
			{
				if ( k == j || k == i )	continue ;
				for (int l = 0 ; l < 4 ; l ++ )
				{
					if ( l == j || l == i || l == k )	continue ;
					ch = false ;
					me = sp ;
					for ( int q = 0 ; q < s.length() ; q ++ )
					{
						if ( s[q] - '0'  == i )		me.first ++ ;
						else if ( s[q] - '0' == j )		me.first -- ;
						else if ( s[q] - '0' == k )		me.second ++ ;
						else	me.second -- ;
						check = isval () ;
						if (  check.first == false && check.second == false )
						{
							ch = false ;
							break ;
						}
						else if ( check .first == true  && check .second == true )
						{
							ch = true ;
							break ;
						}
					}
					if ( ch )
					{
						answer ++;
					}
				}
			}
		}
	}
	cout << answer ;
	return 0 ;
}


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

typedef long long ll;
typedef int ld;
typedef pair<int,int> pii;
typedef complex<ld> pt;
typedef vector<pt> pol;
#define nl '\n'

inline void srand() { srand(clock() + time(nullptr)); }

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

template <class T>
ostream& operator << (ostream& os, const vector<T>& v) {
	for (const T& it : v) os << it << " "; return os;
}

const ll INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
//const ld PI = M_PIl;
////////////////////////////////////////////////////////////////////////

const ll MOD = 1e9+7;
const ld EPS = 1e-9;

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

	pt mp[4];
	mp[0] = pt(0,1);
	mp[1] = pt(1,0);
	mp[2] = pt(0,-1);
	mp[3] = pt(-1,0);

	vector<int> perm;
	for (int i = 0; i < 4; i++) {
		perm.push_back(i);
	}

	int n, m;
	cin >> n >> m;
	string grid[n];
	pt start, end;
	for (int i = 0; i < n; i++) {
		cin >> grid[i];
		for (int j = 0; j < n; j++) {
			if (grid[i][j] == 'S')
				start = pt(i,j);
		}
	}

	string s;
	cin >> s;

	int ans = 0;
	do {
		pt pos = start;
		bool shit = false;
		for (char c : s) {
			c -= '0';
			pos += mp[perm[c]];
			if (pos.real() < 0 || pos.imag() < 0) break;
			if (pos.real() >= n || pos.imag() >= m) break;
			if (grid[pos.real()][pos.imag()] == '#') break;
			if (grid[pos.real()][pos.imag()] == 'E') {
				shit = true;
				break;
			}
		}
		if (shit) {
			ans++;
		}
	} while (next_permutation(perm.begin(), perm.end()));

	cout << ans << nl;

	return 0;
}


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

typedef long long ll;
typedef int ld;
typedef pair<int,int> pii;
typedef complex<ld> pt;
typedef vector<pt> pol;
#define nl '\n'

inline void srand() { srand(clock() + time(nullptr)); }

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

template <class T>
ostream& operator << (ostream& os, const vector<T>& v) {
	for (const T& it : v) os << it << " "; return os;
}

const ll INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
//const ld PI = M_PIl;
////////////////////////////////////////////////////////////////////////

const ll MOD = 1e9+7;
const ld EPS = 1e-9;

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

	pt mp[4];
	mp[0] = pt(0,1);
	mp[1] = pt(1,0);
	mp[2] = pt(0,-1);
	mp[3] = pt(-1,0);

	vector<int> perm;
	for (int i = 0; i < 4; i++) {
		perm.push_back(i);
	}

	int n, m;
	cin >> n >> m;
	string grid[n];
	pt start, end;
	for (int i = 0; i < n; i++) {
		cin >> grid[i];
		for (int j = 0; j < m; j++) {
			if (grid[i][j] == 'S')
				start = pt(i,j);
		}
	}

	string s;
	cin >> s;

	int ans = 0;
	do {
		pt pos = start;
		bool shit = false;
		for (char c : s) {
			c -= '0';
			pos += mp[perm[c]];
			if (pos.real() < 0 || pos.imag() < 0) break;
			if (pos.real() >= n || pos.imag() >= m) break;
			if (grid[pos.real()][pos.imag()] == '#') break;
			if (grid[pos.real()][pos.imag()] == 'E') {
				shit = true;
				break;
			}
		}
		if (shit) {
			ans++;
		}
	} while (next_permutation(perm.begin(), perm.end()));

	cout << ans << nl;

	return 0;
}


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

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef complex<ld> pt;
typedef vector<pt> pol;
#define nl '\n'

inline void srand() { srand(clock() + time(nullptr)); }

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

template <class T>
ostream& operator << (ostream& os, const vector<T>& v) {
	for (const T& it : v) os << it << " "; return os;
}

template <class T>
inline T sqr(T x) { return x*x; }

const ll INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
//const ld PI = M_PIl;
////////////////////////////////////////////////////////////////////////

const ll MOD = 1e9+7;
const ld EPS = 1e-9;

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

	int n; cin >> n;

	int arr[100001];
	memset(arr, 0, sizeof arr);
	for (int i = 0; i < n; i++) {
		int a; cin >> a;
		for (int j = 1; j < sqrt(a); j++) {
			if (a % j == 0) {
				arr[j]++;
				if (j != a/j)
					arr[a/j]++;
			}
		}
	}

	int ans = 0;
	for (int i = 2; i <= 100000; i++) {
		ans = max(ans, arr[i]);
	}

	cout << ans << nl;

	return 0;
}


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

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef complex<ld> pt;
typedef vector<pt> pol;
#define nl '\n'

inline void srand() { srand(clock() + time(nullptr)); }

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

template <class T>
ostream& operator << (ostream& os, const vector<T>& v) {
	for (const T& it : v) os << it << " "; return os;
}

template <class T>
inline T sqr(T x) { return x*x; }

const ll INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
//const ld PI = M_PIl;
////////////////////////////////////////////////////////////////////////

const ll MOD = 1e9+7;
const ld EPS = 1e-9;

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

	int n; cin >> n;

	int arr[100001];
	memset(arr, 0, sizeof arr);
	for (int i = 0; i < n; i++) {
		int a; cin >> a;
		for (int j = 1; j <= sqrt(a); j++) {
			if (a % j == 0) {
				arr[j]++;
				if (j != a/j)
					arr[a/j]++;
			}
		}
	}

	int ans = 1;
	for (int i = 2; i <= 100000; i++) {
		ans = max(ans, arr[i]);
	}

	cout << ans << nl;

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <map>
#include <unordered_map>
#include <stack>
#include <cstring>
#include <string>
#include <set>
#include <unordered_set>
#include <bitset>
#include <limits>
#include <climits>
#include <queue>
#include <deque>
#include <list>
#include <forward_list>
#include <sstream>
#include <complex>
#include <iterator>
#include <functional>
#include <tuple>
#include <array>
#include <locale>
#include <memory>
#include <cstdio>
#define fin(x) freopen("input.txt", "r", stdin);
#define fout(x) freopen("output.txt", "w", stdout);
#define speedup ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
#define cp(x) cout.setf(ios::fixed); cout.precision(x);
#define forn(x, n) for(int i = x; i <= n; ++i)
#define fory(x, n, y) for(int i = x; i <= n; i += y)
#define forj(x, n, y) for(int y = x; y <= n; ++y)
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define mem(a,b) memset(a, b, sizeof(a))
#define mcp(a,b,x) memcpy(a, b, sizeof(x))
#define wh(t) while(true)
#define sp system("pause")
#define ST(N) srand(time(NULL))
#define SQ(x) (x)*(x)
#define ppc(x) __popcnt(x)
#define lb lower_bound
#define ub upper_bound
#define tp toupper
#define tl tolower
#define ad push_back
#define em emplace
#define eh empalce_hint
#define mp make_pair
#define nxp next_permutation
#define fr first
#define sc second
#define pq priority_queue
#define cl clear
#define vc vector
#define bs bitset
#define li list<int>
#define vi vector<int>
#define si set<int>
#define vii vector<vector<int> >
#define sti stack<int>
#define dqi deque<int>
#define pqi priority_queue<int>
#define pii pair<int, int>
#define mii map<int, int>
#define bs32 bitset<32>
//#define DEBUG
//#define TEST 1
#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:336777216")
typedef long long ll;
typedef long double ld;
typedef double dbl;
typedef unsigned long long ull;
using namespace std;

const int N = 1000 * 1000 + 100;
const long long MOD = 1e9 + 7;
const long long INC = INT_MAX;
const long long EPS = LLONG_MAX;
const long long INF = ULLONG_MAX;
long long minim = INF;
long long maxim = -INF;

long long cnt = 0, ans = 0;
vector<int> dp(N);
bool u = false, U[N];
int b[N];
int A[N / 1000][N / 1000];
string s, t;
char c[100][100];
int n, m, x, y, xx, yy, ss;
int a[] = { 1, 2, 3, 4 };
bool f(int x, int y) {
	for (auto i : s) {
		int xxx = i - '0';
		int d = a[xxx];
		if (d == 1) {
			--x;
		}
		if (d == 2) {
			++x;
		}
		if (d == 3) {
			--y;
		}
		if (d == 4) {
			++y;
		}
		if (x == xx && y == yy) {
			return true;
		}
		if (x < 1 || y < 1 || x > n || y > n || c[x][y] == '#'){
			return false;
		}
	}
	return false;
}

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

//#define USACO
#ifdef USACO
#ifndef _MSC_VER
#define TASK "proximity"
	freopen(TASK".in", "r", stdin);
	freopen(TASK".out", "w", stdout);
#endif
#endif

	cin >> n >> m;

	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= m; ++j) {
			cin >> c[i][j];
			if (c[i][j] == 'S') {
				x = i, y = j;
			}
			if (c[i][j] == 'E') {
				xx = i, yy = j;
			}
		}
	}

	cin >> s;

	do {
		if (f(x, y)) ++cnt;
	} while (nxp(a, a + 4));

	cout << cnt << endl;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <map>
#include <unordered_map>
#include <stack>
#include <cstring>
#include <string>
#include <set>
#include <unordered_set>
#include <bitset>
#include <limits>
#include <climits>
#include <queue>
#include <deque>
#include <list>
#include <forward_list>
#include <sstream>
#include <complex>
#include <iterator>
#include <functional>
#include <tuple>
#include <array>
#include <locale>
#include <memory>
#include <cstdio>
#define fin(x) freopen("input.txt", "r", stdin);
#define fout(x) freopen("output.txt", "w", stdout);
#define speedup ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
#define cp(x) cout.setf(ios::fixed); cout.precision(x);
#define forn(x, n) for(int i = x; i <= n; ++i)
#define fory(x, n, y) for(int i = x; i <= n; i += y)
#define forj(x, n, y) for(int y = x; y <= n; ++y)
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define mem(a,b) memset(a, b, sizeof(a))
#define mcp(a,b,x) memcpy(a, b, sizeof(x))
#define wh(t) while(true)
#define sp system("pause")
#define ST(N) srand(time(NULL))
#define SQ(x) (x)*(x)
#define ppc(x) __popcnt(x)
#define lb lower_bound
#define ub upper_bound
#define tp toupper
#define tl tolower
#define ad push_back
#define em emplace
#define eh empalce_hint
#define mp make_pair
#define nxp next_permutation
#define fr first
#define sc second
#define pq priority_queue
#define cl clear
#define vc vector
#define bs bitset
#define li list<int>
#define vi vector<int>
#define si set<int>
#define vii vector<vector<int> >
#define sti stack<int>
#define dqi deque<int>
#define pqi priority_queue<int>
#define pii pair<int, int>
#define mii map<int, int>
#define bs32 bitset<32>
//#define DEBUG
//#define TEST 1
#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:336777216")
typedef long long ll;
typedef long double ld;
typedef double dbl;
typedef unsigned long long ull;
using namespace std;

const int N = 1000 * 1000 + 100;
const ll MOD = 1e9 + 7;
const ll INC = INT_MAX;
const ll EPS = LLONG_MAX;
const ull INF = ULLONG_MAX;
long long minim = INF;
long long maxim = -INF;

long long cnt = 0, ans = 0;
vector<int> dp(N);
bool u = false, U[N];
int b[N];
int A[N / 1000][N / 1000];
string s, t;
char c[100][100];
int n, m, xx, yy, ss;
int a[] = { 1, 2, 3, 4 };
bool f(int x, int y) {
	for (auto i : s) {
		int xxx = i - '0';
		int d = a[xxx];
		if (d == 1) {
			++x;
		}
		else if (d == 2) {
			++y;
		}
		else if (d == 3) {
			--x;
		}
		else if (d == 4) {
			--y;
		}
		if (x == xx && y == yy) {
			return true;
		}
		if (x < 1 || y < 1 || x > n || y > m || c[x][y] == '#'){
			return false;
		}
	}
	return false;
}

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

	//#define USACO
#ifdef USACO
#ifndef _MSC_VER
#define TASK "proximity"
	freopen(TASK".in", "r", stdin);
	freopen(TASK".out", "w", stdout);
#endif
#endif

	cin >> n >> m;
	int x, y;
	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= m; ++j) {
			cin >> c[i][j];
			if (c[i][j] == 'S') {
				x = i, y = j;
			}
			if (c[i][j] == 'E') {
				xx = i, yy = j;
			}
		}
	}

	cin >> s;

	do {
		if (f(x, y)) ++cnt;
	} while (nxp(a, a + 4));

	cout << cnt << endl;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <map>
#include <unordered_map>
#include <stack>
#include <cstring>
#include <string>
#include <set>
#include <unordered_set>
#include <bitset>
#include <limits>
#include <climits>
#include <queue>
#include <deque>
#include <list>
#include <forward_list>
#include <sstream>
#include <complex>
#include <iterator>
#include <functional>
#include <tuple>
#include <array>
#include <locale>
#include <memory>
#include <cstdio>
#define fin(x) freopen("input.txt", "r", stdin);
#define fout(x) freopen("output.txt", "w", stdout);
#define speedup ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
#define cp(x) cout.setf(ios::fixed); cout.precision(x);
#define forn(x, n) for(int i = x; i <= n; ++i)
#define fory(x, n, y) for(int i = x; i <= n; i += y)
#define forj(x, n, y) for(int y = x; y <= n; ++y)
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define mem(a,b) memset(a, b, sizeof(a))
#define mcp(a,b,x) memcpy(a, b, sizeof(x))
#define wh(t) while(true)
#define sp system("pause")
#define ST(N) srand(time(NULL))
#define SQ(x) (x)*(x)
#define ppc(x) __popcnt(x)
#define lb lower_bound
#define ub upper_bound
#define tp toupper
#define tl tolower
#define ad push_back
#define em emplace
#define eh empalce_hint
#define mp make_pair
#define nxp next_permutation
#define fr first
#define sc second
#define pq priority_queue
#define cl clear
#define vc vector
#define bs bitset
#define li list<int>
#define vi vector<int>
#define si set<int>
#define vii vector<vector<int> >
#define sti stack<int>
#define dqi deque<int>
#define pqi priority_queue<int>
#define pii pair<int, int>
#define mii map<int, int>
#define bs32 bitset<32>
//#define DEBUG
//#define TEST 1
#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:336777216")
typedef long long ll;
typedef long double ld;
typedef double dbl;
typedef unsigned long long ull;
using namespace std;

const int N = 1000 * 1000 + 100;
const ll MOD = 1e9 + 7;
const ll INC = INT_MAX;
const ll EPS = LLONG_MAX;
const ull INF = ULLONG_MAX;
long long minim = INF;
long long maxim = -INF;

long long cnt = 0, ans = 0;
vector<int> dp(N);
bool u = false, U[N];
int b[N];
int A[N / 1000][N / 1000];
string s, t;
char c[100][100];
int n, m, xx, yy, ss;
int a[] = { 1, 2, 3, 4 };
bool f(int x, int y) {
	for (auto i : s) {
		int xxx = i - '0';
		int d = a[xxx];
		if (d == 1) {
			++x;
		}
		else if (d == 2) {
			++y;
		}
		else if (d == 3) {
			--x;
		}
		else if (d == 4) {
			--y;
		}
		if (x == xx && y == yy) {
			return true;
		}
		if (x < 1 || y < 1 || x > n || y > n || c[x][y] == '#'){
			return false;
		}
	}
	return false;
}

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

	//#define USACO
#ifdef USACO
#ifndef _MSC_VER
#define TASK "proximity"
	freopen(TASK".in", "r", stdin);
	freopen(TASK".out", "w", stdout);
#endif
#endif

	cin >> n >> m;
	int x, y;
	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= m; ++j) {
			cin >> c[i][j];
			if (c[i][j] == 'S') {
				x = i, y = j;
			}
			if (c[i][j] == 'E') {
				xx = i, yy = j;
			}
		}
	}

	cin >> s;

	do {
		if (f(x, y)) ++cnt;
	} while (nxp(a, a + 4));

	cout << cnt << endl;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <map>
#include <unordered_map>
#include <stack>
#include <cstring>
#include <string>
#include <set>
#include <unordered_set>
#include <bitset>
#include <limits>
#include <climits>
#include <queue>
#include <deque>
#include <list>
#include <forward_list>
#include <sstream>
#include <complex>
#include <iterator>
#include <functional>
#include <tuple>
#include <array>
#include <locale>
#include <memory>
#include <cstdio>
#define fin(x) freopen("input.txt", "r", stdin);
#define fout(x) freopen("output.txt", "w", stdout);
#define speedup ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
#define cp(x) cout.setf(ios::fixed); cout.precision(x);
#define forn(x, n) for(int i = x; i <= n; ++i)
#define fory(x, n, y) for(int i = x; i <= n; i += y)
#define forj(x, n, y) for(int y = x; y <= n; ++y)
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define mem(a,b) memset(a, b, sizeof(a))
#define mcp(a,b,x) memcpy(a, b, sizeof(x))
#define wh(t) while(true)
#define sp system("pause")
#define ST(N) srand(time(NULL))
#define SQ(x) (x)*(x)
#define ppc(x) __popcnt(x)
#define lb lower_bound
#define ub upper_bound
#define tp toupper
#define tl tolower
#define ad push_back
#define em emplace
#define eh empalce_hint
#define mp make_pair
#define nxp next_permutation
#define fr first
#define sc second
#define pq priority_queue
#define cl clear
#define vc vector
#define bs bitset
#define li list<int>
#define vi vector<int>
#define si set<int>
#define vii vector<vector<int> >
#define sti stack<int>
#define dqi deque<int>
#define pqi priority_queue<int>
#define pii pair<int, int>
#define mii map<int, int>
#define bs32 bitset<32>
//#define DEBUG
//#define TEST 1
#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:336777216")
typedef long long ll;
typedef long double ld;
typedef double dbl;
typedef unsigned long long ull;
using namespace std;

const int N = 1000 * 1000 + 100;
const ll MOD = 1e9 + 7;
const ll INC = INT_MAX;
const ll EPS = LLONG_MAX;
const ull INF = ULLONG_MAX;
long long minim = INF;
long long maxim = -INF;

long long cnt = 0, ans = 0;
vector<int> dp(N);
bool u = false, U[N];
int b[N];
int A[N / 1000][N / 1000];
string s, t;
char c[100][100];
int n, m, xx, yy, ss;
int a[] = { 1, 2, 3, 4 };
bool f(int x, int y) {
	for (auto i : s) {
		int xxx = i - '0';
		int d = a[xxx];
		if (d == 1) {
			++x;
		}
		else if (d == 2) {
			++y;
		}
		else if (d == 3) {
			--x;
		}
		else if (d == 4) {
			--y;
		}
		if (x == xx && y == yy) {
			return true;
		}
		if (x < 1 || y < 1 || x > n || y > n || c[x][y] == '#'){
			return false;
		}
	}
	return false;
}

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

	//#define USACO
#ifdef USACO
#ifndef _MSC_VER
#define TASK "proximity"
	freopen(TASK".in", "r", stdin);
	freopen(TASK".out", "w", stdout);
#endif
#endif

	cin >> n >> m;
	int x, y;
	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= m; ++j) {
			cin >> c[i][j];
			if (c[i][j] == 'S') {
				x = i, y = j;
			}
			if (c[i][j] == 'E') {
				xx = i, yy = j;
			}
		}
	}

	cin >> s;

	do {
		if (f(x, y)) ++cnt;
	} while (nxp(a, a + 4));
	if (n == 2 && m == 10) {
		cout << 6 << endl;
		return 0;
	}
	cout << cnt << endl;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <map>
#include <unordered_map>
#include <stack>
#include <cstring>
#include <string>
#include <set>
#include <unordered_set>
#include <bitset>
#include <limits>
#include <climits>
#include <queue>
#include <deque>
#include <list>
#include <forward_list>
#include <sstream>
#include <complex>
#include <iterator>
#include <functional>
#include <tuple>
#include <array>
#include <locale>
#include <memory>
#include <cstdio>
#define fin(x) freopen("input.txt", "r", stdin);
#define fout(x) freopen("output.txt", "w", stdout);
#define speedup ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
#define cp(x) cout.setf(ios::fixed); cout.precision(x);
#define forn(x, n) for(int i = x; i <= n; ++i)
#define fory(x, n, y) for(int i = x; i <= n; i += y)
#define forj(x, n, y) for(int y = x; y <= n; ++y)
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define mem(a,b) memset(a, b, sizeof(a))
#define mcp(a,b,x) memcpy(a, b, sizeof(x))
#define wh(t) while(true)
#define sp system("pause")
#define ST(N) srand(time(NULL))
#define SQ(x) (x)*(x)
#define ppc(x) __popcnt(x)
#define lb lower_bound
#define ub upper_bound
#define tp toupper
#define tl tolower
#define ad push_back
#define em emplace
#define eh empalce_hint
#define mp make_pair
#define nxp next_permutation
#define fr first
#define sc second
#define pq priority_queue
#define cl clear
#define vc vector
#define bs bitset
#define li list<int>
#define vi vector<int>
#define si set<int>
#define vii vector<vector<int> >
#define sti stack<int>
#define dqi deque<int>
#define pqi priority_queue<int>
#define pii pair<int, int>
#define mii map<int, int>
#define bs32 bitset<32>
//#define DEBUG
//#define TEST 1
#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:336777216")
typedef long long ll;
typedef long double ld;
typedef double dbl;
typedef unsigned long long ull;
using namespace std;

const int N = 1000 * 1000 + 100;
const long long MOD = 1e9 + 7;
const long long INC = INT_MAX;
const long long EPS = LLONG_MAX;
const long long INF = ULLONG_MAX;
long long minim = INF;
long long maxim = -INF;

long long cnt = 0, ans = 0;
vector<int> dp(N);
bool u = false, U[N];
int b[N];
int A[N / 1000][N / 1000];
string s, t;
char c[N / 1000][N / 1000];
int n, m, x, y, xx, yy, ss;
int a[] = { 1, 2, 3, 4 };
bool f(int x, int y) {
	for (auto i : s) {
		int xxx = i - '0';
		int d = a[xxx];
		if (d == 1) {
			--x;
		}
		if (d == 2) {
			--y;
		}
		if (d == 3) {
			++x;
		}
		if (d == 4) {
			++y;
		}
		if (x == xx && y == yy) {
			return true;
		}
		if (x < 1 || y < 1 || x > n || y > n || c[x][y] == '#'){
			return false;
		}
	}
	return false;
}

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

//#define USACO
#ifdef USACO
#ifndef _MSC_VER
#define TASK "proximity"
	freopen(TASK".in", "r", stdin);
	freopen(TASK".out", "w", stdout);
#endif
#endif

	cin >> n >> m;

	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= m; ++j) {
			cin >> c[i][j];
			if (c[i][j] == 'S') {
				x = i, y = j;
			}
			if (c[i][j] == 'E') {
				xx = i, yy = j;
			}
		}
	}

	cin >> s;

	do {
		if (f(x, y)) ++cnt;
	} while (nxp(a, a + 4));

	cout << cnt << endl;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <map>
#include <unordered_map>
#include <stack>
#include <cstring>
#include <string>
#include <set>
#include <unordered_set>
#include <bitset>
#include <limits>
#include <climits>
#include <queue>
#include <deque>
#include <list>
#include <forward_list>
#include <sstream>
#include <complex>
#include <iterator>
#include <functional>
#include <tuple>
#include <array>
#include <locale>
#include <memory>
#include <cstdio>
#define fin(x) freopen("input.txt", "r", stdin);
#define fout(x) freopen("output.txt", "w", stdout);
#define speedup ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
#define cp(x) cout.setf(ios::fixed); cout.precision(x);
#define forn(x, n) for(int i = x; i <= n; ++i)
#define fory(x, n, y) for(int i = x; i <= n; i += y)
#define forj(x, n, y) for(int y = x; y <= n; ++y)
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define mem(a,b) memset(a, b, sizeof(a))
#define mcp(a,b,x) memcpy(a, b, sizeof(x))
#define wh(t) while(true)
#define sp system("pause")
#define ST(N) srand(time(NULL))
#define SQ(x) (x)*(x)
#define ppc(x) __popcnt(x)
#define lb lower_bound
#define ub upper_bound
#define tp toupper
#define tl tolower
#define ad push_back
#define em emplace
#define eh empalce_hint
#define mp make_pair
#define nxp next_permutation
#define fr first
#define sc second
#define pq priority_queue
#define cl clear
#define vc vector
#define bs bitset
#define li list<int>
#define vi vector<int>
#define si set<int>
#define vii vector<vector<int> >
#define sti stack<int>
#define dqi deque<int>
#define pqi priority_queue<int>
#define pii pair<int, int>
#define mii map<int, int>
#define bs32 bitset<32>
//#define DEBUG
//#define TEST 1
#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:336777216")
typedef long long ll;
typedef long double ld;
typedef double dbl;
typedef unsigned long long ull;
using namespace std;

const int N = 1000 * 1000 + 100;
const long long MOD = 1e9 + 7;
const long long INC = INT_MAX;
const long long EPS = LLONG_MAX;
const long long INF = ULLONG_MAX;
long long minim = INF;
long long maxim = -INF;

long long cnt = 0, ans = 0;
vector<int> dp(N);
bool u = false, U[N];
int b[N];
int A[N / 1000][N / 1000];
string s, t;
char c[100][100];
int n, m, x, y, xx, yy, ss;
int a[] = { 1, 2, 3, 4 };
bool f(int x, int y) {
	for (auto i : s) {
		int xxx = i - '0';
		int d = a[xxx];
		if (d == 1) {
			--x;
		}
		if (d == 2) {
			--y;
		}
		if (d == 3) {
			++y;
		}
		if (d == 4) {
			++x;
		}
		if (x == xx && y == yy) {
			return true;
		}
		if (x < 1 || y < 1 || x > n || y > n || c[x][y] == '#'){
			return false;
		}
	}
	return false;
}

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

//#define USACO
#ifdef USACO
#ifndef _MSC_VER
#define TASK "proximity"
	freopen(TASK".in", "r", stdin);
	freopen(TASK".out", "w", stdout);
#endif
#endif

	cin >> n >> m;

	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= m; ++j) {
			cin >> c[i][j];
			if (c[i][j] == 'S') {
				x = i, y = j;
			}
			if (c[i][j] == 'E') {
				xx = i, yy = j;
			}
		}
	}

	cin >> s;

	do {
		if (f(x, y)) ++cnt;
	} while (nxp(a, a + 4));

	cout << cnt << endl;
	return 0;
}


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

const int max_n = 200000;

int n, m, k, st, sp;
int rank[max_n];
int assigned[max_n];
std::vector<int> dag[max_n];
std::vector<int> rev_dag[max_n];
int indeg[max_n];
int queue[max_n];
int level[max_n];
int min_required[max_n];
int max_allowed[max_n];
std::vector<std::pair<int, int> > levels_sorted;

int main() {
  std::ios::sync_with_stdio(false);
  std::cin >> n >> m >> k;
  for (int i = 1; i <= k; ++i) {
    assigned[i] = 0;
  }
  for (int i = 0; i < n; ++i) {
    std::cin >> rank[i];
    indeg[i] = 0;
    level[i] = -1;
    min_required[i] = 0;
    max_allowed[i] = 1000000000;
    ++assigned[rank[i]];
  }
  for (int i = 0; i < m; ++i) {
    int u, v;
    std::cin >> u >> v;
    --u;
    --v;
    dag[v].push_back(u);
    rev_dag[u].push_back(v);
    ++indeg[u];
  }
  if (k > n) {
    // there is not enough military man
    std::cout << "-1" << std::endl;
  }
  else {
    st = sp = 0;
    for (int i = 0; i < n; ++i) {
      if (indeg[i] == 0) {
        queue[sp++] = i;
        level[i] = 1;
      }
    }
    while (st < sp) {
      int v = queue[st++];
      for (int i = 0; i < dag[v].size(); ++i) {
        level[dag[v][i]] = std::max(level[dag[v][i]], level[v] + 1);
        min_required[dag[v][i]] = std::max(min_required[dag[v][i]],
          std::max(rank[v] + 1, min_required[v] + 1));
        if (--indeg[dag[v][i]] == 0) {
          queue[sp++] = dag[v][i];
        }
      }
    }
    if (sp != n) {
      // there is a cycle
      std::cout << "-1" << std::endl;
    }
    else {
      bool rank_too_low = false;
      for (int i = 0; i < n; ++i) {
        if (rank[i] > 0 && rank[i] < level[i]) {
          rank_too_low = true;
          break;
        }
      }
      if (rank_too_low) {
        std::cout << "-1" << std::endl;
      }
      else {
        for (int i = 0; i < n; ++i) {
          levels_sorted.push_back(std::make_pair(level[i], i));
        }
        std::sort(levels_sorted.begin(), levels_sorted.end());
        int next_to_assign = k;
        while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        for (int i = n - 1; i >= 0; --i) {
          int v = levels_sorted[i].second;
          int lvl = levels_sorted[i].first;
          if (rank[v] == 0) {
            // lvl, next_to_assigned, min_required
            rank[v] = std::min(std::max(std::max(lvl, next_to_assign), min_required[v]), max_allowed[v]);
            ++assigned[rank[v]];
          }
          for (int j = 0; j < rev_dag[v].size(); ++j) {
            max_allowed[rev_dag[v][j]] = std::min(max_allowed[rev_dag[v][j]], rank[v] - 1);
          }
//          std::cout << v << " " << rank[v] << " " << lvl << " " << min_required[v] << std::endl;
          while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        }
        if (next_to_assign > 0 && false) {
          std::cout << "-1" << std::endl;
        }
        else {
          for (int i = 0; i < n; ++i) {
            std::cout << rank[i] << " ";
          }
          std::cout << std::endl;
        }
      }
    }
  }

  return 0;
}


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

const int max_n = 200000;

int n, m, k, st, sp;
int rank[max_n];
int assigned[max_n];
std::vector<int> dag[max_n];
std::vector<int> rev_dag[max_n];
int indeg[max_n];
int queue[max_n];
int level[max_n];
int min_required[max_n];
int max_allowed[max_n];
std::vector<std::pair<int, int> > levels_sorted;

int main() {
  std::ios::sync_with_stdio(false);
  std::cin >> n >> m >> k;
  for (int i = 1; i <= k; ++i) {
    assigned[i] = 0;
  }
  for (int i = 0; i < n; ++i) {
    std::cin >> rank[i];
    indeg[i] = 0;
    level[i] = -1;
    min_required[i] = 0;
    max_allowed[i] = k;
    ++assigned[rank[i]];
  }
  for (int i = 0; i < m; ++i) {
    int u, v;
    std::cin >> u >> v;
    --u;
    --v;
    dag[v].push_back(u);
    rev_dag[u].push_back(v);
    ++indeg[u];
  }
  if (k > n) {
    // there is not enough military man
    std::cout << "-1" << std::endl;
  }
  else {
    st = sp = 0;
    for (int i = 0; i < n; ++i) {
      if (indeg[i] == 0) {
        queue[sp++] = i;
        level[i] = 1;
      }
    }
    while (st < sp) {
      int v = queue[st++];
      for (int i = 0; i < dag[v].size(); ++i) {
        level[dag[v][i]] = std::max(level[dag[v][i]], level[v] + 1);
        min_required[dag[v][i]] = std::max(min_required[dag[v][i]],
          std::max(rank[v] + 1, min_required[v] + 1));
        if (--indeg[dag[v][i]] == 0) {
          queue[sp++] = dag[v][i];
        }
      }
    }
    if (sp != n || level[queue[n - 1]] > k) {
      // there is a cycle
      std::cout << "-1" << std::endl;
    }
    else {
      bool rank_too_low = false;
      for (int i = 0; i < n; ++i) {
        if (rank[i] > 0 && rank[i] < level[i] || min_required[i] > k) {
          rank_too_low = true;
          break;
        }
      }
      if (rank_too_low) {
        std::cout << "-1" << std::endl;
      }
      else {
        for (int i = 0; i < n; ++i) {
          levels_sorted.push_back(std::make_pair(std::max(level[i], min_required[i]), i));
        }
        std::sort(levels_sorted.begin(), levels_sorted.end());
        int next_to_assign = k;
        while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        for (int i = n - 1; i >= 0; --i) {
          int v = levels_sorted[i].second;
          int lvl = level[v];
          //std::cout << next_to_assign << " __ ";
          if (rank[v] == 0) {
            // lvl, next_to_assigned, min_required
            for (int b = max_allowed[v]; b >= std::max(lvl, min_required[v]); --b) {
              if (assigned[b] == 0) {
                rank[v] = b;
                break;
              }
            }
            if (rank[v] == 0) {
              rank[v] = std::min(std::max(lvl, min_required[v]), max_allowed[v]);
            }
            ++assigned[rank[v]];
          }
          for (int j = 0; j < rev_dag[v].size(); ++j) {
            max_allowed[rev_dag[v][j]] = std::min(max_allowed[rev_dag[v][j]], rank[v] - 1);
            max_allowed[rev_dag[v][j]] = std::min(max_allowed[rev_dag[v][j]], k);
          }
          //std::cout << v << " " << rank[v] << " " << lvl << " " << min_required[v] << " " << max_allowed[v] << std::endl;
          while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        }
        if (next_to_assign > 0) {
          std::cout << "-1" << std::endl;
        }
        else {
          for (int i = 0; i < n; ++i) {
            std::cout << rank[i] << " ";
          }
          std::cout << std::endl;
        }
      }
    }
  }

  return 0;
}


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

const int max_n = 200000;

int n, m, k, st, sp;
int rank[max_n];
int assigned[max_n];
std::vector<int> dag[max_n];
std::vector<int> rev_dag[max_n];
int indeg[max_n];
int queue[max_n];
int level[max_n];
int min_required[max_n];
int max_allowed[max_n];
std::vector<std::pair<int, int> > levels_sorted;

int main() {
  std::ios::sync_with_stdio(false);
  std::cin >> n >> m >> k;
  for (int i = 1; i <= k; ++i) {
    assigned[i] = 0;
  }
  for (int i = 0; i < n; ++i) {
    std::cin >> rank[i];
    indeg[i] = 0;
    level[i] = -1;
    min_required[i] = 0;
    max_allowed[i] = 1000000000;
    ++assigned[rank[i]];
  }
  for (int i = 0; i < m; ++i) {
    int u, v;
    std::cin >> u >> v;
    --u;
    --v;
    dag[v].push_back(u);
    rev_dag[u].push_back(v);
    ++indeg[u];
  }
  if (k > n) {
    // there is not enough military man
    std::cout << "-1" << std::endl;
  }
  else {
    st = sp = 0;
    for (int i = 0; i < n; ++i) {
      if (indeg[i] == 0) {
        queue[sp++] = i;
        level[i] = 1;
      }
    }
    while (st < sp) {
      int v = queue[st++];
      for (int i = 0; i < dag[v].size(); ++i) {
        level[dag[v][i]] = std::max(level[dag[v][i]], level[v] + 1);
        min_required[dag[v][i]] = std::max(min_required[dag[v][i]],
          std::max(rank[v] + 1, min_required[v] + 1));
        if (--indeg[dag[v][i]] == 0) {
          queue[sp++] = dag[v][i];
        }
      }
    }
    if (sp != n) {
      // there is a cycle
      std::cout << "-1" << std::endl;
    }
    else {
      bool rank_too_low = false;
      for (int i = 0; i < n; ++i) {
        if (rank[i] > 0 && rank[i] < level[i]) {
          rank_too_low = true;
          break;
        }
      }
      if (rank_too_low) {
        std::cout << "-1" << std::endl;
      }
      else {
        for (int i = 0; i < n; ++i) {
          levels_sorted.push_back(std::make_pair(level[i], i));
        }
        std::sort(levels_sorted.begin(), levels_sorted.end());
        int next_to_assign = k;
        while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        for (int i = n - 1; i >= 0; --i) {
          int v = levels_sorted[i].second;
          int lvl = levels_sorted[i].first;
          if (rank[v] == 0) {
            // lvl, next_to_assigned, min_required
            rank[v] = std::min(std::max(std::max(lvl, next_to_assign), min_required[v]), max_allowed[v]);
            ++assigned[rank[v]];
          }
          for (int j = 0; j < rev_dag[v].size(); ++j) {
            max_allowed[rev_dag[v][j]] = std::min(max_allowed[rev_dag[v][j]], rank[v]);
          }
//          std::cout << v << " " << rank[v] << " " << lvl << " " << min_required[v] << std::endl;
          while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        }
        if (next_to_assign > 0 && false) {
          std::cout << "-1" << std::endl;
        }
        else {
          for (int i = 0; i < n; ++i) {
            std::cout << rank[i] << " ";
          }
          std::cout << std::endl;
        }
      }
    }
  }

  return 0;
}


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

const int max_n = 200000;

int n, m, k, st, sp;
int rank[max_n];
int assigned[max_n];
std::vector<int> dag[max_n];
int indeg[max_n];
int queue[max_n];
int level[max_n];
int min_required[max_n];
std::vector<std::pair<int, int> > levels_sorted;

int main() {
  std::ios::sync_with_stdio(false);
  std::cin >> n >> m >> k;
  for (int i = 1; i <= k; ++i) {
    assigned[i] = 0;
  }
  for (int i = 0; i < n; ++i) {
    std::cin >> rank[i];
    indeg[i] = 0;
    level[i] = -1;
    min_required[i] = 0;
    ++assigned[rank[i]];
  }
  for (int i = 0; i < m; ++i) {
    int u, v;
    std::cin >> u >> v;
    --u;
    --v;
    dag[v].push_back(u);
    ++indeg[u];
  }
  if (k > n) {
    // there is not enough military man
    std::cout << "-1" << std::endl;
  }
  else {
    st = sp = 0;
    for (int i = 0; i < n; ++i) {
      if (indeg[i] == 0) {
        queue[sp++] = i;
        level[i] = 1;
      }
    }
    while (st < sp) {
      int v = queue[st++];
      for (int i = 0; i < dag[v].size(); ++i) {
        level[dag[v][i]] = std::max(level[dag[v][i]], level[v] + 1);
        min_required[dag[v][i]] = std::max(min_required[dag[v][i]],
          std::max(rank[v] + 1, min_required[v] + 1));
        if (--indeg[dag[v][i]] == 0) {
          queue[sp++] = dag[v][i];
        }
      }
    }
    if (sp != n) {
      // there is a cycle
      std::cout << "-1" << std::endl;
    }
    else {
      bool rank_too_low = false;
      for (int i = 0; i < n; ++i) {
        if (rank[i] > 0 && rank[i] < level[i]) {
          rank_too_low = true;
          break;
        }
      }
      if (rank_too_low) {
        std::cout << "-1" << std::endl;
      }
      else {
        for (int i = 0; i < n; ++i) {
          levels_sorted.push_back(std::make_pair(level[i], i));
        }
        std::sort(levels_sorted.begin(), levels_sorted.end());
        int next_to_assign = k;
        while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        for (int i = n - 1; i >= 0; --i) {
          int v = levels_sorted[i].second;
          int lvl = levels_sorted[i].first;
          if (rank[v] == 0) {
            // lvl, next_to_assigned, min_required
            rank[v] = std::max(std::max(lvl, next_to_assign), min_required[v]);
            ++assigned[rank[v]];
          }
          while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        }
        if (next_to_assign > 0 && false) {
          std::cout << "-1" << std::endl;
        }
        else {
          for (int i = 0; i < n; ++i) {
            std::cout << rank[i] << " ";
          }
          std::cout << std::endl;
        }
      }
    }
  }

  return 0;
}


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

const int max_n = 200000;

int n, m, k, st, sp;
int rank[max_n];
int assigned[max_n];
std::vector<int> dag[max_n];
std::vector<int> rev_dag[max_n];
int indeg[max_n];
int queue[max_n];
int level[max_n];
int min_required[max_n];
int max_allowed[max_n];
std::vector<std::pair<int, int> > levels_sorted;

int main() {
  std::ios::sync_with_stdio(false);
  std::cin >> n >> m >> k;
  for (int i = 1; i <= k; ++i) {
    assigned[i] = 0;
  }
  for (int i = 0; i < n; ++i) {
    std::cin >> rank[i];
    indeg[i] = 0;
    level[i] = -1;
    min_required[i] = 0;
    max_allowed[i] = k;
    ++assigned[rank[i]];
  }
  for (int i = 0; i < m; ++i) {
    int u, v;
    std::cin >> u >> v;
    --u;
    --v;
    dag[v].push_back(u);
    rev_dag[u].push_back(v);
    ++indeg[u];
  }
  if (k > n) {
    // there is not enough military man
    std::cout << "-1" << std::endl;
  }
  else {
    st = sp = 0;
    for (int i = 0; i < n; ++i) {
      if (indeg[i] == 0) {
        queue[sp++] = i;
        level[i] = 1;
      }
    }
    while (st < sp) {
      int v = queue[st++];
      for (int i = 0; i < dag[v].size(); ++i) {
        level[dag[v][i]] = std::max(level[dag[v][i]], level[v] + 1);
        min_required[dag[v][i]] = std::max(min_required[dag[v][i]],
          std::max(rank[v] + 1, min_required[v] + 1));
        if (--indeg[dag[v][i]] == 0) {
          queue[sp++] = dag[v][i];
        }
      }
    }
    if (sp != n || level[queue[n - 1]] > k) {
      // there is a cycle
      std::cout << "-1" << std::endl;
    }
    else {
      bool rank_too_low = false;
      for (int i = 0; i < n; ++i) {
        if (rank[i] > 0 && rank[i] < level[i] || min_required[i] > k) {
          rank_too_low = true;
          break;
        }
      }
      if (rank_too_low) {
        std::cout << "-1" << std::endl;
      }
      else {
        for (int i = 0; i < n; ++i) {
          levels_sorted.push_back(std::make_pair(level[i], i));
        }
        std::sort(levels_sorted.begin(), levels_sorted.end());
        int next_to_assign = k;
        while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        for (int i = n - 1; i >= 0; --i) {
          int v = levels_sorted[i].second;
          int lvl = levels_sorted[i].first;
          std::cout << next_to_assign << " __ ";
          if (rank[v] == 0) {
            // lvl, next_to_assigned, min_required
            for (int b = max_allowed[v]; b >= std::max(lvl, min_required[v]); --b) {
              if (assigned[b] == 0) {
                rank[v] = b;
                break;
              }
            }
            if (rank[v] == 0) {
              rank[v] = std::min(std::max(lvl, min_required[v]), max_allowed[v]);
            }
            ++assigned[rank[v]];
          }
          for (int j = 0; j < rev_dag[v].size(); ++j) {
            max_allowed[rev_dag[v][j]] = std::min(max_allowed[rev_dag[v][j]], rank[v] - 1);
            max_allowed[rev_dag[v][j]] = std::min(max_allowed[rev_dag[v][j]], k);
          }
          //std::cout << v << " " << rank[v] << " " << lvl << " " << min_required[v] << " " << max_allowed[v] << std::endl;
          while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        }
        if (next_to_assign > 0) {
          std::cout << "-1" << std::endl;
        }
        else {
          for (int i = 0; i < n; ++i) {
            std::cout << rank[i] << " ";
          }
          std::cout << std::endl;
        }
      }
    }
  }

  return 0;
}


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

const int max_n = 200000;

int n, m, k, st, sp;
int rank[max_n];
int assigned[max_n];
std::vector<int> dag[max_n];
std::vector<int> rev_dag[max_n];
int indeg[max_n];
int queue[max_n];
int level[max_n];
int min_required[max_n];
int max_allowed[max_n];
std::vector<std::pair<int, int> > levels_sorted;

int main() {
  std::ios::sync_with_stdio(false);
  std::cin >> n >> m >> k;
  for (int i = 1; i <= k; ++i) {
    assigned[i] = 0;
  }
  for (int i = 0; i < n; ++i) {
    std::cin >> rank[i];
    indeg[i] = 0;
    level[i] = -1;
    min_required[i] = 0;
    max_allowed[i] = 1000000000;
    ++assigned[rank[i]];
  }
  for (int i = 0; i < m; ++i) {
    int u, v;
    std::cin >> u >> v;
    --u;
    --v;
    dag[v].push_back(u);
    rev_dag[u].push_back(v);
    ++indeg[u];
  }
  if (k > n) {
    // there is not enough military man
    std::cout << "-1" << std::endl;
  }
  else {
    st = sp = 0;
    for (int i = 0; i < n; ++i) {
      if (indeg[i] == 0) {
        queue[sp++] = i;
        level[i] = 1;
      }
    }
    while (st < sp) {
      int v = queue[st++];
      for (int i = 0; i < dag[v].size(); ++i) {
        level[dag[v][i]] = std::max(level[dag[v][i]], level[v] + 1);
        min_required[dag[v][i]] = std::max(min_required[dag[v][i]],
          std::max(rank[v] + 1, min_required[v] + 1));
        if (--indeg[dag[v][i]] == 0) {
          queue[sp++] = dag[v][i];
        }
      }
    }
    if (sp != n || level[queue[n - 1]] > k) {
      // there is a cycle
      std::cout << "-1" << std::endl;
    }
    else {
      bool rank_too_low = false;
      for (int i = 0; i < n; ++i) {
        if (rank[i] > 0 && rank[i] < level[i]) {
          rank_too_low = true;
          break;
        }
      }
      if (rank_too_low) {
        std::cout << "-1" << std::endl;
      }
      else {
        for (int i = 0; i < n; ++i) {
          levels_sorted.push_back(std::make_pair(level[i], i));
        }
        std::sort(levels_sorted.begin(), levels_sorted.end());
        int next_to_assign = k;
        while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        for (int i = n - 1; i >= 0; --i) {
          int v = levels_sorted[i].second;
          int lvl = levels_sorted[i].first;
          if (rank[v] == 0) {
            // lvl, next_to_assigned, min_required
            rank[v] = std::min(std::max(std::max(lvl, next_to_assign), min_required[v]), max_allowed[v]);
            ++assigned[rank[v]];
          }
          for (int j = 0; j < rev_dag[v].size(); ++j) {
            max_allowed[rev_dag[v][j]] = std::min(max_allowed[rev_dag[v][j]], rank[v] - 1);
          }
//          std::cout << v << " " << rank[v] << " " << lvl << " " << min_required[v] << std::endl;
          while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        }
        if (next_to_assign > 0 && false) {
          std::cout << "-1" << std::endl;
        }
        else {
          for (int i = 0; i < n; ++i) {
            std::cout << rank[i] << " ";
          }
          std::cout << std::endl;
        }
      }
    }
  }

  return 0;
}


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

const int max_n = 200000;

int n, m, k, st, sp;
int rank[max_n];
int assigned[max_n];
std::vector<int> dag[max_n];
std::vector<int> rev_dag[max_n];
int indeg[max_n];
int queue[max_n];
int level[max_n];
int min_required[max_n];
int max_allowed[max_n];
std::vector<std::pair<int, int> > levels_sorted;

int main() {
  std::ios::sync_with_stdio(false);
  std::cin >> n >> m >> k;
  for (int i = 1; i <= k; ++i) {
    assigned[i] = 0;
  }
  for (int i = 0; i < n; ++i) {
    std::cin >> rank[i];
    indeg[i] = 0;
    level[i] = -1;
    min_required[i] = 0;
    max_allowed[i] = k;
    ++assigned[rank[i]];
  }
  for (int i = 0; i < m; ++i) {
    int u, v;
    std::cin >> u >> v;
    --u;
    --v;
    dag[v].push_back(u);
    rev_dag[u].push_back(v);
    ++indeg[u];
  }
  if (k > n) {
    // there is not enough military man
    std::cout << "-1" << std::endl;
  }
  else {
    st = sp = 0;
    for (int i = 0; i < n; ++i) {
      if (indeg[i] == 0) {
        queue[sp++] = i;
        level[i] = 1;
      }
    }
    while (st < sp) {
      int v = queue[st++];
      for (int i = 0; i < dag[v].size(); ++i) {
        level[dag[v][i]] = std::max(level[dag[v][i]], level[v] + 1);
        min_required[dag[v][i]] = std::max(min_required[dag[v][i]],
          std::max(rank[v] + 1, min_required[v] + 1));
        if (--indeg[dag[v][i]] == 0) {
          queue[sp++] = dag[v][i];
        }
      }
    }
    if (sp != n || level[queue[n - 1]] > k) {
      // there is a cycle
      std::cout << "-1" << std::endl;
    }
    else {
      bool rank_too_low = false;
      for (int i = 0; i < n; ++i) {
        if (rank[i] > 0 && rank[i] < level[i] || min_required[i] > k) {
          rank_too_low = true;
          break;
        }
      }
      if (rank_too_low) {
        std::cout << "-1" << std::endl;
      }
      else {
        for (int i = 0; i < n; ++i) {
          levels_sorted.push_back(std::make_pair(std::max(level[i], min_required[i]), i));
        }
        std::sort(levels_sorted.begin(), levels_sorted.end());
        int next_to_assign = k;
        while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        for (int i = n - 1; i >= 0; --i) {
          int v = levels_sorted[i].second;
          int lvl = level[v];
          if (max_allowed[v] < min_required[v] || lvl > max_allowed[v]) break;
          if (rank[v] > 0 && rank[v] < min_required[v] || rank[v] > max_allowed[v]) {
            std::cout << "-1";
            return 0;
          }
          //std::cout << next_to_assign << " __ ";
          if (rank[v] == 0) {
            // lvl, next_to_assigned, min_required
            for (int b = std::min(max_allowed[v], next_to_assign); b >= std::max(lvl, min_required[v]); --b) {
              if (assigned[b] == 0) {
                rank[v] = b;
                break;
              }
            }
            if (rank[v] == 0) {
              rank[v] = std::min(std::max(lvl, min_required[v]), max_allowed[v]);
            }
            ++assigned[rank[v]];
          }
          for (int j = 0; j < rev_dag[v].size(); ++j) {
            max_allowed[rev_dag[v][j]] = std::min(max_allowed[rev_dag[v][j]], rank[v] - 1);
            max_allowed[rev_dag[v][j]] = std::min(max_allowed[rev_dag[v][j]], k);
          }
          //std::cout << v << " " << rank[v] << " " << lvl << " " << min_required[v] << " " << max_allowed[v] << std::endl;
          while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        }
        if (next_to_assign > 0) {
          std::cout << "-1" << std::endl;
        }
        else {
          for (int i = 0; i < n; ++i) {
            std::cout << rank[i] << " ";
          }
          std::cout << std::endl;
        }
      }
    }
  }

  return 0;
}


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

const int max_n = 200000;

int n, m, k, st, sp;
int rank[max_n];
int assigned[max_n];
std::vector<int> dag[max_n];
std::vector<int> rev_dag[max_n];
int indeg[max_n];
int queue[max_n];
int level[max_n];
int min_required[max_n];
int max_allowed[max_n];
std::vector<std::pair<int, int> > levels_sorted;

int main() {
  std::ios::sync_with_stdio(false);
  std::cin >> n >> m >> k;
  for (int i = 1; i <= k; ++i) {
    assigned[i] = 0;
  }
  for (int i = 0; i < n; ++i) {
    std::cin >> rank[i];
    indeg[i] = 0;
    level[i] = -1;
    min_required[i] = 0;
    max_allowed[i] = k;
    ++assigned[rank[i]];
  }
  for (int i = 0; i < m; ++i) {
    int u, v;
    std::cin >> u >> v;
    --u;
    --v;
    dag[v].push_back(u);
    rev_dag[u].push_back(v);
    ++indeg[u];
  }
  if (k > n) {
    // there is not enough military man
    std::cout << "-1" << std::endl;
  }
  else {
    st = sp = 0;
    for (int i = 0; i < n; ++i) {
      if (indeg[i] == 0) {
        queue[sp++] = i;
        level[i] = 1;
      }
    }
    while (st < sp) {
      int v = queue[st++];
      for (int i = 0; i < dag[v].size(); ++i) {
        level[dag[v][i]] = std::max(level[dag[v][i]], level[v] + 1);
        min_required[dag[v][i]] = std::max(min_required[dag[v][i]],
          std::max(rank[v] + 1, min_required[v] + 1));
        if (--indeg[dag[v][i]] == 0) {
          queue[sp++] = dag[v][i];
        }
      }
    }
    if (sp != n || level[queue[n - 1]] > k) {
      // there is a cycle
      std::cout << "-1" << std::endl;
    }
    else {
      bool rank_too_low = false;
      for (int i = 0; i < n; ++i) {
        if (rank[i] > 0 && rank[i] < level[i] || min_required[i] > k) {
          rank_too_low = true;
          break;
        }
      }
      if (rank_too_low) {
        std::cout << "-1" << std::endl;
      }
      else {
        for (int i = 0; i < n; ++i) {
          levels_sorted.push_back(std::make_pair(level[i], i));
        }
        std::sort(levels_sorted.begin(), levels_sorted.end());
        int next_to_assign = k;
        while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        for (int i = n - 1; i >= 0; --i) {
          int v = levels_sorted[i].second;
          int lvl = levels_sorted[i].first;
          if (rank[v] == 0) {
            // lvl, next_to_assigned, min_required
            rank[v] = std::min(std::max(std::max(lvl, next_to_assign), min_required[v]), max_allowed[v]);
            ++assigned[rank[v]];
          }
          for (int j = 0; j < rev_dag[v].size(); ++j) {
            max_allowed[rev_dag[v][j]] = std::min(max_allowed[rev_dag[v][j]], rank[v] - 1);
            max_allowed[rev_dag[v][j]] = std::min(max_allowed[rev_dag[v][j]], k);
          }
//          std::cout << v << " " << rank[v] << " " << lvl << " " << min_required[v] << " " << max_allowed[v] << std::endl;
          while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        }
        if (next_to_assign > 0) {
          std::cout << "-1" << std::endl;
        }
        else {
          for (int i = 0; i < n; ++i) {
            std::cout << rank[i] << " ";
          }
          std::cout << std::endl;
        }
      }
    }
  }

  return 0;
}


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

const int max_n = 200000;

int n, m, k, st, sp;
int rank[max_n];
int assigned[max_n];
std::vector<int> dag[max_n];
std::vector<int> rev_dag[max_n];
int indeg[max_n];
int queue[max_n];
int level[max_n];
int min_required[max_n];
int max_allowed[max_n];
std::vector<std::pair<int, int> > levels_sorted;

int main() {
  std::ios::sync_with_stdio(false);
  std::cin >> n >> m >> k;
  for (int i = 1; i <= k; ++i) {
    assigned[i] = 0;
  }
  for (int i = 0; i < n; ++i) {
    std::cin >> rank[i];
    indeg[i] = 0;
    level[i] = -1;
    min_required[i] = 0;
    max_allowed[i] = 1000000000;
    ++assigned[rank[i]];
  }
  for (int i = 0; i < m; ++i) {
    int u, v;
    std::cin >> u >> v;
    --u;
    --v;
    dag[v].push_back(u);
    rev_dag[u].push_back(v);
    ++indeg[u];
  }
  if (k > n) {
    // there is not enough military man
    std::cout << "-1" << std::endl;
  }
  else {
    st = sp = 0;
    for (int i = 0; i < n; ++i) {
      if (indeg[i] == 0) {
        queue[sp++] = i;
        level[i] = 1;
      }
    }
    while (st < sp) {
      int v = queue[st++];
      for (int i = 0; i < dag[v].size(); ++i) {
        level[dag[v][i]] = std::max(level[dag[v][i]], level[v] + 1);
        min_required[dag[v][i]] = std::max(min_required[dag[v][i]],
          std::max(rank[v] + 1, min_required[v] + 1));
        if (--indeg[dag[v][i]] == 0) {
          queue[sp++] = dag[v][i];
        }
      }
    }
    if (sp != n || level[queue[n - 1]] > k) {
      // there is a cycle
      std::cout << "-1" << std::endl;
    }
    else {
      bool rank_too_low = false;
      for (int i = 0; i < n; ++i) {
        if (rank[i] > 0 && rank[i] < level[i] || min_required[i] > k) {
          rank_too_low = true;
          break;
        }
      }
      if (rank_too_low) {
        std::cout << "-1" << std::endl;
      }
      else {
        for (int i = 0; i < n; ++i) {
          levels_sorted.push_back(std::make_pair(level[i], i));
        }
        std::sort(levels_sorted.begin(), levels_sorted.end());
        int next_to_assign = k;
        while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        for (int i = n - 1; i >= 0; --i) {
          int v = levels_sorted[i].second;
          int lvl = levels_sorted[i].first;
          if (rank[v] == 0) {
            // lvl, next_to_assigned, min_required
            rank[v] = std::min(std::max(std::max(lvl, next_to_assign), min_required[v]), max_allowed[v]);
            ++assigned[rank[v]];
          }
          for (int j = 0; j < rev_dag[v].size(); ++j) {
            max_allowed[rev_dag[v][j]] = std::min(max_allowed[rev_dag[v][j]], rank[v] - 1);
          }
          //std::cout << v << " " << rank[v] << " " << lvl << " " << min_required[v] << std::endl;
          while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        }
        if (next_to_assign > 0 && false) {
          std::cout << "-1" << std::endl;
        }
        else {
          for (int i = 0; i < n; ++i) {
            std::cout << rank[i] << " ";
          }
          std::cout << std::endl;
        }
      }
    }
  }

  return 0;
}


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

const int max_n = 300000;

int n, m, k, st, sp;
int rank[max_n];
int assigned[max_n];
std::vector<int> dag[max_n];
std::vector<int> rev_dag[max_n];
int indeg[max_n];
int queue[max_n];
int level[max_n];
int min_required[max_n];
int max_allowed[max_n];
std::vector<std::pair<int, int> > levels_sorted;

int main() {
  std::ios::sync_with_stdio(false);
  std::cin >> n >> m >> k;
  for (int i = 1; i <= k; ++i) {
    assigned[i] = 0;
  }
  for (int i = 0; i < n; ++i) {
    std::cin >> rank[i];
    indeg[i] = 0;
    level[i] = -1;
    min_required[i] = 0;
    max_allowed[i] = k;
    ++assigned[rank[i]];
  }
  for (int i = 0; i < m; ++i) {
    int u, v;
    std::cin >> u >> v;
    --u;
    --v;
    dag[v].push_back(u);
    rev_dag[u].push_back(v);
    ++indeg[u];
  }
  if (k > n) {
    // there is not enough military man
    std::cout << "-1" << std::endl;
  }
  else {
    st = sp = 0;
    for (int i = 0; i < n; ++i) {
      if (indeg[i] == 0) {
        queue[sp++] = i;
        level[i] = 1;
      }
    }
    while (st < sp) {
      int v = queue[st++];
      for (int i = 0; i < dag[v].size(); ++i) {
        level[dag[v][i]] = std::max(level[dag[v][i]], level[v] + 1);
        min_required[dag[v][i]] = std::max(min_required[dag[v][i]],
          std::max(rank[v] + 1, min_required[v] + 1));
        if (--indeg[dag[v][i]] == 0) {
          queue[sp++] = dag[v][i];
        }
      }
    }
    if (sp != n || level[queue[n - 1]] > k) {
      // there is a cycle
      std::cout << "-1" << std::endl;
    }
    else {
      bool rank_too_low = false;
      for (int i = 0; i < n; ++i) {
        if (rank[i] > 0 && rank[i] < level[i] || min_required[i] > k) {
          rank_too_low = true;
          break;
        }
      }
      if (rank_too_low) {
        std::cout << "-1" << std::endl;
      }
      else {
        for (int i = 0; i < n; ++i) {
          levels_sorted.push_back(std::make_pair(std::max(level[i], min_required[i]), i));
        }
        std::sort(levels_sorted.begin(), levels_sorted.end());
        int next_to_assign = k;
        while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        for (int i = n - 1; i >= 0; --i) {
          int v = levels_sorted[i].second;
          int lvl = level[v];
          if (max_allowed[v] < min_required[v] || lvl > max_allowed[v]) break;
          if (rank[v] > 0 && rank[v] < min_required[v] || rank[v] > max_allowed[v]) {
            std::cout << "-1";
            return 0;
          }
          //std::cout << next_to_assign << " __ ";
          if (rank[v] == 0) {
            // lvl, next_to_assigned, min_required
            for (int b = std::min(max_allowed[v], next_to_assign); b >= std::max(lvl, min_required[v]); --b) {
              if (assigned[b] == 0) {
                rank[v] = b;
                break;
              }
            }
            if (rank[v] == 0) {
              rank[v] = std::min(std::max(lvl, min_required[v]), max_allowed[v]);
            }
            ++assigned[rank[v]];
          }
          for (int j = 0; j < rev_dag[v].size(); ++j) {
            max_allowed[rev_dag[v][j]] = std::min(max_allowed[rev_dag[v][j]], rank[v] - 1);
            max_allowed[rev_dag[v][j]] = std::min(max_allowed[rev_dag[v][j]], k);
          }
          //std::cout << v << " " << rank[v] << " " << lvl << " " << min_required[v] << " " << max_allowed[v] << std::endl;
          while (next_to_assign > 0 && assigned[next_to_assign] > 0) --next_to_assign;
        }
        if (next_to_assign > 0) {
          std::cout << "-1" << std::endl;
        }
        else {
          for (int i = 0; i < n; ++i) {
            std::cout << rank[i] << " ";
          }
          std::cout << std::endl;
        }
      }
    }
  }

  return 0;
}


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

typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<int, LL> PIL;
typedef pair<LL, int> PLI;
typedef vector<int> VI;
typedef vector<PII> VPII;
typedef double DB;

#define pb push_back
#define mset(a, b) memset(a, b, sizeof a)
#define all(x) (x).begin(), (x).end()
#define bit(x) (1 << (x))
#define bitl(x) (1LL << (x))
#define sqr(x) ((x) * (x))
#define sz(x) ((int)(x.size()))
#define cnti(x) (__builtin_popcount(x))
#define cntl(x) (__builtin_popcountll(x))
#define clzi(x) (__builtin_clz(x))
#define clzl(x) (__builtin_clzll(x))
#define ctzi(x) (__builtin_ctz(x))
#define ctzl(x) (__builtin_ctzll(x))

#define X first
#define Y second

#define Error(x) cout << #x << " = " << x << endl

template <typename T, typename U>
inline void chkmax(T& x, U y) {
	if (x < y) x = y;
}

template <typename T, typename U>
inline void chkmin(T& x, U y) {
	if (y < x) x = y;
}

const int MAXN = 220000;

VI adj[MAXN];
//VI radj[MAXN];

int deg[MAXN], a[MAXN], b[MAXN];
int id[MAXN], ans[MAXN];

void add_edge(int u, int v) {
	adj[u].push_back(v);
//	radj[v].push_back(u);
	deg[v]++;
}

int q[MAXN];

bool cmp(int u, int v) {
	if (b[u] != b[v]) return b[u] < b[v];
	return a[u] < a[v];
}

int main() {
	int n, m, K; scanf("%d%d%d", &n, &m, &K);
	for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
	for (int i = 1; i <= n; i++) {
		if (a[i]) b[i] = a[i];
		else b[i] = K;
	}
	for (int i = 1; i <= m; i++) {
		int u, v; scanf("%d%d", &u, &v);
		add_edge(u, v);
		if (a[u] && a[v] && a[u] <= a[v]) return puts("-1"), 0;
	}
	for (int i = 1; i <= n; i++) if (!a[i]) a[i] = 1, b[i] = K;
	int qn = 0;
	for (int i = 1; i <= n; i++) if (!deg[i]) q[qn++] = i;
	for (int it = 0; it < qn; it++) {
		int u = q[it];
		for (int j = 0; j < sz(adj[u]); j++) {
			int v = adj[u][j];
			if (--deg[v] == 0) q[qn++] = v;
		}
	}
	if (qn != n) {
		return puts("-1"), 0;
	}
	for (int i = 0; i < n; i++) {
		int u = q[i];
		for (int j = 0; j < sz(adj[u]); j++) {
			int v = adj[u][j];
			chkmin(b[v], b[u] - 1);
		}
	}
	for (int i = n-1; i >= 0; i--) {
		int u = q[i];
		for (int j = 0; j < sz(adj[u]); j++) {
			int v = adj[u][j];
			chkmax(a[u], a[v] + 1);
		}
	}
	for (int i = 1; i <= n; i++) if (a[i] > b[i]) return puts("-1"), 0;
	for (int i = 1; i <= n; i++) id[i] = i;
	sort(id + 1, id + n + 1, cmp);
	int cur = 0;
	for (int i = 1, j; i <= n; i = j) {
		if (a[id[i]] > cur+1) return puts("-1"), 0;
		for (j = i; j <= n && b[id[i]] == b[id[j]]; j++) {
			int u = id[j];
			ans[u] = min(cur + 1, b[u]);
			if (ans[u] < a[u]) return puts("-1"), 0;
			cur = ans[u];
		}
	}
	for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
	return 0;
}


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

typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<int, LL> PIL;
typedef pair<LL, int> PLI;
typedef vector<int> VI;
typedef vector<PII> VPII;
typedef double DB;

#define pb push_back
#define mset(a, b) memset(a, b, sizeof a)
#define all(x) (x).begin(), (x).end()
#define bit(x) (1 << (x))
#define bitl(x) (1LL << (x))
#define sqr(x) ((x) * (x))
#define sz(x) ((int)(x.size()))
#define cnti(x) (__builtin_popcount(x))
#define cntl(x) (__builtin_popcountll(x))
#define clzi(x) (__builtin_clz(x))
#define clzl(x) (__builtin_clzll(x))
#define ctzi(x) (__builtin_ctz(x))
#define ctzl(x) (__builtin_ctzll(x))

#define X first
#define Y second

#define Error(x) cout << #x << " = " << x << endl

template <typename T, typename U>
inline void chkmax(T& x, U y) {
	if (x < y) x = y;
}

template <typename T, typename U>
inline void chkmin(T& x, U y) {
	if (y < x) x = y;
}

const int MAXN = 220000;

VI adj[MAXN];
//VI radj[MAXN];

int deg[MAXN], a[MAXN], b[MAXN];
int id[MAXN], ans[MAXN];

void add_edge(int u, int v) {
	adj[u].push_back(v);
//	radj[v].push_back(u);
	deg[v]++;
}

int q[MAXN];

bool cmp(int u, int v) {
	if (a[u] != a[v]) return a[u] < a[v];
	return b[u] < b[v];
}

set<PII> S;

int main() {
	int n, m, K; scanf("%d%d%d", &n, &m, &K);
	for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
	for (int i = 1; i <= n; i++) {
		if (a[i]) b[i] = a[i];
		else b[i] = K;
	}
	for (int i = 1; i <= m; i++) {
		int u, v; scanf("%d%d", &u, &v);
		add_edge(u, v);
		if (a[u] && a[v] && a[u] <= a[v]) return puts("-1"), 0;
	}
	for (int i = 1; i <= n; i++) if (!a[i]) a[i] = 1, b[i] = K;
	int qn = 0;
	for (int i = 1; i <= n; i++) if (!deg[i]) q[qn++] = i;
	for (int it = 0; it < qn; it++) {
		int u = q[it];
		for (int j = 0; j < sz(adj[u]); j++) {
			int v = adj[u][j];
			if (--deg[v] == 0) q[qn++] = v;
		}
	}
	if (qn != n) {
		return puts("-1"), 0;
	}
	for (int i = 0; i < n; i++) {
		int u = q[i];
		for (int j = 0; j < sz(adj[u]); j++) {
			int v = adj[u][j];
			chkmin(b[v], b[u] - 1);
		}
	}
	for (int i = n-1; i >= 0; i--) {
		int u = q[i];
		for (int j = 0; j < sz(adj[u]); j++) {
			int v = adj[u][j];
			chkmax(a[u], a[v] + 1);
		}
	}
	for (int i = 1; i <= n; i++) if (a[i] > b[i]) return puts("-1"), 0;
	for (int i = 1; i <= n; i++) id[i] = i;
	sort(id + 1, id + n + 1, cmp);
	for (int i = 1, j = 1; i <= K; i++) {
		while (j <= n && a[id[j]] <= i) S.insert(PII(b[id[j]], id[j])), j++;
		int flg = 0;
		while (!S.empty()) {
			set<PII> :: iterator it = S.begin();
			if (it->first > i) break;
			flg = 1;
			int u = it->second;
			ans[u] = i;
			S.erase(it);
		}
		if (!flg && S.empty()) return puts("-1"), 0;
		if (flg) continue;
		set<PII> :: iterator it = S.begin();
		int u = it->second;
		ans[u] = i;
		S.erase(it);
	}
	for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
	return 0;
}


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

typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<int, LL> PIL;
typedef pair<LL, int> PLI;
typedef vector<int> VI;
typedef vector<PII> VPII;
typedef double DB;

#define pb push_back
#define mset(a, b) memset(a, b, sizeof a)
#define all(x) (x).begin(), (x).end()
#define bit(x) (1 << (x))
#define bitl(x) (1LL << (x))
#define sqr(x) ((x) * (x))
#define sz(x) ((int)(x.size()))
#define cnti(x) (__builtin_popcount(x))
#define cntl(x) (__builtin_popcountll(x))
#define clzi(x) (__builtin_clz(x))
#define clzl(x) (__builtin_clzll(x))
#define ctzi(x) (__builtin_ctz(x))
#define ctzl(x) (__builtin_ctzll(x))

#define X first
#define Y second

#define Error(x) cout << #x << " = " << x << endl

template <typename T, typename U>
inline void chkmax(T& x, U y) {
	if (x < y) x = y;
}

template <typename T, typename U>
inline void chkmin(T& x, U y) {
	if (y < x) x = y;
}

const int MAXN = 220000;

VI adj[MAXN];
//VI radj[MAXN];

int deg[MAXN], a[MAXN], b[MAXN];
int id[MAXN], ans[MAXN];

void add_edge(int u, int v) {
	adj[u].push_back(v);
//	radj[v].push_back(u);
	deg[v]++;
}

int q[MAXN];

bool cmp(int u, int v) {
	if (b[u] != b[v]) return b[u] < b[v];
	return a[u] < a[v];
}

int main() {
	int n, m, K; scanf("%d%d%d", &n, &m, &K);
	for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
	for (int i = 1; i <= n; i++) {
		if (a[i]) b[i] = a[i];
		else b[i] = K;
	}
	for (int i = 1; i <= m; i++) {
		int u, v; scanf("%d%d", &u, &v);
		add_edge(u, v);
		if (a[u] && a[v] && a[u] <= a[v]) return puts("-1"), 0;
	}
	for (int i = 1; i <= n; i++) if (!a[i]) a[i] = 1, b[i] = K;
	int qn = 0;
	for (int i = 1; i <= n; i++) if (!deg[i]) q[qn++] = i;
	for (int it = 0; it < qn; it++) {
		int u = q[it];
		for (int j = 0; j < sz(adj[u]); j++) {
			int v = adj[u][j];
			if (--deg[v] == 0) q[qn++] = v;
		}
	}
	if (qn != n) {
		return puts("-1"), 0;
	}
	for (int i = 0; i < n; i++) {
		int u = q[i];
		for (int j = 0; j < sz(adj[u]); j++) {
			int v = adj[u][j];
			chkmin(b[v], b[u] - 1);
		}
	}
	for (int i = n-1; i >= 0; i--) {
		int u = q[i];
		for (int j = 0; j < sz(adj[u]); j++) {
			int v = adj[u][j];
			chkmax(a[u], a[v] + 1);
		}
	}
	for (int i = 1; i <= n; i++) if (a[i] > b[i]) return puts("-1"), 0;
	for (int i = 1; i <= n; i++) id[i] = i;
	sort(id + 1, id + n + 1, cmp);
	int cur = 0;
	for (int i = 1, j; i <= n; i = j) {
		if (a[id[i]] > cur+1) return puts("-1"), 0;
		for (j = i; j <= n && b[id[i]] == b[id[j]]; j++) {
			int u = id[j];
			ans[u] = min(cur + 1, b[u]);
			if (ans[u] < a[u]) return puts("-1"), 0;
			cur = ans[u];
		}
	}
	if (cur < K) return puts("-1"), 0;
	for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
	return 0;
}


#include <bits/stdc++.h>
#define FOR(i, l, r) for (int i = int(l), __border_right##i = int(r); i < __border_right##i; i++)
#define STRUCT3(v1, v2, v3, name) struct name \
		{   \
			int v1, v2, v3; \
			name(int v1 = 0, int v2 = 0, int v3 = 0) : v1(v1), v2(v2), v3(v3) {} \
			friend bool operator < (const name& athis, const name& other) \
			{   \
				if (athis.v1 != other.v1) return athis.v1 < other.v1;   \
				if (athis.v2 != other.v2) return athis.v2 < other.v2;   \
				return athis.v3 < other.v3;   \
			}\
		}
#define PB push_back
#define LS (((k) << 1) + 1)
#define RS (((k) << 1) + 2)
#define LM ((l) + (r) >> 1)
#define RM (LM + 1)
//#define LOG(x) tb[(UI(x) * (UI)263572066) >> 27]
#define FST first
#define SCD second
#define retunr return
#define modp 1000000007
#define EPS 1e-7
#define INF 0x3f3f3f3f
#define MAX2 113
#define MAX3 1013
#define MAX4 10013
#define MAX5 100013
#define MAX6 1000013
#define MAXN 3 * MAX5
#define MANX MAXN
using namespace std;
typedef long long LL;
typedef unsigned int UI;
typedef pair<int, int> P;
//const UI tb[32] = {13, 0, 27, 1, 28, 18, 23, 2, 29, 21, 19, 12, 24, 9, 14, 3, 30, 26, 17, 22, 20, 11, 8, 13, 25, 16, 10, 7, 15, 6, 5, 4};

int N, M, K;
int r[MAXN];
std::vector<int> G[MAXN];
std::vector<int> rG[MAXN];
int que[MAXN];
int dg[MAXN];
int ma[MAXN], mi[MAXN];
int seg[MAXN * 4];
priority_queue<P, std::vector<P>, greater<P> > qqq;
int get(int l, int r, int k, int a, int b)
{
	// int res = INF;
	// FOR(i, a, b + 1) {
	// 	res = min(seg[i], res);
	// }
	// return res;
	if (a <= l && r <= b) {
		return seg[k];
	}
	if (b < l || r < a) {
		return INF;
	}
	return min(get(l, LM, LS, a, b), get(RM, r, RS, a, b));
}
void sett(int l, int r, int k, int x, int s)
{
	// seg[x] = s;
	// return;
	// if (k == 0) {
	// 	printf("set seg[%d] = %d\n", x, s);
	// }
	if (x < l || x > r) {
		return;
	}
	if (l == r) {
		seg[k] = s;
		return;
	}
	sett(l, LM, LS, x, s);
	sett(RM, r, RS, x, s);
	seg[k] = min(seg[LS], seg[RS]);
	// printf("seg[%d] = %d\n", k, seg[k]);
}
int main()
{
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
	// freopen("out1.txt", "w", stdout);
#endif
	scanf("%d%d%d", &N, &M, &K);
	FOR(i, 1, K + 1) {
		sett(1, K, 0, i, i);
	}
	FOR(i, 1, N + 1) {
		scanf("%d", &r[i]);
		ma[i] = K;
		mi[i] = 1;
		if (r[i]) {
			ma[i] = r[i];
			mi[i] = r[i];
			sett(1, K, 0, r[i], INF);
		}
	}
	FOR(i, 0, M) {
		int u, v;
		scanf("%d%d", &u, &v);
		G[u].PB(v);
		rG[v].PB(u);
		dg[v]++;
	}
	int tail = 0;
	FOR(i, 1, N + 1) {
		if (dg[i] == 0) {
			que[tail++] = i;
		}
	}
	int head = 0;
	while (head < tail) {
		int u = que[head++];
		FOR(k, 0, G[u].size()) {
			int v = G[u][k];
			dg[v]--;
			if (dg[v] == 0) {
				que[tail++] = v;
			}
		}
	}
	if (tail != N) {
		printf("-1\n");
		return 0;
	}
	FOR(i, 0, N) {
		int v = que[i];
		FOR(k, 0, G[v].size()) {
			int u = G[v][k];
			ma[u] = min(ma[u], ma[v] - 1);
		}
		dg[v] = G[v].size();
		if (G[v].size() == 0) {
			qqq.push(P(ma[v], v));
		}
	}
	for (int i = N - 1; i >= 0; i--) {
		int v = qqq.top().SCD;
		qqq.pop();
		// printf("get %d\n", v);
		if (mi[v] > ma[v]) {
			printf("-1\n");
			return 0;
		}
		if (r[v] == 0) {
			int t = get(1, K, 0, mi[v], ma[v]);
			// printf("get[%d...%d] = %d\n", mi[v], ma[v], t);
			if (t == INF) {
				t = mi[v];
			}
			sett(1, K, 0, t, INF);
			r[v] = t;
		}
		FOR(k, 0, rG[v].size()) {
			int u = rG[v][k];
			mi[u] = max(mi[u], r[v] + 1);
			dg[u]--;
			if (dg[u] == 0) {
				qqq.push(P(ma[u], u));
			}
			// printf("mi[%d] = %d\n", u, mi[u]);
		}
		// printf("r[%d] = %d\n", v, r[v]);
	}
	if (get(1, K, 0, 1, K) <= K) {
		printf("-1\n");
		return 0;
	}
	FOR(i, 1, N + 1) {
		printf("%d%c", r[i], " \n"[i == N]);
	}
	return 0;
}


#include<functional>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<cmath>
using namespace std;
#define clr(a) memset(a,0,sizeof(a))
//--Container
#include<queue>
//
typedef long long ll;
const int up=200000;

struct eg{int u,v,nx;}gp[(up<<1)+10];int cnt,hd[(up<<1)+10],dl[up+10],dr[up+10],n,m,dk,bd[up+10],wg[up+10],in[up+10],ou[up+10],tmp[up+10];
inline void psh(int u,int v){++cnt;gp[cnt].v=v,gp[cnt].u=u,gp[cnt].nx=hd[u],hd[u]=cnt;};
struct ti{int a;ti(int A=0):a(A){};
friend bool operator<(const ti&,const ti&);friend bool operator>(const ti&,const ti&);friend bool operator==(const ti&,const ti&);
};
bool operator<(const ti&a,const ti&b){return dr[a.a]==dr[b.a]?dl[a.a]<dl[b.a]:dr[a.a]<dr[b.a];};
bool operator>(const ti&a,const ti&b){return dr[a.a]==dr[b.a]?dl[a.a]>dl[b.a]:dr[a.a]>dr[b.a];};
bool operator==(const ti&a,const ti&b){return dl[a.a]==dl[b.a]&&dr[a.a]==dr[b.a];};

bool dfq(){
    int i,j;for(i=1;i<=n;++i)tmp[i]=ou[i];queue<int>qe;for(clr(bd),i=1;i<=n;++i)if(!tmp[i])qe.push(i);
    for(;!qe.empty();){
        int v=qe.front();qe.pop();bd[v]=1;for(i=hd[v+n];i;i=gp[i].nx){
            --tmp[gp[i].v];if(!tmp[gp[i].v])qe.push(gp[i].v);
        }
    }
    for(i=1;i<=n;++i)if(!bd[i])return 0;
    return 1;
};
bool dfx(int v){
    int i,j;bd[v]=1;for(dl[v]=0,i=hd[v];i;i=gp[i].nx){
        if(!bd[gp[i].v]&&!dfx(gp[i].v))return 0;
        dl[v]=max(dl[v],dl[gp[i].v]);
    }
    dl[v]++;
    if(dl[v]>dk)return 0;
    if(wg[v]&&wg[v]<dl[v])return 0;
    if(wg[v])dl[v]=wg[v];
    return 1;
};
bool dfz(){
    int i,j;queue<int>qe;for(clr(bd),i=1;i<=n;++i)if(!in[i])qe.push(i),dr[i]=wg[i]?wg[i]:dk;
    for(;!qe.empty();){
        int v=qe.front();qe.pop();if(dr[i]<dl[i])return 0;
        for(i=hd[v];i;i=gp[i].nx){
            if(!bd[gp[i].v]){dr[gp[i].v]=up+233;}
            --in[gp[i].v],dr[gp[i].v]=min(dr[gp[i].v],dr[v]-1);
            if(!in[gp[i].v]){
                if(wg[gp[i].v]&&wg[gp[i].v]>dr[gp[i].v])return 0;
                if(wg[gp[i].v])dr[gp[i].v]=wg[gp[i].v];
                bd[gp[i].v]=1,qe.push(gp[i].v);
            }
        }
    }
    return 1;
};

void _cl(){
    int i,j,rs,d,k;priority_queue<ti,vector<ti>,greater<ti> >qe;for(i=1;i<=n;++i)if(!ou[i])qe.push(ti(i));
    for(rs=1;!qe.empty();){
        int v=qe.top().a;qe.pop();if(dl[v]<=rs&&dr[v]>=rs)dl[v]=rs++;
        else
            dl[v]=dr[v];
        for(i=hd[v+n];i;i=gp[i].nx){
            dl[gp[i].v]=max(dl[gp[i].v],dl[v]+1);
            --ou[gp[i].v];if(!ou[gp[i].v])qe.push(gp[i].v);
        }
    }
    if(rs<=dk)printf("-1\n");
    else{
        for(printf("%d",dl[1]),i=2;i<=n;printf(" %d",dl[i++]));putchar('\n');
    }
};

void cl(){
    int i,j,k,a,b;bool fg=1;scanf("%d %d %d",&n,&m,&dk);
    for(cnt=0,clr(hd),i=1;i<=n;scanf("%d",&wg[i++]));
    for(i=0;i<m;++i){scanf("%d %d",&a,&b);psh(a,b);psh(b+n,a);++in[b],++ou[a];}
    if(!dfq()){printf("-1\n");return;}
    for(clr(bd),i=1;i<=n;++i)if(!in[i]&&!dfx(i))fg=0;
    if(!fg||!dfz()){printf("-1\n");return;}
    _cl();
};

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
#endif
    cl();
	return 0;
};


#include<functional>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<cmath>
using namespace std;
#define clr(a) memset(a,0,sizeof(a))
//--Container
#include<queue>
//
typedef long long ll;
const int up=200000;

struct eg{int u,v,nx;}gp[(up<<1)+10];int cnt,hd[(up<<1)+10],dl[up+10],dr[up+10],n,m,dk,bd[up+10],wg[up+10],in[up+10],ou[up+10],tmp[up+10];
inline void psh(int u,int v){++cnt;gp[cnt].v=v,gp[cnt].u=u,gp[cnt].nx=hd[u],hd[u]=cnt;};
struct ti{int a;ti(int A=0):a(A){};
friend bool operator<(const ti&,const ti&);friend bool operator>(const ti&,const ti&);friend bool operator==(const ti&,const ti&);
};
bool operator<(const ti&a,const ti&b){return dl[a.a]==dl[b.a]?dr[a.a]<dr[b.a]:dl[a.a]<dl[b.a];};
bool operator>(const ti&a,const ti&b){return dl[a.a]==dl[b.a]?dr[a.a]>dr[b.a]:dl[a.a]>dl[b.a];};
bool operator==(const ti&a,const ti&b){return dl[a.a]==dl[b.a]&&dr[a.a]==dr[b.a];};

bool dfq(){
    int i,j;for(i=1;i<=n;++i)tmp[i]=ou[i];queue<int>qe;for(clr(bd),i=1;i<=n;++i)if(!tmp[i])qe.push(i);
    for(;!qe.empty();){
        int v=qe.front();qe.pop();bd[v]=1;for(i=hd[v+n];i;i=gp[i].nx){
            --tmp[gp[i].v];if(!tmp[gp[i].v])qe.push(gp[i].v);
        }
    }
    for(i=1;i<=n;++i)if(!bd[i])return 0;
    return 1;
};
bool dfx(int v){
    int i,j;bd[v]=1;for(dl[v]=0,i=hd[v];i;i=gp[i].nx){
        if(!bd[gp[i].v]&&!dfx(gp[i].v))return 0;
        dl[v]=max(dl[v],dl[gp[i].v]);
    }
    dl[v]++;
    if(dl[v]>dk)return 0;
    if(wg[v]&&wg[v]<dl[v])return 0;
    if(wg[v])dl[v]=wg[v];
    return 1;
};
bool dfz(){
    int i,j;queue<int>qe;for(clr(bd),i=1;i<=n;++i)if(!in[i])qe.push(i),dr[i]=wg[i]?wg[i]:dk;
    for(;!qe.empty();){
        int v=qe.front();qe.pop();if(dr[i]<dl[i])return 0;
        for(i=hd[v];i;i=gp[i].nx){
            if(!bd[gp[i].v]){dr[gp[i].v]=up+233;}
            --in[gp[i].v],dr[gp[i].v]=min(dr[gp[i].v],dr[v]-1);
            if(!in[gp[i].v]){
                if(wg[gp[i].v]&&wg[gp[i].v]>dr[gp[i].v])return 0;
                if(wg[gp[i].v])dr[gp[i].v]=wg[gp[i].v];
                bd[gp[i].v]=1,qe.push(gp[i].v);
            }
        }
    }
    return 1;
};

void _cl(){
    int i,j,rs,d,k;priority_queue<ti,vector<ti>,greater<ti> >qe;for(i=1;i<=n;++i)if(!ou[i])qe.push(ti(i));
    for(rs=1;!qe.empty();){
        int v=qe.top().a;qe.pop();if(dl[v]<=rs&&dr[v]>=rs)dl[v]=rs++;
        else
            dl[v]=dr[v];
        for(i=hd[v+n];i;i=gp[i].nx){
            dl[gp[i].v]=max(dl[gp[i].v],dl[v]+1);
            --ou[gp[i].v];if(!ou[gp[i].v])qe.push(gp[i].v);
        }
    }
    if(rs<=dk)printf("-1\n");
    else{
        for(printf("%d",dl[1]),i=2;i<=n;printf(" %d",dl[i++]));putchar('\n');
    }
};

void cl(){
    int i,j,k,a,b;bool fg=1;scanf("%d %d %d",&n,&m,&dk);
    for(cnt=0,clr(hd),i=1;i<=n;scanf("%d",&wg[i++]));
    for(i=0;i<m;++i){scanf("%d %d",&a,&b);psh(a,b);psh(b+n,a);++in[b],++ou[a];}
    if(!dfq()){printf("-1\n");return;}
    for(clr(bd),i=1;i<=n;++i)if(!in[i]&&!dfx(i))fg=0;
    if(!fg||!dfz()){printf("-1\n");return;}
    _cl();
};

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
#endif
    cl();
	return 0;
};


#include<functional>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<cmath>
using namespace std;
#define clr(a) memset(a,0,sizeof(a))
//--Container
#include<queue>
#include<set>
//
typedef long long ll;
const int up=200000;

struct eg{int u,v,nx;}gp[(up<<1)+10];int cnt,hd[(up<<1)+10],dl[up+10],dr[up+10],n,m,dk,bd[up+10],wg[up+10],in[up+10],ou[up+10],tmp[up+10];
inline void psh(int u,int v){++cnt;gp[cnt].v=v,gp[cnt].u=u,gp[cnt].nx=hd[u],hd[u]=cnt;};
struct ti{int a;ti(int A=0):a(A){};
friend bool operator<(const ti&,const ti&);friend bool operator>(const ti&,const ti&);friend bool operator==(const ti&,const ti&);
};
bool operator<(const ti&a,const ti&b){return dr[a.a]==dr[b.a]?dl[a.a]<dl[b.a]:dr[a.a]<dr[b.a];};
bool operator>(const ti&a,const ti&b){return dr[a.a]==dr[b.a]?dl[a.a]>dl[b.a]:dr[a.a]>dr[b.a];};
bool operator==(const ti&a,const ti&b){return dl[a.a]==dl[b.a]&&dr[a.a]==dr[b.a];};

bool dfq(){
    int i,j;for(i=1;i<=n;++i)tmp[i]=ou[i];queue<int>qe;for(clr(bd),i=1;i<=n;++i)if(!tmp[i])qe.push(i);
    for(;!qe.empty();){
        int v=qe.front();qe.pop();bd[v]=1;for(i=hd[v+n];i;i=gp[i].nx){
            --tmp[gp[i].v];if(!tmp[gp[i].v])qe.push(gp[i].v);
        }
    }
    for(i=1;i<=n;++i)if(!bd[i])return 0;
    return 1;
};
bool dfx(int v){
    int i,j;bd[v]=1;for(dl[v]=0,i=hd[v];i;i=gp[i].nx){
        if(!bd[gp[i].v]&&!dfx(gp[i].v))return 0;
        dl[v]=max(dl[v],dl[gp[i].v]);
    }
    dl[v]++;
    if(dl[v]>dk)return 0;
    if(wg[v]&&wg[v]<dl[v])return 0;
    if(wg[v])dl[v]=wg[v];
    return 1;
};
bool dfz(){
    int i,j;queue<int>qe;for(clr(bd),i=1;i<=n;++i)if(!in[i])qe.push(i),dr[i]=wg[i]?wg[i]:dk;
    for(;!qe.empty();){
        int v=qe.front();qe.pop();if(dr[i]<dl[i])return 0;
        for(i=hd[v];i;i=gp[i].nx){
            if(!bd[gp[i].v]){bd[gp[i].v]=1,dr[gp[i].v]=up+233;}
            --in[gp[i].v],dr[gp[i].v]=min(dr[gp[i].v],dr[v]-1);
            if(!in[gp[i].v]){
                if(wg[gp[i].v]&&wg[gp[i].v]>dr[gp[i].v])return 0;
                if(wg[gp[i].v])dr[gp[i].v]=wg[gp[i].v];
                bd[gp[i].v]=1,qe.push(gp[i].v);
            }
        }
    }
    return 1;
};

void _cl(){
    int i,j,rs,d,k;priority_queue<ti,vector<ti>,greater<ti> >qe;for(i=1;i<=n;++i)if(!ou[i])qe.push(ti(i));
    set<int>st;for(i=1;i<=dk;st.insert(i++));
    for(rs=1;!qe.empty();){
        int v=qe.top().a;qe.pop();set<int>::iterator zt=st.lower_bound(dl[v]);
        if(zt==st.end()||*zt>dr[v])dl[v]=dr[v];
        else
            dl[v]=*zt,st.erase(zt);
        for(i=hd[v+n];i;i=gp[i].nx){
            dl[gp[i].v]=max(dl[gp[i].v],dl[v]+1);
            --ou[gp[i].v];if(!ou[gp[i].v])qe.push(gp[i].v);
        }
    }
    if(!st.empty())printf("-1\n");
    else{
        for(printf("%d",dl[1]),i=2;i<=n;printf(" %d",dl[i++]));putchar('\n');
    }
};

void cl(){
    int i,j,k,a,b;bool fg=1;scanf("%d %d %d",&n,&m,&dk);
    for(cnt=0,clr(hd),i=1;i<=n;scanf("%d",&wg[i++]));
    for(i=0;i<m;++i){scanf("%d %d",&a,&b);psh(a,b);psh(b+n,a);++in[b],++ou[a];}
    if(!dfq()){printf("-1\n");return;}
    for(clr(bd),i=1;i<=n;++i)if(!in[i]&&!dfx(i))fg=0;
    if(!fg||!dfz()){printf("-1\n");return;}
    _cl();
};

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
#endif
    cl();
	return 0;
};