#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
#include<map>
#include<cstdlib>

using namespace std;

class Dice{

public:
  int top,bottom,north,south,west,east;

  static const int TOP = 0;
  static const int BOTTOM = 1;
  static const int NORTH = 2;
  static const int SOUTH = 3;
  static const int EAST = 4;
  static const int WEST = 5;
  
 Dice(int t = 0, int b = 1, int n = 2, int s = 3, int w = 5, int e = 4)
   :top(t),bottom(b),north(n),south(s),west(w),east(e){}


 void setDice(int t, int b, int n, int s, int w, int e){
   top = t; bottom = b, north = n; south = s, west = w; east = e;
 }

 void rotateNorth(){setDice(south,north,top,bottom,west,east);}
 void rotateSouth(){setDice(north,south,bottom,top,west,east);}
 void rotateEast(){setDice(west,east,north,south,bottom,top);}
 void rotateWest(){setDice(east,west,north,south,top,bottom);}
 void rotateCW(){setDice(top,bottom,west,east,south,north);}
 void rotateCCW(){setDice(top,bottom,east,west,north,south);}

 //in for loop this function is convenient
 //able to access variables like array
 //this function can only get specific variable
 int getAt(int pos) const {
   if(pos == TOP) return top;
   if(pos == BOTTOM) return bottom;
   if(pos == NORTH) return north;
   if(pos == SOUTH) return south;
   if(pos == WEST) return west;
   if(pos == EAST) return east;
 }

  // express state of this dice as a 6-base number.
  string getState() const {
    string res = "";
    for(int i = 0; i < 6; i++){
      int pos = getAt(i);
      res += (pos+'0');
    }
    return res;
  }
};

struct State{
  int t,h,w,done;
  Dice dice;
  bool operator < (const State& st) const {
    return t > st.t;
  }
};

const int SIZE = 31;
const int INF = (1<<28);
const int DONE = (1<<6);
int T[SIZE][SIZE][DONE][6][6];

int W,H;
int dx[] = {1,0,-1,0};
int dy[] = {0,1,0,-1};
string order;

char field[SIZE][SIZE];

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

bool canMove(State& st){
  int h = st.h;
  int w = st.w;
  if(field[h][w] == 'k') return false;
  if(field[h][w] == 'w') return true;

  int top = st.dice.getAt(Dice::TOP);
  string colstr = "rcgmby";
  
  if(colstr[top] != field[h][w]) return false;

  int nexpos = __builtin_popcount(st.done);	
  if(colstr[top] != order[nexpos]) return false;

  bool res = ((st.done&(1<<nexpos)) == 0);
  st.done = st.done|(1<<nexpos);
  return res;
}

void input(){
  for(int i = 0; i < H; i++)
    for(int j = 0; j < W; j++) cin >> field[i][j];
  cin >> order;
}

void solve(){

  fill(T[0][0][0][0],T[0][0][0][0]+SIZE*SIZE*DONE*6*6,INF);

  priority_queue<State> Q;

  for(int i = 0; i < H; i++)
    for(int j = 0; j < W; j++){
      if(field[i][j] == '#'){
	State tmp = (State){0,i,j,0,Dice()};
	Q.push(tmp);
	T[tmp.h][tmp.w][tmp.done][tmp.dice.getAt(Dice::TOP)][tmp.dice.getAt(Dice::NORTH)] = 0;
	field[i][j] = 'w';
      }
    }

  const int comp = (1<<6)-1;
  int res = INF;

  while(!Q.empty()){

    const State now = Q.top();
    Q.pop();

    if(now.done == comp) res = min(res,now.t);

    if(T[now.h][now.w][now.done][now.dice.getAt(Dice::TOP)][now.dice.getAt(Dice::NORTH)] < now.t) continue;

    for(int i = 0; i < 4; i++){
      //E S W N
      State nex = now;
      nex.h += dy[i];
      nex.w += dx[i];
      nex.t++;
      if(i == 0) nex.dice.rotateEast();
      if(i == 1) nex.dice.rotateSouth();
      if(i == 2) nex.dice.rotateWest();
      if(i == 3) nex.dice.rotateNorth();

      if(!isInside(nex.h, nex.w)) continue;
    
      if(canMove(nex)){
	if(T[nex.h][nex.w][nex.done][nex.dice.getAt(Dice::TOP)][nex.dice.getAt(Dice::NORTH)] > nex.t){
	  T[nex.h][nex.w][nex.done][nex.dice.getAt(Dice::TOP)][nex.dice.getAt(Dice::NORTH)] = nex.t;
	  Q.push(nex);
	}
      }
    }
  }

  if(res == INF) cout << "unreachable" << endl;
  else cout << res << endl; 		    
}

int main(){
  
  while(cin >> W >> H && W+H){
    input();
    solve();
  }
  return 0;
}

Measured memory_bytes: 9996