#include<iostream>
#include<tuple>
#include<vector>
#include<deque>
#include<queue>
#include<cstring>
using namespace std;
typedef tuple<int, int, int, int, int> i5;

int n, m, sx, sy, gx, gy, d;
int dy[] = {-1, 0, 1, 0}, dx[] = {0, -1, 0, 1};

int diry[4][4] = {{-1, -1,  0,  1},
                  { 0, -1, -1, -1},
                  { 1,  1,  0, -1},
                  { 0,  1,  1,  1}};

int dirx[4][4] = {{ 0,  1,  1,  1},
                  {-1, -1,  0,  1},
                  { 0, -1, -1, -1},
                  { 1,  1,  0, -1}};

bool range(int y, int x){
  return (0 <= y and y < n and 0 <= x and x < m);
}

int main(int argc, char *argv[]){
  cin >> n >> m;
  n += 2, m += 2;
  vector<string> grid(n);
  grid[0] = string(m, '#');
  for (int i = 1; i < n - 1; i++) {
    string tmp;
    cin >> tmp;
    grid[i] = "#" + tmp + "#";
    for (int j = 0; j < grid[i].size(); j++) {
      if(grid[i][j] == 'G')gx = j, gy = i;
      if(grid[i][j] == '^')sx = j, sy = i, d = 0; 
      if(grid[i][j] == '<')sx = j, sy = i, d = 1; 
      if(grid[i][j] == 'v')sx = j, sy = i, d = 2; 
      if(grid[i][j] == '>')sx = j, sy = i, d = 3; 
    }
  }
  grid[n - 1] = string(m, '#');
  
  int g[n][m][4][4];//y, x, dir, hand
  for (int i = 0; i < n; i++) 
    for (int j = 0; j < m; j++) 
      for (int k = 0; k < 4; k++) 
        for (int l = 0; l < 4; l++) g[i][j][k][l] = 1e9;
  
  priority_queue<i5, vector<i5>, greater<i5> > que;
  bool used[n][m];
  memset(used, false, sizeof(used));
    
  g[sy][sx][d][2] = 1;
  que.push(i5(1, sy, sx, d, 2));

  while(not que.empty()){
    int y    = get<1>(que.top());
    int x    = get<2>(que.top());
    int dir  = get<3>(que.top());
    int hand = get<4>(que.top());
    int cost = g[y][x][dir][hand];
    que.pop();
    used[y][x] = true;
    int ny = y + dy[dir], nx = x + dx[dir];
    //std::cout << "x:" << x << " y:" << y << " hand:" << hand << " dir:" << dir <<  std::endl;
    //??´???
    if(range(ny, nx) and (hand != 0 and hand != 3) and
       grid[ny][nx] != '#'){
      int c = not used[ny][nx];
      if(g[ny][nx][dir][hand + 1] > cost + c) {
        g[ny][nx][dir][hand + 1] = cost + c;
        que.push(i5(cost + c, ny, nx, dir, hand + 1));
      }
    }
    //????????¢???
    for (int i = 0; i < 2; i++) {
      int nd;
      if(i == 0)nd = (dir + 3)%4;//?????¢???
      else nd = (dir + 1)%4;//?????¢???
      if(i == 0 and (hand == 0 or hand == 1))continue;
      if(i == 1 and (hand == 2 or hand == 3))continue;
      // if(i == 0)std::cout << "trun right" << std::endl;
      // else std::cout << "trun left" << std::endl;
      int nh = (hand + 2)%4;
      if(g[y][x][nd][nh] > cost) {
        g[y][x][nd][nh] = cost;
        que.push(i5(cost, y, x, nd, nh));
      }
    }
    //????????????????????´
    for (int i = 0; i < 4; i++) {
      int ny = y + diry[dir][i];
      int nx = x + dirx[dir][i];
      if(hand == 0 and (i == 3))continue;
      if(hand == 1 and (i == 3))continue;
      if(hand == 3 and (i == 0 or i == 1))continue;
      if(range(ny, nx) and grid[ny][nx] == '#'){
        if(g[y][x][dir][i] > cost){
          //std::cout << "i:" << i << std::endl;
          g[y][x][dir][i] = cost;
          que.push(i5(cost, y, x, dir, i));
        }
      }
    }
  }
  int ans = 1e9;
  for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
      ans = min(ans, g[gy][gx][i][j]);
    }
  }
  // for (int i = 0; i < n; i++) {
  //   for (int j = 0; j < m; j++) {
  //     int mini = 1e9;
  //     for (int k = 0; k < 4; k++) {
  //       for (int l = 0; l < 4; l++) {
  //         mini = min(mini, g[i][j][k][l]);
  //       }
  //     }
  //     if(mini == 1e9)std::cout << -1;
  //     else std::cout << " " << mini;
  //   }
  //   std::cout << std::endl;
  // }
  std::cout << ((ans == 1e9)?-1:ans) << std::endl;
  return 0;
}

Measured memory_bytes: 3372