#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int maxn=100010;
const int maxm=4001100;
const int INF=0X3f3f3f3f;
struct Edge
{
    int to,next,cap,flow;
}edge[maxm];
int tol;
int head[maxn];
int gap[maxn],dep[maxn],cur[maxn];
void init()
{
    tol=0;
    memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w,int rw=0)
{
    //cout<<u<<" "<<v<<" "<<w<<endl;
    edge[tol].to=v; edge[tol].cap=w; edge[tol].flow=0;
    edge[tol].next=head[u]; head[u]=tol++;
    edge[tol].to=u; edge[tol].cap=rw; edge[tol].flow=0;
    edge[tol].next=head[v]; head[v]=tol++;
}
int Q[maxn];
void BFS(int start,int end)
{
    memset(dep,-1,sizeof(dep));
    memset(gap,0,sizeof(gap));
    gap[0]=1;
    int front=0,rear=0;
    dep[end]=0;
    Q[rear++]=end;
    while(front!=rear)
    {
        int u=Q[front++];
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].to;
            if(dep[v]!=-1) continue;
            Q[rear++]=v;
            dep[v]=dep[u]+1;
            gap[dep[v]]++;
        }
    }
}
int S[maxn];
int sap(int start,int end,int N)
{
    BFS(start,end);
    memcpy(cur,head,sizeof(head));
    int top=0;
    int u=start;
    int ans=0;
    while(dep[start]<N)
    {
        if(u==end)
        {
            int Min=INF;
            int inser;
            for(int i=0;i<top;++i)
                if(Min>edge[S[i]].cap-edge[S[i]].flow)
                {
                    Min=edge[S[i]].cap-edge[S[i]].flow;
                    inser=i;
                }
            for(int i=0;i<top;++i)
            {
                edge[S[i]].flow+=Min;
                edge[S[i]^1].flow-=Min;
            }
            ans+=Min;
            top=inser;
            u=edge[S[top]^1].to;
            continue;
        }
        bool flag=false;
        int v;
        for(int i=cur[u];i!=-1;i=edge[i].next)
        {
            v=edge[i].to;
            if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u])
            {
                flag=true;
                cur[u]=i;
                break;
            }
        }
        if(flag)
        {
            S[top++]=cur[u];
            u=v;
            continue;
        }
        int Min=N;
        for(int i=head[u];i!=-1;i=edge[i].next)
            if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<Min)
            {
                Min=dep[edge[i].to];
                cur[u]=i;
            }
        gap[dep[u]]--;
        if(!gap[dep[u]]) return ans;
        dep[u]=Min+1;
        gap[dep[u]]++;
        if(u!=start) u=edge[S[--top]^1].to;
    }
    return ans;
}
char s[150][150];
int sx,sy,ex,ey;
vector<int>g1[150],g2[150];
int n,m;
int get_poi(int x,int y,int add)
{
    return x*m+y+add;
}
int main()
{
    scanf("%d%d",&n,&m);
    init();
    for(int i=0;i<n;++i) scanf("%s",s[i]);
    for(int i=0;i<n;++i) g1[i].clear();
    for(int i=0;i<m;++i) g2[i].clear();
    for(int i=0;i<n;++i)
        for(int j=0;j<m;++j)
        {
            if(s[i][j]=='.') continue;
            if(s[i][j]=='S')
            {
                sx=i;
                sy=j;
            }
            if(s[i][j]=='T')
            {
                ex=i;
                ey=j;
            }
            g1[i].push_back(j);
            g2[j].push_back(i);
        }
    int px,py;
    if(sx==ex||sy==ey) {puts("-1"); exit(0);}
    for(int i=0;i<n;++i)
    {
        for(int j=0;j<(int)g1[i].size();++j)
        {
            px=i; py=g1[i][j];
            addedge(get_poi(px,py,0),get_poi(px,py,n*m),1);
            for(int k=0;k<(int)g1[i].size();++k)
                if(j!=k)
                    addedge(get_poi(px,py,n*m),get_poi(i,g1[i][k],0),INF);
        }
    }
    for(int i=0;i<m;++i)
    {
        for(int j=0;j<(int)g2[i].size();++j)
            for(int k=0;k<(int)g2[i].size();++k)
                if(j!=k)
                    addedge(get_poi(g2[i][j],i,n*m),get_poi(g2[i][k],i,0),INF);
    }
    int ans=sap(get_poi(sx,sy,n*m),get_poi(ex,ey,0),n*m*2);
    printf("%d\n",ans);
    return 0;
}


Measured memory_bytes: 64256