import std.stdio;
import std.conv;
import std.container;
import std.string;
import std.array;
import std.algorithm;
import std.digest.sha;

int[][] duplicate(int[][] F) {
    int[][] copy = new int[][F.length];
    foreach (i, L; F) {
        copy[i] = L.dup;
    }
    return copy;
}

int[][] set(int[][] F, int v) {
    int y = cast(int)F.length;
    int x = cast(int)F[0].length;
    int[][] copy = F.duplicate;
    auto mark = new bool[][](y, x);
    void setMark(int i, int j) {
        const dy = [1, 0, -1, 0];
        const dx = [0, 1, 0, -1];
        if (mark[i][j]) return;
        mark[i][j] = true;
        foreach (k; 0 .. 4) {
            int ny = i + dy[k], nx = j + dx[k];
            if (0 <= ny && ny < y && 0 <= nx && nx < x) {
                if (F[i][j] == F[ny][nx] && !mark[ny][nx]) {
                    setMark(ny, nx);
                }
            }
        }
    }
    setMark(0, 0);
    foreach (i; 0 .. y) 
        foreach (j; 0 .. x) 
            if (mark[i][j]) copy[i][j] = v;
    return copy;
}

class State {
    int t;
    int[][] F;
    this(int t, int[][] F) {
        this.t = t;
        this.F = F;
    }
    bool finished() {
        int v = F[0][0];
        foreach (L; F) 
            foreach (C; L) 
                if (C != v) return false;
        return true;
    }
}

void dump(int[][] F) {
    foreach (L; F) {
        L.map!(to!string).join(" ").writeln;
    }
}

string encode(int[][] F) {
    return sha1Of(F).toHexString;
}

void main() {
    int x, y; 
    int[][] F;
    while (readf("%d %d\n", &x, &y), x || y) {
        F = new int[][y];
        foreach (ref L; F) {
            L = readln.chomp.split(" ").map!(function(string s) {
                switch (s) {
                    case "R": return 0;
                    case "G": return 1;
                    case "B": return 2;
                    default: // XXX;
                }
                throw new Error("?");
            }).array;
        }
        auto Q = new DList!State(new State(0, F.duplicate));
        bool[string] used;
        while (!Q.empty) {
            State s = Q.front;
            Q.removeFront;
            scope(exit) {
                delete(s.F);
                delete(s);
            }
            //s.t.writeln;
            //s.F.dump;
            if (s.finished) {
                s.t.writeln;
                break;
            }
            foreach (v; 0 .. 3) {
                if (s.F[0][0] == v) continue;
                auto next = s.F.set(v);
                auto hash = next.encode;
                if (used.get(hash, false)) {
                    delete(next);
                    continue;
                } 
                Q.insert(new State(s.t + 1, next));
            }
        }
    }
}