#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
using namespace std;
typedef long long LL;
int gi() {
	int w=0;bool q=1;char c=getchar();
	while ((c<'0'||c>'9') && c!='-') c=getchar();
	if (c=='-') q=0,c=getchar();
	while (c>='0'&&c <= '9') w=w*10+c-'0',c=getchar();
	return q? w:-w;
}
const int N=110;
int h[N][N],u[N][N];
int f[N][N][N],g[N][N][N];
inline void upd(int &x,int y) { x<y?x=y:0; }
int main()
{
	int n=gi(),m=gi(),i,j,x,y,lx,rx,ly,ry,t;
	char c;
	for (i=1;i<=n;i++)
		for (j=1;j<=m;j++) {
			h[i][j]=h[i][j-1];u[i][j]=u[i-1][j];
			while ((c=getchar())!='.'&&c!='E'&&c!='o');
			if (c=='E') x=i,y=j;
			else if (c=='o') h[i][j]++,u[i][j]++;
		}
	for (lx=0;lx<x;lx++) {
		memcpy(g,f,sizeof(g));
		memset(f,0,sizeof(f));
		for (rx=0;rx<=n-x;rx++)
			for (ly=0;ly<y;ly++)
				for (ry=0;ry<=m-y;ry++) {
					t=g[rx][ly][ry];
					upd(f[rx][ly][ry],t+(x-lx-1>rx?h[x-lx-1][min(y+ry,m-ly)]-h[x-lx-1][max(y-ly-1,ry)]:0));
					upd(g[rx+1][ly][ry],t+(x+rx+1<=n-lx?h[x+rx+1][min(y+ry,m-ly)]-h[x+rx+1][max(y-ly-1,ry)]:0));
					upd(g[rx][ly+1][ry],t+(y-ly-1>ry?u[min(x+rx,n-lx)][y-ly-1]-u[max(x-lx-1,rx)][y-ly-1]:0));
					upd(g[rx][ly][ry+1],t+(y+ry+1<=m-ly?u[min(x+rx,n-lx)][y+ry+1]-u[max(x-lx-1,rx)][y+ry+1]:0));
				}
	}
	printf("%d\n",g[n-x][y-1][m-y]);
	return 0;
}

#include<bits/stdc++.h>

#define _GLIBCXX_DEBUG
#define all(v) (v).begin(),(v).end()

using namespace std;

using ll=long long;
using pii=pair<int, int>;
using vi=vector<int>;
using vii=vector<vector<int>>;

const ll LINF=1LL<<60;
const int INF=1<<29;
const int MOD=1e9+7;

template<typename T> bool chmax(T &a,const T b){if(a < b){a=b; return true;} return false;}
template<typename T> bool chmin(T &a,const T b){if(a > b){a=b; return true;} return false;}

const int MAX_N=1005;
const int MAX_V=MAX_N*(MAX_N-1)/2;
vii G(MAX_V);
int id[MAX_N][MAX_N];
bool vis[MAX_V];
bool fin[MAX_V];
int dp[MAX_V];

int dfs(int v){
    if(vis[v]){
        if(!fin[v]) return -1;
        else return dp[v];
    }
    vis[v]=true;
    dp[v]=1;
    for(auto &nv : G[v]){
        int res=dfs(nv);
        if(res == -1) return -1;
        dp[v]=max(dp[v], res+1);
    }
    fin[v]=true;
    return dp[v];
}

int main(){
    int n; cin >> n;
    vii a(n, vi(n-1));
    for(int i=0; i<n; i++){
        for(int j=0; j<n-1; j++){
            cin >> a[i][j];
            a[i][j]--;
        }
    }
    int num=0;
    for(int i=0; i<n-1; i++) for(int j=i+1; j<n; j++) id[i][j]=num++;
    for(int i=0; i<n; i++){
        for(int j=0; j<n-1; j++){
            if(i > a[i][j]) a[i][j]=id[a[i][j]][i];
            else a[i][j]=id[i][a[i][j]];
        }
        for(int j=0; j<n-2; j++){
            G[a[i][j]].push_back(a[i][j+1]);
        }
    }
    int ans=0;
    for(int i=0; i<num; i++){
        int res=dfs(i);
        if(res == -1){
            ans=-1;
            break;
        }
        chmax(ans, res);
    }
    cout << ans << endl;
    return 0;
}