#include <iostream>
#include <vector>
#include <queue>
#include <tuple>
#include <cmath>
#include <set>
using namespace std;

constexpr int INF = 1e9;

using P = pair<int, int>;
using data = tuple<int, int, int, int, set<P>>; // dir, right hand, y, x
// right hand: 0 -> front, 1 -> right front, 2 -> right, 3 -> back right

int main() {
    int N, M;
    cin >> N >> M;
    vector<string> v(N);
    vector<vector<vector<vector<int>>>> res(4, vector<vector<vector<int>>>(4, vector<vector<int>>(N, vector<int>(M, INF))));
    queue<data> que;
    for(int i=0; i<N; ++i) {
        cin >> v[i];
    }
    int gy = 0, gx = 0;
    for(int i=0; i<N; ++i) {
        for(int j=0; j<M; ++j) {
            set<P> s;
            if(v[i][j] == '^') {
                res[0][2][i][j] = 0;
                s.insert(P{i, j});
                que.push(make_tuple(0, 2, i, j, s));
            } else if(v[i][j] == '<') {
                res[1][2][i][j] = 0;
                s.insert(P{i, j});
                que.push(make_tuple(1, 2, i, j, s));
            } else if(v[i][j] == 'v') {
                res[2][2][i][j] = 0;
                s.insert(P{i, j});
                que.push(make_tuple(2, 2, i, j, s));
            } else if(v[i][j] == '>') {
                res[3][2][i][j] = 0;
                s.insert(P{i, j});
                que.push(make_tuple(3, 2, i, j, s));
            }
            if(v[i][j] == 'G') {
                gy = i; gx = j;
            }
        }
    }
    int dx[4] = {0, -1, 0, 1},
        dy[4] = {-1, 0, 1, 0};
    int hand_pos_x[4][4] = {{0, 1, 1, 1},
                            {-1, -1, 0, 1},
                            {0, -1, -1, -1},
                            {1, 1, 0, -1}};
    int hand_pos_y[4][4] = {{-1, -1, 0, 1},
                            {0, -1, -1, -1},
                            {1, 1, 0, -1},
                            {0, 1, 1, 1}};
    int ans = INF;
    while(!que.empty()) {
        int dir, hand, y, x;
        set<P> s;
        tie(dir, hand, y, x, s) = que.front(); que.pop();
        if(v[y][x] == 'G') {
            ans = min(ans, (int)s.size());
            continue;
        }
        int now = s.size();
        //cout << "d: " << dir << "  h: " << hand << "  y: " << y << "  x: " << x << "  t: " << now << endl;
        
        if(hand == 0 && res[(dir+1)%4][2][y][x] > now) {
            res[(dir+1)%4][2][y][x] = now;
            que.push(make_tuple((dir+1)%4, 2, y, x, s));
        } else if(hand == 1 && res[(dir+1)%4][3][y][x] > now) {
            res[(dir+1)%4][3][y][x] = now;
            que.push(make_tuple((dir+1)%4, 3, y, x, s));
        } else if(hand == 2 && res[(dir+3)%4][0][y][x] > now) {
            res[(dir+3)%4][0][y][x] = now;
            que.push(make_tuple((dir+3)%4, 0, y, x, s));
        } else if(hand == 3 && res[(dir+3)%4][1][y][x] > now) {
            res[(dir+3)%4][1][y][x] = now;
            que.push(make_tuple((dir+3)%4, 1, y, x, s));
        }

        for(int i=hand+1; i<4; ++i) {
            int hand_nx = x + hand_pos_x[dir][i],
                hand_ny = y + hand_pos_y[dir][i];
            if(hand_nx < 0 || M <= hand_nx || hand_ny < 0 || N <= hand_ny || v[hand_ny][hand_nx] == '#') {
                if(res[dir][i][y][x] > now) {
                    res[dir][i][y][x] = now;
                    que.push(make_tuple(dir, i, y, x, s));
                }
            } else if(i != 1) {
                break;
            }
        }
        for(int i=hand-1; i>=0; --i) {
            int hand_nx = x + hand_pos_x[dir][i],
                hand_ny = y + hand_pos_y[dir][i];
            if(hand_nx < 0 || M <= hand_nx || hand_ny < 0 || N <= hand_ny || v[hand_ny][hand_nx] == '#') {
                if(res[dir][i][y][x] > now) {
                    res[dir][i][y][x] = now;
                    que.push(make_tuple(dir, i, y, x, s));
                }
            } else if(i != 1){
                break;
            }
        }
        int ny = y + dy[dir], nx = x + dx[dir];
        if(0 <= ny && ny < N && 0 <= nx && nx < M && v[ny][nx] != '#' && hand != 3 && res[dir][hand+1][ny][nx] > now+1) {
            s.insert(P{ny, nx});
            res[dir][hand+1][ny][nx] = s.size();
            que.push(make_tuple(dir, hand+1, ny, nx, move(s)));
        }
    }
    cout << (ans == INF ? -1 : ans) << endl;
}


Measured memory_bytes: 3756