mod max_flow {
    use std;
    type F = i32;
    pub const INF: F = 200;
    const ZERO: F = 0;
    fn non_zero(f: F) -> bool {
        f > ZERO
    }
    fn min(a: F, b: F) -> F {
        if a < b {a} else {b}
    }
    pub struct Graph {
        n: usize,
        depth: Vec<usize>,
        it: Vec<usize>,
        g: Vec<Vec<(usize, F, usize)>>,
    }
    impl Graph {
        pub fn new(n: usize) -> Graph {
            Graph {
                n: n,
                depth: vec![n + 1; n],
                it: vec![0; n],
                g: vec![vec![]; n],
            }
        }
        pub fn add_edge(&mut self, s: usize, t: usize, f: F) {
            let x = self.g[s].len();
            let y = self.g[t].len();
            self.g[s].push((t, f, y));
            self.g[t].push((s, ZERO, x));
        }
        fn bfs(&mut self, src: usize, dst: usize) {
            let g = &self.g;
            let n = self.n;
            let dp  = &mut self.depth;
            dp.clear();
            dp.resize(n, n + 1);
            dp[src] = 0;
            let mut q = std::collections::VecDeque::new();
            q.push_back(src);
            'outer: while let Some(v) = q.pop_front() {
                for &(u, f, _) in g[v].iter() {
                    if dp[u] > dp[v] + 1 && non_zero(f) {
                        dp[u] = dp[v] + 1;
                        if u == dst {
                            break 'outer;
                        }
                        q.push_back(u);
                    }
                }
            }
        }
        fn dfs(&mut self, v: usize, src: usize, f: F) -> F {
            if v == src {
                return f;
            }
            while self.it[v] < self.g[v].len() {
                let (u, _, inv) = self.g[v][self.it[v]];
                if self.depth[u] < self.depth[v] && non_zero(self.g[u][inv].1) {
                    let capa = min(f, self.g[u][inv].1);
                    let c = self.dfs(u, src, capa);
                    if non_zero(c) {
                        self.g[v][self.it[v]].1 += c;
                        self.g[u][inv].1 -= c;
                        return c;
                    }
                }
                self.it[v] += 1;
            }
            ZERO
        }
        pub fn flow(&mut self, src: usize, dst: usize) -> F {
            let mut ans = ZERO;
            loop {
                self.bfs(src, dst);
                if self.depth[dst] > self.n {
                    break;
                }
                self.it.clear();
                self.it.resize(self.n, 0);
                loop {
                    let f = self.dfs(dst, src, INF);
                    if non_zero(f) {
                        ans += f;
                    } else {
                        break;
                    }
                }
            }
            ans
        }
    }
}

use std::io::Read;

fn run() {
    let mut s = String::new();
    std::io::stdin().read_to_string(&mut s).unwrap();
    let mut it = s.trim().split_whitespace();
    let h: usize = it.next().unwrap().parse().unwrap();
    let w: usize = it.next().unwrap().parse().unwrap();
    let mut s: Vec<Vec<char>> = (0..h).map(|_| it.next().unwrap().chars().collect()).collect();
    let mut g = max_flow::Graph::new(2 * h * w);
    let mut src = 2 * h * w;
    let mut dst = 2 * h * w;
    for i in 0..h {
        for j in 0..w {
            if s[i][j] == 'S' {
                s[i][j] = 'o';
                src = i * w + j;
                g.add_edge(h * w + src, src, max_flow::INF);
            }
            if s[i][j] == 'T' {
                s[i][j] = 'o';
                dst = i * w + j;
                g.add_edge(h * w + dst, dst, max_flow::INF);
            }
        }
    }
    for i in 0..h {
        for j in 0..w {
            if s[i][j] == '.' {
                continue;
            }
            g.add_edge((h + i) * w + j, i * w + j, 1);
            for k in 0..h {
                if k == i {
                    continue;
                }
                if s[k][j] == 'o' {
                    g.add_edge(i * w + j, (h + k) * w + j, max_flow::INF);
                }
            }
            for k in 0..w {
                if k == j {
                    continue;
                }
                if s[i][k] == 'o' {
                    g.add_edge(i * w + j, (h + i) * w + k, max_flow::INF);
                }
            }
        }
    }
    let ans = g.flow(src, dst);
    if ans < 200 {
        println!("{}", ans);
    } else {
        println!("-1");
    }
}

fn main() {
    run();
}


Measured memory_bytes: 129276