import std.stdio;
import std.datetime;
import core.time;
import std.range;
import std.array;
import std.functional;
import std.algorithm;
import std.conv;
import std.container;
import std.math;
import std.numeric;
import std.string;

const bool DEBUG = false;

auto smap(alias f, Range)(Range r) {
    return r.map!(f).array;
}

int findZpos(long F) {
    int i = 1;
    while (true) {
        if (F % 10 == 0) return (9 - i);
        F /= 10;
        i++;
    }
}

uint[][] adj;
static this() {
    adj = [
        "BIGD",
        "CAHE",
        "DBIF",
        "ECAG",
        "FDBH",
        "GECI",
        "HFDA",
        "IGEB",
        "AHFC"
    ].smap!(s => s.smap!(c => c - 'A'));
}

long startE, goalE;

int dist(long a) {
    long b = goalE;
    int x = 9;
    foreach (i; 0 .. 9) {
        if (a % 10 == b % 10) x--;
        a /= 10;
        b /= 10;
    }
    return x;
}

struct P {
    long F;
    int cost;
    int zpos;
    int opCmp(P o) {
        /*if (cost == o.cost) {
            dist(F) - dist(o.F);
        } */
        return cost - o.cost;
    }
}

bool equals(in int[] a, in int[] b) {
    if (a.length != b.length) return false;
    foreach (i; 0 .. a.length) {
        if (a[i] != b[i]) return false;
    }
    return true;
}

long encode(int[] F) {
    long ret = 0;
    foreach (i; 0 .. 9) {
        ret = ret * 10 + F[i];
    }
    return ret;
}

int[] decode(long F) {
    int[] ret;
    foreach (i; 0 .. 9) {
        ret ~= (F % 10);
        F /= 10;
    }
    return ret.reverse;
}

long lswap(long v, int x, int y) {
    immutable static pow10 = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000];
    long xv = (v % pow10[9 - x]) / pow10[8 - x];
    long yv = (v % pow10[9 - y]) / pow10[8 - y];
    return v - xv * pow10[8 - x] - yv * pow10[8 - y]
             + xv * pow10[8 - y] + yv * pow10[8 - x];
}

void main() {
    int ch, cv;
    static if (DEBUG) {
        auto startTime = Clock.currTime;
    }
    while (readf("%d %d\n", &ch, &cv), ch || cv) {
        int[] start, goal;
        foreach (i; 0 .. 3)
            start ~= readln.chomp.split(" ").map!(to!int).array;
        foreach (i; 0 .. 3)
            goal ~= readln.chomp.split(" ").map!(to!int).array;

        startE = start.encode,
        goalE = goal.encode;
        
        BinaryHeap!(Array!P, "a >= b") PQ;
        PQ.insert(P(startE, 0, startE.findZpos));
        BinaryHeap!(Array!P, "a >= b") PQ2;
        PQ2.insert(P(goalE, 0, goalE.findZpos));
        int[long] fromS, fromG;
        bool[long] used;
        bool f = true;
        while (true) {
            if (PQ.empty && PQ2.empty) {
                break;
            }
            P cur = (f ? PQ : PQ2).front; (f ? PQ : PQ2).removeFront;
            //writeln(f, " ", cur);
            if (f && cur.F == goalE) {
                writeln(cur.cost);
                break;
            }
            if (f) {
                if (fromG.get(cur.F, -1) >= 0) {
                    writeln(fromG[cur.F] + cur.cost);
                    break;
                }
                fromS[cur.F] = cur.cost;
            }
            if (!f) {
                if (fromS.get(cur.F, -1) >= 0) {
                    writeln(fromS[cur.F] + cur.cost);
                    break;
                }
                fromG[cur.F] = cur.cost;
            }
            used[cur.F] = true;
            auto zpos = cur.zpos;
            //writeln(cur.F, " ", "zpos: ", cur.F.zpos);
            foreach (index, i; adj[zpos]) {
                long nF = cur.F.lswap(i, zpos);
                if (used.get(nF, false)) continue;
                (f ? PQ : PQ2).insert(P(nF, cur.cost + (index < 2 ? ch : cv), i));
            }
            f = !f;
        }
    }
}