#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <map>
#include <numeric>
using namespace std;
  
struct state {
    int x, y, d, wall;
    state(int x, int y, int d, int w):x(x), y(y), d(d), wall(w) {}
};
 
int h, w, l;
const int MAX = 25;
string board[MAX];
 
const int MAX_D = 3;
const int MAX_WALL = (1 << 5);
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
 
int sx, sy, gx, gy;
int label[MAX][MAX][MAX_D][MAX_WALL];
bool visited[MAX][MAX][MAX_D][MAX_WALL];
 
inline bool valid(int x, int y) {
    return 0 <= x && x < w && 0 <= y && y < h;
}
 
inline bool special_wall(int x, int y, int wall) {
    if(board[y][x] < 'a' || board[y][x] > 'e')
        return false;
 
    return !(wall & (1 << (board[y][x] - 'a')));
}
 
bool check(int ax, int ay, int bx, int by, int w) {
    if(!valid(ax, ay) || !valid(bx, by))
        return false;
 
    for(int i = ay; i <= by; ++i) {
        for(int j = ax; j <= bx; ++j) {
            if(board[i][j] == '#' || special_wall(j, i, w)) return false;
        }
    }
 
    return true;
}
 
inline void change(int& ax, int& ay, int& bx, int& by) {
    if(ax > bx) swap(ax, bx);
    if(ay > by) swap(ay, by);
}
 
int bfs() {
	queue<state> que;
	que.push(state(sx, sy, 0, 0));
 
    memset(label, -1, sizeof(label));
    memset(visited, false, sizeof(visited));
     
    label[sy][sx][0][0] = 0;
    while(!que.empty()) {
        const state s = que.front();
        que.pop();

        if (visited[s.y][s.x][s.d][s.wall]) continue;
        visited[s.y][s.x][s.d][s.wall] = true;
 
        if(s.x == gx && s.y == gy && s.d == 0) return label[s.y][s.x][s.d][s.wall];
		
		const int nl = label[s.y][s.x][s.d][s.wall] + 1;
        switch(s.d) {
        case 0:
        {
            for(int i = 0; i < 4; ++i) {
                int ax = s.x + dx[i];
                int ay = s.y + dy[i];
                int bx = s.x + dx[i] * l;
                int by = s.y + dy[i] * l;
                change(ax, ay, bx, by);
                if(check(ax, ay, bx, by, s.wall)) {
					const int next_dist = (i & 1) + 1;
                    if(label[ay][ax][next_dist][s.wall] != -1) continue;
                    label[ay][ax][next_dist][s.wall] = nl;
                    que.push(state(ax, ay, next_dist, s.wall));
                }
            }
            break;
        }
        case 1:
        {
            for(int i = 1; i <= 3; i += 2) {
                int ax = s.x;
                int ay = s.y + dy[i];
                int bx = s.x + l - 1;
                int by = ay;
                change(ax, ay, bx, by);
                if(check(ax, ay, bx, by, s.wall)) {
                    if(label[ay][ax][1][s.wall] != -1) continue;
                    label[ay][ax][1][s.wall] = nl;
                    que.push(state(ax, ay, 1, s.wall));
                }
            }
 
            int nx = s.x - 1;
            const int ny = s.y;
            int nwall = s.wall;
            if(check(nx, ny, nx, ny, nwall)) {
                if(board[ny][nx] != '^') {
                    if('A' <= board[ny][nx] && board[ny][nx] <= 'E') {
                        nwall |= (1 << (board[ny][nx] - 'A'));
                    }
                    if (label[ny][nx][0][nwall] == -1) {
                        label[ny][nx][0][nwall] = nl;
                        que.push(state(nx, ny, 0, nwall));
                    }
                }
            }
 
            nx = s.x + l;
            nwall = s.wall;
            if(check(nx, ny, nx, ny, nwall)) {
                if(board[ny][nx] != '^') {
                    if('A' <= board[ny][nx] && board[ny][nx] <= 'E') {
                        nwall |= (1 << (board[ny][nx] - 'A'));
                    }
                    if (label[ny][nx][0][nwall] == -1) {
                        label[ny][nx][0][nwall] = nl;
                        que.push(state(nx, ny, 0, nwall));
                    }
                }
            }
            break;
        }
        case 2:
        {
            for(int i = 0; i <= 2; i += 2) {
                const int ax = s.x + dx[i];
                const int ay = s.y;
                const int bx = ax;
                const int by = s.y + l - 1;

                if(check(ax, ay, bx, by, s.wall)) {
                    if (label[ay][ax][2][s.wall] != -1) continue;
                    label[ay][ax][2][s.wall] = nl;
                    que.push(state(ax, ay, 2, s.wall));
                }
            }
 
            const int nx = s.x;
            int ny = s.y - 1;
            int nwall = s.wall;
            if(check(nx, ny, nx, ny, nwall)) {
                if(board[ny][nx] != '^') {
                    if('A' <= board[ny][nx] && board[ny][nx] <= 'E') {
                        nwall |= (1 << (board[ny][nx] - 'A'));
                    }
                    if (label[ny][nx][0][nwall] == -1) {
                        label[ny][nx][0][nwall] = nl;
                        que.push(state(nx, ny, 0, nwall));
                    }
                }
            }
 
            ny = s.y + l;
            nwall = s.wall;
            if(check(nx, ny, nx, ny, nwall)) {
                if(board[ny][nx] != '^') {
                    if('A' <= board[ny][nx] && board[ny][nx] <= 'E') {
                        nwall |= (1 << (board[ny][nx] - 'A'));
                    }
                    if (label[ny][nx][0][nwall] == -1) {
                        label[ny][nx][0][nwall] = nl;
                        que.push(state(nx, ny, 0, nwall));
                    }
                }
            }
            break;
        }
        }
    }
 
    return -1;
}
 
int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

    cin >> h >> w >> l;

	for(int i = 0; i < h; ++i) {
        cin >> board[i];
	}

	for(int i = 0; i < h; ++i) {
		for(int j = 0; j < w; ++j) {
            if (board[i][j] == 'S') {
				sy = i;
				sx = j;
                board[i][j] = '.';
            } else if (board[i][j] == 'G') {
				gy = i;
				gx = j;
                board[i][j] = '.';
            }
        }
    }
 
    cout << bfs() << endl;
 
    return 0;
}