#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_H = 25;
const int MAX_W = 25;
const int MAX_L = 10;
const int MAX_SB = 1 << 5;

const int INF = 1 << 30;

const int dxs[] = {1, 0, -1, 0};
const int dys[] = {0, 1, 0, -1};

enum { S_U, S_H, S_V };
enum { D_E, D_S, D_W, D_N };

/* typedef */

struct Bar {
  int x, y;
  int st;	// 0: upright, 1: horizontal, 2: vertical

  Bar() {}
  Bar(int _x, int _y) { set(_x, _y, S_U); }
  Bar(int _x, int _y, int _st) { set(_x, _y, _st); }
  void set(int _x, int _y, int _st) { x = _x, y = _y, st = _st; }

  Bar rot(int di, int len) {
    Bar bar;
    switch (st) {
    case S_U:
      switch (di) {
      case D_E: bar.set(x + 1, y, S_H); break;
      case D_S: bar.set(x, y + 1, S_V); break;
      case D_W: bar.set(x - len, y, S_H); break;
      case D_N: bar.set(x, y - len, S_V); break;
      }
      break;
    case S_H:
      switch (di) {
      case D_E: bar.set(x + len, y, S_U); break;
      case D_S: bar.set(x, y + 1, S_H); break;
      case D_W: bar.set(x - 1, y, S_U); break;
      case D_N: bar.set(x, y - 1, S_H); break;
      }
      break;
    case S_V:
      switch (di) {
      case D_E: bar.set(x + 1, y, S_V); break;
      case D_S: bar.set(x, y + len, S_U); break;
      case D_W: bar.set(x - 1, y, S_V); break;
      case D_N: bar.set(x, y - 1, S_U); break;
      }
      break;
    }
    return bar;
  }

  bool inside(int h, int w, int len) {
    int x1 = x, y1 = y;
    if (st == S_H) x1 += len - 1;
    else if (st == S_V) y1 += len - 1;
    return (x >= 0 && x1 < w && y >= 0 && y1 < h);
  }
};

struct Stat {
  int x, y, st, sb;
  Stat() {}
  Stat(int _x, int _y, int _st, int _sb) {
    x = _x, y = _y, st = _st, sb = _sb;
  }
};

/* global variables */

int h, w, l;
string lines[MAX_H];

int dists[MAX_H][MAX_W][3][MAX_SB];

/* subroutines */

/* main */

int main() {
  cin >> h >> w >> l;

  int sx, sy, gx, gy;
  
  for (int y = 0; y < h; y++) {
    cin >> lines[y];
    for (int x = 0; x < w; x++) {
      if (lines[y][x] == 'S')
	sx = x, sy = y, lines[y][x] = '.';
      else if (lines[y][x] == 'G')
	gx = x, gy = y, lines[y][x] = '.';
    }
  }

  for (int y = 0; y < h; y++)
    for (int x = 0; x < w; x++)
      for (int k = 0; k < 3; k++)
	for (int b = 0; b < MAX_SB; b++)
	  dists[y][x][k][b] = INF;

  queue<Stat> q;
  q.push(Stat(sx, sy, S_U, 0));
  dists[sy][sx][S_U][0] = 0;

  int mindist = -1;
  
  while (! q.empty()) {
    Stat u = q.front();
    q.pop();

    int ud = dists[u.y][u.x][u.st][u.sb];
    if (u.x == gx && u.y == gy && u.st == S_U) {
      mindist = ud;
      break;
    }

    Bar ub(u.x, u.y, u.st);
    
    for (int di = 0; di < 4; di++) {
      Bar vb = ub.rot(di, l);
      if (! vb.inside(h, w, l)) continue;

      int vsb = u.sb;
      
      if (vb.st == S_U) {
	char ch = lines[vb.y][vb.x];
	if (ch == '#' || ch == '^') continue;
	if (ch >= 'A' && ch <= 'E')
	  vsb ^= 1 << (ch - 'A');
	else if (ch >= 'a' && ch <= 'e' && ! (vsb & (1 << (ch - 'a'))))
	  continue;
      }
      else {
	int x = vb.x, y = vb.y, dx, dy;
	if (vb.st == S_H) dx = 1, dy = 0;
	else dx = 0, dy = 1;

	bool ok = true;
	for (int i = 0; i < l; i++, x += dx, y += dy) {
	  char ch = lines[y][x];
	  if (ch == '#' ||
	      (ch >= 'a' && ch <= 'e' && ! (vsb & (1 << (ch - 'a'))))) {
	    ok = false;
	    break;
	  }
	}
	if (! ok) continue;
      }

      if (dists[vb.y][vb.x][vb.st][vsb] >= INF) {
	dists[vb.y][vb.x][vb.st][vsb] = ud + 1;
	q.push(Stat(vb.x, vb.y, vb.st, vsb));
      }
    }
  }

  cout << mindist << endl;
  
  return 0;
}

Measured memory_bytes: 1496