#include <bits/stdc++.h>

using namespace std;

#define REP(i,a,b) for(int i=a;i<(int)b;i++)
#define rep(i,n) REP(i,0,n)
#define all(c) (c).begin(), (c).end()
#define zero(a) memset(a, 0, sizeof a)
#define minus(a) memset(a, -1, sizeof a)
#define watch(a) { cout << #a << " = " << a << endl; }
template<class T1, class T2> inline bool minimize(T1 &a, T2 b) { return b < a && (a = b, 1); }
template<class T1, class T2> inline bool maximize(T1 &a, T2 b) { return a < b && (a = b, 1); }

typedef long long ll;
int const inf = 1<<29;

enum Face : int { Top=0, Front=1, Right=2, Left=3, Back=4, Bottom=5 };
class cube {
private:
  int f[6];
  unordered_map<int, string> name_;

public:
  cube(){}
  cube(vector<int> const& vs){ assert(vs.size() == 6); for(int i=0; i<6; i++) f[i] = vs[i]; }
  cube(vector<string> const& vs) { assert(vs.size() == 6); for(int i=0; i<6; i++) f[i] = i, name_[i] = vs[i]; }
  void roll_z() { roll(1, 2, 4, 3); }
  void roll_y() { roll(0, 2, 5, 3); }
  void roll_x() { roll(0, 1, 5, 4); }
  void roll(int i, int j, int k, int l) {
    int t = f[i]; f[i] = f[j]; f[j] = f[k]; f[k] = f[l]; f[l] = t;
  }

  const int& operator[] (int idx) const { return f[idx]; }
  const string& name(int idx) { return name_[f[idx]]; }

  void roll(int k) {
    if(k == 0) roll_y();
    if(k == 1) roll_x();
    if(k == 2) for(int i=0; i<3; i++) roll_y();
    if(k == 3) for(int i=0; i<3; i++) roll_x();
  }

  bool roll_top_front(int top, int front) {
    for(int k = 0; k < 6; (k & 1 ? roll_y() : roll_x()), k++)
      for(int i = 0; i < 4; roll_z(), ++i)
        if(top == f[Top] && front == f[Front]) return true;
    return false;
  }

  bool operator== (cube const& rhs) const {
    for(int i=0; i<6; i++)
      if(f[i] != rhs.f[i]) return false;
    return true;
  }

  bool isomorphic(cube rhs) const {
    for(int k = 0; k < 6; (k & 1 ? rhs.roll_y() : rhs.roll_x()), k++)
      for(int i = 0; i < 4; rhs.roll_z(), ++i)
        if(operator==(rhs)) return true;
    return false;
  }

};

int dx[4] = {-1,0,1,0}, dy[4] = {0,-1,0,1};
template<class T> constexpr bool in_range(T y, T x, T H, T W) { return 0<=y&&y<H&&0<=x&&x<W; }

int main() {
  for(int W, H; cin >> W >> H && (W|H);) {
    vector<string> G(H); rep(i, H) cin >> G[i]; string S; cin >> S;
    int sy, sx; rep(i, H) rep(j, W) if(G[i][j] == '#') sy = i, sx = j;
    G[sy][sx] = 'w';
    queue<tuple<cube, int, int, int>> q;
    cube c({"red", "magenta", "blue", "yellow", "green", "cyan"});
    q.emplace(c, sy, sx, 0);
    static int dist[33][33][7][7][8];
    rep(i, 33) rep(j, 33) rep(k, 7) rep(l, 7) rep(m, 8) dist[i][j][k][l][m] = inf;
    dist[sy][sx][c[Top]][c[Front]][0] = 0;
    while(!q.empty()) {
      cube c; int y, x, col; tie(c, y, x, col) = q.front(); q.pop();
      if(col == 6) { cout << dist[y][x][c[Top]][c[Front]][col] << endl; goto next_f; }
      rep(k, 4) {
        int ny = y + dy[k], nx = x + dx[k];
        if(!in_range(ny, nx, H, W)) continue;
        if(G[ny][nx] == 'k') continue;
        cube nc = c; nc.roll(k);
        if(G[ny][nx] != 'w' && (G[ny][nx] != S[col] || nc.name(Top)[0] != S[col])) continue;
        int ncol = col + (G[ny][nx] == S[col] && nc.name(Top)[0] == S[col]);
        if(dist[ny][nx][nc[Top]][nc[Front]][ncol] < inf) continue;
        bool ng = 0;
        rep(t, 7) rep(f, 7) rep(k, ncol) ng |= G[ny][nx] != 'w' && (dist[ny][nx][t][f][k] < inf); if(ng) continue;
        dist[ny][nx][nc[Top]][nc[Front]][ncol] = dist[y][x][c[Top]][c[Front]][col] + 1;
        q.emplace(nc, ny, nx, ncol);
      }
    }
    cout << "unreachable" << endl; next_f:;
  }
  return 0;
}

Measured memory_bytes: 5032