#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <algorithm>

#define rep(i, n) for (int i = 0; i < (n); ++i)

using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;

int main()
{
  int N;
  cin >> N;
  std::unordered_map<int, int> mx;
  std::unordered_map<int, int> mn;

  rep(i, N)
  {
    int x, c;
    cin >> x >> c;

    if (mx.find(c) != mx.end())
    {
      mx[c] = std::max(mx[c], x);
      mn[c] = std::min(mn[c], x);
    }
    else
    {
      mx[c] = x;
      mn[c] = x;
    }
  }

  long long time1 = 0;
  long long time2 = 0;
  int pos1 = 0;
  int pos2 = 0;
  for (int i = 1; i <= N; i++)
  {
    if (mx.find(i) != mx.end())
    {
      long long diff = std::abs(mx[i] - mn[i]);
      long long tmp1 = time1;
      long long tmp2 = time2;
      // from pos1, mx -> mn
      tmp1 += std::abs(pos1 - mx[i]) + diff;

      // from pos2, mx -> mn
      tmp2 += std::abs(pos2 - mx[i]) + diff;

      long long tmp3 = time1;
      long long tmp4 = time2;
      // from pos1, mn -> mx
      tmp3 += std::abs(pos1 - mn[i]) + diff;

      // from pos2, mn -> mx
      tmp4 += std::abs(pos2 - mn[i]) + diff;

      time1 = std::min(tmp1, tmp2);
      time2 = std::min(tmp3, tmp4);

      pos1 = mn[i];
      pos2 = mx[i];
    }
  }

  time1 += std::abs(pos1);
  time2 += std::abs(pos2);

  cout << std::min(time1, time2) << endl;

  return 0;
}

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
ll H, W;
ll d[2000][2000];

bool onBoard(int y, int x) {
    if (y >= 0 && y < H && x >= 0 && x < W) {
        return true;
    }
    return false;
}

int main() {
    cin >> H >> W;
    vector<string> S(H);
    rep(i, H) {
        cin >> S[i];
    }
    vector<set<P>> sets(26);

    P start, goal;

    rep(i, H) rep(j, W) {
        int t = S[i][j] - 'a';
        if (t >= 0 && t < 26) {
            // cerr << "i=" << i << " j=" << j << "S[i][j] =" << S[i][j] << endl;
            sets[t].insert(P(i, j));
        }
        if (S[i][j] == 'S') {
            start = P(i, j);
        }
        if (S[i][j] == 'G') {
            goal = P(i, j);
            S[i][j] = '.';
        }
    }
    rep(i, H) rep(j, W) {
        d[i][j] = -1;
    }

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

    queue<P> q;
    q.push(start);
    d[start.first][start.second] = 0;
    while (!q.empty()) {
        P p = q.front();
        q.pop();
        for (int i = 0; i < 4; i++) {
            int ny = p.first + dy[i];
            int nx = p.second + dx[i];
            if (onBoard(ny, nx) && S[ny][nx] != '#' && d[ny][nx] == -1) {
                d[ny][nx] = d[p.first][p.second] + 1;
                q.push(P(ny, nx));
            }
        }
        int t = S[p.first][p.second] - 'a';
        if (t >= 0 && t < 26) {
            for (auto itr = sets[t].begin(); itr != sets[t].end(); ++itr) {
                int ny = itr->first, nx = itr->second;
                if (d[ny][nx] == -1) {
                    d[ny][nx] = d[p.first][p.second] + 1;
                    q.push(P(ny, nx));
                }
            }
            sets[t].clear();
        }
    }

    cout << d[goal.first][goal.second] << endl;

    return 0;
}