#include <bits/stdc++.h>
#define inf (long long)(1e10)
using namespace std;

struct data {
  int x, y, dir, wall, dist;
};

long long m, n, gx, gy;
int d[4] = {-1, 0, 1, 0};
vector<string> s;
long long dist[55][55][4][4] = {0};
queue<data> qu;

bool isvalid(data now) {
  return now.x >= 0 && now.x < m && now.y >= 0 &&
         now.y < n && s[now.x][now.y] == '.';
}
long long solve();

int main() {
  cin >> m >> n;
  s.resize(m);
  for(int i = 0; i < m; ++i) cin >> s[i];
  cout << solve() << endl;
  return 0;
}

long long solve() {
  long long ans = inf;
  for(int i = 0; i < m; ++i)
    for(int j = 0; j < n; ++j)
      for(int k = 0; k < 4; ++k)
        for(int l = 0; l < 4; ++l) dist[i][j][k][l] = inf;
  for(int i = 0; i < m; ++i)
    for(int j = 0; j < n; ++j)
      if(s[i][j] == 'G') {
        gx = i, gy = j;
        s[i][j] = '.';
      }
      else if(s[i][j] == '^') {
        qu.push({i, j, 0, 1, 0});
        dist[i][j][0][1] = 0;
        s[i][j] = '.';
      }
      else if(s[i][j] == 'v') {
        qu.push({i, j, 2, 1, 0});
        dist[i][j][2][1] = 0;
        s[i][j] = '.';
      }
      else if(s[i][j] == '<') {
        qu.push({i, j, 1, 1, 0});
        dist[i][j][1][1] = 0;
        s[i][j] = '.';
      }
      else if(s[i][j] == '>') {
        qu.push({i, j, 3, 1, 0});
        dist[i][j][3][1] = 0;
        s[i][j] = '.';
      }
  while(!qu.empty()) {
    data now = qu.front(), nextp, nextwall;
    qu.pop();
    // go straight
    nextp = now;
    nextp.x += d[now.dir];
    nextp.y += d[1 ^ now.dir];
    --nextp.wall;
    ++nextp.dist;
    if(isvalid(nextp) &&
       (nextp.wall == 0 || nextp.wall == 1) &&
       dist[nextp.x][nextp.y][nextp.dir][nextp.wall] >
           nextp.dist) {
      dist[nextp.x][nextp.y][nextp.dir][nextp.wall] =
          nextp.dist;
      if(nextp.x != gx || nextp.y != gy) qu.push(nextp);
    }
    // turn right
    nextp = now;
    (nextp.dir += 3) %= 4;
    nextp.wall += 2;
    ++nextp.dist;
    if(nextp.wall <= 3 &&
       dist[nextp.x][nextp.y][nextp.dir][nextp.wall] >
           nextp.dist) {
      dist[nextp.x][nextp.y][nextp.dir][nextp.wall] =
          nextp.dist;
      qu.push(nextp);
    }
    // turn left
    nextp = now;
    (nextp.dir += 1) %= 4;
    nextp.wall -= 2;
    ++nextp.dist;
    if(nextp.wall >= 0 &&
       dist[nextp.x][nextp.y][nextp.dir][nextp.wall] >
           nextp.dist) {
      dist[nextp.x][nextp.y][nextp.dir][nextp.wall] =
          nextp.dist;
      qu.push(nextp);
    }
    // wall change pattern 0
    if(now.wall == 1) {
      nextp = now;
      ++nextp.dist;
      nextp.wall = 0;
      nextwall = now;
      nextwall.x +=
          d[(now.dir + 2) % 4] + d[(now.dir + 3) % 4];
      nextwall.y += d[1 ^ ((now.dir + 2) % 4)] +
                    d[1 ^ ((now.dir + 3) % 4)];
      if(!isvalid(nextwall) &&
         dist[nextp.x][nextp.y][nextp.dir][nextp.wall] >
             nextp.dist) {
        dist[nextp.x][nextp.y][nextp.dir][nextp.wall] =
            nextp.dist;
        qu.push(nextp);
      }
    }
    // wall cahnge pattern 1
    nextp = now;
    ++nextp.dist;
    nextp.wall = 1;
    nextwall = now;
    nextwall.x += d[(now.dir + 3) % 4];
    nextwall.y += d[1 ^ ((now.dir + 3) % 4)];
    if(!isvalid(nextwall) &&
       dist[nextp.x][nextp.y][nextp.dir][nextp.wall] >
           nextp.dist) {
      dist[nextp.x][nextp.y][nextp.dir][nextp.wall] =
          nextp.dist;
      qu.push(nextp);
    }
    // wall change pattern 2
    if(now.wall == 1 || now.wall == 3) {
      nextp = now;
      ++nextp.dist;
      nextp.wall = 2;
      nextwall = now;
      nextwall.x += d[now.dir] + d[(now.dir + 3) % 4];
      nextwall.y +=
          d[1 ^ now.dir] + d[1 ^ ((now.dir + 3) % 4)];
      if(!isvalid(nextwall) &&
         dist[nextp.x][nextp.y][nextp.dir][nextp.wall] >
             nextp.dist) {
        dist[nextp.x][nextp.y][nextp.dir][nextp.wall] =
            nextp.dist;
        qu.push(nextp);
      }
    }
    // wall change pattern 3
    if(now.wall == 2 || now.wall == 1) {
      nextp = now;
      ++nextp.dist;
      nextp.wall = 3;
      nextwall = now;
      nextwall.x += d[now.dir];
      nextwall.y += d[1 ^ now.dir];
      if(!isvalid(nextwall) &&
         dist[nextp.x][nextp.y][nextp.dir][nextp.wall] >
             nextp.dist) {
        dist[nextp.x][nextp.y][nextp.dir][nextp.wall] =
            nextp.dist;
        qu.push(nextp);
      }
    }
  }
  for(int i = 0; i < 4; ++i)
    for(int j = 0; j < 4; ++j)
      ans = min(ans, dist[gx][gy][i][j]);
  if(ans == inf) return -1;
  ans = 0;
  for(int i = 0; i < m; ++i)
    for(int j = 0; j < n; ++j) {
      bool ch = 0;
      for(int k = 0; k < 4; ++k)
        for(int l = 0; l < 4; ++l)
          if(dist[i][j][k][l] != inf) ch = 1;
      ans += ch;
    }
  return ans;
}


Measured memory_bytes: 3540