Problem: On a small planet named Bandai, a landing party of the starship Tadamigawa discovered colorful cubes traveling on flat areas of the planet surface, which the landing party named beds. A cube appears at a certain position on a bed, travels on the bed for a while, and then disappears. After a longtime observation, a science officer Lt. Alyssa Ogawa of Tadamigawa found the rule how a cube travels on a bed.

A bed is a rectangular area tiled with squares of the same size.

* One of the squares is colored red,
* one colored green,
* one colored blue,
* one colored cyan,
* one colored magenta,
* one colored yellow,
* one or more colored white, and
* all others, if any, colored black.



Initially, a cube appears on one of the white squares. The cube’s faces are colored as follows.


top  red
bottom  cyan
north  green
south  magenta
east  blue
west  yellow


The cube can roll around a side of the current square at a step and thus rolls on to an adjacent square. When the cube rolls on to a chromatically colored (red, green, blue, cyan, magenta or yellow) square, the top face of the cube after the roll should be colored the same. When the cube rolls on to a white square, there is no such restriction. The cube should never roll on to a black square.

Throughout the travel, the cube can visit each of the chromatically colored squares only once, and any of the white squares arbitrarily many times. As already mentioned, the cube can never visit any of the black squares. On visit to the final chromatically colored square, the cube disappears. Somehow the order of visits to the chromatically colored squares is known to us before the travel starts.

Your mission is to find the least number of steps for the cube to visit all the chromatically colored squares in the given order.



Input

The input is a sequence of datasets. A dataset is formatted as follows:


w d

c11 . . . cw1
.        .
.        .
.        .
c1d . . . cwd
v1v2v3v4v5v6


The first line is a pair of positive integers w and d separated by a space. The next d lines are w-character-long strings c11 . . . cw1 , . . . , c1d . . . cwd with no spaces. Each character cij is one of the letters r, g, b, c, m, y, w and k, which stands for red, green, blue, cyan, magenta, yellow, white and black respectively, or a sign #. Each of r, g, b, c, m, y and # occurs once and only once in a dataset. The last line is a six-character-long string v1v2v3v4v5v6 which is a permutation of “rgbcmy”.

The integers w and d denote the width (the length from the east end to the west end) and the depth (the length from the north end to the south end) of a bed. The unit is the length of a side of a square. You can assume that neither w nor d is greater than 30.

Each character cij shows the color of a square in the bed. The characters c11 , cw1 , c1d and cwd correspond to the north-west corner, the north-east corner, the south-west corner and the south- east corner of the bed respectively. If cij is a letter, it indicates the color of the corresponding square. If cij is a #, the corresponding square is colored white and is the initial position of the cube.

The string v1v2v3v4v5v6 shows the order of colors of squares to visit. The cube should visit the squares colored v1, v2 , v3 , v4 , v5 and v6 in this order.

The end of the input is indicated by a line containing two zeros separated by a space.

Output

For each input dataset, output the least number of steps if there is a solution, or "unreachable" if there is no solution. In either case, print it in one line for each input dataset.

Example

Input

10 5
kkkkkwwwww
w#wwwrwwww
wwwwbgwwww
kwwmcwwwkk
kkwywwwkkk
rgbcmy
10 5
kkkkkkkkkk
k#kkkkkkkk
kwkkkkkwwk
kcmyrgbwwk
kwwwwwwwwk
cmyrgb
10 5
kkkkkkkkkk
k#kkkkkkkk
kwkkkkkwkk
kcmyrgbwwk
kwwwwwwwwk
cmyrgb
0 0


Output

9
49
unreachable

Solution (in JAVA):

Solution:

import java.io.*;
import java.util.*;



public class Main {
	int W, D;
	char[][] field;
	String col;
	
	class State{
		int x;
		int y;
		Dice<Character> dice;
		int idx;
		int d;
		public State(int x, int y, Dice<Character> dice, int idx, int d){
			this.x = x;
			this.y = y;
			this.dice = dice;
			this.idx = idx;
			this.d = d;
		}
		public boolean equals(Object o){
			if(o != null && o instanceof State){
				State d = (State)o;
				return d.x == x && d.y == y && d.idx == idx && d.dice.equalsDirection(dice);
			}else{
				return false;
			}
		}
		public int hashCode(){
			return Objects.hash(x, y, dice.getId(Dice.TOP), dice.getId(Dice.EAST));
		}
		public String toString(){
			return String.format("[(%d,%d),%d,%d, %s]", x, y, idx, d, dice.toString());
		}
	}
	
	public void solve() {
		while(true){
			W = nextInt();
			D = nextInt();
			if(W == 0) break;
			
			field = new char[D + 2][W + 2];
			int sx = 0, sy = 0;
			for(int i = 1; i <= D; i++){
				String str = next();
				for(int j = 1; j <= W; j++){
					switch(str.charAt(j - 1)){
					case '#':
						sx = j;
						sy = i;
					case 'w':
						field[i][j] = 1;
						break;
					case 'k':
						field[i][j] = 0;
						break;
					default:
						field[i][j] = str.charAt(j - 1);	
					}
				}
			}
			col = next();
			State s = new State(sx, sy, new Dice<Character>('r', 'c', 'g', 'm', 'b', 'y'), 0, 0);
			HashSet<State> reach = new HashSet<>();
			Queue<State> queue = new ArrayDeque<>();
			queue.add(s);
			int ans = -1;
			while(!queue.isEmpty()){
				s = queue.poll();
				if(!reach.contains(s)){
					char c = field[s.y][s.x];
					if(c == 1 ||
							(c == col.charAt(s.idx) &&
							field[s.y][s.x] == c &&
							c == s.dice.getTop())){
						reach.add(s);
						int ni = s.idx;
						if(c != 1){
							ni++;
							if(ni == 6){
								ans = s.d;
								break;
							}
						}
						queue.add(new State(s.x + 1, s.y, s.dice.rollEast(), ni, s.d + 1));
						queue.add(new State(s.x, s.y - 1, s.dice.rollNorth(), ni, s.d + 1));
						queue.add(new State(s.x - 1, s.y, s.dice.rollWest(), ni, s.d + 1));
						queue.add(new State(s.x, s.y + 1, s.dice.rollSouth(), ni, s.d + 1));
						
					}
				}
			}
			if(ans == -1){
				out.println("unreachable");
			}else{
				out.println(ans);
			}
		}
	}
	
