#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<queue>
#include<string>
#include<iostream>
#include<set>
using namespace std;
const int N = 52, M = 5;
char mz[N][N];
int n, m, k, dir[4][2] = { 0, 1, 1, 0, 0, -1, -1, 0 };
string f[N*N][M];
const string inf = "{";
struct po{
	int v, k;
	po(){}
	po(int v, int k) :v(v), k(k){}
};
bool inQ[N*N][M];
void spfa(int s,int t){
	for (int i = 0; i < n*m; i++){
		memset(inQ[i], false, sizeof(inQ[i]));
		for (int j = 0; j <= k; j++)
			f[i][j] = inf;
	}
	queue<po>que;
	que.push(po(s, 0));
	for (int i = 0; i < 5; i++){
		inQ[s][i] = true;
		f[s][i] = "";
	}
	while (que.size()){
		po tp = que.front();
		que.pop();
		int u = tp.v, uk = tp.k, ux = u / m, uy = u%m;
		inQ[u][uk] = false;
		for (int i = 0; i < 4; i++){
			int vx = ux + dir[i][0], vy = uy + dir[i][1];
			if (vx >= 0 && vx < n&vy >= 0 && vy < m){
				int v = vx*m + vy;

				for (int j = 0; j <= k; j++){
					string tmp = f[u][uk];
					sort(tmp.begin(), tmp.end());
					int sz = unique(tmp.begin(), tmp.end()) - tmp.begin(), add = 1;
					for (int i = 0; i < sz; i++)
					if (tmp[i] == mz[vx][vy])
						add = 0;
					string ns;
					if (mz[vx][vy] == 'T'){
						add = 0;
						mz[vx][vy] = 0;
					}
					int nk = uk + j + add;
					if (nk <= k&&f[u][uk] + mz[vx][vy] < f[v][nk]){
						if (mz[vx][vy] != 0)
							f[v][nk] = min(f[v][nk], f[u][uk] + mz[vx][vy]);
						else
							f[v][nk] = min(f[v][nk], f[u][uk]);
						if (!inQ[v][nk]){
							inQ[v][nk] = true;
							que.push(po(v, nk));
						}
					}
				}
			}
		}
	}
	if (f[t][k] < inf)
		cout << f[t][k];
	else
		puts("-1");
}
int main(){
	int s, t;
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 0; i < n; i++)
		scanf("%s", mz[i]);
	for (int i = 0; i < n;i++)
	for (int j = 0; j < m;j++)
	if (mz[i][j] == 'S')
		s = i*m + j;
	else if (mz[i][j] == 'T')
		t = i*m + j;
	spfa(s, t);
	return 0;
}


#include<vector>//created by matitesio
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<iostream>
#include<string>
#include<functional>
using namespace std;
typedef long long ll;
using namespace std;
const int N = 52;
char mat[N][N];
int dx[] = { 0, 0, 1, -1 };
int dy[] = { 1, -1, 0, 0 };
ll d(ll x1, ll x2, ll y1, ll y2) {
	return abs(y2 - y1) + abs(x2 - x1);
}
typedef struct po{
	ll dis;
	string r;
	ll mask;
	int v;
	po(){}
	po(ll dis, string r, ll mask, int v) :dis(dis), r(r), mask(mask), v(v){}
	bool operator<(const po&b)const{
		if (dis == b.dis){
			if (r == b.r){
				if (mask == b.mask)
					return v>b.v;
				return mask>b.mask;
			}
			return r>b.r;
		}
		return dis>b.dis;
	}
}node;
//typedef pair<ll, pair<pair<string, ll>, ll> > node;
int bc(ll x){
	int rt = 0;
	while (x){
		rt++;
		x -= x&-x;
	}
	return rt;
}
int main() {
	ll n, m, k, sx, sy, gx, gy;
	scanf("%I64d%I64d%I64d", &n, &m, &k);
	string tmp;
	for (int i = 0; i < n;i++) {
		scanf("%s", mat[i]);
		for (int j = 0; j < m;j++) {
			if (mat[i][j] == 'S') {
				sy = i;
				sx = j;
			}
			else if (mat[i][j] == 'T') {
				gy = i;
				gx = j;
			}
		}
	}
	//typedef pair<ll, pair<pair<string, ll>, ll> > node;
	//priority_queue<node, vector<node>, greater<node> > pq;
	priority_queue<po>pq;
	set<pair<ll, ll> > ss;
	pq.push(po(d(sx, gx, sy, gy), "", 0, sy*m + sx));
	while (!pq.empty()) {
		ll an = pq.top().v;
		ll ay = pq.top().v / m;
		ll ax = pq.top().v%m;
		string astr = pq.top().r;
		ll mask = pq.top().mask;
		pq.pop();
		if (ss.count(make_pair(mask, an)))
			continue;
		ss.insert(make_pair(mask, an));
		for (int i = 0; i < 4;i++) {
			int nx = ax + dx[i];
			int ny = ay + dy[i];
			if (ny < 0 || ny >= n || nx < 0 || nx >= m)
				continue;
			if (ny == gy && nx == gx) {
				cout << astr << endl;
				return 0;
			}
			string nstr = astr + mat[ny][nx];
			ll nmask = mask | (1ll << (mat[ny][nx] - 'a'));
			if (bc(nmask) <= k)
				pq.push(po(d(nx, gx, ny, gy) + nstr.size(), nstr, nmask, ny*m + nx));
		}
	}
	puts("-1");
}


#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<queue>
#include<string>
#include<iostream>
#include<set>
using namespace std;
const int N = 52, M = 5;
char mz[N][N];
int n, m, k, dir[4][2] = { 0, 1, 1, 0, 0, -1, -1, 0 };
struct num{
	string s;
	num(){}
	num(string s) :s(s){}
	bool operator<(const num&b)const{
		if (s.length() == b.s.length())
			return s < b.s;
		return s.length() < b.s.length();
	}
	num operator+(const char&b)const{
		return num(s + b);
	}
}f[N*N][M];
const num inf = num("{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{");
struct po{
	int v, k;
	po(){}
	po(int v, int k) :v(v), k(k){}
};
bool inQ[N*N][M];
void spfa(int s,int t){
	for (int i = 0; i < n*m; i++){
		memset(inQ[i], false, sizeof(inQ[i]));
		for (int j = 0; j <= k; j++)
			f[i][j] = inf;
	}
	queue<po>que;
	que.push(po(s, 0));
	for (int i = 0; i < 5; i++){
		inQ[s][i] = true;
		f[s][i].s = "";
	}
	while (que.size()){
		po tp = que.front();
		que.pop();
		int u = tp.v, uk = tp.k, ux = u / m, uy = u%m;
		inQ[u][uk] = false;
		for (int i = 0; i < 4; i++){
			int vx = ux + dir[i][0], vy = uy + dir[i][1];
			if (vx >= 0 && vx < n&vy >= 0 && vy < m){
				int v = vx*m + vy;

				for (int j = 0; j <= k; j++){
					string tmp = f[u][uk].s;
					sort(tmp.begin(), tmp.end());
					int sz = unique(tmp.begin(), tmp.end()) - tmp.begin(), add = 1;
					for (int i = 0; i < sz; i++)
					if (tmp[i] == mz[vx][vy])
						add = 0;
					string ns;
					if (mz[vx][vy] == 'T'){
						add = 0;
					}
					int nk = uk + j + add;
					if (nk <= k){
						if (mz[vx][vy] != 'T'){
							if (f[u][uk] + mz[vx][vy] < f[v][nk])
								f[v][nk] = f[u][uk] + mz[vx][vy];
							else
								continue;
						}
						else{
							if (f[u][uk] < f[v][nk])
								f[v][nk] = f[u][uk];
							else
								continue;
						}
						if (!inQ[v][nk]){
							inQ[v][nk] = true;
							que.push(po(v, nk));
						}
					}
				}
			}
		}
	}
	if (f[t][k] < inf)
		cout << f[t][k].s;
	else
		puts("-1");
}
int main(){
	int s, t;
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 0; i < n; i++)
		scanf("%s", mz[i]);
	for (int i = 0; i < n;i++)
	for (int j = 0; j < m;j++)
	if (mz[i][j] == 'S')
		s = i*m + j;
	else if (mz[i][j] == 'T')
		t = i*m + j;
	spfa(s, t);
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<queue>
#include<string>
#include<iostream>
#include<set>
using namespace std;
const int N = 52, M = 5;
char mz[N][N];
int n, m, k, dir[4][2] = { 0, 1, 1, 0, 0, -1, -1, 0 };
string f[N*N][M];
const string inf = "{";
struct po{
	int v, k;
	po(){}
	po(int v, int k) :v(v), k(k){}
};
bool inQ[N*N][M];
void spfa(int s,int t){
	for (int i = 0; i < n*m; i++){
		memset(inQ[i], false, sizeof(inQ[i]));
		for (int j = 0; j <= k; j++)
			f[i][j] = inf;
	}
	queue<po>que;
	que.push(po(s, 0));
	for (int i = 0; i < 5; i++){
		inQ[s][i] = true;
		f[s][i] = "";
	}
	while (que.size()){
		po tp = que.front();
		que.pop();
		int u = tp.v, uk = tp.k, ux = u / m, uy = u%m;
		inQ[u][uk] = false;
		for (int i = 0; i < 4; i++){
			int vx = ux + dir[i][0], vy = uy + dir[i][1];
			if (vx >= 0 && vx < n&vy >= 0 && vy < m){
				int v = vx*m + vy;

				for (int j = 0; j <= k; j++){
					string tmp = f[u][uk];
					sort(tmp.begin(), tmp.end());
					int sz = unique(tmp.begin(), tmp.end()) - tmp.begin(), add = 1;
					for (int i = 0; i < sz; i++)
					if (tmp[i] == mz[vx][vy])
						add = 0;
					string ns;
					if (mz[vx][vy] == 'T'){
						add = 0;
					}
					int nk = uk + j + add;
					if (nk <= k&&f[u][uk] + mz[vx][vy] < f[v][nk]){
						if (mz[vx][vy] != 'T')
							f[v][nk] = min(f[v][nk], f[u][uk] + mz[vx][vy]);
						else
							f[v][nk] = min(f[v][nk], f[u][uk]);
						if (!inQ[v][nk]){
							inQ[v][nk] = true;
							que.push(po(v, nk));
						}
					}
				}
			}
		}
	}
	if (f[t][k] < inf)
		cout << f[t][k];
	else
		puts("-1");
}
int main(){
	int s, t;
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 0; i < n; i++)
		scanf("%s", mz[i]);
	for (int i = 0; i < n;i++)
	for (int j = 0; j < m;j++)
	if (mz[i][j] == 'S')
		s = i*m + j;
	else if (mz[i][j] == 'T')
		t = i*m + j;
	spfa(s, t);
	return 0;
}


#include<vector>//created by matitesio
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<iostream>
#include<stdio.h>
#include<string>
#include<functional>
using namespace std;
typedef long long ll;
using namespace std;
const int N = 52;
char mat[N][N];
int dx[] = { 0, 0, 1, -1 };
int dy[] = { 1, -1, 0, 0 };
ll d(ll x1, ll x2, ll y1, ll y2) {
	return abs(y2 - y1) + abs(x2 - x1);
}
typedef struct po{
	ll dis;
	string r;
	ll mask;
	int v;
	po(){}
	po(ll dis, string r, ll mask, int v) :dis(dis), r(r), mask(mask), v(v){}
	bool operator<(const po&b)const{
		if (dis == b.dis){
			if (r == b.r){
				if (mask == b.mask)
					return v>b.v;
				return mask>b.mask;
			}
			return r>b.r;
		}
		return dis>b.dis;
	}
}node;
//typedef pair<ll, pair<pair<string, ll>, ll> > node;
int bc(ll x){
	int rt = 0;
	while (x){
		rt++;
		x -= x&-x;
	}
	return rt;
}
struct flag{
	ll mask;
	int v;
	flag(){}
	flag(ll mask, int v) :mask(mask), v(v){}
	bool operator<(const flag&b)const{
		if (mask == b.mask)
			return v < b.v;
		return mask < b.mask;
	}
};
int main() {
	ll n, m, k, sx, sy, gx, gy;
	scanf("%I64d%I64d%I64d", &n, &m, &k);
	string tmp;
	for (int i = 0; i < n;i++) {
		scanf("%s", mat[i]);
		for (int j = 0; j < m;j++) {
			if (mat[i][j] == 'S') {
				sy = i;
				sx = j;
			}
			else if (mat[i][j] == 'T') {
				gy = i;
				gx = j;
			}
		}
	}
	//typedef pair<ll, pair<pair<string, ll>, ll> > node;
	//priority_queue<node, vector<node>, greater<node> > pq;
	priority_queue<po>pq;
	set<flag>st;
	pq.push(po(d(sx, gx, sy, gy), "", 0, sy*m + sx));
	while (!pq.empty()) {
		ll an = pq.top().v;
		ll ay = pq.top().v / m;
		ll ax = pq.top().v%m;
		string astr = pq.top().r;
		ll mask = pq.top().mask;
		pq.pop();
		if (st.find(flag(mask, an)) != st.end())
			continue;
		st.insert(flag(mask, an));
		for (int i = 0; i < 4;i++) {
			int nx = ax + dx[i];
			int ny = ay + dy[i];
			if (ny < 0 || ny >= n || nx < 0 || nx >= m)
				continue;
			if (ny == gy && nx == gx) {
				cout << astr << endl;
				return 0;
			}
			string nstr = astr + mat[ny][nx];
			ll nmask = mask | (1ll << (mat[ny][nx] - 'a'));
			if (bc(nmask) <= k)
				pq.push(po(d(nx, gx, ny, gy) + nstr.size(), nstr, nmask, ny*m + nx));
		}
	}
	puts("-1");
}


