Language: C++

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 100005
#define inf 1e9
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

inline int read()
{
	int x=0,w=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
	while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
	return w==1?x:-x;
}

char ch[maxn][maxn];

struct node{int from,to,cap,flow;};
vector <node> edges;
vector <int> mp[maxn];
int n,m,s,t,d[maxn],cur[maxn],F;
bool vis[maxn];
queue <int> que;

inline void A(int u,int v,int w)
{
	//cout<<u<<" "<<v<<" "<<w<<endl;
	edges.push_back((node){u,v,w,0});
	edges.push_back((node){v,u,0,0});
	int pp=edges.size();
	mp[u].push_back(pp-2);
	mp[v].push_back(pp-1);
}

inline bool bfs()
{
	for(int i=0;i<=2*n*m;i++) d[i]=inf,vis[i]=0; d[s]=0; vis[s]=1; que.push(s);
	while(!que.empty())
	{
		int u=que.front(); que.pop();
		for(int i=0;i<mp[u].size();i++)
		{
			node v=edges[mp[u][i]];
			if(v.cap-v.flow>0&&!vis[v.to])
			{
				d[v.to]=d[u]+1;
				vis[v.to]=1; que.push(v.to);
			}
		}
	}
	if(vis[t]) return true;
	return false;
}

inline int dfs(int u,int w)
{
	int flow=0,r=0;
	if(u==t||w==0) return w;
	for(int i=0;i<mp[u].size();i++)
	{
		node &v=edges[mp[u][i]];
		if(d[v.to]==d[u]+1&&(r=dfs(v.to,min(v.cap-v.flow,w)))>0)
		{
			flow+=r;
			edges[mp[u][i]].flow+=r;
			edges[mp[u][i]^1].flow-=r;
			w-=r;
			if(w==0) break;
		}
	}
	return flow;
}

inline int max_flow()
{
	int ff=0;
	while(bfs())
	{
		memset(cur,0,sizeof(cur));
		ff+=dfs(s,inf);
	}
	return ff;
}

inline int X(int x,int y){return (x-1)*m+y;}

inline void jud(int x,int y)
{
	for(int i=1;i<=n;i++) if(ch[i][y]=='T') F=1;
	for(int i=1;i<=m;i++) if(ch[x][i]=='T') F=1;
}

inline void a1(int x,int y)
{
	for(int i=1;i<=n;i++) if(ch[i][y]=='o') A(s,X(i,y),1);
	for(int i=1;i<=m;i++) if(ch[x][i]=='o') A(s,X(x,i),1);
}

inline void a2(int x,int y)
{
	for(int i=1;i<=n;i++) if(ch[i][y]=='o') A(X(i,y),t,1);
	for(int i=1;i<=m;i++) if(ch[x][i]=='o') A(X(x,i),t,1);
}

inline void a3(int x,int y)
{
	for(int i=1;i<=n;i++) if(ch[i][y]=='o'&&i!=x) A(X(x,y)+n*m,X(i,y),1);
	for(int i=1;i<=m;i++) if(ch[x][i]=='o'&&i!=y) A(X(x,y)+n*m,X(x,i),1);
}

int main()
{
	n=read(); m=read(); rep(i,1,n) scanf("%s",ch[i]+1);
	rep(i,1,n) rep(j,1,m)
	{
		if(ch[i][j]=='.') continue;
		if(ch[i][j]=='S') s=X(i,j),jud(i,j),a1(i,j);
		else if(ch[i][j]=='T') t=X(i,j)+n*m,a2(i,j);
	}
	rep(i,1,n) rep(j,1,m) if(ch[i][j]=='o') a3(i,j);
	rep(i,1,n) rep(j,1,m) if(ch[i][j]!='S'&&ch[i][j]!='T') A(X(i,j),X(i,j)+n*m,1);
	if(F) return puts("-1"),0;
	printf("%d\n",max_flow());
	return 0;
}

Compiler output:
/tmp/ccAmseN1.o: in function `__tcf_0':
a.cc:(.text+0x10): relocation truncated to fit: R_X86_64_PC32 against symbol `mp' defined in .bss section in /tmp/ccAmseN1.o
a.cc:(.text+0x17): relocation truncated to fit: R_X86_64_PC32 against symbol `mp' defined in .bss section in /tmp/ccAmseN1.o
/tmp/ccAmseN1.o: in function `__static_initialization_and_destruction_0()':
a.cc:(.text+0x3e): relocation truncated to fit: R_X86_64_PC32 against symbol `edges' defined in .bss section in /tmp/ccAmseN1.o
a.cc:(.text+0x57): relocation truncated to fit: R_X86_64_PC32 against symbol `edges' defined in .bss section in /tmp/ccAmseN1.o
a.cc:(.text+0x70): relocation truncated to fit: R_X86_64_PC32 against symbol `mp' defined in .bss section in /tmp/ccAmseN1.o
a.cc:(.text+0xb4): relocation truncated to fit: R_X86_64_PC32 against symbol `que' defined in .bss section in /tmp/ccAmseN1.o
a.cc:(.text+0xcd): relocation truncated to fit: R_X86_64_PC32 against symbol `que' defined in .bss section in /tmp/ccAmseN1.o
/tmp/ccAmseN1.o: in function `A(int, int, int)':
a.cc:(.text._Z1Aiii[_Z1Aiii]+0x7): relocation truncated to fit: R_X86_64_PC32 against symbol `edges' defined in .bss section in /tmp/ccAmseN1.o
a.cc:(.text._Z1Aiii[_Z1Aiii]+0x6c): relocation truncated to fit: R_X86_64_PC32 against symbol `mp' defined in .bss section in /tmp/ccAmseN1.o
/tmp/ccAmseN1.o: in function `bfs()':
a.cc:(.text._Z3bfsv[_Z3bfsv]+0x10): relocation truncated to fit: R_X86_64_PC32 against symbol `n' defined in .bss section in /tmp/ccAmseN1.o
a.cc:(.text._Z3bfsv[_Z3bfsv]+0x17): additional relocation overflows omitted from the output
collect2: error: ld returned 1 exit status