#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
using namespace std;

typedef long long  ll;

typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 1000000007;
typedef double ld;
typedef complex<ld> Point;
const ll INF = mod * mod;
typedef pair<int, int> P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
typedef vector<int> vec;

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

bool isalf(char t) {
	if ('a' <= t && t <= 'z')return true;
	return false;
}
bool isAlf(char t) {
	if ('A' <= t && t <= 'Z')return true;
	return false;
}

int h, w, n;
bool used[256][256][256];
char mp[16][16];
void solve() {
	int sx[3] = {}, sy[3] = {}, gx[3] = {}, gy[3] = {};
	string s; getline(cin, s);
	rep(i, h) {
		getline(cin, s);
		rep(j, w) {
			mp[i][j] = s[j];
			if (isalf(s[j])) {
				int z = s[j] - 'a';
				sx[z] = i, sy[z] = j;
			}
			else if (isAlf(s[j])) {
				int z = s[j] - 'A';
				gx[z] = i, gy[z] = j;
			}
		}
	}
	queue<vec> q;
	rep(i, h*w)rep(j, h*w)rep(k, h*w)used[i][j][k] = false;
	int cs[3];
	int cg[3];
	rep(i, 3)cs[i] = sx[i] * w + sy[i];
	rep(i, 3)cg[i] = gx[i] * w + gy[i];
	//rep(i, c)cout << cs[i] << endl;
	used[cs[0]][cs[1]][cs[2]] = true;
	q.push({ cs[0] , cs[1], cs[2] });
	int tmp = 0;
	while (!q.empty()) {
		int len = q.size();
		rep(aa, len) {
			vec v = q.front(); q.pop();
			if (v == vec{cg[0], cg[1], cg[2]}) {
				cout << tmp << endl; return;
			}
			int nx[3], ny[3],nz[3];
			rep(i, 9) {
				if (i % 2 == 0 && i != 4)continue;
				nx[0] = v[0] / w + i%3 - 1;
				ny[0] = v[0] % w + i/3 - 1;
				nz[0] = nx[0] * w + ny[0];
				if (mp[nx[0]][ny[0]] == '#')continue;
				if (n == 1) {
					if (used[nz[0]][0][0])continue;
					used[nz[0]][0][0] = true;
					q.push({ nz[0],0,0 });
					continue;
				}
				rep(j, 9) {
					if (j % 2 == 0 && j != 4)continue;
					nx[1] = v[1] / w + j % 3 - 1;
					ny[1] = v[1] % w + j / 3 - 1;
					nz[1] = nx[1] * w + ny[1];
					if (mp[nx[1]][ny[1]] == '#')continue;
					if (nz[0] == nz[1])continue;
					if (nz[0] == v[1] && v[0] == nz[1])continue;
					if (n == 2) {
						if (used[nz[0]][nz[1]][0])continue;
						used[nz[0]][nz[1]][0] = true;
						q.push({ nz[0],nz[1],0 });
						continue;
					}
					rep(k, 9) {
						if (k % 2 == 0 && k != 4)continue;
						nx[2] = v[2] / w + k % 3 - 1;
						ny[2] = v[2] % w + k / 3 - 1;
						nz[2] = nx[2] * w + ny[2];
						if (mp[nx[2]][ny[2]] == '#')continue;
							if (used[nz[0]][nz[1]][nz[2]])continue;
							if (nz[0] == nz[2]||nz[1]==nz[2])continue;
							if (nz[0] == v[2] && v[0] == nz[2])continue;
							if (nz[1] == v[2] && v[1] == nz[2])continue;
							used[nz[0]][nz[1]][nz[2]] = true;
							q.push({ nz[0],nz[1],nz[2] });
					}
				}
			}
		}
		tmp++;
	}

}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(5);
	while (cin >> w>>h>>n,n)solve();
	//solve();
	//stop
	return 0;
}



Measured memory_bytes: 32152