#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;   }