#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <tuple>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(x) ;
#else
#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template <typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 200010

int dx[8] = {0,0,1,-1,1,1,-1,-1};
int dy[8] = {1,-1,0,0,1,-1,1,-1};
char dirchar[] = "DURL"; // "SNWE"

int hx[8] = {0,0,1,-1,1,1,-1,-1};
int hy[8] = {1,-1,0,0,1,-1,1,-1};

//pos -> (x, y, dxdy, hand)

int check(int dir, int hand) {
  if (dir == 3) // < : 0 -1, -1 0, -1 -1, 1 -1
    return hand == 1 || hand == 3 || hand == 7 || hand == 5;
  if (dir == 2) // > : 0 1, 1 0, 1 1, -1 1
    return hand == 0 || hand == 2 || hand == 4 || hand == 6;
  if (dir == 1) // ^ : 0 -1, 1 -1, 1 0, 1 1
    return hand == 1 || hand == 5 || hand == 2 || hand == 4;
  if (dir == 0) // v : 0 1, -1 1, -1 0, -1 -1
    return hand == 0 || hand == 6 || hand == 3 || hand == 7;

  return false;
}

bool visited[51][51][8][8];

int main(){
  int H, W;
  char S[51][51];

  scanf("%d%d", &H, &W);

  int dir = -1;
  int hand = -1;
  int y, x;

  for (int i=0; i<H; i++) {
    scanf("%s", S[i]);

    for (int j=0; j<W; j++) {
      if (S[i][j] == '<') { y = i; x = j; dir = 3; hand = 1; }
      if (S[i][j] == '>') { y = i; x = j; dir = 2; hand = 0; }
      if (S[i][j] == '^') { y = i; x = j; dir = 1; hand = 2; }
      if (S[i][j] == 'v') { y = i; x = j; dir = 0; hand = 3; }
    }
  }


  queue<pair<pair<int, int>, pair<int, int>>> que;

  que.push({{y, x}, {dir, hand}});

  set<pair<int,int> > ss;

  ss.insert({y, x});

  for (int i=0; que.size(); i++) {
    queue<pair<pair<int, int>, pair<int, int>>> que2;

    while(que.size()) {
      auto p = que.front();
      que.pop();

      int y = p.first.first;
      int x = p.first.second;
      int dir = p.second.first;
      int hand = p.second.second;

      debug(make_pair(y, x));

      if (y < 0 || x < 0 || H <= y || W <= x) continue;
      if (S[y][x] == '#') continue;
      if (!check(dir, hand)) continue;

      if (visited[y][x][dir][hand]) continue;
      visited[y][x][dir][hand] = true;

      int handY = y + hy[hand];
      int handX = x + hx[hand];

      /*
      debug(hand);
      debug(S[handY][handX]);
      debug(make_pair(handY, handX));
      */

      if (!(handY < 0 || handX < 0 || H <= handY || W <= handX || S[handY][handX] == '#'))
        continue;

      ss.insert({y, x});

      if (S[y][x] == 'G') {
        printf("%d\n", (int)ss.size());
        return 0;
      }

      debug(make_pair(y, x));

      int nextHandY = hy[hand] - dy[dir];
      int nextHandX = hx[hand] - dx[dir];
      int nextHand = -1;
      for (int i=0; i<8; i++)
        if (nextHandY == hy[i] && nextHandX == hx[i])
          nextHand = i;

      if (nextHand != -1)
        que2.push({{y + dy[dir], x + dx[dir]}, {dir, nextHand}});

      for (int nextDir=0; nextDir<4; nextDir++) {
        if (dx[dir] == dx[nextDir] || dy[dir] == dy[nextDir]) continue;
        que.push({{y, x}, {nextDir, hand}});
      }

      for (int nextHand=0; nextHand<8; nextHand++) {
        if (abs(dx[hand] - dx[nextHand]) > 1 || abs(dy[hand] - dy[nextHand]) > 1) continue;
        que.push({{y, x}, {dir, nextHand}});
      }
    }

    que = que2;
  }

  puts("-1");

  return 0;
}




Measured memory_bytes: 3476