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;
    bool f;
    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;
    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, true));
        PQ.insert(P(goalE, 0, goalE.findZpos, false));
        int[long] fromS, fromG;

        fromS[startE] = 0;
        fromG[goalE] = 0;

        int ans = int.max;
        bool g = false;
        while (!PQ.empty) {
            P cur = PQ.front; PQ.removeFront;
            if (fromS.get(cur.F, -1) >= 0 && fromG.get(cur.F, -1) >= 0) {
                ans = min(ans, (fromS[cur.F] + fromG[cur.F]));
                g = true;
                continue;
            }
            if (cur.f && g) continue;
            if (ans <= cur.cost) continue;
            auto zpos = cur.zpos;
            foreach (index, i; adj[zpos]) {
                long nF = cur.F.lswap(i, zpos);
                int ncost = cur.cost + (index < 2 ? ch : cv);
                if (cur.f) {
                    if (fromS.get(nF, -1) >= 0) continue;
                    fromS[nF] = ncost;
                } else {
                    if (fromG.get(nF, -1) >= 0) continue;
                    fromG[nF] = ncost;
                }
                PQ.insert(P(nF, ncost, i, cur.f));
            }
        }
        ans.writeln;
    }
}