macro_rules ! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut iter = $ s . split_whitespace ( ) ; input_inner ! { iter , $ ( $ r ) * } } ; ( iter = $ iter : ident , $ ( $ r : tt ) * ) => { let s = { use std :: io :: Read ; let mut s = String :: new ( ) ; std :: io :: stdin ( ) . read_to_string ( & mut s ) . unwrap ( ) ; s } ; let mut $ iter = s . split_whitespace ( ) ; input_inner ! { $ iter , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { let s = { use std :: io :: Read ; let mut s = String :: new ( ) ; std :: io :: stdin ( ) . read_to_string ( & mut s ) . unwrap ( ) ; s } ; let mut iter = s . split_whitespace ( ) ; input_inner ! { iter , $ ( $ r ) * } } ; }
macro_rules ! input_inner { ( $ iter : expr ) => { } ; ( $ iter : expr , ) => { } ; ( $ iter : expr , mut $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let mut $ var = read_value ! ( $ iter , $ t ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , mut $ var : ident $ ( $ r : tt ) * ) => { input_inner ! { $ iter , mut $ var : usize $ ( $ r ) * } } ; ( $ iter : expr , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ iter , $ t ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , $ var : ident $ ( $ r : tt ) * ) => { input_inner ! { $ iter , $ var : usize $ ( $ r ) * } } ; }
macro_rules ! read_value { ( $ iter : expr , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ iter , $ t ) ) ,* ) } ; ( $ iter : expr , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ iter , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ iter : expr , { chars : $ base : expr } ) => { read_value ! ( $ iter , String ) . chars ( ) . map ( | c | ( c as u8 - $ base as u8 ) as usize ) . collect ::< Vec < usize >> ( ) } ; ( $ iter : expr , { char : $ base : expr } ) => { read_value ! ( $ iter , { chars : $ base } ) [ 0 ] } ; ( $ iter : expr , chars ) => { read_value ! ( $ iter , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ iter : expr , char ) => { read_value ! ( $ iter , chars ) [ 0 ] } ; ( $ iter : expr , usize1 ) => { read_value ! ( $ iter , usize ) - 1 } ; ( $ iter : expr , $ t : ty ) => { $ iter . next ( ) . unwrap ( ) . parse ::<$ t > ( ) . unwrap ( ) } ; }
#[derive(Debug, Clone)]
pub struct RevEdge {
    pub to: usize,
    pub rev: usize,
    pub cap: u64,
}
impl RevEdge {
    pub fn new(to: usize, rev: usize, cap: u64) -> RevEdge {
        RevEdge {
            to: to,
            rev: rev,
            cap: cap,
        }
    }
}
#[derive(Debug)]
pub struct Dinic {
    graph: Vec<Vec<RevEdge>>,
    iter: Vec<usize>,
    level: Vec<usize>,
}
impl Dinic {
    pub fn new(n: usize) -> Dinic {
        Dinic {
            graph: vec![vec![]; n],
            iter: vec![],
            level: vec![],
        }
    }
    pub fn add_edge(&mut self, from: usize, to: usize, cap: u64) {
        let e1 = RevEdge::new(to, self.graph[to].len(), cap);
        let e2 = RevEdge::new(from, self.graph[from].len(), 0);
        self.graph[from].push(e1);
        self.graph[to].push(e2);
    }
    fn bfs(&mut self, s: usize) {
        self.level = vec![std::usize::MAX; self.graph.len()];
        let mut deq = std::collections::VecDeque::new();
        self.level[s] = 0;
        deq.push_back(s);
        while let Some(u) = deq.pop_front() {
            for e in &self.graph[u] {
                if e.cap > 0 && self.level[e.to] == std::usize::MAX {
                    self.level[e.to] = self.level[u] + 1;
                    deq.push_back(e.to);
                }
            }
        }
    }
    fn dfs(&mut self, u: usize, t: usize, f: u64) -> u64 {
        if u == t {
            return f;
        }
        for i in self.iter[u]..self.graph[u].len() {
            self.iter[u] = i;
            let RevEdge { to, rev, cap } = self.graph[u][i];
            if cap > 0 && self.level[u] < self.level[to] {
                let d = self.dfs(to, t, std::cmp::min(f, cap));
                if d > 0 {
                    self.graph[u][i].cap -= d;
                    self.graph[to][rev].cap += d;
                    return d;
                }
            }
        }
        0
    }
    pub fn maximum_flow(&mut self, s: usize, t: usize) -> u64 {
        let mut flow = 0;
        loop {
            self.bfs(s);
            if self.level[t] == std::usize::MAX {
                return flow;
            }
            self.iter = vec![0; self.graph.len()];
            loop {
                let f = self.dfs(s, t, std::u64::MAX);
                if f == 0 {
                    break;
                }
                flow += f;
            }
        }
    }
}
fn main() {
    input! { h, w, a: [chars; h] };
    let mut dinic = Dinic::new(h + w + 2);
    const INF: u64 = 1_001_001_001;
    for i in 0..h {
        for j in 0..w {
            match a[i][j] {
                'S' => {
                    dinic.add_edge(h + w, i, INF);
                    dinic.add_edge(h + w, h + j, INF);
                }
                'T' => {
                    dinic.add_edge(i, h + w + 1, INF);
                    dinic.add_edge(h + j, h + w + 1, INF);
                }
                'o' => {
                    dinic.add_edge(i, h + j, 1);
                    dinic.add_edge(h + j, i, 1);
                }
                _ => {}
            }
        }
    }
    let f = dinic.maximum_flow(h + w, h + w + 1);
    println!("{}", if f >= INF { -1i64 } else { f as i64 });
}


Measured memory_bytes: 4352