#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<queue>
#include<string>
#include<iostream>
#include<set>
using namespace std;
const int N = 52, M = 5;
char mz[N][N];
int n, m, k, dir[4][2] = { 0, 1, 1, 0, 0, -1, -1, 0 };
struct num{
	string s;
	num(){}
	num(string s) :s(s){}
	bool operator<(const num&b)const{
		if (s.length() == b.s.length())
			return s < b.s;
		return s.length() < b.s.length();
	}
	num operator+(const char&b)const{
		return num(s + b);
	}
}f[N*N][M];
const num inf = num("{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{");
struct po{
	int v, k;
	po(){}
	po(int v, int k) :v(v), k(k){}
};
bool inQ[N*N][M];
void spfa(int s,int t){
	for (int i = 0; i < n*m; i++){
		memset(inQ[i], false, sizeof(inQ[i]));
		for (int j = 0; j <= k; j++)
			f[i][j] = inf;
	}
	queue<po>que;
	que.push(po(s, 0));
	for (int i = 0; i < 5; i++){
		inQ[s][i] = true;
		f[s][i].s = "";
	}
	while (que.size()){
		po tp = que.front();
		que.pop();
		int u = tp.v, uk = tp.k, ux = u / m, uy = u%m;
		inQ[u][uk] = false;
		for (int i = 0; i < 4; i++){
			int vx = ux + dir[i][0], vy = uy + dir[i][1];
			if (vx >= 0 && vx < n&vy >= 0 && vy < m){
				int v = vx*m + vy;

				for (int j = 0; j <= k; j++){
					string tmp = f[u][uk].s;
					sort(tmp.begin(), tmp.end());
					int sz = unique(tmp.begin(), tmp.end()) - tmp.begin(), add = 1;
					for (int i = 0; i < sz; i++)
					if (tmp[i] == mz[vx][vy])
						add = 0;
					string ns;
					if (mz[vx][vy] == 'T'){
						add = 0;
					}
					int nk = uk + j + add;
					if (nk <= k&&f[u][uk] + mz[vx][vy] < f[v][nk]){
						if (mz[vx][vy] != 'T')
							f[v][nk] = min(f[v][nk], f[u][uk] + mz[vx][vy]);
						else
							f[v][nk] = min(f[v][nk], f[u][uk]);
						if (!inQ[v][nk]){
							inQ[v][nk] = true;
							que.push(po(v, nk));
						}
					}
				}
			}
		}
	}
	if (f[t][k] < inf)
		cout << f[t][k].s;
	else
		puts("-1");
}
int main(){
	int s, t;
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 0; i < n; i++)
		scanf("%s", mz[i]);
	for (int i = 0; i < n;i++)
	for (int j = 0; j < m;j++)
	if (mz[i][j] == 'S')
		s = i*m + j;
	else if (mz[i][j] == 'T')
		t = i*m + j;
	spfa(s, t);
	return 0;
}


#include <iomanip>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <map>
#include <set>
#include <string>
#include <cmath>

#define fr(i,N) for (i = 0; i <(int)(N); i++)
#define SZ(u) ((int)(u).size())
#define pb push_back
#define MP make_pair
#define F first
#define S second
#define Eps 1e-9

using namespace std;

typedef pair<int, int> p2;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef long long ll;

int R, C, K, Tail;
int Board[60][60], Road[60][60], Best[60][60], Oki[60][60];
int Allow[100000][5];
int Last[60][60];
char Now[5];

int Res;
int Check[30];
char Ans[10000];
int QR[10000], QC[10000];

void pre_process(char now, int left) {
  if (now > 'z') {
    if (left == 0) {
      int i;
      fr (i, K) Allow[Tail][i] = (int)(Now[i] - 'a');
      Tail++;
    }
    return;
  }

  pre_process(now + 1, left);
  if (left > 0) {
    Now[left-1] = now;
    pre_process(now+1, left-1);
  }
}

bool isValid(int r, int c) {
  return 0 <= r && r < R && 0 <= c && c < C && Road[r][c];
}

int main() {
  int i, j, k, r, c;
  int sr, sc, er, ec;
  char a;
  int dr[4] = {-1, 0, 1, 0};
  int dc[4] = {0, 1, 0, -1};
  int tt, et;
  scanf("%d%d%d", &R, &C, &K);
  fr (i, R) {
    fr (j, C) {
      scanf("%c", &a);
      /*if (i == 0 && j == 0) a = 'S';
      else if (i == R-1 && j == C-1) a = 'T';
      else a = rand()%5 + 'a';
      */if (!('a' <= a && a <= 'z') && a != 'S' && a != 'T') {
        j--;
        continue;
      }

      if ('a' <= a && a <= 'z') Board[i][j] = a - 'a';
      else if (a == 'S') Board[i][j] = -1, sr = i, sc = j;
      else Board[i][j] = -2, er = i, ec = j;
    }
  }

  Tail = 0;
  pre_process('a', K);

  Res = -1;
  fr (i, Tail) {
    fr (j, 26) Check[j] = 0;
    fr (j, K) Check[Allow[i][j]] = 1;
    fr (r, R) fr (c, C) {
      if (Board[r][c] >= 0) Road[r][c] = Check[Board[r][c]];
      else Road[r][c] = 1;
      Best[r][c] = -1;
      Oki[r][c] = 0;
      Last[r][c] = 0;
    }

    tt = 1;
    QR[0] = sr, QC[0] = sc;
    Best[sr][sc] = 0;
    fr (j, tt) {
      r = QR[j], c = QC[j];
      fr (k, 4) if (isValid(r+dr[k], c+dc[k]) && Best[r+dr[k]][c+dc[k]] == -1) {
        Best[r+dr[k]][c+dc[k]] = Best[r][c] + 1;
        QR[tt] = r+dr[k], QC[tt] = c+dc[k];
        tt++;
      }
    }

    if (Best[er][ec] == -1 || (Res != -1 && Best[er][ec] > Res)) continue;

    bool update = false;
    if (Res == -1 || Best[er][ec] < Res) update = true;
    Res = Best[er][ec];
    Ans[Res-1] = Ans[Res] = 0;

    tt = 1;
    QR[0] = er, QC[0] = ec;
    Oki[er][ec] = 1;
    fr (j, tt) {
      r = QR[j], c = QC[j];
      fr (k, 4) if (isValid(r+dr[k], c+dc[k])
        && Best[r+dr[k]][c+dc[k]] == Best[r][c] - 1 && !Oki[r+dr[k]][c+dc[k]]) {
        Oki[r+dr[k]][c+dc[k]] = 1;
        QR[tt] = r+dr[k], QC[tt] = c+dc[k];
        tt++;
      }
    }

    int cur = 0, tt = 1, move = 0;
    QR[0] = sr, QC[0] = sc;
    Best[sr][sc] = 0;
    while (cur < Res-1) {
      et = tt;
      int best = -1;
      for (j = move; j < et; j++) {
        r = QR[j], c = QC[j];
        fr (k, 4) if (isValid(r+dr[k], c+dc[k]) && Oki[r+dr[k]][c+dc[k]]
          && Best[r+dr[k]][c+dc[k]] == cur+1) {
          if (best == -1 || best > Board[r+dr[k]][c+dc[k]]) {
            best = Board[r+dr[k]][c+dc[k]];
          }
        }
      }

      if (!update && (char)(best + 'a') > Ans[cur]) break;
      if (!update && (char)(best + 'a') < Ans[cur]) update = true;
      Ans[cur] = (char)(best + 'a');
      cur++;

      for (j = move; j < et; j++) {
        r = QR[j], c = QC[j];
        fr (k, 4) if (isValid(r+dr[k], c+dc[k]) && Oki[r+dr[k]][c+dc[k]]
          && Best[r+dr[k]][c+dc[k]] == cur && !Last[r+dr[k]][c+dc[k]]) {
          if (best == Board[r+dr[k]][c+dc[k]]) {
            Last[r+dr[k]][c+dc[k]] = 1;
            QR[tt] = r+dr[k], QC[tt] = c+dc[k];
            tt++;
          }
        }
      }

      move = et;
    }
  }

  if (Res == -1) printf("%d\n", Res);
  else printf("%s\n", Ans);

  return 0;
}


#include <iomanip>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <map>
#include <set>
#include <string>
#include <cmath>

#define fr(i,N) for (i = 0; i <(int)(N); i++)
#define SZ(u) ((int)(u).size())
#define pb push_back
#define MP make_pair
#define F first
#define S second
#define Eps 1e-9

using namespace std;

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef long long ll;
typedef pair<ll, ll> p2;
typedef pair<p2, ll> p3;

int N, M, Ans[100000];
vector<p3> Target;
vector<p3> Shoot;

bool check(int tdx, int sdx) {
  return ((Target[tdx].F.F-Shoot[sdx].F.F)*(Target[tdx].F.F-Shoot[sdx].F.F) +
    Shoot[sdx].F.S*Shoot[sdx].F.S) <= Target[tdx].F.S*Target[tdx].F.S;
}

void update(int tdx, int sdx) {
  if (Ans[tdx] == -1 || Ans[tdx] > sdx) Ans[tdx] = sdx;
}

int main() {
  int i, a, b;
  scanf("%d", &N);
  fr (i, N) {
    scanf("%d%d", &a, &b);
    Target.pb(MP(MP(a,b),i));
  }
  scanf("%d", &M);
  fr (i, M) {
    scanf("%d%d", &a, &b);
    Shoot.pb(MP(MP(a,b), i));
  }

  sort(Target.begin(), Target.end());
  sort(Shoot.begin(), Shoot.end());

  int start = 0;
  memset(Ans, 255, sizeof(Ans));

  fr (i, M) {
    while (start < N && Target[start].F.F + Target[start].F.S < Shoot[i].F.F) start++;
    if (start < N && check(start, i)) update(Target[start].S, Shoot[i].S);
    if (start + 1 < N && check(start+1, i)) update(Target[start+1].S, Shoot[i].S);
  }

  int res = 0;
  fr (i, N) res += (Ans[i] != -1 ? 1 : 0);

  printf("%d\n", res);
  fr (i, N) {
    if (i != 0) printf(" ");
    printf("%d", (Ans[i] == -1) ? -1 : (Ans[i]+1));
  }

  printf("\n");
  return 0;
}


#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

typedef pair <int, int> ii;

const int Inf = 1000000000;
const int Maxn = 50;
const int Maxl = 26;
const int Maxd = 4;
const int dy[Maxd] = {1, 0, -1, 0};
const int dx[Maxd] = {0, 1, 0, -1};

int n, m, k;
char B[Maxn][Maxn];
int sx, sy, ex, ey;
int has[Maxl];
int dist[Maxn][Maxn];
ii p[Maxn][Maxn];
string s, res;
bool sol;

void BFS()
{
    fill((int*)dist, (int*)dist + Maxn * Maxn, Inf);
    ii v = make_pair(ex, ey); dist[v.first][v.second] = 0;
    vector <ii> seq, buck[Maxl];
    seq.push_back(v);
    for (int i = 0; !seq.empty(); i++) {
        for (int j = 0; j < seq.size(); j++) {
            v = seq[j];
            for (int d = 0; d < Maxd; d++) {
                int ni = v.first + dy[d], nj = v.second + dx[d];
                if (0 <= ni && ni < n && 0 <= nj && nj < m &&
                    i + 1 < dist[ni][nj] && (B[ni][nj] == 'S' || has[B[ni][nj] - 'a'])) {
                        dist[ni][nj] = i + 1;
                        p[ni][nj] = make_pair(v.first, v.second);
                        if (B[ni][nj] == 'S') return;
                        else buck[B[ni][nj] - 'a'].push_back(make_pair(ni, nj));
                    }
            }
        }
        seq.clear();
        for (int j = 0; j < Maxl; j++) {
            for (int l = 0; l < buck[j].size(); l++) seq.push_back(buck[j][l]);
            buck[j].clear();
        }
    }
}

void getPath(string &s)
{
    s = "";
    ii v = p[sx][sy];
    while (v.first != ex || v.second != ey) {
        s += B[v.first][v.second];
        v = p[v.first][v.second];
    }
}

void Search(int v, int from)
{
    if (v == k) {
        BFS();
        if (dist[sx][sy] == Inf) return;
        getPath(s);
        if (!sol || s.length() < res.length() || s.length() == res.length() && s < res) res = s;
        sol = true;
    } else for (int i = from; i < Maxl; i++) {
                has[i] = true;
                Search(v + 1, i + 1);
                has[i] = false;
           }
}

int main()
{
    scanf("%d %d %d", &n, &m, &k);
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++) {
            scanf(" %c", &B[i][j]);
            if (B[i][j] == 'S') { sx = i; sy = j; }
            else if (B[i][j] == 'T') { ex = i; ey = j; B[i][j] = 'a'; }
        }
    Search(0, 0);
    if (!sol) printf("-1\n");
    else printf("%s\n", res.c_str());
    return 0;
}


#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

typedef pair <int, int> ii;

const int Inf = 1000000000;
const int Maxn = 50;
const int Maxl = 26;
const int Maxd = 4;
const int dy[Maxd] = {1, 0, -1, 0};
const int dx[Maxd] = {0, 1, 0, -1};

int n, m, k;
char B[Maxn][Maxn];
int sx, sy, ex, ey;
int has[Maxl];
int dist[Maxn][Maxn];
ii p[Maxn][Maxn];
vector <ii> seq, buck[Maxl];
string s, res;
bool sol;

void BFS()
{
    fill((int*)dist, (int*)dist + Maxn * Maxn, Inf);
    ii v = make_pair(ex, ey); dist[v.first][v.second] = 0;
    seq.clear(); seq.push_back(v);
    for (int i = 0; !seq.empty(); i++) {
        for (int j = 0; j < seq.size(); j++) {
            v = seq[j];
            for (int d = 0; d < Maxd; d++) {
                int ni = v.first + dy[d], nj = v.second + dx[d];
                if (0 <= ni && ni < n && 0 <= nj && nj < m &&
                    i + 1 < dist[ni][nj] && (B[ni][nj] == 'S' || has[B[ni][nj] - 'a'])) {
                        dist[ni][nj] = i + 1;
                        p[ni][nj] = make_pair(v.first, v.second);
                        if (B[ni][nj] == 'S') return;
                        else buck[B[ni][nj] - 'a'].push_back(make_pair(ni, nj));
                    }
            }
        }
        seq.clear();
        for (int j = 0; j < Maxl; j++) {
            for (int l = 0; l < buck[j].size(); l++) seq.push_back(buck[j][l]);
            buck[j].clear();
        }
    }
}

