import std.stdio;
import std.container;
import std.string;
import std.array;
import std.algorithm;

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 = new int[][y];
    foreach (i, L; F) copy[i] = L.dup;
    void _set(int i, int j) {
        if (i + 1 < y && copy[i][j] == copy[i + 1][j]) _set(i + 1, j);
        if (j + 1 < x && copy[i][j] == copy[i][j + 1]) _set(i, j + 1);
        copy[i][j] = v;
    }
    _set(0, 0);
    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 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));
        while (!Q.empty) {
            State s = Q.front;
            Q.removeFront;
            if (s.finished) {
                s.t.writeln;
                break;
            }
            foreach (v; 0 .. 3) {
                if (s.F[0][0] == v) continue;
                Q.insert(new State(s.t + 1, s.F.set(v)));
            }
            delete(s.F);
            delete(s);
        }
    }
}