#include <bits/stdc++.h>
using namespace std;
struct vertex {
  int x, y, d, dir;
  bool operator<(const vertex &r) const { return d > r.d; }
};
char grid[1005][1005];
bool seen[1005][1005][4];
int dist[1005][1005][4];
int n, m;
int sp(pair<int, int> s, pair<int, int> t) {
  priority_queue<vertex> pq;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      for (int k = 0; k < 4; k++) {
        dist[i][j][k] = 1000000000;
        seen[i][j][k] = 0;
      }
  vertex v = {s.first, s.second, 0, 0};
  for (int d = 0; d < 4; d++) {
    v.dir = d;
    pq.push(v);
    dist[v.x][v.y][d] = 0;
  }
  while (!pq.empty()) {
    vertex p = pq.top();
    pq.pop();
    if (p.x == t.first && p.y == t.second) return p.d;
    if (seen[p.x][p.y][p.dir]) continue;
    seen[p.x][p.y][p.dir] = 1;
    for (int d = 0; d < 4; d++) {
      if (1 + dist[p.x][p.y][p.dir] < dist[p.x][p.y][d]) {
        vertex p1 = p;
        p1.dir = d;
        p1.d = dist[p.x][p.y][p.dir] + 1;
        dist[p.x][p.y][d] = p1.d;
        pq.push(p1);
      }
    }
    int xo = 0, yo = 0;
    switch (p.dir) {
      case 0:
        xo = -1;
        break;
      case 1:
        yo = 1;
        break;
      case 2:
        xo = 1;
        break;
      case 3:
        yo = -1;
        break;
    }
    if (p.x + xo < n && p.x + xo >= 0 && p.y + yo < m && p.y + yo >= 0) {
      if (grid[p.x + xo][p.y + yo] != '*') {
        if (dist[p.x][p.y][p.dir] < dist[p.x + xo][p.y + yo][p.dir]) {
          vertex p1 = p;
          p1.x += xo;
          p1.y += yo;
          dist[p1.x][p1.y][p.dir] = dist[p.x][p.y][p.dir];
          pq.push(p1);
        }
      }
    }
  }
  return 1000000000;
}
int main() {
  cin >> n >> m;
  pair<int, int> s, t;
  for (int i = 0; i < n; i++) {
    cin >> grid[i];
    for (int j = 0; j < m; j++)
      if (grid[i][j] == 'S')
        s = pair<int, int>(i, j);
      else if (grid[i][j] == 'T')
        t = pair<int, int>(i, j);
  }
  if (sp(s, t) <= 2)
    cout << "YES\n";
  else
    cout << "NO\n";
}
