using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("3 4");
WillReturn.Add("###.");
WillReturn.Add("#.T.");
WillReturn.Add("...#");
//3
}
else if (InputPattern == "Input2") {
WillReturn.Add("3 3");
WillReturn.Add("###");
WillReturn.Add("#T#");
WillReturn.Add("###");
//-1
}
else if (InputPattern == "Input3") {
WillReturn.Add("5 5");
WillReturn.Add("###..");
WillReturn.Add("#T...");
WillReturn.Add("..##.");
WillReturn.Add("##..#");
WillReturn.Add("#..#.");
//5
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static long[] GetSplitArr(string pStr)
{
return (pStr == "" ? new string[0] : pStr.Split(' ')).Select(pX => long.Parse(pX)).ToArray();
}
static char[,] mBanArr;
static int UB_X;
static int UB_Y;
static int mTakaX;
static int mTakaY;
static void Main()
{
List<string> InputList = GetInputList();
mBanArr = CreateBanArr(InputList.Skip(1));
UB_X = mBanArr.GetUpperBound(0);
UB_Y = mBanArr.GetUpperBound(1);
for (int X = 0; X <= UB_X; X++) {
for (int Y = 0; Y <= UB_Y; Y++) {
if (mBanArr[X, Y] == 'T') {
mTakaX = X;
mTakaY = Y;
}
}
}
var Que = new Queue<JyoutaiDef>();
JyoutaiDef WillEnqueue;
WillEnqueue.Cost = 0;
WillEnqueue.ByteArr = new byte[UB_X + 1, UB_Y + 1];
for (int X = 0; X <= UB_X; X++) {
for (int Y = 0; Y <= UB_Y; Y++) {
if (mBanArr[X, Y] == '#') {
WillEnqueue.ByteArr[X, Y] = 1;
}
}
}
Que.Enqueue(WillEnqueue);
var VisitedSet = new HashSet<string>();
while (Que.Count > 0) {
JyoutaiDef Dequeued = Que.Dequeue();
byte[,] CurrByteArr = Dequeued.ByteArr;
if (IsClear(CurrByteArr)) {
Console.WriteLine(Dequeued.Cost);
return;
}
Action<int, int> EnqueueAct = (pVectX, pVectY) =>
{
byte[,] NewByteArr = new byte[UB_X + 1, UB_Y + 1];
for (int X = 0; X <= UB_X; X++) {
int TargetX = X + pVectX;
if (TargetX < 0 || UB_X < TargetX) continue;
for (int Y = 0; Y <= UB_Y; Y++) {
int TargetY = Y + pVectY;
if (TargetY < 0 || UB_Y < TargetY) continue;
if (CurrByteArr[X, Y] == 1) {
if (TargetX == mTakaX && TargetY == mTakaY) return;
}
NewByteArr[TargetX, TargetY] = CurrByteArr[X, Y];
}
}
string Hash = GetHash(NewByteArr);
if (VisitedSet.Add(Hash)) {
WillEnqueue.Cost = Dequeued.Cost + 1;
WillEnqueue.ByteArr = NewByteArr;
Que.Enqueue(WillEnqueue);
}
};
EnqueueAct(0, -1);
EnqueueAct(0, +1);
EnqueueAct(-1, 0);
EnqueueAct(+1, 0);
}
Console.WriteLine(-1);
}
// クリア判定
static bool IsClear(byte[,] pByteArr)
{
for (int X = 0; X <= UB_X; X++) {
for (int Y = 0; Y <= UB_Y; Y++) {
if (pByteArr[X, Y] == 1) return false;
}
}
return true;
}
struct JyoutaiDef
{
internal int Cost;
internal byte[,] ByteArr;
}
static string GetHash(byte[,] pByteArr)
{
var sb = new System.Text.StringBuilder();
for (int X = 0; X <= UB_X; X++) {
for (int Y = 0; Y <= UB_Y; Y++) {
sb.Append(pByteArr[X, Y]);
}
}
return sb.ToString();
}
////////////////////////////////////////////////////////////////
// IEnumerable<string>をcharの2次元配列に設定
////////////////////////////////////////////////////////////////
static char[,] CreateBanArr(IEnumerable<string> pStrEnum)
{
var StrList = pStrEnum.ToList();
if (StrList.Count == 0) {
return new char[0, 0];
}
int UB_X = StrList[0].Length - 1;
int UB_Y = StrList.Count - 1;
char[,] WillReturn = new char[UB_X + 1, UB_Y + 1];
for (int Y = 0; Y <= UB_Y; Y++) {
for (int X = 0; X <= UB_X; X++) {
WillReturn[X, Y] = StrList[Y][X];
}
}
return WillReturn;
}
}