#include <bits/stdc++.h>
using namespace std;
int n, m;
char board[2002][2002];
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
bool canInf = false;
bool v[2002][2002];
bool done[2002][2002];
int len[2002][2002];
int treeMax[4000001];
int treeID = 0;
int id[2002][2002];
void dfs(int x, int y) {
  if (v[x][y]) {
    if (done[x][y] == false) canInf = true;
    return;
  }
  v[x][y] = true;
  if (board[x][y] == '#') {
    len[x][y] = 0;
  } else {
    int f = 0;
    if (board[x][y] == '^') f = 0;
    if (board[x][y] == '>') f = 1;
    if (board[x][y] == 'v') f = 2;
    if (board[x][y] == '<') f = 3;
    dfs(x + dx[f], y + dy[f]);
    len[x][y] = len[x + dx[f]][y + dy[f]] + 1;
    if (len[x][y] == 1) {
      treeID++;
      id[x][y] = treeID;
    } else
      id[x][y] = id[x + dx[f]][y + dy[f]];
    treeMax[id[x][y]] = max(treeMax[id[x][y]], len[x][y]);
  }
  done[x][y] = true;
}
int MAIN() {
  cin >> n >> m;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) cin >> board[i][j];
  memset(v, 0, sizeof(v));
  memset(done, 0, sizeof(done));
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      if (!v[i][j]) dfs(i, j);
  if (canInf)
    cout << -1 << endl;
  else {
    int max1 = 0, max2 = 0;
    for (int i = 1; i <= treeID; i++) {
      if (treeMax[i] > max2) max2 = treeMax[i];
      if (max2 > max1) swap(max2, max1);
    }
    cout << max(max1 + max2, 2 * max1 - 1) << endl;
  }
  return 0;
}
int main() {
  ios ::sync_with_stdio(false);
  cout << fixed << setprecision(16);
  return MAIN();
}
