#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <utility>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <tuple>
#include <numeric>
#include <functional>
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vector<ll>> vvl;
typedef pair<ll, ll> P;
#define rep(i, n) for(ll i = 0; i < n; i++)
#define exrep(i, a, b) for(ll i = a; i <= b; i++)
#define out(x) cout << x << endl
#define exout(x) printf("%.10f\n", x)
#define chmax(x, y) x = max(x, y)
#define chmin(x, y) x = min(x, y)
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define pb push_back
#define re0 return 0
const ll mod = 1000000007;
const ll INF = 1e16;

// a^n (mod.MOD)を求める。計算量はO(logn)
ll modpow(ll a, ll n, ll MOD = mod) {
    if(n == 0) {
        return 1;
    }
    if(n%2 == 1) {
        return (a * modpow(a, n-1, MOD)) % MOD;
    }
    return (modpow(a, n/2, MOD) * modpow(a, n/2, MOD)) % MOD;
}

// nCrをO(r)で求める。
ll Comb(ll n, ll r) {
    if(n < r) {
        return 0;
    }
    if(r > n-r) {
        return Comb(n, n-r);
    }
    ll Mul = 1, Div = 1;
    rep(i, r) {
        Mul *= (n-i);  Div *= (i+1);
        Mul %= mod;  Div %= mod;
    }
    return Mul * modpow(Div, mod - 2) % mod; 
}

int main() {
    ll n, m;
    cin >> n >> m;

    ll s = 0;
    rep(i, n) {
        ll a;
        cin >> a;
        s += a;
    }

    out(Comb(n+m, n+s));
    re0;
}
#include <bits/stdc++.h>

using namespace std;

#define flush cout.flush

using ll = int;
using ull = unsigned long long;
using ld = long double;
using pl = pair<ll, ll>;
const ll INF = 1e9 + 7;
const ll mod = 1e9 + 7;
const ll mod2 = 998244353;
const ld eps = 1e-9;
const ld PI = acos(-1);
ll n, m;
vector<vector<char>> mx;
vector<char> used(26, 0);
vector<vector<pl>> to(26);
queue<pl> q;
vector<vector<ll>> d;

void go(pl a, pl b) {
    if (a.first < 0 || a.first >= n)return;
    if (a.second < 0 || a.second >= m)return;
    if (mx[a.first][a.second] == '#')return;
    if (d[a.first][a.second] != -1)return;
    d[a.first][a.second] = d[b.first][b.second] + 1;
    q.push(a);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n >> m;
    mx.assign(n, vector<char>(m));
    d.assign(n, vector<ll>(m, -1));
    pl st, en;
    for (ll i = 0; i < n; ++i) {
        for (ll j = 0; j < m; ++j) {
            cin >> mx[i][j];
            if (mx[i][j] == 'S') {
                st = {i, j};
            }
            if (mx[i][j] == 'G') {
                en = {i, j};
            }
            if (mx[i][j] >= 'a' && mx[i][j] <= 'z') {
                to[mx[i][j] - 'a'].push_back({i, j});
            }
        }
    }
    d[st.first][st.second] = 0;
    q.push(st);
    while (!q.empty()) {
        pl v = q.front();
        q.pop();
        if (mx[v.first][v.second] >= 'a' && mx[v.first][v.second] <= 'z' && !used[mx[v.first][v.second] - 'a']) {
            ll x = mx[v.first][v.second] - 'a';
            used[x] = 1;
            for (auto t : to[x]) {
                go(t, v);
            }
        }
        go({v.first - 1, v.second}, v);
        go({v.first + 1, v.second}, v);
        go({v.first, v.second - 1}, v);
        go({v.first, v.second + 1}, v);
    }
    cout << d[en.first][en.second] << "\n";
    return 0;
}