void getPath(string &s)
{
    s = "";
    ii v = p[sx][sy];
    while (v.first != ex || v.second != ey) {
        s += B[v.first][v.second];
        v = p[v.first][v.second];
    }
}

void Search(int v, int from)
{
    if (v == k) {
        BFS();
        if (dist[sx][sy] == Inf) return;
        sol = true;
        getPath(s);
        if (res == "" || s < res) res = s;
    } else for (int i = from; i < Maxl; i++) {
                has[i] = true;
                Search(v + 1, i + 1);
                has[i] = false;
           }
}

int main()
{
    scanf("%d %d %d", &n, &m, &k);
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++) {
            scanf(" %c", &B[i][j]);
            if (B[i][j] == 'S') { sx = i; sy = j; }
            else if (B[i][j] == 'T') { ex = i; ey = j; B[i][j] = 'a'; }
        }
    Search(0, 0);
    if (!sol) printf("-1\n");
    else printf("%s\n", res.c_str());
    return 0;
}


#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

typedef pair <int, int> ii;

const int Inf = 1000000000;
const int Maxn = 50;
const int Maxl = 26;
const int Maxd = 4;
const int dy[Maxd] = {1, 0, -1, 0};
const int dx[Maxd] = {0, 1, 0, -1};

int n, m, k;
char B[Maxn][Maxn];
int sx, sy, ex, ey;
int has[Maxl];
int dist[Maxn][Maxn];
ii p[Maxn][Maxn];
vector <ii> seq, buck[Maxl];
string s, res;
bool sol;

void BFS()
{
    fill((int*)dist, (int*)dist + Maxn * Maxn, Inf);
    ii v = make_pair(ex, ey); dist[v.first][v.second] = 0;
    seq.clear(); seq.push_back(v);
    for (int i = 0; !seq.empty(); i++) {
        for (int j = 0; j < seq.size(); j++) {
            v = seq[j];
            for (int d = 0; d < Maxd; d++) {
                int ni = v.first + dy[d], nj = v.second + dx[d];
                if (0 <= ni && ni < n && 0 <= nj && nj < m &&
                    i + 1 < dist[ni][nj] && (B[ni][nj] == 'S' || has[B[ni][nj] - 'a'])) {
                        dist[ni][nj] = i + 1;
                        p[ni][nj] = make_pair(v.first, v.second);
                        if (B[ni][nj] == 'S') return;
                        else buck[B[ni][nj] - 'a'].push_back(make_pair(ni, nj));
                    }
            }
        }
        seq.clear();
        for (int j = 0; j < Maxl; j++) {
            for (int l = 0; l < buck[j].size(); l++) seq.push_back(buck[j][l]);
            buck[j].clear();
        }
    }
}

void getPath(string &s)
{
    s = "";
    ii v = p[sx][sy];
    while (v.first != ex || v.second != ey) {
        s += B[v.first][v.second];
        v = p[v.first][v.second];
    }
}

void Search(int v, int from)
{
    if (v == k) {
        BFS();
        if (dist[sx][sy] == Inf) return;
        getPath(s);
        if (!sol || s.length() < res.length() || s.length() == res.length() && s < res) res = s;
        sol = true;
    } else for (int i = from; i < Maxl; i++) {
                has[i] = true;
                Search(v + 1, i + 1);
                has[i] = false;
           }
}

int main()
{
    scanf("%d %d %d", &n, &m, &k);
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++) {
            scanf(" %c", &B[i][j]);
            if (B[i][j] == 'S') { sx = i; sy = j; }
            else if (B[i][j] == 'T') { ex = i; ey = j; B[i][j] = 'a'; }
        }
    Search(0, 0);
    if (!sol) printf("-1\n");
    else printf("%s\n", res.c_str());
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <ctime>
#include <cassert>
#include <queue>
using namespace std;

#define f first
#define s second
#define mp make_pair
#define pb push_back
#define forit(it,con) for (typeof(con.begin()) it = con.begin(); it != con.end(); ++it)
#define f0(a) memset(a, 0, sizeof(a))
#define all(v) v.begin(), v.end()
#define pii pair<int,int>
#define vi vector<int>

#ifdef WIN32
	#define I64 "%I64d"
#else
	#define I64 "%lld"
#endif
const int di[4] = {0,0,1,-1};
const int dj[4] = {1,-1,0,0};

char let[30000], a[55][55];
int letsz, can[300], n, m, ansdist;
string ansS;

int dist[55][55];
pii q[1000000];

void Solve() {
	//8cerr << can['y'];
	int head = 0, tail = 0;

	memset(dist, -1, sizeof(dist));

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < m; ++j)
			if (a[i][j] == 'T') {
				q[tail++] = mp(i,j);
				dist[i][j] = 0;
				break;
			}

	while (head != tail) {

		int i = q[head].f, j = q[head].s;
		head++;

		if (a[i][j] == 'S') {
			if (dist[i][j] > ansdist)
				return;
		    int si = i, sj = j;
			string s = "";

			vector<pair<int,int > > ver, tvec;
			ver.pb(mp(i,j));

			for (int it = 0; it < dist[si][sj] - 1; ++it) {

				char minch = 'z' + 1;

				forit (it, ver) {
					int i = it -> f;
					int j = it -> s;

            		for (int k = 0; k < 4; ++k) {
            			int ii = i + di[k];
            			int jj = j + dj[k];
            			if (0 <= ii && ii < n && 0 <= jj && jj < m && dist[i][j] == dist[ii][jj] + 1)
            				minch = min(minch, a[ii][jj]);
            		}
            	}
            	s += minch;
            	tvec.clear();

				forit (it, ver) {
					int i = it -> f;
					int j = it -> s;

            		for (int k = 0; k < 4; ++k) {
            			int ii = i + di[k];
            			int jj = j + dj[k];
            			if (0 <= ii && ii < n && 0 <= jj && jj < m && dist[i][j] == dist[ii][jj] + 1 && a[ii][jj] == minch)
            				tvec.pb(mp(ii,jj));

            		}
            	}

            	sort(all(tvec));
            	tvec.resize(unique(all(tvec)) - tvec.begin());
            	ver = tvec;

			}
			i = si; j = sj;

			if (dist[i][j] < ansdist || (dist[i][j] == ansdist && ansS > s)) {
				ansdist = dist[i][j];
				ansS = s;
			}

			return;
		}

		for (int k = 0; k < 4; ++k) {
			int ii = i + di[k];
			int jj = j + dj[k];

			if (!(0 <= ii && ii < n && 0 <= jj && jj < m) || !can[a[ii][jj]])
				continue;

			if (dist[ii][jj] == -1) {
				q[tail++] = mp(ii,jj);
				dist[ii][jj] = dist[i][j] + 1;
			}
		}
	}
}

void gen(int k,int cur) {
	if (!k) {
		Solve();
		return;
	}

	for (int i = cur; i < letsz; ++i) {
		can[let[i]] = true;
			gen(k - 1, i + 1);
		can[let[i]] = false;
	}
	gen(k - 1, cur);
}

int main() {
	#ifdef LOCAL
		freopen("in" , "r", stdin);
		freopen("out", "w", stdout);
	#endif
	int k;
	scanf("%d%d%d\n", &n, &m, &k);
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j)  {
			scanf("%c", &a[i][j]);
			if (a[i][j] != 'S' && a[i][j] != 'T')
				let[letsz++] = a[i][j];
		}

		scanf("\n");
	}

	can['S'] = can['T'] = true;

	sort(let, let + letsz);

	letsz = unique(let, let + letsz) - let;

	ansdist = (1<<30);

	let[letsz] = 1;
	gen(k, 0);

	if (ansdist == (1<<30))
		cout << -1;
	else
		cout << ansS<<endl;
	return 0;

}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <ctime>
#include <cassert>
#include <queue>
using namespace std;

#define f first
#define s second
#define mp make_pair
#define pb push_back
#define forit(it,con) for (typeof(con.begin()) it = con.begin(); it != con.end(); ++it)
#define f0(a) memset(a, 0, sizeof(a))
#define all(v) v.begin(), v.end()
#define pii pair<int,int>
#define vi vector<int>

#ifdef WIN32
	#define I64 "%I64d"
#else
	#define I64 "%lld"
#endif
const int di[4] = {0,0,1,-1};
const int dj[4] = {1,-1,0,0};

char let[30], a[55][55];
int letsz, can[300], n, m, ansdist;
string ansS;

int dist[55][55];
pii q[100000];

void Solve() {
	cerr << can['y'];
	int head = 0, tail = 0;

	memset(dist, -1, sizeof(dist));

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < m; ++j)
			if (a[i][j] == 'T') {
				q[tail++] = mp(i,j);
				dist[i][j] = 0;
				break;
			}

	while (head != tail) {

		int i = q[head].f, j = q[head].s;
		head++;

		if (a[i][j] == 'S') {
			if (dist[i][j] > ansdist)
				return;
		    int si = i, sj = j;
			string s = "";

			while (a[i][j] != 'T') {
				int curi = -1, curj;
				for (int k = 0; k < 4; ++k) {
					int ii = i + di[k];
					int jj = j + dj[k];

					if (0 <= ii && ii < n && 0 <= jj && jj < m && dist[ii][jj] + 1 == dist[i][j]) {

						if (curi == -1 || a[ii][jj] < a[curi][curj])
							curi = ii, curj = jj;
					}
				}

				i = curi; j = curj;
				if (a[i][j] != 'T')
					s += a[i][j];

			}
			i = si; j = sj;

			if (dist[i][j] < ansdist || (dist[i][j] == ansdist && ansS > s)) {
				ansdist = dist[i][j];
				ansS = s;
			}

			return;
		}

		for (int k = 0; k < 4; ++k) {
			int ii = i + di[k];
			int jj = j + dj[k];

			if (!(0 <= ii && ii < n && 0 <= jj && jj < m) || !can[a[ii][jj]])
				continue;

			if (dist[ii][jj] == -1) {
				q[tail++] = mp(ii,jj);
				dist[ii][jj] = dist[i][j] + 1;
			}
		}
	}
}

void gen(int k,int cur) {
	if (!k) {
		Solve();
		return;
	}

	for (int i = cur; i < letsz; ++i) {
		can[let[i]] = true;
			gen(k - 1, i + 1);
		can[let[i]] = false;
	}
	gen(k - 1, cur);
}

int main() {
	#ifdef LOCAL
		freopen("in" , "r", stdin);
		freopen("out", "w", stdout);
	#endif
	int k;
	scanf("%d%d%d\n", &n, &m, &k);
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j)  {
			scanf("%c", &a[i][j]);
			if (a[i][j] != 'S' && a[i][j] != 'T')
				let[letsz++] = a[i][j];
		}

		scanf("\n");
	}

	can['S'] = can['T'] = true;

	sort(let, let + letsz);

	letsz = unique(let, let + letsz) - let;

	ansdist = (1<<30);

	let[letsz] = 1;
	gen(k, 0);

	if (ansdist == (1<<30))
		cout << -1;
	else
		cout << ansS<<endl;
	return 0;

}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <ctime>
#include <cassert>
#include <queue>
using namespace std;

#define f first
#define s second
#define mp make_pair
#define pb push_back
#define forit(it,con) for (typeof(con.begin()) it = con.begin(); it != con.end(); ++it)
#define f0(a) memset(a, 0, sizeof(a))
#define all(v) v.begin(), v.end()
#define pii pair<int,int>
#define vi vector<int>

#ifdef WIN32
	#define I64 "%I64d"
#else
	#define I64 "%lld"
#endif
const int di[4] = {0,0,1,-1};
const int dj[4] = {1,-1,0,0};

char let[3000], a[55][55];
int letsz, can[300], n, m, ansdist;
string ansS;

int dist[55][55];
pii q[100000];

void Solve() {
	cerr << can['y'];
	int head = 0, tail = 0;

	memset(dist, -1, sizeof(dist));

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < m; ++j)
			if (a[i][j] == 'T') {
				q[tail++] = mp(i,j);
				dist[i][j] = 0;
				break;
			}

	while (head != tail) {

		int i = q[head].f, j = q[head].s;
		head++;

		if (a[i][j] == 'S') {
			if (dist[i][j] > ansdist)
				return;
		    int si = i, sj = j;
			string s = "";

			while (a[i][j] != 'T') {
				int curi = -1, curj;
				for (int k = 0; k < 4; ++k) {
					int ii = i + di[k];
					int jj = j + dj[k];

					if (0 <= ii && ii < n && 0 <= jj && jj < m && dist[ii][jj] + 1 == dist[i][j]) {

						if (curi == -1 || a[ii][jj] < a[curi][curj])
							curi = ii, curj = jj;
					}
				}

				i = curi; j = curj;
				if (a[i][j] != 'T')
					s += a[i][j];

			}
			i = si; j = sj;

			if (dist[i][j] < ansdist || (dist[i][j] == ansdist && ansS > s)) {
				ansdist = dist[i][j];
				ansS = s;
			}

			return;
		}

		for (int k = 0; k < 4; ++k) {
			int ii = i + di[k];
			int jj = j + dj[k];

			if (!(0 <= ii && ii < n && 0 <= jj && jj < m) || !can[a[ii][jj]])
				continue;

			if (dist[ii][jj] == -1) {
				q[tail++] = mp(ii,jj);
				dist[ii][jj] = dist[i][j] + 1;
			}
		}
	}
}

void gen(int k,int cur) {
	if (!k) {
		Solve();
		return;
	}

	for (int i = cur; i < letsz; ++i) {
		can[let[i]] = true;
			gen(k - 1, i + 1);
		can[let[i]] = false;
	}
	gen(k - 1, cur);
}

