#include <bits/stdc++.h>
using namespace std;
int main() {
  ios::sync_with_stdio(false);
  int n, m;
  cin >> n >> m;
  vector<string> deck(n);
  string tmp;
  getline(cin, tmp);
  for (int r = 0; r < n; ++r) {
    getline(cin, deck[r]);
  }
  int row = 0, column = 0;
  int cur_comp = 1;
  int max_length = 0;
  int longest_comp = -1;
  vector<int> visited(n * m, 0);
  vector<int> lp(n * m, 0);
  while (1) {
    bool unvisited_found = false;
    int r = row;
    int c = column;
    for (; c < m; ++c) {
      if (deck[row][c] != '#' && !visited[row * m + c]) {
        unvisited_found = true;
        break;
      }
    }
    if (!unvisited_found) {
      c = 0;
      ++r;
      for (; r < n; ++r) {
        for (c = 0; c < m; ++c) {
          if (deck[r][c] != '#' && !visited[r * m + c]) {
            unvisited_found = true;
            break;
          }
        }
        if (unvisited_found) {
          break;
        }
      }
    }
    if (!unvisited_found) {
      break;
    }
    column = (c + 1) % m;
    row = r;
    if (!column) {
      ++row;
    }
    int index = r * m + c;
    int long_path = 0;
    int actual_component = cur_comp;
    visited[index] = cur_comp;
    stack<int> S;
    while (deck[r][c] != '#') {
      S.push(index);
      if (deck[r][c] == '<') {
        --c;
      } else if (deck[r][c] == '>') {
        ++c;
      } else if (deck[r][c] == '^') {
        --r;
      } else if (deck[r][c] == 'v') {
        ++r;
      }
      index = r * m + c;
      if (visited[index]) {
        if (visited[index] == cur_comp) {
          cout << -1 << endl;
          return 0;
        }
        long_path = lp[index];
        if (deck[r][c] != '#') {
          actual_component = visited[index];
        }
        break;
      } else {
        visited[index] = cur_comp;
      }
    }
    while (!S.empty()) {
      index = S.top();
      S.pop();
      ++long_path;
      lp[index] = long_path;
      visited[index] = actual_component;
    }
    if (long_path > max_length) {
      max_length = long_path;
      longest_comp = actual_component;
    }
    if (actual_component == cur_comp) {
      ++cur_comp;
    }
  }
  int res = 2 * max_length;
  bool res_ok = false;
  int not_blocked_count = 0;
  for (int r = 0; r < n; ++r) {
    for (int c = 0; c < m; ++c) {
      not_blocked_count += int(deck[r][c] != '#');
      if (lp[r * m + c] == max_length && visited[r * m + c] != longest_comp) {
        res_ok = true;
      }
    }
  }
  if (!res_ok || not_blocked_count <= 1) {
    --res;
  }
  cout << max(res, 0) << endl;
  return 0;
}
