#include <bits/stdc++.h>
using namespace std;

const int DIM = 2e4 + 5;
int nrNodes, nrEdges, node1, node2, cost;

char arr[DIM / 100][DIM / 100];

vector<int> Edges[DIM]; int Father[DIM];
bitset<DIM> Marked; deque <int> Queue;
 bitset<DIM> Quantity[DIM], maxFlow[DIM], Value[DIM];


inline int f( int x, int y ) {
    if( maxFlow[x][y] == 0 && Value[x][y] == 0 ) return 0;
    if( maxFlow[x][y] == 1 && Value[x][y] == 0 ) return 1;
    return -1;
}

inline void g( int x, int y, int z ) {
    if( z == 0 )
        maxFlow[x][y] = Value[x][y] = 0;
    else
    if( z == -1 )
        maxFlow[x][y] = Value[x][y] = 1;
    else {
        maxFlow[x][y] = 1;
        Value[x][y] = 0;
    }

    return;
}

bool BFS (int startNode, int finishNode)
{
    Father[startNode] = -1;
    Marked.reset();
    Queue.clear();
    
    int ok = 0;
    Queue.push_back(startNode);
    Marked[startNode] = 1;
    
    while (!Queue.empty())
    {
        int node = Queue.front();
        
        vector <int> :: iterator it;
        for (it = Edges[node].begin(); it != Edges[node].end(); it ++)
        {
            int nextNode = *it;
            
            if (!Marked[nextNode] && f( node, nextNode ) < Quantity[node][nextNode])
            {
                Marked[nextNode] = 1;
                Father[nextNode] = node;
                Queue.push_back(nextNode);
                
                if (nextNode == finishNode)
                    ok = 1;
            }
        }
        
        Queue.pop_front();
    }
    
    return ok;
}

int main ()
{
    
    int n, m;
    scanf( "%d %d", &n, &m );
    
    bool ok = true;
    
    int st = 0, nrNodes = 0;
    for( int i = 0; i < n; i ++ ) {
        cin >> arr[i];
        
        for( int j = 0; j < m; j ++ ) {
            Edges[i * m + j + n * m].push_back( i * m + j );
            Edges[i * m + j].push_back( i * m + j + n * m );
            Quantity[i * m + j + n * m][i * m + j] = 1;
            
            if( arr[i][j] == 'S' )
                st = i * m + j;
            if( arr[i][j] == 'T' )
                nrNodes = i * m + j + n * m;
            
            if( arr[i][j] == '.' )
                continue;
            
            for( int k = j - 1; k >= 0; k -- ) {
                if( arr[i][k] != '.' ) {
                    if( arr[i][k] != 'o' && arr[i][j] != 'o' )
                        ok = false;
                    
                    Quantity[i * m + k][i * m + j + n * m] = Quantity[i * m + j][i * m + k + n * m] = 1;
                    
                    Edges[i * m + k].push_back( i * m + j + n * m );
                    Edges[i * m + j].push_back( i * m + k + n * m );
                    Edges[ i * m + j + n * m ].push_back( i * m + k );
                    Edges[ i * m + k + n * m ].push_back( i * m + j );
                }
            }
            
            for( int k = i - 1; k >= 0; k -- ) {
                if( arr[k][j] != '.' ) {
                    if( arr[k][j] != 'o' && arr[i][j] != 'o' )
                        ok = false;
                    
                    Quantity[k * m + j][i * m + j + n * m] = Quantity[i * m + j][k * m + j + n * m] = 1;
                    
                    Edges[i * m + j].push_back( k * m + j + n * m );
                    Edges[k * m + j].push_back( i * m + j + n * m );
                    Edges[k * m + j + n * m].push_back( i * m + j );
                    Edges[i * m + j + n * m].push_back( k * m + j );
                }
            }
        }
    }
    
    if( ok == false ) {
        printf( "-1" );
        return 0;
    }
    
    int sum = 0;
    while ( BFS(st, nrNodes) )
    {
        int node = nrNodes;
        
        vector <int> :: iterator it;
        for (it = Edges[node].begin(); it != Edges[node].end(); it ++)
        {
            int nextNode = *it;
            
            if (Marked[nextNode] && f( nextNode, node ) < Quantity[nextNode][node])
            {
                int minim = Quantity[nextNode][node] - f( nextNode, node ), newNode;
                
                newNode = nextNode;
                while (Father[newNode] != -1)
                {
                    minim = min(minim, Quantity[Father[newNode]][newNode] - f( Father[newNode], newNode ) );
                    newNode = Father[newNode];
                }
                
                sum += minim;
                g( nextNode, node, f( nextNode, node ) + minim );
                g( node, nextNode, f( node, nextNode ) - minim );
                
                newNode = nextNode;
                while (Father[newNode] != -1)
                {
                    g( Father[newNode], newNode, f( Father[newNode], newNode ) + minim );
                    g( newNode, Father[newNode], f( newNode, Father[newNode] ) - minim );
                    newNode = Father[newNode];
                }
            }
        }
    }
    
    printf ("%d\n", sum);
    
    fclose (stdin );
    fclose (stdout);
    
    return 0;
}

Measured memory_bytes: 166272