int main() {
	#ifdef LOCAL
		freopen("in" , "r", stdin);
		freopen("out", "w", stdout);
	#endif
	int k;
	scanf("%d%d%d\n", &n, &m, &k);
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j)  {
			scanf("%c", &a[i][j]);
			if (a[i][j] != 'S' && a[i][j] != 'T')
				let[letsz++] = a[i][j];
		}

		scanf("\n");
	}

	can['S'] = can['T'] = true;

	sort(let, let + letsz);

	letsz = unique(let, let + letsz) - let;

	ansdist = (1<<30);

	let[letsz] = 1;
	gen(k, 0);

	if (ansdist == (1<<30))
		cout << -1;
	else
		cout << ansS<<endl;
	return 0;

}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <ctime>
#include <cassert>
#include <queue>
using namespace std;

#define f first
#define s second
#define mp make_pair
#define pb push_back
#define forit(it,con) for (typeof(con.begin()) it = con.begin(); it != con.end(); ++it)
#define f0(a) memset(a, 0, sizeof(a))
#define all(v) v.begin(), v.end()
#define pii pair<int,int>
#define vi vector<int>

#ifdef WIN32
	#define I64 "%I64d"
#else
	#define I64 "%lld"
#endif
const int di[4] = {0,0,1,-1};
const int dj[4] = {1,-1,0,0};

char let[30], a[55][55];
int letsz, can[300], n, m, ansdist;
string ansS;

int dist[55][55];
pii q[10000];

void Solve() {
	cerr << can['y'];
	int head = 0, tail = 0;

	memset(dist, -1, sizeof(dist));

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < m; ++j)
			if (a[i][j] == 'T') {
				q[tail++] = mp(i,j);
				dist[i][j] = 0;
				break;
			}

	while (head != tail) {

		int i = q[head].f, j = q[head].s;
		head++;

		if (a[i][j] == 'S') {
			if (dist[i][j] > ansdist)
				return;
		    int si = i, sj = j;
			string s = "";

			while (a[i][j] != 'T') {
				int curi = -1, curj;
				for (int k = 0; k < 4; ++k) {
					int ii = i + di[k];
					int jj = j + dj[k];

					if (0 <= ii && ii < n && 0 <= jj && jj < m && dist[ii][jj] + 1 == dist[i][j]) {

						if (curi == -1 || a[ii][jj] < a[curi][curj])
							curi = ii, curj = jj;
					}
				}

				i = curi; j = curj;
				if (a[i][j] != 'T')
					s += a[i][j];

			}
			i = si; j = sj;

			if (dist[i][j] < ansdist || (dist[i][j] == ansdist && ansS > s)) {
				ansdist = dist[i][j];
				ansS = s;
			}

			return;
		}

		for (int k = 0; k < 4; ++k) {
			int ii = i + di[k];
			int jj = j + dj[k];

			if (!(0 <= ii && ii < n && 0 <= jj && jj < m) || !can[a[ii][jj]])
				continue;

			if (dist[ii][jj] == -1) {
				q[tail++] = mp(ii,jj);
				dist[ii][jj] = dist[i][j] + 1;
			}
		}
	}
}

void gen(int k,int cur) {
	if (!k) {
		Solve();
		return;
	}

	for (int i = cur; i < letsz; ++i) {
		can[let[i]] = true;
			gen(k - 1, i + 1);
		can[let[i]] = false;
	}
	gen(k - 1, cur);
}

int main() {
	#ifdef LOCAL
		freopen("in" , "r", stdin);
		freopen("out", "w", stdout);
	#endif
	int k;
	scanf("%d%d%d\n", &n, &m, &k);
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j)  {
			scanf("%c", &a[i][j]);
			if (a[i][j] != 'S' && a[i][j] != 'T')
				let[letsz++] = a[i][j];
		}

		scanf("\n");
	}

	can['S'] = can['T'] = true;

	sort(let, let + letsz);

	letsz = unique(let, let + letsz) - let;

	ansdist = (1<<30);

	let[letsz] = 1;
	gen(k, 0);

	if (ansdist == (1<<30))
		cout << -1;
	else
		cout << ansS<<endl;
	return 0;

}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <ctime>
#include <cassert>
#include <queue>
using namespace std;

#define f first
#define s second
#define mp make_pair
#define pb push_back
#define forit(it,con) for (typeof(con.begin()) it = con.begin(); it != con.end(); ++it)
#define f0(a) memset(a, 0, sizeof(a))
#define all(v) v.begin(), v.end()
#define pii pair<int,int>
#define vi vector<int>

#ifdef WIN32
	#define I64 "%I64d"
#else
	#define I64 "%lld"
#endif
const int di[4] = {0,0,1,-1};
const int dj[4] = {1,-1,0,0};

char let[30000], a[55][55];
int letsz, can[300], n, m, ansdist;
string ansS;

int dist[55][55];
pii q[1000000];

void Solve() {
	cerr << can['y'];
	int head = 0, tail = 0;

	memset(dist, -1, sizeof(dist));

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < m; ++j)
			if (a[i][j] == 'T') {
				q[tail++] = mp(i,j);
				dist[i][j] = 0;
				break;
			}

	while (head != tail) {

		int i = q[head].f, j = q[head].s;
		head++;

		if (a[i][j] == 'S') {
			if (dist[i][j] > ansdist)
				return;
		    int si = i, sj = j;
			string s = "";

			while (a[i][j] != 'T') {
				int curi = -1, curj;
				for (int k = 0; k < 4; ++k) {
					int ii = i + di[k];
					int jj = j + dj[k];

					if (0 <= ii && ii < n && 0 <= jj && jj < m && dist[ii][jj] + 1 == dist[i][j]) {

						if (curi == -1 || a[ii][jj] < a[curi][curj])
							curi = ii, curj = jj;
					}
				}

				i = curi; j = curj;
				if (a[i][j] != 'T')
					s += a[i][j];

			}
			i = si; j = sj;

			if (dist[i][j] < ansdist || (dist[i][j] == ansdist && ansS > s)) {
				ansdist = dist[i][j];
				ansS = s;
			}

			return;
		}

		for (int k = 0; k < 4; ++k) {
			int ii = i + di[k];
			int jj = j + dj[k];

			if (!(0 <= ii && ii < n && 0 <= jj && jj < m) || !can[a[ii][jj]])
				continue;

			if (dist[ii][jj] == -1) {
				q[tail++] = mp(ii,jj);
				dist[ii][jj] = dist[i][j] + 1;
			}
		}
	}
}

void gen(int k,int cur) {
	if (!k) {
		Solve();
		return;
	}

	for (int i = cur; i < letsz; ++i) {
		can[let[i]] = true;
			gen(k - 1, i + 1);
		can[let[i]] = false;
	}
	gen(k - 1, cur);
}

int main() {
	#ifdef LOCAL
		freopen("in" , "r", stdin);
		freopen("out", "w", stdout);
	#endif
	int k;
	scanf("%d%d%d\n", &n, &m, &k);
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j)  {
			scanf("%c", &a[i][j]);
			if (a[i][j] != 'S' && a[i][j] != 'T')
				let[letsz++] = a[i][j];
		}

		scanf("\n");
	}

	can['S'] = can['T'] = true;

	sort(let, let + letsz);

	letsz = unique(let, let + letsz) - let;

	ansdist = (1<<30);

	let[letsz] = 1;
	gen(k, 0);

	if (ansdist == (1<<30))
		cout << -1;
	else
		cout << ansS<<endl;
	return 0;

}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <queue>
#include <set>
#include <map>
#include <cmath>
using namespace std;

typedef long long llint;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;

#define pii pair< int, int >
#define piiLL pair< llint, llint >
#define mp make_pair
#define pb push_back
#define lu lower_bound
#define uu upper_bound
#define all( a ) ( a ).begin( ), ( a ).end( )
#define GC getchar( )
#define x first
#define y second

const int N = 55;

int n;
int m;
int k;
char M[ N ][ N ];
int dist[ N ][ N ];
bool reco[ N ][ N ];
bool in[ N ][ N ];

string SOL;
int FF;

bool bio[ 26 ];
int raz[ N ];

int px, py;
int ex, ey;
bool AA;

inline void load( ) {
    FF = ( 1 << 30 );
    scanf( "%d %d %d", &n, &m, &k );
    for( int i = 0; i < n; i++ ) scanf( "%s", M[ i ] );
    for( int i = 0; i < n; i++ ) {
        for( int j = 0; j < m; j++ ) {
            if( M[ i ][ j ] == 'S' ) px = i, py = j;
            if( M[ i ][ j ] == 'T' ) ex = i, ey = j;
        }
    }
}

queue< pii > Q;

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

inline bool bfs( ) {
    memset( dist, -1, sizeof( dist ) );
    memset( in, 0, sizeof( in ) );
    while( !Q.empty( ) ) Q.pop( );
    dist[ px ][ py ] = 0;
    Q.push( mp( px, py ) );
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        Q.pop( );
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || dist[ X ][ Y ] != -1 ) continue;
            if( M[ X ][ Y ] != 'T' && !bio[ M[ X ][ Y ] - 'a' ] ) continue;
            dist[ X ][ Y ] = dist[ x ][ y ] + 1;
            Q.push( mp( X, Y ) );
        }
    }
    int curr = dist[ ex ][ ey ];
    if( curr == -1 ) return false;
    memset( reco, 0, sizeof( reco ) );
    Q.push( mp( ex, ey ) );
    reco[ ex ][ ey ] = 0;
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        Q.pop( );
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || dist[ x ][ y ] != dist[ X ][ Y ] + 1 ) continue;
            if( reco[ X ][ Y ] ) continue;
            reco[ X ][ Y ] = 1;
            Q.push( mp( X, Y ) );
        }
    }
    Q.push( mp( px, py ) );
    in[ px ][ py ] = 1;
    string tmp = "";
    memset( raz, 0, sizeof( raz ) );
    while( !Q.empty( ) ) {

        int x = Q.front( ).first;
        int y = Q.front( ).second;
        if( x == ex && y == ey ) break;
        Q.pop( );
        int mini = ( 1 << 30 );
        bool ok = false;
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || !reco[ X ][ Y ] || in[ X ][ Y ] ) continue;
            if( dist[ x ][ y ] + 1 != dist[ X ][ Y ] ) continue;
            if( mini == ( 1 << 30 ) || M[ X ][ Y ] < mini ) mini = M[ X ][ Y ];
        }
        if( mini != ( 1 << 30 ) && !raz[ dist[ x ][ y ] ]  ) tmp += mini, raz[ dist[ x ][ y ] ] = 1;
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || !reco[ X ][ Y ] || in[ X ][ Y ] ) continue;
            if( dist[ x ][ y ] + 1 != dist[ X ][ Y ] ) continue;
            if( M[ X ][ Y ] == mini ) Q.push( mp( X, Y ) );
            in[ X ][ Y ] = 1;
        }
    }
    if( FF == ( 1 << 30 ) || dist[ ex ][ ey ] < FF && ( int )tmp.size( ) == dist[ ex ][ ey ] - 1 ) {
        FF = dist[ ex ][ ey ];
        SOL = tmp;
    }
    else if( FF == dist[ ex ][ ey ] && ( int )tmp.size( ) == dist[ ex ][ ey ] - 1 ) {
        if( tmp < SOL ) SOL = tmp;
    }
    AA = true;
    return true;
}

void dfs( int pos, int go ) {
    if( pos == k ) {
        bfs( );
        return;
    }
    for( int i = go + 1; i < 26; i++ ) {
        bio[ i ] = 1;
        dfs( pos + 1, i );
        bio[ i ] = 0;
    }
}

inline void solve( ) {
    for( int i = -1; i <= 24; i++ ) {
        memset( bio, 0, sizeof( bio ) );
        dfs( 0, i );
    }
    if( AA ) {
        cout << SOL;
    }
    else printf( "-1" );
}

int main( void ) {
    load( );
    solve( );
  //  system( "pause" );
    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <queue>
#include <set>
#include <map>
#include <cmath>
using namespace std;

typedef long long llint;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;

#define pii pair< int, int >
#define piiLL pair< llint, llint >
#define mp make_pair
#define pb push_back
#define lu lower_bound
#define uu upper_bound
#define all( a ) ( a ).begin( ), ( a ).end( )
#define GC getchar( )
#define x first
#define y second

const int N = 55;

int n;
int m;
int k;
char M[ N ][ N ];
int dist[ N ][ N ];
bool reco[ N ][ N ];

string SOL;

bool bio[ 26 ];

int px, py;
int ex, ey;
bool AA;

inline void load( ) {
    scanf( "%d %d %d", &n, &m, &k );
    for( int i = 0; i < n; i++ ) scanf( "%s", M[ i ] );
    for( int i = 0; i < n; i++ ) {
        for( int j = 0; j < m; j++ ) {
            if( M[ i ][ j ] == 'S' ) px = i, py = j;
            if( M[ i ][ j ] == 'T' ) ex = i, ey = j;
        }
    }
}

queue< pii > Q;

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

inline bool bfs( ) {
    memset( dist, -1, sizeof( dist ) );
    while( !Q.empty( ) ) Q.pop( );
    dist[ px ][ py ] = 0;
    Q.push( mp( px, py ) );
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        Q.pop( );
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || dist[ X ][ Y ] != -1 ) continue;
            if( M[ X ][ Y ] != 'T' && !bio[ M[ X ][ Y ] - 'a' ] ) continue;
            dist[ X ][ Y ] = dist[ x ][ y ] + 1;
            Q.push( mp( X, Y ) );
        }
    }
    int curr = dist[ ex ][ ey ];
    if( curr == -1 ) return false;
    memset( reco, 0, sizeof( reco ) );
    Q.push( mp( ex, ey ) );
    reco[ ex ][ ey ] = 0;
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        Q.pop( );
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || dist[ x ][ y ] != dist[ X ][ Y ] + 1 ) continue;
            if( reco[ X ][ Y ] ) continue;
            reco[ X ][ Y ] = 1;
            Q.push( mp( X, Y ) );
        }
    }
    Q.push( mp( px, py ) );
    curr = 0;
    string tmp;
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        if( x == ex && y == ey ) break;
        Q.pop( );
        int mini = ( 1 << 30 );
        bool ok = false;
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || !reco[ X ][ Y ] ) continue;
            if( dist[ x ][ y ] + 1 != dist[ X ][ Y ] ) continue;
            if( mini == ( 1 << 30 ) || M[ X ][ Y ] < mini ) mini = M[ X ][ Y ];
        }
        if( mini != ( 1 << 30 ) ) tmp += mini;
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || !reco[ X ][ Y ] ) continue;
            if( dist[ x ][ y ] + 1 != dist[ X ][ Y ] ) continue;
            if( M[ X ][ Y ] == mini ) Q.push( mp( X, Y ) );
        }
    }
  //  cout << "TMP == " << tmp << endl;
    if( SOL.empty( ) || tmp < SOL ) SOL = tmp;
    AA = true;
    return true;
}

