Problem:
A さんと B 君は，N × M の長方形のマス目状の地域に住んでいる．各マス目は道か壁か家のどれかである．この地域は，道が複雑で入り組んでいるので痴漢被害がよく起こることで有名であるため，この地域と外部との境界は全て壁で囲まれており，隔離されている．

B 君はなんとなく気が向いたので，A さんの家を眺めに行くことにした．しかし，不幸なことにB 君は明らかに怪しい顔をしているので，A さんの家に行く途中に少しでも痴漢の疑いがあるような行動を取ったらすぐに捕まってしまうだろう．特に，右手を壁から離して歩くことは絶対にやってはならない．B 君は，一瞬たりとも右手を離すことなく，A さんの家に辿り着くことが出来るだろうか？

B 君はつねに上下左右いずれかの方向を向いていて，B 君の右手が届く範囲はB 君の向いている方向に対して正面，斜め右前，右，斜め右後ろの4 マスのみである．B 君は，次のいずれかの行動を繰り返す．ただし，これらを同時に行うことは出来ない．

前方に壁がない場合，1 マス進む．

向いている方向を90 度右に変える．

向いている方向を90 度左に変える．

右手が接するマスを変える．ただし，この時にB 君は右手を離すことが出来ないので，変更前のマスと変更後のマスの間には共通した点を持っていなくてはならない．

Input

入力は以下の形式で与えられる．

N M
S1
S2
:
SN

Si (1 ≤ i ≤ N) は， M 文字の文字列で各文字は次を表す．

"^"，"v"，"<"，">" は B 君の最初の位置と最初に向いている方向（上下左右の向き）を表す．

"." は，何もないマスである．B 君は，このマスの上を移動することができる．

"#" は，壁を表す．壁の上を移動することは出来ない．

"G" は A さんの家の位置を表す．B 君は，A さんの家にたどり着くまで移動を繰り返す．

Constraints

1 ≤ N ≤ 50

1 ≤ M ≤ 50

入力には，文字 "^"，"v"，"<"，">" のうちいずれかが必ず一つのみ現れる．

同様に，入力には，文字 "G" が必ず一つのみ現れる．

初期状態では，B 君が向いている方向から右の壁にB 君の右手が接している．

Output

一度も右手を離さずにA さんの家に辿り着くことが出来る場合には，A さんの家にたどり着くまでに通った異なるマスの数の最小値を出力せよ．A さんの家に辿り着くことが出来ない場合には，-1 を出力せよ．

Sample Input 1

3 3
G##
.#.
.<.

Output for the Sample Input 1

4

Sample Input 2

3 3
G##
.#.
.>.

Output for the Sample Input 2

6

Sample Input 3

3 3
...
.G.
.>.

Output for the Sample Input 3

-1

Sample Input 4

4 4
....
.#.G
...#
^#..

Output for the Sample Input 4

8

Solution in C++ (judge verdict: Memory Limit Exceeded)

#include <bits/stdc++.h>

using namespace std;

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

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

struct Node {
	int x, y, hx, hy, dir;
};

int H, W;
int wall[100][100] = {0};
bool used[100][100] = {0};
bool reach[100][100][100][100][4] = {0};
bool inRange(int x, int y) {
	return 0 <= x && x < W && 0 <= y && y < H;
}
bool inRange2(int x, int y) {
	return -1 <= x && x <= W && -1 <= y && y <= H;
}
bool Wall(int x, int y) {
	if (inRange(x, y)) return wall[y][x];
	return true;
}
bool isInvalidHand(int px, int py, int hx, int hy, int dir) {
//	cout << ":" << px << " " << py << " " << hx << " " << hy << endl;
	if (!Wall(hx, hy)) return true;
	for (int i = 0; i < 4; ++i) {
		int x = px + dhx[dir][i];
		int y = py + dhy[dir][i];
		if (inRange2(x, y) && hx == x && hy == y) {
			return false;
		}
	}
	return true;
}

int main() {
	cin >> H >> W;

	for (int i = 0; i < 4; ++i) {
		Dy[i] = -Dy[i];
		for (int j = 0; j < 4; ++j) {
			dhy[i][j] = -dhy[i][j];
		}
	}

	int sx = -1, sy = -1, sd = -1;
	int gx = -1, gy = -1;
	for (int y = 0; y < H; ++y) {
		string str; cin >> str;
		for (int x = 0; x < W; ++x) {
			switch (str[x]) {
			case '#': wall[y][x] = true; break;
			case 'G': gx = x, gy = y; break;
			case '^': sx = x, sy = y; sd = 0; break;
			case '>': sx = x, sy = y; sd = 1; break;
			case 'v': sx = x, sy = y; sd = 2; break;
			case '<': sx = x, sy = y; sd = 3; break;
			}
		}
	}
	int ans = -1;
	queue<Node> Q;
//	fill(used[0], used[50], false);
//	fill(reach[0][0][0][0], reach[49][49][50][51], false);
	Q.push((Node){sx, sy, sx + Dx[(sd+1)%4], sy + Dy[(sd+1)%4], sd});
	while ( !Q.empty() ) {
		Node node = Q.front(); Q.pop();
		int px = node.x, py = node.y, hx = node.hx, hy = node.hy, dir = node.dir;
		if ( !inRange(px, py) ) continue;
		if ( wall[py][px] ) continue;
		if ( !inRange2(hx, hy) ) continue;
		if ( reach[py][px][hy+1][hx+1][dir] ) continue;
		if ( isInvalidHand(px, py, hx, hy, dir) ) continue;
		reach[py][px][hy+1][hx+1][dir] = true;
		used[py][px] = true;
		if (px == gx && py == gy) {
			break;
		}
//			cout << px << " " << py << " " << hx << " " << hy << " " << dir << endl;

		// move player
		{
			int npx = px + Dx[dir];
			int npy = py + Dy[dir];
			Q.push((Node){npx, npy, hx, hy, dir});
		}

		// move hand
		for (int dx = -1; dx <= 1; ++dx) for (int dy = -1; dy <= 1; ++dy) {
			int nhx = hx + dx;
			int nhy = hy + dy;
			if ( inRange2(nhx, nhy) && Wall(hx, hy) ) {
				Q.push((Node){px, py, nhx, nhy, dir});
			}
		}

		// change dir / turn
		Q.push((Node){px, py, hx, hy, (dir+1)%4});
		Q.push((Node){px, py, hx, hy, (dir-1+4)%4});
	}
	int s = 0;
	for (int y = 0; y < H; ++y) {
		for (int x = 0; x < W; ++x) {
			s += used[y][x];
		}
	}
	if (used[gy][gx] && (ans < 0 || s < ans)) {
		ans = s;
	}
	cout << ans << endl;
}