#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < n; i++)
#define rep2(i, x, n) for(int i = x; i <= n; i++)
#define rep3(i, x, n) for(int i = x; i >= n; i--)
#define each(e, v) for(auto &e: v)
#define pb push_back
#define eb emplace_back
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
using ll = long long;
using pii = pair<int, int>;
using pil = pair<int, ll>;
using pli = pair<ll, int>;
using pll = pair<ll, ll>;
const int MOD = 1000000007;
//const int MOD = 998244353;
const int inf = (1<<30)-1;
const ll INF = (1LL<<60)-1;
template<typename T> bool chmax(T &x, const T &y) {return (x < y)? (x = y, true) : false;};
template<typename T> bool chmin(T &x, const T &y) {return (x > y)? (x = y, true) : false;};

struct io_setup{
    io_setup(){
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        cout << fixed << setprecision(15);
    }
} io_setup;

template<typename T>
vector<T> divisors(const T &n){
    vector<T> ret;
    for(T i = 1; i*i <= n; i++){
        if(n%i == 0){
            ret.pb(i);
            if(i*i != n) ret.pb(n/i);
        }
    }
    sort(all(ret));
    return ret;
}

template<typename T>
vector<pair<T, int>> prime_factor(T n){
    vector<pair<T, int>> ret;
    for(T i = 2; i*i <= n; i++){
        int cnt = 0;
        while(n%i == 0) cnt++, n /= i;
        if(cnt > 0) ret.emplace_back(i, cnt);
    }
    if(n > 1) ret.emplace_back(n, 1);
    return ret;
}

template<typename T>
bool is_prime(const T &n){
    if(n == 1) return false;
    for(T i = 2; i*i <= n; i++){
        if(n%i == 0) return false;
    }
    return true;
}

vector<bool> Eratosthenes(const int &n){
    vector<bool> ret(n+1, true);
    if(n >= 0) ret[0] = false;
    if(n >= 1) ret[1] = false;
    for(int i = 2; i*i <= n; i++){
        if(!ret[i]) continue;
        for(int j = i+i; j <= n; j += i) ret[j] = false;
    }
    return ret;
}

vector<int> Eratosthenes2(const int &n){
    vector<int> ret(n+1);
    iota(begin(ret), end(ret), 0);
    if(n >= 0) ret[0] = -1;
    if(n >= 1) ret[1] = -1;
    for(int i = 2; i*i <= n; i++){
        if(ret[i] < i) continue;
        for(int j = i+i; j <= n; j += i) ret[j] = min(ret[j], i);
    }
    return ret;
}

int main(){
    ll A, B; cin >> A >> B;

    vector<bool> p = Eratosthenes(B-A);

    vector<int> ps;

    rep2(i, 1, B-A){
        if(p[i]) ps.eb(i);
    }

    //cout << sz(ps) << '\n';
    int n = sz(ps);

    vector<int> s(B-A+1, 0);
    rep2(i, 0, B-A){
        ll k = A+i;

        rep(j, n){
            if(k%ps[j] == 0) s[i] |= (1<<j);
        }
    }

    vector<ll> dp(1<<n, 0);
    dp[0] = 1;

    rep(i, B-A+1){
        rep3(j, (1<<n)-1, 0){
            if((j&s[i]) == 0) dp[j|s[i]] += dp[j];
        }
    }

    cout << accumulate(all(dp), 0LL) << '\n';
}
#include <bits/stdc++.h>
using namespace std;

int diri[] = {1, 0, -1, 0}, dirj[] = {0, 1, 0, -1};

#define mp make_pair
typedef pair <int, int> ii;
#define INF 1000000005

int h, w;
char grid[2005][2005];
vector<ii> tele[30];
int dist[2005][2005];
int gi, gj;
queue<ii> q;

int main() {
	scanf("%d%d", &h, &w);
	for (int i = 0; i < h; i++) {
		scanf(" %s", grid[i]);
	}
	for (int i = 0; i < h; i++) {
		for (int j = 0; j < w; j++) {
			dist[i][j] = INF;
		}
	}
	for (int i = 0; i < h; i++) {
		for (int j = 0; j < w; j++) {
			if (grid[i][j] == 'S') {
				dist[i][j] = 0;
				q.push(mp(i, j));
			} else if (grid[i][j] == 'G') {
				gi = i, gj = j;
			} else if (grid[i][j] - 'a' >= 0 && grid[i][j] - 'a' < 27) {
				tele[grid[i][j] - 'a'].push_back(mp(i, j));
			}
		}
	}
	while (!q.empty()) {
		int i, j; tie(i, j) = q.front(); q.pop();
		for (int k = 0; k < 4; k++) {
			int ni = i + diri[k], nj = j + dirj[k];
			if (ni < 0 || ni >= h || nj < 0 || nj >= w) continue;
			if (grid[ni][nj] == '#') continue;
			if (dist[ni][nj] > dist[i][j] + 1) {
				dist[ni][nj] = dist[i][j] + 1;
				q.push(mp(ni, nj));
			}
			if (ni == gi && nj == gj) {
				printf("%d\n", dist[ni][nj]);
				return 0;
			}
		}
		if (grid[i][j] - 'a' >= 0 && grid[i][j] - 'a' < 27) {
			for (ii ports : tele[grid[i][j] - 'a']) {
				int ni, nj; tie(ni, nj) = ports;
				if (ni == i && nj == j) continue;
				if (dist[ni][nj] > dist[i][j] + 1) {
					dist[ni][nj] = dist[i][j] + 1;
					q.push(mp(ni, nj));
				}
			}
		}
	}
	printf("-1\n");
	return 0;
}
