#include <bits/stdc++.h>
class vec2i {
 public:
  int x;
  int y;
  vec2i() : x(0), y(0) {}
  vec2i(int x0, int y0) : x(x0), y(y0) {}
  bool operator==(const vec2i& c) const { return (x == c.x) && (y == c.y); }
  vec2i operator+(const vec2i& c) const { return vec2i(x + c.x, y + c.y); }
  bool operator!=(const vec2i& c) const { return !(*this == c); }
};
class map_point {
 public:
  bool is_free;
  bool is_viewd;
  map_point() : is_free(true), is_viewd(false) {}
};
class city_map_t {
 public:
  int width;
  int height;
  std::vector<map_point> grid;
  city_map_t(int width0, int height0)
      : width(width0), height(height0), grid(width0 * height0) {}
  map_point& operator()(int x, int y) { return grid[y * width + x]; }
  map_point& operator()(const vec2i& coord) {
    return grid[coord.y * width + coord.x];
  }
  const map_point& operator()(int x, int y) const {
    return grid[y * width + x];
  }
  const map_point& operator()(const vec2i& coord) const {
    return grid[coord.y * width + coord.x];
  }
};
bool is_valid(const vec2i& pos, const city_map_t& map) {
  return (pos.x >= 0) && (pos.x < map.width) && (pos.y >= 0) &&
         (pos.y < map.height) && (map(pos).is_free);
};
void trace(const vec2i& start, const vec2i& direction, city_map_t& map,
           std::queue<vec2i>& to_consider) {
  vec2i pos = start + direction;
  while (is_valid(pos, map)) {
    if (!map(pos).is_viewd) {
      map(pos).is_viewd = true;
      to_consider.push(pos);
    }
    pos = pos + direction;
  }
}
bool is_direct_way(const vec2i& start, const vec2i& end, city_map_t& map) {
  vec2i direction = vec2i(0, 0);
  if (!map(end).is_free) {
    return false;
  }
  if (start.x == end.x) {
    direction = vec2i(0, (end.y - start.y > 0) ? 1 : -1);
  } else if (start.y == end.y) {
    direction = vec2i((end.x - start.x > 0) ? 1 : -1, 0);
  } else {
    return false;
  }
  vec2i pos = start + direction;
  while (is_valid(pos, map) && pos != end) {
    pos = pos + direction;
  }
  return (pos == end);
}
bool is_one_turn_way(const vec2i& start, const vec2i& end, city_map_t& map) {
  vec2i first_corner = vec2i(start.x, end.y);
  vec2i second_corner = vec2i(end.x, start.y);
  return (is_direct_way(start, end, map)) ||
         (is_direct_way(start, first_corner, map) &&
          is_direct_way(first_corner, end, map)) ||
         (is_direct_way(start, second_corner, map) &&
          is_direct_way(second_corner, end, map));
}
int main(int argc, char** argv) {
  std::istream& input = std::cin;
  int height = [&]() {
    int tmp = 0;
    input >> tmp;
    return tmp;
  }();
  int width = [&]() {
    int tmp = 0;
    input >> tmp;
    return tmp;
  }();
  city_map_t city_map(width, height);
  vec2i start_pos;
  vec2i end_pos;
  for (int y = 0; y < height; ++y) {
    for (int x = 0; x < width; ++x) {
      char sym = input.get();
      while (sym == ' ' || sym == '\n') {
        sym = input.get();
      }
      switch (sym) {
        case '.':
          city_map(x, y).is_free = true;
          break;
        case '*':
          city_map(x, y).is_free = false;
          break;
        case 'S':
          start_pos = vec2i(x, y);
          break;
        case 'T':
          end_pos = vec2i(x, y);
          break;
        default:
          break;
      }
    }
  }
  std::queue<vec2i> nodes;
  trace(start_pos, vec2i(0, -1), city_map, nodes);
  trace(start_pos, vec2i(0, 1), city_map, nodes);
  trace(start_pos, vec2i(1, 0), city_map, nodes);
  trace(start_pos, vec2i(-1, 0), city_map, nodes);
  std::queue<vec2i> nodes_second_order;
  while (!nodes.empty() && (!(city_map(end_pos).is_viewd))) {
    vec2i cur_pos = nodes.front();
    nodes.pop();
    if (is_one_turn_way(cur_pos, end_pos, city_map)) {
      std::cout << "YES" << std::endl;
      return 0;
    }
  }
  if (city_map(end_pos).is_viewd) {
    std::cout << "YES" << std::endl;
  } else {
    std::cout << "NO" << std::endl;
  }
  return 0;
}
