#include <iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
int n, m;
int map[550][550];
int dis[550][550];
int vis[550][550];
int a, b;
int x, y;
typedef pair<int, int> P;
vector<P> tree;
int getdis(int i, int j) {
if (dis[i][j] != 0)
return dis[i][j];
int mind = 99999999;
for (auto t : tree) {
mind = min(mind, abs(t.first - i) + abs(t.second - j));
}
dis[i][j] = mind;
return mind;
}
bool check(int d) {
queue<P> st;
memset(vis, 0, sizeof(vis));
st.emplace(a, b);
int i, j;
while (!st.empty()) {
i = st.front().first, j = st.front().second;
st.pop();
if (getdis(i, j) < d)
continue;
if (i == x && j == y) {
return 1;
}
if (map[i + 1][j] > 0 && vis[i + 1][j] == 0) {
st.emplace(i + 1, j);
vis[i + 1][j] = 1;
}
if (map[i][j + 1] > 0 && vis[i][j + 1] == 0) {
st.emplace(i, j + 1);
vis[i][j + 1] = 1;
}
if (map[i - 1][j] > 0 && vis[i - 1][j] == 0) {
st.emplace(i - 1, j);
vis[i - 1][j] = 1;
}
if (map[i][j - 1] > 0 && vis[i][j - 1] == 0) {
st.emplace(i, j - 1);
vis[i][j - 1] = 1;
}
}
return 0;
}
int main()
{
cin >> n >> m;
char t;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> t;
map[i][j] = 1;
if (t == 'V')
a = i, b = j;
else if (t == 'J')
x = i, y = j;
else if (t == '+') {
map[i][j] = 2;
dis[i][j] = -1;
tree.emplace_back(i, j);
}
}
}
int l = 0, r = min(getdis(a, b), getdis(x, y)), mid;
while (l < r) {
mid = (l + r + 1) / 2;
if (check(mid))
l = mid;
else
r = mid - 1;
}
cout << l;
return 0;
}