#include <iostream>
#include <algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<iomanip>
#include<ctime>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<bitset>
#define sqr(x) ((x)*(x))
#define fz1(i,n) for ((i)=1;(i)<=(n);(i)++)
#define fd1(i,n) for ((i)=(n);(i)>=1;(i)--)
#define fz0g(i,n) for ((i)=0;(i)<=(n);(i)++)
#define fd0g(i,n) for ((i)=(n);(i)>=0;(i)--)
#define fz0k(i,n) for ((i)=0;(i)<(n);(i)++)
#define fd0k(i,n) for ((i)=(long long)((n)-1);(i)>=0;(i)--)
#define fz(i,x,y) for ((i)=(x);(i)<=(y);(i)++)
#define fd(i,y,x) for ((i)=(y);(i)>=(x);(i)--)
#define fzin fz1(i,n)
#define fzim fz1(i,m)
#define fzjn fz1(j,n)
#define fzjm fz1(j,m)
#define ff(c,itr) for (__typeof((c).begin()) itr=(c).begin();itr!=(c).end();++itr)
#define pb push_back
#define mk make_pair
#define rdst(st,len){static char ss[len];scanf(" %s",ss);(st)=ss;}
#define inc(x,y) {x+=(y);if(x>=mod)x-=mod;}
#define dec(x,y) {x-=(y);if(x<0)x+=mod;}
#define spln(i,n) (i==n?'\n':' ')
#define fac_init(n){fac[0]=fac[1]=inv[1]=fi[0]=fi[1]=1;fz(i,2,n){fac[i]=1ll*fac[i-1]*i%mod;inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;fi[i]=1ll*fi[i-1]*inv[i]%mod;}}
using namespace std;
inline void read(int &x)
{
	char c;int f=1;
	while(!isdigit(c=getchar()))if(c=='-')f=-1;
	x=(c&15);while(isdigit(c=getchar()))x=(x<<1)+(x<<3)+(c&15);
	x*=f;
}
inline void read(char &x)
{
	char c;int f=1;
	while((c=getchar())!='.'&&c!='o'&&c!='#');
	x=c;
}
int n,m,i,j,cp,px[105],py[105],pz[105],cq,qx[2505],qy[2505],qz[2505];
char mp[55][55];int id[55][55],vis2[55][55];

int dis[3005],tot,inq[3005],cst,s=0,t=3001,vis[3005];
struct ii
{
	int y,z,d;
}e[1000005];
vector<int>bi[3005];
void add(int x,int y,int z,int d)
{
	tot++;
	bi[x].push_back(tot*2-2);
	bi[y].push_back(tot*2-1);
	e[tot*2-2]=(ii){y,z,d};
	e[tot*2-1]=(ii){x,0,-d};
}
bool bfs(int s,int t)
{
	queue<int> qx;memset(dis,0x3f,sizeof(dis));
	dis[s]=0;qx.push(s);
	while(!qx.empty()){
		int x=qx.front();qx.pop();inq[x]=0;
		ff(bi[x],it){
			if(e[*it].z&&dis[e[*it].y]>dis[x]+e[*it].d){
				dis[e[*it].y]=dis[x]+e[*it].d;
				if(!inq[e[*it].y]){
					inq[e[*it].y]=1;
					qx.push(e[*it].y);
				}
			}
		}
	}
	return dis[t]<dis[t+1];
}
int dfs(int x,int tt,int flw)
{
	if(!flw) return 0;
	if(x==tt){vis[x]=1;return flw;}
	if(vis[x])return 0;vis[x]=1;
	int ans=0;
	ff(bi[x],it){
		if(e[*it].z&&dis[e[*it].y]==dis[x]+e[*it].d){
			int t=dfs(e[*it].y,tt,min(flw,e[*it].z));
			flw-=t;ans+=t;e[*it].z-=t;e[(*it)^1].z+=t;
			cst+=t*e[*it].d;
		} 
	}
	return ans;
}
int dinic(int s,int t)
{
	int ans=0;
	while(bfs(s,t)){
		do{
			memset(vis,0,sizeof(vis));
			ans+=dfs(s,t,0x3f3f3f3f);
		}while(vis[t]);
	}return ans;
}
void dfs2(int x,int y,int id)
{
	if(x>n||y>m||mp[x][y]=='#'||vis2[x][y]) return;
	vis2[x][y]=1;
	if(mp[x][y]=='.'){
		add(id,cp+::id[x][y],1,-(qz[::id[x][y]]-pz[id]));
	}
	dfs2(x+1,y,id);dfs2(x,y+1,id);
}
int main()
{
	read(n);read(m);
	fz1(i,n){
		fz1(j,m){
			read(mp[i][j]);//cerr<<mp[i][j]<<' ';
			if(mp[i][j]=='o'){
				id[i][j]=++cp;
				px[cp]=i;py[cp]=j;pz[cp]=i+j;
			}
			else if(mp[i][j]=='.'){
				id[i][j]=++cq;
				qx[cq]=i;qy[cq]=j;qz[cq]=i+j;
			}
		}
	}
	fz1(i,cp){
		add(s,i,1,0);add(i,t,1,0);
		memset(vis2,0,sizeof(vis2));
		dfs2(px[i],py[i],i);
	}
	fz1(i,cq) add(i+cp,t,1,0);
	dinic(s,t);
	cout<<-cst<<endl;
	return 0;
}

Measured memory_bytes: 6056