#include using namespace std; typedef long long ll; typedef vector vi; typedef vector vl; typedef complex P; typedef pair pii; #define REP(i,n) for(ll i=0;i=n || b<0 || b>=m)return 0; if(mp[a][b] >= 0)return 0; mp[a][b] = id; int res = 1; REP(i,8){ res += dfs(a+vx[i],b+vy[i],id); } return res; } void dfs2(int a,int b,int par){ if(a<0 || a>=n || b<0 || b>=m)return; if(mp[a][b] == -1)return; if(mp[a][b] > 0){ po[a][b] = par; if(mp[a][b]!=par)return; } mp[a][b] = -1; REP(i,4) dfs2(a+vx[i],b+vy[i],par); } struct node{ int val; vector ch; node(int v):val(v){ ch = vector(); } void addch(node* n){ ch.push_back(n); } }; node* yey[125252]; // first: 直前を使った状態を含むmax // second: 直前を使ってない状態のmax pii dfs3(node* a){ pii ret; int cnt = a->ch.size(); pii sum; REP(i,cnt){ pii rec = dfs3(a->ch[i]); sum.first += rec.first; sum.second += rec.second; } ret.first = a->val + sum.second; ret.second = max(sum.first, sum.second); return ret; } int main(){ cin>>n>>m; n+=2; m+=2; REP(i,n){ string s; if(i==0 || i==n-1){ s = string(m,'.'); }else{ cin>>s; s = '.' + s + '.'; } REP(j,m){ mp[i][j] = (s[j]=='x'?-1:0); } } // grouping int wawa[125252]; int iter = 1; REP(i,n)REP(j,m){ if(mp[i][j]>=0)continue; wawa[iter] = dfs(i,j,iter); iter++; } iter--; // iter個の輪っか // 被覆しながら木構造の形成 int left=0, top=0, right=n-1, bottom=m-1; int root = 125222; yey[root] = new node(0); dfs2(0,0,root); while(true){ bool flag = false; int nl,nt,nr,nb; nl=right; nt=bottom; nr=left; nb=top; FOR(i,left,right+1)FOR(j,top,bottom+1){ if(mp[i][j]<=0)continue; nl=min(nl,i); nr=max(nr,i); nt=min(nt,j); nb=min(nb,j); int id = mp[i][j]; yey[id] = new node(wawa[id]); yey[po[i][j]]->addch(yey[id]); dfs2(i,j,id); flag = true; } if(!flag)break; left=nl; right=nr; top=nt; bottom=nb; } // 終わった~~~~~ int res = 0; REP(i,(yey[root]->ch).size()){ node* to = (yey[root]->ch)[i]; pii x = dfs3(to); res += max(x.first,x.second); } cout<