	private static PrintWriter out;

	public static void main(String[] args) {
		out = new PrintWriter(System.out);
		new Main().solve();
		out.flush();
	}

	public static int nextInt() {
		int num = 0;
		String str = next();
		boolean minus = false;
		int i = 0;
		if(str.charAt(0) == '-'){
			minus = true;
			i++;
		}
		int len = str.length();
		for(; i < len; i++){
			char c = str.charAt(i);
			if(!('0' <= c && c <= '9')) throw new RuntimeException();
			num = num * 10 + (c - '0');
		}
		return minus ? -num : num;
	}

	public static long nextLong() {
		long num = 0;
		String str = next();
		boolean minus = false;
		int i = 0;
		if(str.charAt(0) == '-'){
			minus = true;
			i++;
		}
		int len = str.length();
		for(; i < len; i++){
			char c = str.charAt(i);
			if(!('0' <= c && c <= '9')) throw new RuntimeException();
			num = num * 10l + (c - '0');
		}
		return minus ? -num : num;
	}

	public static String next() {
		int c;
		while(!isAlNum(c = read())){}
		StringBuilder build = new StringBuilder();
		build.append((char)c);
		while(isAlNum(c = read())){
			build.append((char)c);
		}
		return build.toString();
	}

	private static byte[] inputBuffer = new byte[1024];
	private static int bufferLength = 0;
	private static int bufferIndex = 0;

	private static int read() {
		if(bufferLength < 0) throw new RuntimeException();
		if(bufferIndex >= bufferLength){
			try{
				bufferLength = System.in.read(inputBuffer);
				bufferIndex = 0;
			}catch(IOException e){
				throw new RuntimeException(e);
			}
			if(bufferLength <= 0) return(bufferLength = -1);
		}
		return inputBuffer[bufferIndex++];
	}

	private static boolean isAlNum(int c) {
		return '!' <= c && c <= '~';
	}
}


class Dice<T> {
	public static final int TOP = 0;
	public static final int BOTTOM = 5;
	public static final int EAST = 4;
	public static final int WEST = 1;
	public static final int NORTH = 3;
	public static final int SOUTH = 2;
	
	private final int[] id = new int[6];
	private final ArrayList<T> values;
	
	public Dice(){
		values = new ArrayList<>(6);
		for(int i = 0; i < 6; i++){
			id[i] = i;
			values.add(null);
		}
	}
	
	public Dice(T top, T bottom, T north, T south, T east, T west){
		this();
		values.set(TOP, top);
		values.set(BOTTOM, bottom);
		values.set(EAST, east);
		values.set(WEST, west);
		values.set(NORTH, north);
		values.set(SOUTH, south);
	}
	
	private Dice(Dice<T> d){
		values = d.values;
		for(int i = 0; i < 6; i++){
			id[i] = d.id[i];
		}
	}

	public Dice<T> rollNorth(){
		return roll(TOP, SOUTH, BOTTOM, NORTH);
	}
	public Dice<T> rollSouth(){
		return roll(TOP, NORTH, BOTTOM, SOUTH);
	}
	public Dice<T> rollWest(){
		return roll(TOP, EAST, BOTTOM, WEST);
	}
	public Dice<T> rollEast(){
		return roll(TOP, WEST, BOTTOM, EAST);
	}
	public Dice<T> rollClockWise(){
		return roll(NORTH, WEST, SOUTH, EAST);
	}
	public Dice<T> rollCounterClockWise(){
		return roll(NORTH, EAST, SOUTH, WEST);
	}
	
	public T getTop(){
		return values.get(id[TOP]);
	}
	
	public int getId(int face){
		return id[face];
	}
	
	
	public boolean equalsDirection(Dice<T> d){
		return d.getId(TOP) == getId(TOP) && d.getId(EAST) == getId(EAST);
	}

	public String toString(){
		StringBuilder build = new StringBuilder();
		build.append("TOP:");
		build.append(values.get(id[TOP]));
		build.append(",BOTTOM:");
		build.append(values.get(id[BOTTOM]));
		build.append(",NORTH:");
		build.append(values.get(id[NORTH]));
		build.append(",SOUTH:");
		build.append(values.get(id[SOUTH]));
		build.append(",WEST:");
		build.append(values.get(id[WEST]));
		build.append(",EAST:");
		build.append(values.get(id[EAST]));
		return build.toString();
	}
	private Dice<T> roll(int a, int b, int c, int d){
		Dice<T> nd = new Dice<T>(this);
		int tmp = nd.id[a];
		nd.id[a] = nd.id[b];
		nd.id[b] = nd.id[c];
		nd.id[c] = nd.id[d];
		nd.id[d] = tmp;
		return nd;
	}
}