void dfs( int pos, int go ) {
    if( pos == k ) {
        bfs( );
        return;
    }
    for( int i = go + 1; i < 26; i++ ) {
        bio[ i ] = 1;
        dfs( pos + 1, i );
        bio[ i ] = 0;
    }
}

inline void solve( ) {
    for( int i = -1; i <= 24; i++ ) {
        memset( bio, 0, sizeof( bio ) );
        dfs( 0, i );
    }
    if( AA ) {
        cout << SOL;
    }
    else printf( "-1" );
    printf( "\n" );
}

int main( void ) {
    load( );
    solve( );
   // system( "pause" );
    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <queue>
#include <set>
#include <map>
#include <cmath>
using namespace std;

typedef long long llint;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;

#define pii pair< int, int >
#define piiLL pair< llint, llint >
#define mp make_pair
#define pb push_back
#define lu lower_bound
#define uu upper_bound
#define all( a ) ( a ).begin( ), ( a ).end( )
#define GC getchar( )
#define x first
#define y second

const int N = 55;

int n;
int m;
int k;
char M[ N ][ N ];
int dist[ N ][ N ];
bool reco[ N ][ N ];
bool in[ N ][ N ];

string SOL;
int FF;

bool bio[ 26 ];
int raz[ N ];

int px, py;
int ex, ey;
bool AA;

inline void load( ) {
    FF = ( 1 << 30 );
    scanf( "%d %d %d", &n, &m, &k );
    for( int i = 0; i < n; i++ ) scanf( "%s", M[ i ] );
    for( int i = 0; i < n; i++ ) {
        for( int j = 0; j < m; j++ ) {
            if( M[ i ][ j ] == 'S' ) px = i, py = j;
            if( M[ i ][ j ] == 'T' ) ex = i, ey = j;
        }
    }
}

queue< pii > Q;

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

inline bool bfs( ) {
    memset( dist, -1, sizeof( dist ) );
    memset( in, 0, sizeof( in ) );
    while( !Q.empty( ) ) Q.pop( );
    dist[ px ][ py ] = 0;
    Q.push( mp( px, py ) );
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        Q.pop( );
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || dist[ X ][ Y ] != -1 ) continue;
            if( M[ X ][ Y ] != 'T' && !bio[ M[ X ][ Y ] - 'a' ] ) continue;
            dist[ X ][ Y ] = dist[ x ][ y ] + 1;
            Q.push( mp( X, Y ) );
        }
    }
    int curr = dist[ ex ][ ey ];
    if( curr == -1 ) return false;
    memset( reco, 0, sizeof( reco ) );
    Q.push( mp( ex, ey ) );
    reco[ ex ][ ey ] = 0;
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        Q.pop( );
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || dist[ x ][ y ] != dist[ X ][ Y ] + 1 ) continue;
            if( reco[ X ][ Y ] ) continue;
            reco[ X ][ Y ] = 1;
            Q.push( mp( X, Y ) );
        }
    }
    Q.push( mp( px, py ) );
    in[ px ][ py ] = 1;
    string tmp = "";
    memset( raz, 0, sizeof( raz ) );
    while( !Q.empty( ) ) {

        int x = Q.front( ).first;
        int y = Q.front( ).second;
        if( x == ex && y == ey ) break;
        Q.pop( );
        int mini = ( 1 << 30 );
        bool ok = false;
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || !reco[ X ][ Y ] || in[ X ][ Y ] ) continue;
            if( dist[ x ][ y ] + 1 != dist[ X ][ Y ] ) continue;
            if( M[ X ][ Y ] == 'T' ) ok = true;
            if( mini == ( 1 << 30 ) || M[ X ][ Y ] < mini ) mini = M[ X ][ Y ];
        }
        if( ok ) break;
        if( mini != ( 1 << 30 ) && !raz[ dist[ x ][ y ] ]  ) tmp += mini, raz[ dist[ x ][ y ] ] = 1;
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || !reco[ X ][ Y ] || in[ X ][ Y ] ) continue;
            if( dist[ x ][ y ] + 1 != dist[ X ][ Y ] ) continue;
            if( M[ X ][ Y ] == mini ) Q.push( mp( X, Y ) );
            in[ X ][ Y ] = 1;
        }
    }
    if( FF == ( 1 << 30 ) || dist[ ex ][ ey ] < FF && ( int )tmp.size( ) == dist[ ex ][ ey ] - 1 ) {
        FF = dist[ ex ][ ey ];
        SOL = tmp;
    }
    else if( FF == dist[ ex ][ ey ] && ( int )tmp.size( ) == dist[ ex ][ ey ] - 1 ) {
        if( tmp < SOL ) SOL = tmp;
    }
    AA = true;
    return true;
}

void dfs( int pos, int go ) {
    if( pos == k ) {
        bfs( );
        return;
    }
    for( int i = go + 1; i < 26; i++ ) {
        bio[ i ] = 1;
        dfs( pos + 1, i );
        bio[ i ] = 0;
    }
}

inline void solve( ) {
    for( int i = -1; i <= 24; i++ ) {
        memset( bio, 0, sizeof( bio ) );
        dfs( 0, i );
    }
    if( AA ) {
        cout << SOL;
    }
    else printf( "-1" );
}

int main( void ) {
    load( );
    solve( );
  //  system( "pause" );
    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <queue>
#include <set>
#include <map>
#include <cmath>
using namespace std;

typedef long long llint;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;

#define pii pair< int, int >
#define piiLL pair< llint, llint >
#define mp make_pair
#define pb push_back
#define lu lower_bound
#define uu upper_bound
#define all( a ) ( a ).begin( ), ( a ).end( )
#define GC getchar( )
#define x first
#define y second

const int N = 55;

int n;
int m;
int k;
char M[ N ][ N ];
int dist[ N ][ N ];
bool reco[ N ][ N ];
bool in[ N ][ N ];

string SOL;
int FF;

bool bio[ 26 ];
int raz[ N ];

int px, py;
int ex, ey;
bool AA;

inline void load( ) {
    FF = ( 1 << 30 );
    scanf( "%d %d %d", &n, &m, &k );
    for( int i = 0; i < n; i++ ) scanf( "%s", M[ i ] );
    for( int i = 0; i < n; i++ ) {
        for( int j = 0; j < m; j++ ) {
            if( M[ i ][ j ] == 'S' ) px = i, py = j;
            if( M[ i ][ j ] == 'T' ) ex = i, ey = j;
        }
    }
}

queue< pii > Q, Q2, Q3;

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

inline bool bfs( ) {
    memset( dist, -1, sizeof( dist ) );
    memset( in, 0, sizeof( in ) );
    while( !Q.empty( ) ) Q.pop( );
    dist[ px ][ py ] = 0;
    Q.push( mp( px, py ) );
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        Q.pop( );
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || dist[ X ][ Y ] != -1 ) continue;
            if( M[ X ][ Y ] != 'T' && !bio[ M[ X ][ Y ] - 'a' ] ) continue;
            dist[ X ][ Y ] = dist[ x ][ y ] + 1;
            Q.push( mp( X, Y ) );
        }
    }
    int curr = dist[ ex ][ ey ];
    if( curr == -1 ) return false;
    memset( reco, 0, sizeof( reco ) );
    Q.push( mp( ex, ey ) );
    reco[ ex ][ ey ] = 0;
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        Q.pop( );
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || dist[ x ][ y ] != dist[ X ][ Y ] + 1 ) continue;
            if( reco[ X ][ Y ] ) continue;
            reco[ X ][ Y ] = 1;
            Q.push( mp( X, Y ) );
        }
    }
    Q.push( mp( px, py ) );
    in[ px ][ py ] = 1;
    string tmp = "";
    for( int i = 1; i < dist[ ex ][ ey ]; i++ ) {
        while( !Q.empty( ) ) Q2.push( Q.front( ) ), Q.pop( );
        int mini = ( 1 << 30 );
        while( !Q2.empty( ) ) {
            int x = Q2.front( ).first;
            int y = Q2.front( ).second;
            Q2.pop( );
            for( int f = 0; f < 4; f++ ) {
                int X = x + dx[ f ];
                int Y = y + dy[ f ];
                if( X < 0 || X >= n || Y < 0 || Y >= m || in[ X ][ Y ] || !reco[ X ][ Y ] ) continue;
                if( dist[ X ][ Y ] - 1 != dist[ x ][ y ] ) continue;
                Q3.push( mp( X, Y ) );
                if( M[ X ][ Y ] < mini ) mini = M[ X ][ Y ];
            }
        }
        while( !Q3.empty( ) ) {
            int x = Q3.front( ).first;
            int y = Q3.front( ).second;
            Q3.pop( );
            if( M[ x ][ y ] == mini ) Q.push( mp( x, y ) );
        }
        tmp += mini;

    }

    if( FF == ( 1 << 30 ) || dist[ ex ][ ey ] < FF && ( int )tmp.size( ) == dist[ ex ][ ey ] - 1 ) {
        FF = dist[ ex ][ ey ];
        SOL = tmp;
        AA = true;
    }
    else if( FF == dist[ ex ][ ey ] && ( int )tmp.size( ) == dist[ ex ][ ey ] - 1 ) {
        if( tmp < SOL ) SOL = tmp;
        AA = true;
    }
    return true;
}

void dfs( int pos, int go ) {
    if( pos == k ) {
        bfs( );
        return;
    }
    if( go > 25 ) return;
    for( int i = go + 1; i < 26; i++ ) {
        bio[ i ] = 1;
        dfs( pos + 1, i );
        bio[ i ] = 0;
    }
}

inline void solve( ) {
    for( int i = -1; i <= 24; i++ ) {
        memset( bio, 0, sizeof( bio ) );
        dfs( 0, i );
    }
    if( AA ) {
      //  cout << "VEL == " << SOL.size( ) << endl;
        cout << SOL;
    }
    else printf( "-1" );
}

int main( void ) {
    load( );
    solve( );
   // system( "pause" );
    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <queue>
#include <set>
#include <map>
#include <cmath>
using namespace std;

typedef long long llint;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;

#define pii pair< int, int >
#define piiLL pair< llint, llint >
#define mp make_pair
#define pb push_back
#define lu lower_bound
#define uu upper_bound
#define all( a ) ( a ).begin( ), ( a ).end( )
#define GC getchar( )
#define x first
#define y second

const int N = 55;

int n;
int m;
int k;
char M[ N ][ N ];
int dist[ N ][ N ];
bool reco[ N ][ N ];
bool in[ N ][ N ];

string SOL;
int FF;

bool bio[ 26 ];

int px, py;
int ex, ey;
bool AA;

inline void load( ) {
    FF = ( 1 << 30 );
    scanf( "%d %d %d", &n, &m, &k );
    for( int i = 0; i < n; i++ ) scanf( "%s", M[ i ] );
    for( int i = 0; i < n; i++ ) {
        for( int j = 0; j < m; j++ ) {
            if( M[ i ][ j ] == 'S' ) px = i, py = j;
            if( M[ i ][ j ] == 'T' ) ex = i, ey = j;
        }
    }
}

queue< pii > Q;

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

inline bool bfs( ) {
    memset( dist, -1, sizeof( dist ) );
    memset( in, 0, sizeof( in ) );
    while( !Q.empty( ) ) Q.pop( );
    dist[ px ][ py ] = 0;
    Q.push( mp( px, py ) );
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        Q.pop( );
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || dist[ X ][ Y ] != -1 ) continue;
            if( M[ X ][ Y ] != 'T' && !bio[ M[ X ][ Y ] - 'a' ] ) continue;
            dist[ X ][ Y ] = dist[ x ][ y ] + 1;
            Q.push( mp( X, Y ) );
        }
    }
    int curr = dist[ ex ][ ey ];
    if( curr == -1 ) return false;
    memset( reco, 0, sizeof( reco ) );
    Q.push( mp( ex, ey ) );
    reco[ ex ][ ey ] = 0;
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        Q.pop( );
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || dist[ x ][ y ] != dist[ X ][ Y ] + 1 ) continue;
            if( reco[ X ][ Y ] ) continue;
            reco[ X ][ Y ] = 1;
            Q.push( mp( X, Y ) );
        }
    }
    Q.push( mp( px, py ) );
    in[ px ][ py ] = 1;
    string tmp = "";
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        if( x == ex && y == ey ) break;
        Q.pop( );
        int mini = ( 1 << 30 );
        bool ok = false;
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || !reco[ X ][ Y ] || in[ X ][ Y ] ) continue;
            if( dist[ x ][ y ] + 1 != dist[ X ][ Y ] ) continue;
            if( mini == ( 1 << 30 ) || M[ X ][ Y ] < mini ) mini = M[ X ][ Y ];
        }
        if( mini != ( 1 << 30 ) ) tmp += mini;
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || !reco[ X ][ Y ] || in[ X ][ Y ] ) continue;
            if( dist[ x ][ y ] + 1 != dist[ X ][ Y ] ) continue;
            if( M[ X ][ Y ] == mini ) Q.push( mp( X, Y ) );
            in[ X ][ Y ] = 1;
        }
    }
  //  cout << "TMP == " << tmp << endl;
    if( FF == ( 1 << 30 ) || dist[ ex ][ ey ] < FF ) {
        FF = dist[ ex ][ ey ];
        SOL = tmp;
    }
    else if( FF == dist[ ex ][ ey ] ) {
        if( tmp < SOL ) SOL = tmp;
    }
    AA = true;
    return true;
}

