#include <iostream>
#include <cstdio>
#include <fstream>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <tuple>
#include <algorithm>
#include <iterator>
#include <functional>
#include <cmath>
#include <math.h>
#include <time.h>
#include <iomanip>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

const double Pi = 3.14159265359;
const string alphabet = "abcdefghijklmnopqrstuvwxyz";

namespace Helpers {
	class Help {
	public:
		static bool is_prime(const ll& n) {
			for (ll i = 2; i*i <= n; i++)
				if (n%i == 0)
					return false;
			return true;
		}

		static ll gcd(const ll& a, const ll& b) {
			return b ? gcd(b, a % b) : a;
		}

		static ll gcdex(ll a, ll b, ll & x, ll & y) {
			if (a == 0) {
				x = 0; y = 1;
				return b;
			}
			ll x1, y1;
			ll d = gcdex(b%a, a, x1, y1);
			x = y1 - (b / a) * x1;
			y = x1;
			return d;
		}

		static ll lcm(ll a, ll b) {
			return a / gcd(a, b) * b;
		}

		static ll fibonacci(ll n) {
			fibnums.resize(n + 1, -1);
			return fibonacci_core(n);
		}

		static ll kmp(const std::string& sMain, const std::string& sFind) {
			std::vector<ll> vPrefix(sMain.size(), 0);
			// prefix
			for (ll i = 1; i < sMain.size(); i++) {
				ll k = vPrefix[i - 1];
				while (k > 0 && sMain[i] != sMain[k])
					k = vPrefix[k];
				if (sMain[i] == sMain[k])
					k++;
				vPrefix[i] = k;
			}
			// kmp
			ll answer = -1;
			ll k = 0;
			for (ll i = 0; i < sMain.length(); i++) {
				while (k > 0 && sMain[i] != sFind[k])
					k = vPrefix[k - 1];
				if (sMain[i] == sFind[k])
					k++;
				if (k == sFind.size()) {
					answer = i - sFind.size() + 1;
					break;
				}
			}
			return answer;
		}

		static ll combinations(ll n, ll k, ll mod) {
			if (n < k) swap(n, k);

			ll top = 1;
			for (ll x = max(n - k, k) + 1; x <= n; x++)
				top = (top*x) % mod;

			ll bottom = 1;
			for (ll x = 1; x <= min(n - k, k); x++)
				bottom = (bottom*x) % mod;

			ll x, y, g = gcdex(bottom, mod, x, y);

			if (g != 1)	throw(L"COMBINATIONS FAILED!");

			x = (x % mod + mod) % mod;

			return (top * x) % mod;
		}

	private:
		static vector<ll> fibnums;
		static ll fibonacci_core(ll n) {
			if (n == 0)
				return 0;
			if (n == 1 || n == 2)
				return 1;

			return fibnums[n] != -1 ? fibnums[n] : (fibnums[n] = fibonacci_core(n - 1) + fibonacci_core(n - 2));
		}
	};

	vector<ll> Help::fibnums;
}
/*************************************************************************/
/*************************************************************************/

typedef enum {none = 0, up = 1, toright = 2, toleft = 3, down = 4};

typedef struct P {
	int r, c, dir;
};


bool bfs(P start, P end, const vector<vector<char>>& v) {
	int n = v.size(), m = v.front().size();
	vector<vector<bool>> used(n, vector<bool>(m, false));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (v[i][j] == '*') used[i][j] = true;
		}
	}

	vector<vector<int>> turns(n, vector<int>(m, 0));

	queue<P> q;

	q.push(start);
	used[start.r][start.c] = true;


	while (!q.empty()) {

		P top = q.front();
		q.pop();

		if (top.c == end.c && top.r == end.r) {
			return true;
		}

		if (top.r - 1 >= 0 && v[top.r - 1][top.c] != '*' && (!used[top.r - 1][top.c] || ((top.dir == none || top.dir == up) && turns[top.r - 1][top.c] >= turns[top.r][top.c]) || turns[top.r - 1][top.c] >= turns[top.r][top.c] + 1)) { // up
			if (top.dir == none || top.dir == up) {
				turns[top.r - 1][top.c] = turns[top.r][top.c];
				used[top.r - 1][top.c] = 1;
				q.push({ top.r - 1, top.c, up });
			}
			else if (turns[top.r][top.c] < 2) {
				turns[top.r - 1][top.c] = turns[top.r][top.c] + 1;
				used[top.r - 1][top.c] = 1;
				q.push({ top.r - 1, top.c, up });
			}
		}

		if (top.r + 1 < n && v[top.r + 1][top.c] != '*' && (!used[top.r + 1][top.c] || ((top.dir == none || top.dir == down) && turns[top.r + 1][top.c] >= turns[top.r][top.c]) || turns[top.r + 1][top.c] >= turns[top.r][top.c] + 1)) { // down
			if (top.dir == none || top.dir == down) {
				turns[top.r + 1][top.c] = turns[top.r][top.c];
				used[top.r + 1][top.c] = 1;
				q.push({ top.r + 1, top.c, down });
			}
			else if (turns[top.r][top.c] < 2) {
				turns[top.r + 1][top.c] = turns[top.r][top.c] + 1;
				used[top.r + 1][top.c] = 1;
				q.push({ top.r + 1, top.c, down });
			}
		}


		if (top.c - 1 >= 0 && v[top.r][top.c - 1] != '*' &&  (!used[top.r][top.c - 1] || ((top.dir == none || top.dir == toleft) && turns[top.r][top.c - 1] >= turns[top.r][top.c]) || turns[top.r][top.c - 1] >= turns[top.r][top.c] + 1)) { // toleft
			if (top.dir == none || top.dir == toleft) {
				turns[top.r][top.c - 1] = turns[top.r][top.c];
				used[top.r][top.c - 1] = 1;
				q.push({ top.r, top.c - 1, toleft });
			}
			else if (turns[top.r][top.c] < 2) {
				turns[top.r][top.c - 1] = turns[top.r][top.c] + 1;
				used[top.r][top.c - 1] = 1;
				q.push({ top.r, top.c - 1, toleft });
			}
		}

		if (top.c + 1 < m && v[top.r][top.c + 1] != '*' && (!used[top.r][top.c + 1] || ((top.dir == none || top.dir == toright) && turns[top.r][top.c + 1] >= turns[top.r][top.c]) || turns[top.r][top.c + 1] >= turns[top.r][top.c] + 1)) { // toleft
			if (top.dir == none || top.dir == toright) {
				turns[top.r][top.c + 1] = turns[top.r][top.c];
				used[top.r][top.c + 1] = 1;
				q.push({ top.r, top.c + 1, toright });
			}
			else if (turns[top.r][top.c] < 2) {
				turns[top.r][top.c + 1] = turns[top.r][top.c] + 1;
				used[top.r][top.c + 1] = 1;
				q.push({ top.r, top.c + 1, toright });
			}
		}
	}

	return false;
}

int main()
{
	int n, m;

	while (cin >> n >> m) {
		
		vector<vector<char>> v(n, vector<char>(m, 0));
		P start, end;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++) {
				cin >> v[i][j];
				if (v[i][j] == 'S') {
					start.r = i;
					start.c = j;
				}
				if (v[i][j] == 'T') {
					end.r = i;
					end.c = j;
				}
			}

		start.dir = none, end.dir = none;

		cout << (bfs(start, end, v) ? "YES" : "NO") << endl;
		
	}

	return 0;
}
