Problem: Background

Mr. A and Mr. B are enthusiastic about the game "Changing Grids". This game is for two players, with player 1 forming the stage and player 2 challenging the stage and aiming for the goal.

Now, A and B have played this game several times, but B has never won because of A's winning streak. So you decided to give B some tips on how to capture this game.

Problem

The state of the two-dimensional grid with the size of vertical H × horizontal W at time T0 = 0 is given as Area 0. Next, the state of this grid switches to the state Areai at time Ti. This switching process is repeated N times. The initial grid is given a start position'S'and a goal position'G'. If you can reach the goal on any grid, output the minimum number of steps at that time, and if you cannot reach the goal, output'-1'. The following conditions must also be met.


* Areai consists of the following elements.
* ‘.’ Is a movable mass without anything
* ‘#’ Is an obstacle and cannot be moved.
*'S' is the square that represents the start position
*'G' is a square that represents the goal position
* It takes 1 second for the player to move to or stay in the current square, either up, down, left, or right adjacent to the current square. However, it cannot move outside the range of obstacle squares or grids.
* The number of steps increases by 1 when you move 1 square from the square where the player is currently to the squares up, down, left, and right. It does not increase if you stay on the spot.
* The size of all grids is vertical H x horizontal W.
* 1 When the grid is switched after moving or staying in place, it is possible to move regardless of the current grid state as long as there are no obstacles in the next grid.
* In all grids, if the goal position given to the initial grid is reached, it is considered as a goal.

Constraints

The input satisfies the following conditions.

* 2 ≤ H, W ≤ 20
* 1 ≤ N ≤ 15
* 1 ≤ Ti ≤ 200 (T1 <T2 <... <TN)
* There is only one start position'S'and one goal position'G' in the initial 2D grid.

Input

The input is given in the following format.


H W
Area0
N
T1
Area1
T2
Area2
..
..
TN
AreaN


Two integers H and W are given on the first line, separated by blanks. This represents the vertical and horizontal dimensions of the two-dimensional grid, respectively. The initial state of the two-dimensional grid is given to each line from the second line to the H + 1 line. The integer N is given on the second line of H +. This represents the number of changes in the 2D grid. The time Ti and the state of switching of N 2D grids are given after the 3rd line of H +. However, Ti is all integers.

Output

Output the minimum number of steps to reach the goal from the start. However, if you cannot reach the goal, output'-1'.

Examples

Input

2 2
S.
.G
1
3
##
##


Output

2


Input

2 2
S.
.G
1
3


Output

2


Input

2 2
S.
.G
1
2


Output

-1


Input

2 3
S##
G
4
2

.##
3

.#
5

.
7


Output

3


Input

4 3
S..
...
.G.
...
4
2

.#

.#
4

..
..

6

.#

..
8

..
..


Output

3


Input

3 3
S##

G
1
1
...
...
...


Output

4

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
#define valid(y,x,h,w) (0<=y&&y<h&&0<=x&&x<w)
#define tpl(...) make_tuple(__VA_ARGS__)
const int INF = 0x3f3f3f3f;
const double EPS = 1e-8;
const double PI = acos(-1);
typedef long long ll;
typedef pair<int,int> pii;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T>ostream&operator<<(ostream &o,const vector<T>&t){o<<'[';FOR(i,t){if(i!=t.begin())o<<',';o<<*i;}return o<<']';}
template<class S,class T>ostream&operator<<(ostream &o,const pair<S,T>&t){return o<<'('<<t.first<<','<<t.second<<')';}
template<int N,class Tp>void output(ostream&,const Tp&){}
template<int N,class Tp,class,class ...Ts>void output(ostream &o,const Tp&t){if(N)o<<',';o<<get<N>(t);output<N+1,Tp,Ts...>(o,t);}
template<class ...Ts>ostream&operator<<(ostream&o,const tuple<Ts...>&t){o<<'(';output<0,tuple<Ts...>,Ts...>(o,t);return o<<')';}
template<class T>void output(T t,char z=10){if(t<0)t=-t,putchar(45);int c[20];
int k=0;while(t)c[k++]=t%10,t/=10;for(k||(c[k++]=0);k;)putchar(c[--k]^48);putchar(z);}
template<class T>void outputs(T t){output(t);}
template<class S,class ...T>void outputs(S a,T...t){output(a,32);outputs(t...);}
template<class T>void output(T *a,int n){REP(i,n)output(a[i],i!=n-1?',':10);}
template<class T>void output(T *a,int n,int m){REP(i,n)output(a[i],m);}
template<class T>bool input(T &t){int n=1,c;for(t=0;!isdigit(c=getchar())&&~c&&c-45;);
if(!~c)return 0;for(c-45&&(n=0,t=c^48);isdigit(c=getchar());)t=10*t+c-48;t=n?-t:t;return 1;}
template<class S,class ...T>bool input(S&a,T&...t){input(a);return input(t...);}

const int H = 20;
const int W = 20;

const int dy[] = {-1,0,1,0,0};
const int dx[] = {0,1,0,-1,0};

struct P {
  int y,x,t;
  int d;
  bool operator<(const P &rhs) const {
    return d > rhs.d;
  }
};
struct Field {
  char a[801][H][W];
  int h,w;
  int sy,sx;
  int dist[801][H][W];
  bool input_hw() {
    return input(h,w);
  }
  void set_hw(int _h, int _w) {
    h = _h; w = _w;
  }
  void in() {
    REP(i,h)REP(j,w) {
      cin>>a[0][i][j];
      if (a[0][i][j] == 'S') {
        sy = i;
        sx = j;
      }
    }
    int n;
    cin >> n;
    int pre = 0;
    REP(k,n) {
      int t;
      cin >> t;
      for (int s=pre+1; s<t; ++s) {
        REP(i,h)REP(j,w) {
          a[s][i][j] = a[pre][i][j];
        }
      }
      REP(i,h) {
        REP(j,w) {
          cin >> a[t][i][j];
        }
      }
      pre = t;
    }
    for (int s=pre+1; s<=800; ++s) {
      REP(i,h)REP(j,w) {
        a[s][i][j] = a[pre][i][j];
      }
    }    
  }
  int bfs() {
    memset(dist,0x3f,sizeof(dist));
    priority_queue<P> Q;
    Q.push(P{sy,sx,0,0});
    dist[0][sy][sx] = 0;
    while(!Q.empty()) {
      P p = Q.top(); Q.pop();
      int y = p.y;
      int x = p.x;
      if (dist[p.t][y][x] < p.d) continue;
      if (a[0][y][x] == 'G') return dist[p.t][y][x];
      if (p.t == 800) continue;
      // outputs(p.t,y,x, dist[p.t][y][x]);
      REP(i,5) {
        int yy = y + dy[i];
        int xx = x + dx[i];
        char c = a[p.t+1][yy][xx];
        if (valid(yy,xx,h,w) && c != '#') {
          int d2 = dist[p.t][y][x] + (i<4);
          if (dist[p.t+1][yy][xx] > d2) {
            dist[p.t+1][yy][xx] = d2;
            Q.push(P{yy,xx,p.t+1,d2});
          }          
        }            
      }
    }
    return -1;
  }
} field;

int main() {
  while(field.input_hw()) {
    field.in();
    cout << field.bfs() << endl;
  }
}