void dfs( int pos, int go ) {
    if( pos == k ) {
        bfs( );
        return;
    }
    for( int i = go + 1; i < 26; i++ ) {
        bio[ i ] = 1;
        dfs( pos + 1, i );
        bio[ i ] = 0;
    }
}

inline void solve( ) {
    for( int i = -1; i <= 24; i++ ) {
        memset( bio, 0, sizeof( bio ) );
        dfs( 0, i );
    }
    if( AA ) {
        cout << SOL;
    }
    else printf( "-1" );
}

int main( void ) {
    load( );
    solve( );
    //system( "pause" );
    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <queue>
#include <set>
#include <map>
#include <cmath>
using namespace std;

typedef long long llint;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;

#define pii pair< int, int >
#define piiLL pair< llint, llint >
#define mp make_pair
#define pb push_back
#define lu lower_bound
#define uu upper_bound
#define all( a ) ( a ).begin( ), ( a ).end( )
#define GC getchar( )
#define x first
#define y second

const int N = 55;

int n;
int m;
int k;
char M[ N ][ N ];
int dist[ N ][ N ];
bool reco[ N ][ N ];

string SOL;
int FF;

bool bio[ 26 ];

int px, py;
int ex, ey;
bool AA;

inline void load( ) {
    FF = ( 1 << 30 );
    scanf( "%d %d %d", &n, &m, &k );
    for( int i = 0; i < n; i++ ) scanf( "%s", M[ i ] );
    for( int i = 0; i < n; i++ ) {
        for( int j = 0; j < m; j++ ) {
            if( M[ i ][ j ] == 'S' ) px = i, py = j;
            if( M[ i ][ j ] == 'T' ) ex = i, ey = j;
        }
    }
}

queue< pii > Q;

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

inline bool bfs( ) {
    memset( dist, -1, sizeof( dist ) );
    while( !Q.empty( ) ) Q.pop( );
    dist[ px ][ py ] = 0;
    Q.push( mp( px, py ) );
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        Q.pop( );
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || dist[ X ][ Y ] != -1 ) continue;
            if( M[ X ][ Y ] != 'T' && !bio[ M[ X ][ Y ] - 'a' ] ) continue;
            dist[ X ][ Y ] = dist[ x ][ y ] + 1;
            Q.push( mp( X, Y ) );
        }
    }
    int curr = dist[ ex ][ ey ];
    if( curr == -1 ) return false;
    memset( reco, 0, sizeof( reco ) );
    Q.push( mp( ex, ey ) );
    reco[ ex ][ ey ] = 0;
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        Q.pop( );
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || dist[ x ][ y ] != dist[ X ][ Y ] + 1 ) continue;
            if( reco[ X ][ Y ] ) continue;
            reco[ X ][ Y ] = 1;
            Q.push( mp( X, Y ) );
        }
    }
    Q.push( mp( px, py ) );
    curr = 0;
    string tmp = "";
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        if( x == ex && y == ey ) break;
        Q.pop( );
        int mini = ( 1 << 30 );
        bool ok = false;
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || !reco[ X ][ Y ] ) continue;
            if( dist[ x ][ y ] + 1 != dist[ X ][ Y ] ) continue;
            if( mini == ( 1 << 30 ) || M[ X ][ Y ] < mini ) mini = M[ X ][ Y ];
        }
        if( mini != ( 1 << 30 ) ) tmp += mini;
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || !reco[ X ][ Y ] ) continue;
            if( dist[ x ][ y ] + 1 != dist[ X ][ Y ] ) continue;
            if( M[ X ][ Y ] == mini ) Q.push( mp( X, Y ) );
        }
    }
  //  cout << "TMP == " << tmp << endl;
    if( FF == ( 1 << 30 ) || dist[ ex ][ ey ] < FF ) {
        FF = dist[ ex ][ ey ];
        SOL = tmp;
    }
    else if( FF == dist[ ex ][ ey ] ) {
        if( tmp < SOL ) SOL = tmp;
    }
    AA = true;
    return true;
}

void dfs( int pos, int go ) {
    if( pos == k ) {
        bfs( );
        return;
    }
    for( int i = go + 1; i < 26; i++ ) {
        bio[ i ] = 1;
        dfs( pos + 1, i );
        bio[ i ] = 0;
    }
}

inline void solve( ) {
    for( int i = -1; i <= 24; i++ ) {
        memset( bio, 0, sizeof( bio ) );
        dfs( 0, i );
    }
    if( AA ) {
        cout << SOL;
    }
    else printf( "-1" );
}

int main( void ) {
    load( );
    solve( );
   // system( "pause" );
    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <queue>
#include <set>
#include <map>
#include <cmath>
using namespace std;

typedef long long llint;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;

#define pii pair< int, int >
#define piiLL pair< llint, llint >
#define mp make_pair
#define pb push_back
#define lu lower_bound
#define uu upper_bound
#define all( a ) ( a ).begin( ), ( a ).end( )
#define GC getchar( )
#define x first
#define y second

const int N = 55;

int n;
int m;
int k;
char M[ N ][ N ];
int dist[ N ][ N ];
bool reco[ N ][ N ];

string SOL;

bool bio[ 26 ];

int px, py;
int ex, ey;
bool AA;

inline void load( ) {
    scanf( "%d %d %d", &n, &m, &k );
    for( int i = 0; i < n; i++ ) scanf( "%s", M[ i ] );
    for( int i = 0; i < n; i++ ) {
        for( int j = 0; j < m; j++ ) {
            if( M[ i ][ j ] == 'S' ) px = i, py = j;
            if( M[ i ][ j ] == 'T' ) ex = i, ey = j;
        }
    }
}

queue< pii > Q;

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

inline bool bfs( ) {
    memset( dist, -1, sizeof( dist ) );
    while( !Q.empty( ) ) Q.pop( );
    dist[ px ][ py ] = 0;
    Q.push( mp( px, py ) );
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        Q.pop( );
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || dist[ X ][ Y ] != -1 ) continue;
            if( M[ X ][ Y ] != 'T' && !bio[ M[ X ][ Y ] - 'a' ] ) continue;
            dist[ X ][ Y ] = dist[ x ][ y ] + 1;
            Q.push( mp( X, Y ) );
        }
    }
    int curr = dist[ ex ][ ey ];
    if( curr == -1 ) return false;
    memset( reco, 0, sizeof( reco ) );
    Q.push( mp( ex, ey ) );
    reco[ ex ][ ey ] = 0;
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        Q.pop( );
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || dist[ x ][ y ] != dist[ X ][ Y ] + 1 ) continue;
            if( reco[ X ][ Y ] ) continue;
            reco[ X ][ Y ] = 1;
            Q.push( mp( X, Y ) );
        }
    }
    Q.push( mp( px, py ) );
    curr = 0;
    string tmp = "";
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        if( x == ex && y == ey ) break;
        Q.pop( );
        int mini = ( 1 << 30 );
        bool ok = false;
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || !reco[ X ][ Y ] ) continue;
            if( dist[ x ][ y ] + 1 != dist[ X ][ Y ] ) continue;
            if( mini == ( 1 << 30 ) || M[ X ][ Y ] < mini ) mini = M[ X ][ Y ];
        }
        if( mini != ( 1 << 30 ) ) tmp += mini;
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || !reco[ X ][ Y ] ) continue;
            if( dist[ x ][ y ] + 1 != dist[ X ][ Y ] ) continue;
            if( M[ X ][ Y ] == mini ) Q.push( mp( X, Y ) );
        }
    }
  //  cout << "TMP == " << tmp << endl;
    if( SOL.empty( ) || tmp < SOL ) SOL = tmp;
    AA = true;
    return true;
}

void dfs( int pos, int go ) {
    if( pos == k ) {
        bfs( );
        return;
    }
    for( int i = go + 1; i < 26; i++ ) {
        bio[ i ] = 1;
        dfs( pos + 1, i );
        bio[ i ] = 0;
    }
}

inline void solve( ) {
    for( int i = -1; i <= 24; i++ ) {
        memset( bio, 0, sizeof( bio ) );
        dfs( 0, i );
    }
    if( AA ) {
        cout << SOL;
    }
    else printf( "-1" );
}

int main( void ) {
    load( );
    solve( );
   // system( "pause" );
    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <queue>
#include <set>
#include <map>
#include <cmath>
using namespace std;

typedef long long llint;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;

#define pii pair< int, int >
#define piiLL pair< llint, llint >
#define mp make_pair
#define pb push_back
#define lu lower_bound
#define uu upper_bound
#define all( a ) ( a ).begin( ), ( a ).end( )
#define GC getchar( )
#define x first
#define y second

const int N = 55;

int n;
int m;
int k;
char M[ N ][ N ];
int dist[ N ][ N ];
bool reco[ N ][ N ];
bool in[ N ][ N ];

string SOL;
int FF;

bool bio[ 26 ];
int raz[ N ];

int px, py;
int ex, ey;
bool AA;

inline void load( ) {
    FF = ( 1 << 30 );
    scanf( "%d %d %d", &n, &m, &k );
    for( int i = 0; i < n; i++ ) scanf( "%s", M[ i ] );
    for( int i = 0; i < n; i++ ) {
        for( int j = 0; j < m; j++ ) {
            if( M[ i ][ j ] == 'S' ) px = i, py = j;
            if( M[ i ][ j ] == 'T' ) ex = i, ey = j;
        }
    }
}

queue< pii > Q, Q2, Q3;

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

inline bool bfs( ) {
    memset( dist, -1, sizeof( dist ) );
    memset( in, 0, sizeof( in ) );
    while( !Q.empty( ) ) Q.pop( );
    dist[ px ][ py ] = 0;
    Q.push( mp( px, py ) );
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        Q.pop( );
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || dist[ X ][ Y ] != -1 ) continue;
            if( M[ X ][ Y ] != 'T' && !bio[ M[ X ][ Y ] - 'a' ] ) continue;
            dist[ X ][ Y ] = dist[ x ][ y ] + 1;
            Q.push( mp( X, Y ) );
        }
    }
    int curr = dist[ ex ][ ey ];
    if( curr == -1 ) return false;
    memset( reco, 0, sizeof( reco ) );
    Q.push( mp( ex, ey ) );
    reco[ ex ][ ey ] = 0;
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        Q.pop( );
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || dist[ x ][ y ] != dist[ X ][ Y ] + 1 ) continue;
            if( reco[ X ][ Y ] ) continue;
            reco[ X ][ Y ] = 1;
            Q.push( mp( X, Y ) );
        }
    }
    Q.push( mp( px, py ) );
    in[ px ][ py ] = 1;
    string tmp = "";
    for( int i = 1; i < dist[ ex ][ ey ]; i++ ) {
        while( !Q.empty( ) ) Q2.push( Q.front( ) ), Q.pop( );
        int mini = ( 1 << 30 );
        while( !Q2.empty( ) ) {
            int x = Q2.front( ).first;
            int y = Q2.front( ).second;
            Q2.pop( );
            for( int f = 0; f < 4; f++ ) {
                int X = x + dx[ f ];
                int Y = y + dy[ f ];
                if( X < 0 || X >= n || Y < 0 || Y >= m || in[ X ][ Y ] || !reco[ X ][ Y ] ) continue;
                if( dist[ X ][ Y ] - 1 != dist[ x ][ y ] ) continue;
                Q3.push( mp( X, Y ) );
                in[ X ][ Y ] = 1;
                if( M[ X ][ Y ] < mini ) mini = M[ X ][ Y ];
            }
        }
        while( !Q3.empty( ) ) {
            int x = Q3.front( ).first;
            int y = Q3.front( ).second;
            Q3.pop( );
            if( M[ x ][ y ] == mini ) Q.push( mp( x, y ) );
        }
        tmp += mini;

    }

    if( FF == ( 1 << 30 ) || dist[ ex ][ ey ] < FF && ( int )tmp.size( ) == dist[ ex ][ ey ] - 1 ) {
        FF = dist[ ex ][ ey ];
        SOL = tmp;
        AA = true;
    }
    else if( FF == dist[ ex ][ ey ] && ( int )tmp.size( ) == dist[ ex ][ ey ] - 1 ) {
        if( tmp < SOL ) SOL = tmp;
        AA = true;
    }
    return true;
}

void dfs( int pos, int go ) {
    if( pos == k ) {
        bfs( );
        return;
    }
    if( go > 25 ) return;
    for( int i = go + 1; i < 26; i++ ) {
        bio[ i ] = 1;
        dfs( pos + 1, i );
        bio[ i ] = 0;
    }
}

inline void solve( ) {
    for( int i = -1; i <= 24; i++ ) {
        memset( bio, 0, sizeof( bio ) );
        dfs( 0, i );
    }
    if( AA ) {
      //  cout << "VEL == " << SOL.size( ) << endl;
        cout << SOL;
    }
    else printf( "-1" );
}

