#include <bits/stdc++.h>
#include <array>

using namespace std;

namespace {

    template<class T> ostream& operator<<(ostream& os, const vector<T>& vs) {
        if (vs.empty()) return os << "[]";
        os << "[" << vs[0];
        for (int i = 1; i < vs.size(); i++) os << " " << vs[i];
        return os << "]";
    }

    int W, H, N;
    vector<string> F;

    bool input() {
        cin >> W >> H >> N;
        if (W == 0 && H == 0 && N == 0) return false;
        string s; getline(cin, s);
        F.clear(); F.resize(H);
        for (int i = 0; i < H; i++) getline(cin, F[i]);
        return true;
    }
    
    struct Point {
        int y, x;
        Point() {}
        Point(int y, int x) : y(y), x(x) {}
    };
    bool operator==(const Point& a, const Point& b) { return a.x == b.x && a.y == b.y; }
    bool operator<(const Point& a, const Point& b) { return a.x == b.x ? a.y < b.y : a.x < b.x; }
    ostream& operator<<(ostream& os, const Point& a) { return os << "Point(" << a.x << "," << a.y << ")"; }

    array<Point, 3> start, goal;

    void init() {
        for (int i = 0; i < H; i++) {
            for (int j = 0; j < W; j++) {
                char c = F[i][j];
                if (islower(c)) {
                    start[ c - 'a' ] = Point(i, j);
                } else if (isupper(c)) {
                    goal[ c - 'A' ] = Point(i, j);
                }
            }
        }
    }

    struct State {
        array<Point, 3> ps;
        int t;
        State() { }
        State(const array<Point, 3>& ps, int t) : ps(ps), t(t) {}
    };

    const int dy[] = {-1, 0, 1, 0, 0},
              dx[] = {0, 1, 0, -1, 0};

    inline bool check(const State& prev, const State& next) {
        for (int i = 0; i < N; i++) {
            for (int j = i + 1; j < N; j++) {
                if (next.ps[i] == next.ps[j]) return false;
                if (prev.ps[i] == next.ps[j] && prev.ps[j] == next.ps[i]) return false;
            }
        }
        return true;
    }

    inline int encode(const array<Point, 3>& ps) {
        int r = 0;
        for (int i = 0; i < N; i++) {
            const Point& p = ps[i];
            r += (p.y << (i * 8));
            r += (p.x << (i * 8 + 4));
        }
        return r;
    }

    bitset<(1<<24) + 1> D;
    void genNextState(const State& c, queue<State>& Q, State next, int index = 0 ) {
        if (index == N) {
            if (!check(c, next)) return;
            int h = encode(next.ps);
            if (D[h]) return;
            D[h] = true;
            Q.push(next);
            return;
        }
        for (int i = 0; i < 5; i++) {
            int ny = c.ps[index].y + dy[i];
            int nx = c.ps[index].x + dx[i];
            if (F[ny][nx] == '#') continue;
            next.ps[index].y = ny;
            next.ps[index].x = nx;
            genNextState(c, Q, next, index + 1);
        }
    }

    void solve() {
        init();
        D.reset();
        queue<State> Q;
        Q.push(State(start, 0));
        D[encode(start)] = true;
        while (!Q.empty()) {
            State c = Q.front(); Q.pop();
            if (c.ps == goal) {
                cout << c.t << endl;
                break;
            }
            State stub; stub.t = c.t + 1;
            genNextState(c, Q, stub);
        }
    }
}

int main() {
    while (input()) solve();
    return 0;
}

Measured memory_bytes: 11572