#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;

#define mp make_pair
#define mt make_tuple
#define fi first
#define se second
#define pb push_back
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define rep(i, k, n) for (int i = (int)(k); i < (int)(n); ++i)
#define rrep(i, k, n) for (int i = (int)(n) - 1; i >= (int)(k); --i)

typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vi> vvi;
typedef vector<vii> vv_ii;
typedef pair<int,ii> i_ii;
typedef vector<i_ii> vi_ii;

template <class T>
inline ostream& operator<<(ostream & o, vector<T> const& v) {
    for (int i = 0; i < (int)(v.size()) - 1; ++i)
        o << v[i] << ' ';
    if (!v.empty())
        o << v.back();
    return o;
}

template <class T, class Q>
inline ostream& operator<<(ostream & o, pair<T,Q> const& p) {
    o << "(" << p.fi << "," << p.se << ")";
    return o;
}

#define INF 1e9
#define MOD 1000000007

char grid[2001][2001];
int r, c;
const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};


inline bool ok(int x, int y) {
    return x >= 0 && y >= 0 && x < r && y < c;
}

int main() {

    
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    cin >> r >> c;
    int sx, sy, tx, ty;
    vv_ii m(30);
    rep(i, 0, r) {
        cin >> grid[i];
        rep(j, 0, c) {
            if (grid[i][j] == 'S')
                sx = i, sy = j;
            else if (grid[i][j] == 'G')
                tx = i, ty = j;
            else if (grid[i][j] != '#') {
                m[grid[i][j]-'a'].push_back({i, j});
            }
        }
    }
    
    queue<ii> q;
    vvi dist(r, vi(c, INF));
    vvi orig(r, vi(c));
    q.push({sx, sy});
    q.push({tx, ty});
    dist[sx][sy] = dist[tx][ty] = 0;
    orig[sx][sy] = 0;
    orig[tx][ty] = 1;
    int ans = -1;
    while (!q.empty()) {
        auto f = q.front();
        q.pop();
        int ux = f.fi, uy = f.se;
        //if (ux == tx && uy ==  ty)
        //    break;
        rep(k, 0, 4) {
            int vx = ux + dx[k];
            int vy = uy + dy[k];
            if (ok(vx, vy) && grid[vx][vy] != '#') {
                if (dist[vx][vy] == INF) {
                    dist[vx][vy] = 1 + dist[ux][uy];
                    orig[vx][vy] = orig[ux][uy];
                    //if (vx == tx && vy == ty)
                        //goto PRINT;
                    q.push({vx, vy});
                }
                else if (orig[ux][uy] != orig[vx][vy]) {
                    ans = dist[ux][uy] + dist[vx][vy] + 1;
                    goto PRINT;
                }
            }
        }
        if (grid[ux][uy] >= 'a' && grid[ux][uy] <= 'z') {
                for (auto it : m[grid[ux][uy]-'a']) {
                    int vx = it.fi, vy = it.se;
                    if (dist[vx][vy] == INF) {
                        dist[vx][vy] = 1 + dist[ux][uy];
                        orig[vx][vy] = orig[ux][uy];
                        //if (it.fi == tx && it.se == ty)
                            //goto PRINT;
                        q.push({vx, vy});
                    }
                    else if (orig[vx][vy] != orig[ux][uy]) {
                        ans = dist[ux][uy] + dist[vx][vy] + 1;
                        goto PRINT;
                    }
                }
            }
    }
    PRINT:
    cout << ans << '\n';
    /*
    if (dist[tx][ty] == INF)
        cout << -1 << '\n';
    else
        cout << dist[tx][ty] << '\n';
    */
    return 0;
}
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <queue>
#include <stack>
#include <tuple>
#include <cmath>
#include <iomanip>
#include <map>
#include <cstring>
#include <functional>
#include <cctype>
#include <locale>
#define ll long long
#define rep(i,n) for(int i=0;i<(n);i++)
#define rrep(i,n) for(int i=n-1;i>=0;i--)
#define fi first
#define se second
#define pb push_back
#define ALL(a) (a).begin(),(a).end()
using namespace std;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
typedef pair<int,int> P;
typedef pair<long long,long long> Pll;
#define fout(num) cout << fixed << setprecision(20) << (num) << endl
//s[i]=tolower(s[i]); islower(s[i]); cout << tolower(s[i])はバグ
//vector<vector<ll>> dp(n,vector<ll>(n))
//2-dim:vector<vector<Type>> vv(n, vector<Type>(m, d));
//3-dim:vector<vector<vector<Type>>> vvv(n, vector<vector<Type>>(m, vector<Type>(l, d)));

signed main(){
    std::cin.tie(nullptr);
    std::ios_base::sync_with_stdio(false);
    int n; cin >> n;
    vector<P> v(n);
    vector<int> v1(2*n+1,0),v2(2*n+1,0);
    bool flag=0;
    vector<bool> vis(2*n+1,false);
    rep(i,n){
        cin >> v[i].fi >> v[i].se;
        if(v[i].fi!=-1){
            if(vis[v[i].fi])  flag=true;
            vis[v[i].fi]=true;
            v1[v[i].fi]=v[i].se;
            if(v[i].se!=-1){
                if(vis[v[i].se])  flag=true;
                vis[v[i].se]=true;
                v2[v[i].se]=v[i].fi;
            }
        }
        else if(v[i].se!=-1){
            v2[v[i].se]=v[i].fi;
            if(vis[v[i].se])  flag=true;
            vis[v[i].se]=true;
        }
    }
    if(flag){
        cout << "No" << endl;
        return 0;
    }
    vector<bool> dp(n+1,false);
    dp[n]=true;
    for(int i=n-1;i>=0;i--){
        for(int j=i+1;j<=n;j++){
            if(dp[j]==true){
                int d=j-i; //pair number
                bool ok=1;
                for(int k=0;k<d;k++){
                    int ii=2*i+1+k; int jj=ii+d;
                    bool fl=0;
                    if(v1[ii]==jj&&v2[jj]==ii) fl=1;
                    if(v1[ii]==-1&&v2[jj]==0) fl=1;
                    if(v1[ii]==0&&v2[jj]==-1) fl=1;
                    if(v1[ii]==0&&v2[ii]==0&&v1[jj]==0&&v2[jj]==0) fl=1;
                    if(!fl) ok=0;
                }
                //cout << ok << " " << okk << endl;
                if(ok) dp[i]=true;
            }
        }
    }
    //rep(i,n) cout << dp[i] << " ";
    if(dp[0]) cout  << "Yes" << endl;
    else cout << "No" << endl;
}