int main( void ) {
    load( );
    solve( );
   // system( "pause" );
    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <queue>
#include <set>
#include <map>
#include <cmath>
using namespace std;

typedef long long llint;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;

#define pii pair< int, int >
#define piiLL pair< llint, llint >
#define mp make_pair
#define pb push_back
#define lu lower_bound
#define uu upper_bound
#define all( a ) ( a ).begin( ), ( a ).end( )
#define GC getchar( )
#define x first
#define y second

const int N = 55;

int n;
int m;
int k;
char M[ N ][ N ];
int dist[ N ][ N ];
bool reco[ N ][ N ];

string SOL;

bool bio[ 26 ];

int px, py;
int ex, ey;
bool AA;

inline void load( ) {
    scanf( "%d %d %d", &n, &m, &k );
    for( int i = 0; i < n; i++ ) scanf( "%s", M[ i ] );
    for( int i = 0; i < n; i++ ) {
        for( int j = 0; j < m; j++ ) {
            if( M[ i ][ j ] == 'S' ) px = i, py = j;
            if( M[ i ][ j ] == 'T' ) ex = i, ey = j;
        }
    }
}

queue< pii > Q;

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

inline bool bfs( ) {
    memset( dist, -1, sizeof( dist ) );
    while( !Q.empty( ) ) Q.pop( );
    dist[ px ][ py ] = 0;
    Q.push( mp( px, py ) );
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        Q.pop( );
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || dist[ X ][ Y ] != -1 ) continue;
            if( M[ X ][ Y ] != 'T' && !bio[ M[ X ][ Y ] - 'a' ] ) continue;
            dist[ X ][ Y ] = dist[ x ][ y ] + 1;
            Q.push( mp( X, Y ) );
        }
    }
    int curr = dist[ ex ][ ey ];
    if( curr == -1 ) return false;
    memset( reco, 0, sizeof( reco ) );
    Q.push( mp( ex, ey ) );
    reco[ ex ][ ey ] = 0;
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        Q.pop( );
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || dist[ x ][ y ] != dist[ X ][ Y ] + 1 ) continue;
            if( reco[ X ][ Y ] ) continue;
            reco[ X ][ Y ] = 1;
            Q.push( mp( X, Y ) );
        }
    }
    Q.push( mp( px, py ) );
    curr = 0;
    string tmp = "";
    while( !Q.empty( ) ) {
        int x = Q.front( ).first;
        int y = Q.front( ).second;
        if( x == ex && y == ey ) break;
        Q.pop( );
        int mini = ( 1 << 30 );
        bool ok = false;
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || !reco[ X ][ Y ] ) continue;
            if( dist[ x ][ y ] + 1 != dist[ X ][ Y ] ) continue;
            if( mini == ( 1 << 30 ) || M[ X ][ Y ] < mini ) mini = M[ X ][ Y ];
        }
        if( mini != ( 1 << 30 ) ) tmp += mini;
        for( int i = 0; i < 4; i++ ) {
            int X = x + dx[ i ];
            int Y = y + dy[ i ];
            if( X < 0 || X >= n || Y < 0 || Y >= m || !reco[ X ][ Y ] ) continue;
            if( dist[ x ][ y ] + 1 != dist[ X ][ Y ] ) continue;
            if( M[ X ][ Y ] == mini ) Q.push( mp( X, Y ) );
        }
    }
  //  cout << "TMP == " << tmp << endl;
    if( SOL.empty( ) || tmp < SOL ) SOL = tmp;
    AA = true;
    return true;
}

void dfs( int pos, int go ) {
    if( pos == k ) {
        bfs( );
        return;
    }
    for( int i = go + 1; i < 26; i++ ) {
        bio[ i ] = 1;
        dfs( pos + 1, i );
        bio[ i ] = 0;
    }
}

inline void solve( ) {
    for( int i = -1; i <= 24; i++ ) {
        memset( bio, 0, sizeof( bio ) );
        dfs( 0, i );
    }
    if( AA ) {
        cout << SOL;
    }
    else printf( "-1" );
}

int main( void ) {
    load( );
    solve( );
    system( "pause" );
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <cstring>
#include <map>
#include <cstdlib>
#include <ctime>
#include <cassert>
#include <bitset>
#define f first
#define s second
#define ll long long
#define ull unsigned long long
#define mp make_pair
#define pb push_back
#define vi vector <int>
#define ld long double
#define pii pair<int, int>
using namespace std;
const int N = 55, mod = int(1e9)  + 7;
int n,m,k;
char s[N][N];
string ans;
bool u[500];
int d[N][N];

int sx,sy,fx,fy;
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
int dist = mod;
bool used[N][N];

void go(){
	queue <pair<int,int> > q;
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m; j++){
			d[i][j] = mod;
			used[i][j] = 0;
		}
	}
	d[fx][fy] = 0;
	q.push(mp(fx,fy));
	while(!q.empty()){
		int x = q.front().f;
		int y = q.front().s;
		q.pop();
		for(int i = 0; i < 4; i++){
			int xx = x + dx[i];
			int yy = y + dy[i];
			if(d[xx][yy] == mod && u[s[xx][yy]]){
				d[xx][yy] = d[x][y] + 1;
				q.push(mp(xx,yy));
			}
		}
	}
	if(d[sx][sy] == mod || d[sx][sy] > dist) return;
	dist = d[sx][sy];
	vector <pii> v;
	v.pb(mp(sx,sy));
	string cur = "";
	while(true){
		vector <pii> rb;
		char mn = 'z' + 1;
		for(int i = 0;i < v.size(); i++){
			int x = v[i].f;
			int y = v[i].s;
			for(int j = 0; j < 4; j++){
				int xx = x + dx[j];
				int yy = y + dy[j];
				if(d[xx][yy] == d[x][y] - 1 && u[s[xx][yy]]){
					if(mn > s[xx][yy]){
						rb.clear();
						rb.pb(mp(xx,yy));
						mn = s[xx][yy];
						used[xx][yy] = 1;
					}
					else if(mn == s[xx][yy] && !used[xx][yy]){
						rb.pb(mp(xx,yy));
						used[xx][yy] = 1;
					}
				}
			}
		}
		if(mn == 'T'){
			if(ans == "" || (cur.size() < ans.size() || (ans.size() == cur.size() && cur < ans)) ) ans = cur;
			return;
		}
		cur += mn;
		v = rb;
	}
}

void rec(int x,int cnt){
	if(x == 26){
		go();
		return;
	}
	u[x + 'a'] = 0;
	rec(x + 1,cnt);
	if(cnt == k) return;
	u[x + 'a'] = 1;
	rec(x + 1,cnt + 1);
}

int main () {
	scanf("%d%d%d\n",&n,&m,&k);
	u['T'] = 1;
	u['S'] = 1;
	for(int i = 1; i <= n; i++){
		scanf("%s\n",s[i] + 1);
		for(int j = 1; j <= m; j++){
			if(s[i][j] == 'S'){
				sx = i;
				sy = j;
			}
			if(s[i][j] == 'T'){
				fx = i;
				fy = j;
			}
		}
	}
	rec(0,0);
	if(ans == "" && dist == mod) ans = "-1";
	cout << ans;

return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <cstring>
#include <map>
#include <cstdlib>
#include <ctime>
#include <cassert>
#include <bitset>
#define f first
#define s second
#define ll long long
#define ull unsigned long long
#define mp make_pair
#define pb push_back
#define vi vector <int>
#define ld long double
#define pii pair<int, int>
using namespace std;
const int N = 55, mod = int(1e9)  + 7;
int n,m,k;
char s[N][N];
string ans;
bool u[500];
int d[N][N];

int sx,sy,fx,fy;
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
int dist = mod;

void go(){
	queue <pair<int,int> > q;
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m; j++){
			d[i][j] = mod;
		}
	}
	d[fx][fy] = 0;
	q.push(mp(fx,fy));
	while(!q.empty()){
		int x = q.front().f;
		int y = q.front().s;
		q.pop();
		for(int i = 0; i < 4; i++){
			int xx = x + dx[i];
			int yy = y + dy[i];
			if(d[xx][yy] == mod && u[s[xx][yy]]){
				d[xx][yy] = d[x][y] + 1;
				q.push(mp(xx,yy));
			}
		}
	}
	if(d[sx][sy] == mod || d[sx][sy] > dist) return;
	dist = d[sx][sy];
	vector <pii> v;
	v.pb(mp(sx,sy));
	string cur = "";
	while(true){
		vector <pii> rb;
		char mn = 'z' + 1;
		for(int i = 0;i < v.size(); i++){
			int x = v[i].f;
			int y = v[i].s;
			for(int j = 0; j < 4; j++){
				int xx = x + dx[j];
				int yy = y + dy[j];
				if(d[xx][yy] == d[x][y] - 1 && u[s[xx][yy]]){
					if(mn > s[xx][yy]){
						rb.clear();
						rb.pb(mp(xx,yy));
						mn = s[xx][yy];
					}
					else if(mn == s[xx][yy]){
						rb.pb(mp(xx,yy));
					}
				}
			}
		}
		if(mn == 'T'){
			if(ans == "" || (cur.size() < ans.size() || (ans.size() == cur.size() && cur < ans)) ) ans = cur;
			return;
		}
		cur += mn;
		v = rb;
	}
}

void rec(int x,int cnt){
	if(x == 26){
		go();
		return;
	}
	u[x + 'a'] = 0;
	rec(x + 1,cnt);
	if(cnt == k) return;
	u[x + 'a'] = 1;
	rec(x + 1,cnt + 1);
}

int main () {
	scanf("%d%d%d\n",&n,&m,&k);
	u['T'] = 1;
	u['S'] = 1;
	for(int i = 1; i <= n; i++){
		scanf("%s\n",s[i] + 1);
		for(int j = 1; j <= m; j++){
			if(s[i][j] == 'S'){
				sx = i;
				sy = j;
			}
			if(s[i][j] == 'T'){
				fx = i;
				fy = j;
			}
		}
	}
	rec(0,0);
	if(ans == "") ans = "-1";
	cout << ans;

return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <cstring>
#include <map>
#include <cstdlib>
#include <ctime>
#include <cassert>
#include <bitset>
#define f first
#define s second
#define ll long long
#define ull unsigned long long
#define mp make_pair
#define pb push_back
#define vi vector <int>
#define ld long double
#define pii pair<int, int>
using namespace std;
const int N = 55, mod = int(1e9)  + 7;
int n,m,k;
char s[N][N];
string ans;
bool u[500];
int d[N][N];

int sx,sy,fx,fy;
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
int dist = mod;

void go(){
	queue <pair<int,int> > q;
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m; j++){
			d[i][j] = mod;
		}
	}
	d[fx][fy] = 0;
	q.push(mp(fx,fy));
	while(!q.empty()){
		int x = q.front().f;
		int y = q.front().s;
		q.pop();
		for(int i = 0; i < 4; i++){
			int xx = x + dx[i];
			int yy = y + dy[i];
			if(d[xx][yy] == mod && u[s[xx][yy]]){
				d[xx][yy] = d[x][y] + 1;
				q.push(mp(xx,yy));
			}
		}
	}
	if(d[sx][sy] == mod || d[sx][sy] > dist) return;
	dist = d[sx][sy];
	vector <pii> v;
	v.pb(mp(sx,sy));
	string cur = "";
	while(true){
		vector <pii> rb;
		char mn = 'z' + 1;
		for(int i = 0;i < v.size(); i++){
			int x = v[i].f;
			int y = v[i].s;
			for(int j = 0; j < 4; j++){
				int xx = x + dx[j];
				int yy = y + dy[j];
				if(d[xx][yy] == d[x][y] - 1 && u[s[xx][yy]]){
					if(mn > s[xx][yy]){
						rb.clear();
						rb.pb(mp(xx,yy));
						mn = s[xx][yy];
					}
					else if(mn == s[xx][yy]){
						rb.pb(mp(xx,yy));
					}
				}
			}
		}
		if(mn == 'T'){
			if(ans == "" || (cur.size() < ans.size() || (ans.size() == cur.size() && cur < ans)) ) ans = cur;
			return;
		}
		cur += mn;
		v = rb;
	}
}

void rec(int x,int cnt){
	if(x == 26){
		go();
		return;
	}
	u[x + 'a'] = 0;
	rec(x + 1,cnt);
	if(cnt == k) return;
	u[x + 'a'] = 1;
	rec(x + 1,cnt + 1);
}

int main () {
	scanf("%d%d%d\n",&n,&m,&k);
	u['T'] = 1;
	u['S'] = 1;
	for(int i = 1; i <= n; i++){
		scanf("%s\n",s[i] + 1);
		for(int j = 1; j <= m; j++){
			if(s[i][j] == 'S'){
				sx = i;
				sy = j;
			}
			if(s[i][j] == 'T'){
				fx = i;
				fy = j;
			}
		}
	}
	rec(0,0);
	if(ans == "" && dist == mod) ans = "-1";
	cout << ans;

return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <cstring>
#include <map>
#include <cstdlib>
#include <ctime>
#include <cassert>
#include <bitset>
#define f first
#define s second
#define ll long long
#define ull unsigned long long
#define mp make_pair
#define pb push_back
#define vi vector <int>
#define ld long double
#define pii pair<int, int>
using namespace std;
const int N = 55, mod = int(1e9)  + 7;
int n,m,k;
char s[N][N];
string ans;
bool u[500];
int d[N][N];

int sx,sy,fx,fy;
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
int dist = mod;
bool used[N][N];

void go(){
	queue <pair<int,int> > q;
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m; j++){
			d[i][j] = mod;
			used[i][j] = 0;
		}
	}
	d[fx][fy] = 0;
	q.push(mp(fx,fy));
	while(!q.empty()){
		int x = q.front().f;
		int y = q.front().s;
		q.pop();
		for(int i = 0; i < 4; i++){
			int xx = x + dx[i];
			int yy = y + dy[i];
			if(d[xx][yy] == mod && u[s[xx][yy]]){
				d[xx][yy] = d[x][y] + 1;
				q.push(mp(xx,yy));
			}
		}
	}
	if(d[sx][sy] == mod || d[sx][sy] > dist) return;
	dist = d[sx][sy];
	vector <pii> v;
	v.pb(mp(sx,sy));
	string cur = "";
	while(true){
		vector <pii> rb;
		char mn = 'z' + 1;
		for(int i = 0;i < v.size(); i++){
			int x = v[i].f;
			int y = v[i].s;
			for(int j = 0; j < 4; j++){
				int xx = x + dx[j];
				int yy = y + dy[j];
				if(d[xx][yy] == d[x][y] - 1 && u[s[xx][yy]]){
					if(mn > s[xx][yy]){
						rb.clear();
						rb.pb(mp(xx,yy));
						mn = s[xx][yy];
						used[xx][yy] = 1;
					}
					else if(mn == s[xx][yy]){
						rb.pb(mp(xx,yy));
						used[xx][yy] = 1;
					}
				}
			}
		}
		if(mn == 'T'){
			if(ans == "" || (cur.size() < ans.size() || (ans.size() == cur.size() && cur < ans)) ) ans = cur;
			return;
		}
		cur += mn;
		v = rb;
	}
}

