#include <bits/stdc++.h>
using namespace std;
char board[2100][2100];
int mark[2100][2100];
class Graph {
  int V;
  list<int> *adj;
  bool isCyclicUtil(int v, bool visited[], bool *rs);

 public:
  Graph(int V);
  void addEdge(int v, int w);
  bool isCyclic();
};
Graph::Graph(int V) {
  this->V = V;
  adj = new list<int>[V];
}
void Graph::addEdge(int v, int w) { adj[v].push_back(w); }
bool Graph::isCyclicUtil(int v, bool visited[], bool *recStack) {
  if (visited[v] == false) {
    visited[v] = true;
    recStack[v] = true;
    list<int>::iterator i;
    for (i = adj[v].begin(); i != adj[v].end(); ++i) {
      if (!visited[*i] && isCyclicUtil(*i, visited, recStack))
        return true;
      else if (recStack[*i])
        return true;
    }
  }
  recStack[v] = false;
  return false;
}
bool Graph::isCyclic() {
  bool *visited = new bool[V];
  bool *recStack = new bool[V];
  for (int i = 0; i < V; i++) {
    visited[i] = false;
    recStack[i] = false;
  }
  for (int i = 0; i < V; i++)
    if (isCyclicUtil(i, visited, recStack)) return true;
  return false;
}
int move(int i, int j) {
  int i0 = i, j0 = j;
  if (board[i][j] == '#') return 0;
  int di = 0, dj = 0;
  if (mark[i][j] != 0) {
    return mark[i][j];
  }
  di = 0;
  dj = 0;
  if (board[i][j] == 'v') di = 1;
  if (board[i][j] == '^') di = -1;
  if (board[i][j] == '>') dj = 1;
  if (board[i][j] == '<') dj = -1;
  i += di;
  j += dj;
  if (mark[i][j] != 0) {
    mark[i0][j0] = mark[i][j] + 1;
    return mark[i][j] + 1;
  } else {
    int d = move(i, j);
    mark[i0][j0] = d + 1;
    return d + 1;
  }
}
bool check(int i1, int j1, int i2, int j2) {
  if (board[i1][j1] == '#' || board[i1][j2] == '#') return false;
  int di1 = 0, dj1 = 0, di2 = 0, dj2 = 0;
  while (board[i1][j1] != '#' || board[i2][j2] != '#') {
    di1 = 0;
    dj1 = 0, di2 = 0, dj2 = 0;
    if (board[i1][j1] == 'v') di1 = 1;
    if (board[i1][j1] == '^') di1 = -1;
    if (board[i1][j1] == '>') dj1 = 1;
    if (board[i1][j1] == '<') dj1 = -1;
    i1 += di1;
    j1 += dj1;
    if (board[i2][j2] == 'v') di2 = 1;
    if (board[i2][j2] == '^') di2 = -1;
    if (board[i2][j2] == '>') dj2 = 1;
    if (board[i2][j2] == '<') dj2 = -1;
    i2 += di2;
    j2 += dj2;
    if (i1 == i2 && j1 == j2)
      if (board[i1][j1] != '#') return false;
  }
  return true;
}
Graph g(2000 * 2000);
int main() {
  int n, m, max = 0, val = 0, maxi[2000], maxj[2000], num = 0, cnt = 0;
  bool f = false;
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> board[i][j];
      if (board[i][j] == 'v' && cnt < 10000) {
        g.addEdge(m * i + j, m * (i + 1) + j);
        cnt++;
      }
      if (board[i][j] == '^' && cnt < 10000) {
        g.addEdge(m * i + j, m * (i - 1) + j);
        cnt++;
      }
      if (board[i][j] == '>' && cnt < 10000) {
        g.addEdge(m * i + j, m * i + j + 1);
        cnt++;
      }
      if (board[i][j] == '<' && cnt < 10000) {
        g.addEdge(m * i + j, m * i + j - 1);
        cnt++;
      }
    }
  }
  if (g.isCyclic()) {
    cout << -1;
    return 0;
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      val = move(i, j);
      if (val == max && !f && max != 0) {
        maxj[num] = j;
        maxi[num] = i;
        num++;
      }
      if (val > max) {
        max = val;
        maxi[0] = i;
        maxj[0] = j;
        num = 1;
        f = false;
      }
    }
  }
  if (max == 0) {
    cout << 0;
    return 0;
  }
  if (num > 1) f = check(maxi[0], maxj[0], maxi[1], maxj[1]);
  if (num > 2) {
    for (int i = 2; i < num; i++) {
      if (!f) {
        f = check(maxi[1], maxj[1], maxi[i], maxj[i]);
      }
    }
  }
  if (f)
    cout << max * 2;
  else
    cout << max * 2 - 1;
}