void rec(int x,int cnt){
	if(x == 26){
		go();
		return;
	}
	u[x + 'a'] = 0;
	rec(x + 1,cnt);
	if(cnt == k) return;
	u[x + 'a'] = 1;
	rec(x + 1,cnt + 1);
}

int main () {
	scanf("%d%d%d\n",&n,&m,&k);
	u['T'] = 1;
	u['S'] = 1;
	for(int i = 1; i <= n; i++){
		scanf("%s\n",s[i] + 1);
		for(int j = 1; j <= m; j++){
			if(s[i][j] == 'S'){
				sx = i;
				sy = j;
			}
			if(s[i][j] == 'T'){
				fx = i;
				fy = j;
			}
		}
	}
	rec(0,0);
	if(ans == "" && dist == mod) ans = "-1";
	cout << ans;

return 0;
}


#include <stdio.h>
#include <iostream>
#include <math.h>
#include <algorithm>
#include <vector>
#include <list>
#include <queue>
#include <map>
#include <set>
#include <string.h>

#define fori(i, l, r) for(int i = l; i < (int)(r); ++i)
#define rep(i, n) for(int i = 0; i < (int)(n); ++i)
#define dbg(x) cerr << #x << " = " << x << endl
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define sz(x) (int)(x).size()
#define TASKNAME ""
typedef long long int64;
typedef long double real;

const int magicconst = 73743071;

using namespace std;

int dx[4] = {0, 0, -1, 1};
int dy[4] = {-1, 1, 0, 0};
int sx, sy, tx, ty;
int n, m;
int d[55][55];
char u[55][55];
bool b[255];

bool crt(int x, int y)
{
	return 0 <= x && x < n && 0 <= y && y < m && b[u[x][y] - 'a'];
}

inline void bfs()
{
	queue<pair<int, int> > q;
	q.push(mp(tx, ty));
	memset(d, -1, sizeof d);
	d[tx][ty] = 0;

	while(!q.empty())
	{
		pair<int, int> temp = q.front();
		q.pop();
		rep(i, 4)
			if(crt(temp.x + dx[i], temp.y + dy[i]) && d[temp.x + dx[i]][temp.y + dy[i]] == -1)
			{
				d[temp.x + dx[i]][temp.y + dy[i]] = d[temp.x][temp.y] + 1;
				q.push(mp(temp.x + dx[i], temp.y + dy[i]));
			}
	}
	/*rep(i, 26) if(b[i]) printf("%c ", i + 'a');
	printf("\n");
	rep(i, n) rep(j, m) printf("%d%c", d[i][j], " \n"[j == m - 1]);
	printf("---------\n");
	*/
}

char ans[55 * 55];
int t = 0;
int len = -1;

char str[55 * 55];
int w = 0;
pair<int, int>  p[55 * 55];
int pt = 0;
pair<int, int>  q[55 * 55];
int qt = 0;

int go(int v, int k)
{
	if(k == 0)
	{
		bfs();

		if(d[sx][sy] != -1 && (len == -1 || d[sx][sy] <= len))
		{
			w = 0;
			pt = 0;
			qt = 0;
			p[pt++] = mp(sx, sy);
			rep(j, d[sx][sy] - 1)
            {
            	int mm = 100500;
            	rep(o, pt)
            		rep(i, 4)
            			if(crt(p[o].x + dx[i], p[o].y + dy[i]) && d[p[o].x + dx[i]][p[o].y + dy[i]] == d[p[o].x][p[o].y] - 1)
            			{
            				if(u[p[o].x + dx[i]][p[o].y + dy[i]] < mm)
            				{
            					qt = 0;
            					q[qt++] = (mp(p[o].x + dx[i], p[o].y + dy[i]));
            					mm = u[p[o].x + dx[i]][p[o].y + dy[i]];
            				}
            				else if(u[p[o].x + dx[i]][p[o].y + dy[i]] == mm)
            				{
            					q[qt++] = (mp(p[o].x, p[o].y));
                            }
            			}
            	str[w++] = (char)mm;
            	pt = 0;
            	rep(i, qt) p[pt++] = (q[i]);
            	qt = 0;
            }
			if(len == -1 || len > d[sx][sy])
			{
				len = d[sx][sy];
		        rep(i, w) ans[i] = str[i];
			}
			bool ok = false;
			rep(i, w)
			{
				if(ans[i] > str[i])
				{
					ok = true;
					break;
				}
				else if(ans[i] < str[i]);
				{
					break;
				}
			}
			if(ok)
			{
				len = d[sx][sy];
		        rep(i, len) ans[i] = str[i];
			}
		}
	}
	else
	{
		fori(i, v + 1, 26)
		{
			b[i] = 1;
			go(i, k - 1);
			b[i] = 0;
	   	}
	}
}

int main()
{
//	freopen(TASKNAME ".in", "rt", stdin);
//	freopen(TASKNAME ".out", "wt", stdout);

	int k;
	scanf("%d%d%d\n", &n, &m, &k);

	rep(i, n)
	{
		rep(j, m)
		{
			scanf("%c", &u[i][j]);
			if(u[i][j] == 'S') sx = i, sy = j;
			if(u[i][j] == 'T') tx = i, ty = j;
		}
		scanf("\n");
	}
	memset(b, 0, sizeof b);
	b['S' - 'a'] = 1;
	b['T' - 'a'] = 1;
	go(-1, k);
	if(len == -1) printf("-1");
	else
	{
		rep(i, len) printf("%c", ans[i]);
	}

	return 0;
}


#include <stdio.h>
#include <iostream>
#include <math.h>
#include <algorithm>
#include <vector>
#include <list>
#include <queue>
#include <map>
#include <set>
#include <string.h>

#define fori(i, l, r) for(int i = l; i < (int)(r); ++i)
#define rep(i, n) for(int i = 0; i < (int)(n); ++i)
#define dbg(x) cerr << #x << " = " << x << endl
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define sz(x) (int)(x).size()
#define TASKNAME ""
typedef long long int64;
typedef long double real;

const int magicconst = 73743071;

using namespace std;

int dx[4] = {0, 0, -1, 1};
int dy[4] = {-1, 1, 0, 0};
int sx, sy, tx, ty;
int n, m;
int d[55][55];
char u[55][55];
bool b[255];

bool crt(int x, int y)
{
	return 0 <= x && x < n && 0 <= y && y < m && b[u[x][y] - 'a'];
}

inline void bfs()
{
	queue<pair<int, int> > q;
	q.push(mp(tx, ty));
	memset(d, -1, sizeof d);
	d[tx][ty] = 0;

	while(!q.empty())
	{
		pair<int, int> temp = q.front();
		q.pop();
		rep(i, 4)
			if(crt(temp.x + dx[i], temp.y + dy[i]) && d[temp.x + dx[i]][temp.y + dy[i]] == -1)
			{
				d[temp.x + dx[i]][temp.y + dy[i]] = d[temp.x][temp.y] + 1;
				q.push(mp(temp.x + dx[i], temp.y + dy[i]));
			}
	}
	/*rep(i, 26) if(b[i]) printf("%c ", i + 'a');
	printf("\n");
	rep(i, n) rep(j, m) printf("%d%c", d[i][j], " \n"[j == m - 1]);
	printf("---------\n");
	*/
}

string ans;
int len = -1;

vector<pair<int, int> > p;
vector<pair<int, int> > q;
string str;

int go(int v, int k)
{
	if(k == 0)
	{
		bfs();

		if(d[sx][sy] != -1 && (len == -1 || d[sx][sy] <= len))
		{
			str.clear();
			p.clear();
			q.clear();
			p.pb(mp(sx, sy));
			rep(j, d[sx][sy] - 1)
            {
            	int mm = 100500;
            	rep(o, p.size())
            		rep(i, 4)
            			if(crt(p[o].x + dx[i], p[o].y + dy[i]) && d[p[o].x + dx[i]][p[o].y + dy[i]] == d[p[o].x][p[o].y] - 1)
            			{
            				if(u[p[o].x + dx[i]][p[o].y + dy[i]] < mm)
            				{
            					q.clear();
            					q.pb(mp(p[o].x + dx[i], p[o].y + dy[i]));
            					mm = u[p[o].x + dx[i]][p[o].y + dy[i]];
            				}
            				else if(u[p[o].x + dx[i]][p[o].y + dy[i]] == mm)
            				{
            					q.pb(mp(p[o].x, p[o].y));
                            }
            			}
            	str.pb((char)mm);
            	p.clear();
               	rep(i, q.size()) p.pb(q[i]);
               	q.clear();
			}
			if(len == -1 || (len > d[sx][sy] || str < ans)) ans = str, len = d[sx][sy];
		}
	}
	else
	{
		fori(i, v + 1, 26)
		{
			b[i] = 1;
			go(i, k - 1);
			b[i] = 0;
	   	}
	}
}

int main()
{
//	freopen(TASKNAME ".in", "rt", stdin);
//	freopen(TASKNAME ".out", "wt", stdout);

	int k;
	scanf("%d%d%d\n", &n, &m, &k);

	rep(i, n)
	{
		rep(j, m)
		{
			scanf("%c", &u[i][j]);
			if(u[i][j] == 'S') sx = i, sy = j;
			if(u[i][j] == 'T') tx = i, ty = j;
		}
		scanf("\n");
	}
	memset(b, 0, sizeof b);
	b['S' - 'a'] = 1;
	b['T' - 'a'] = 1;
	go(-1, k);
	if(len == -1) printf("-1");
	else printf("%s", ans.c_str());

	return 0;
}


#include <stdio.h>
#include <iostream>
#include <math.h>
#include <algorithm>
#include <vector>
#include <list>
#include <queue>
#include <map>
#include <set>
#include <string.h>

#define fori(i, l, r) for(int i = l; i < (int)(r); ++i)
#define rep(i, n) for(int i = 0; i < (int)(n); ++i)
#define dbg(x) cerr << #x << " = " << x << endl
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define sz(x) (int)(x).size()
#define TASKNAME ""
typedef long long int64;
typedef long double real;

const int magicconst = 73743071;

using namespace std;

int dx[4] = {0, 0, -1, 1};
int dy[4] = {-1, 1, 0, 0};
int sx, sy, tx, ty;
int n, m;
int d[55][55];
char u[55][55];
bool b[255];

bool crt(int x, int y)
{
	return 0 <= x && x < n && 0 <= y && y < m && b[u[x][y] - 'a'];
}

inline void bfs()
{
	queue<pair<int, int> > q;
	q.push(mp(tx, ty));
	memset(d, -1, sizeof d);
	d[tx][ty] = 0;

	while(!q.empty())
	{
		pair<int, int> temp = q.front();
		q.pop();
		rep(i, 4)
			if(crt(temp.x + dx[i], temp.y + dy[i]) && d[temp.x + dx[i]][temp.y + dy[i]] == -1)
			{
				d[temp.x + dx[i]][temp.y + dy[i]] = d[temp.x][temp.y] + 1;
				q.push(mp(temp.x + dx[i], temp.y + dy[i]));
			}
	}
	/*rep(i, 26) if(b[i]) printf("%c ", i + 'a');
	printf("\n");
	rep(i, n) rep(j, m) printf("%d%c", d[i][j], " \n"[j == m - 1]);
	printf("---------\n");
	*/
}

char ans[55 * 55];
int t = 0;
int len = -1;

char str[55 * 55];
int w = 0;
pair<int, int>  p[55 * 55];
int pt = 0;
set<pair<int, int> > q;

int go(int v, int k)
{
	if(k == 0)
	{
		bfs();

		if(d[sx][sy] != -1 && (len == -1 || d[sx][sy] <= len))
		{
			w = 0;
			pt = 0;
			p[pt++] = mp(sx, sy);
			rep(j, d[sx][sy] - 1)
            {
            	int mm = 100500;
            	rep(o, pt)
            	{
            		//cerr << p[o].x <<" " << p[o].y << endl;
            		rep(i, 4)
            			if(crt(p[o].x + dx[i], p[o].y + dy[i]) && d[p[o].x + dx[i]][p[o].y + dy[i]] == d[p[o].x][p[o].y] - 1)
            			{
            				if(u[p[o].x + dx[i]][p[o].y + dy[i]] < mm)
            				{
            					q.clear();
            					q.insert(mp(p[o].x + dx[i], p[o].y + dy[i]));
            					mm = u[p[o].x + dx[i]][p[o].y + dy[i]];
            				}
            				else if(u[p[o].x + dx[i]][p[o].y + dy[i]] == mm)
            				{
            					q.insert(mp(p[o].x + dx[i], p[o].y + dy[i]));
            	            }
            			}
            	}
            	str[w++] = (char)mm;
            	pt = 0;
            	for(set<pair<int, int> >::iterator iter = q.begin(); iter != q.end(); ++iter) p[pt++] = *(iter);
            	q.clear();
            }

            if(len == -1 || len > d[sx][sy])
			{
				len = d[sx][sy];
		        rep(i, w) ans[i] = str[i];
		    }
			else
			{
				bool ok = false;
				rep(i, w)
				{
					if(ans[i] > str[i])
					{
						ok = true;
						break;
					}
					else if(ans[i] < str[i])
					{
						break;
					}
				}
				if(ok)
				{
					rep(i, w) ans[i] = str[i];
				}
			}
		}
	}
	else
	{
		fori(i, v + 1, 26)
		{
			b[i] = 1;
			go(i, k - 1);
			b[i] = 0;
	   	}
	}
}

int main()
{
//	freopen(TASKNAME ".in", "rt", stdin);
//	freopen(TASKNAME ".out", "wt", stdout);

	int k;
	scanf("%d%d%d\n", &n, &m, &k);

	rep(i, n)
	{
		rep(j, m)
		{
			scanf("%c", &u[i][j]);
			if(u[i][j] == 'S') sx = i, sy = j;
			if(u[i][j] == 'T') tx = i, ty = j;
		}
		scanf("\n");
	}
	memset(b, 0, sizeof b);
	b['S' - 'a'] = 1;
	b['T' - 'a'] = 1;
	go(-1, k);
	if(len == -1) printf("-1");
	else
	{
		rep(i, len - 1) printf("%c", ans[i]);
	}

	return 0;
}