#include <bits/stdc++.h>
using namespace std;
template <typename T>
using minheap = priority_queue<T, vector<T>, greater<T>>;
template <typename T>
using maxheap = priority_queue<T>;
template <typename T>
using dpair = pair<T, T>;
template <class T1, class T2>
istream &operator>>(istream &is, pair<T1, T2> &p) {
  return is >> p.first >> p.second;
}
template <class T1, class T2>
void operator+=(vector<T1> &v, const T2 &obj) {
  v.push_back(obj);
}
template <class T1>
void operator+=(vector<T1> &v, const T1 &obj) {
  v.push_back(obj);
}
long long get_millis() {
  using namespace std::chrono;
  return duration_cast<milliseconds>(system_clock::now().time_since_epoch())
      .count();
}
const int INF = 0x3f3f3f3f;
const long long mod = 1e9 + 7;
class xrange {
 public:
  xrange(int end) : _start(0), _end(end), _step(1) {}
  xrange(int start, int end) : _start(start), _end(end), _step(1) {}
  xrange(int start, int end, int step)
      : _start(start), _end(end), _step(step) {}
  class iterator {
   public:
    iterator(int v, xrange &par) : val(v), parent(par){};
    int operator*() const { return val; }
    int operator++() { return (val += parent._step); }
    bool operator==(const xrange::iterator &iter) const {
      if (&parent != &iter.parent) return false;
      if (val == iter.val) return true;
      if (parent._step > 0)
        return val >= parent._end && iter.val >= parent._end;
      else
        return val <= parent._end && iter.val <= parent._end;
    }
    bool operator!=(const xrange::iterator &iter) const {
      return !(this->operator==(iter));
    }

   private:
    int val;
    xrange &parent;
  };
  xrange::iterator begin() { return {_start, *this}; }
  xrange::iterator end() { return {_end, *this}; }

 protected:
  int _start, _end, _step;

 private:
};
struct irange : public xrange {
  irange(int i) : xrange(1, i + 1) {}
  irange(int i, int j) : xrange(i, j + 1) {}
};
const int MAXN = 1e4 + 5;
namespace std {
template <>
struct hash<dpair<int>> {
  size_t operator()(dpair<int> p) const {
    return p.first * 123456789 + p.second;
  }
};
}  // namespace std
unordered_map<dpair<int>, int> ump;
int N, M, K;
struct dir {
  bool lit;
  int r, c;
  int dist;
  dir(int _l, int _r, int _c, int _d) {
    lit = _l;
    r = _r;
    c = _c;
    dist = _d;
  }
  bool operator>(const dir &d) const { return dist > d.dist; }
};
minheap<dir> pq;
set<int> availR[MAXN], availC[MAXN];
int best[MAXN];
int main() {
  cin.tie(0);
  cin.sync_with_stdio(0);
  cin >> N >> M >> K;
  for (int a = 0; a < K; a++) {
    int r, c;
    cin >> r >> c;
    availR[r].insert(c);
    availC[c].insert(r);
    ump[{r, c}] = a;
  }
  pq.push({false, 1, 1, 0});
  pq.push({true, 1, 1, 1});
  availR[1].erase(1);
  availC[1].erase(1);
  memset(best, 0x3f, sizeof(best));
  best[ump[{1, 1}]] = 0;
  while (!pq.empty()) {
    dir top = pq.top();
    pq.pop();
    if (top.lit) {
      for (int r = max(1, top.r - 2); r <= top.r + 2; r++) {
        for (int i : availR[r]) {
          int id = ump[{r, i}];
          best[id] = min(best[id], top.dist);
          pq.push(dir{false, r, i, top.dist});
          pq.push(dir{true, r, i, top.dist + 1});
        }
        availR[r].clear();
      }
      for (int c = max(1, top.c - 2); c <= top.c + 2; c++) {
        for (int i : availC[c]) {
          int id = ump[{i, c}];
          best[id] = min(best[id], top.dist);
          pq.push(dir{false, i, c, top.dist});
          pq.push(dir{true, i, c, top.dist + 1});
        }
        availC[c].clear();
      }
    } else {
      int dr = 1, dc = 0;
      if (ump.count({top.r + dr, top.c + dc}) &&
          best[ump[{top.r + dr, top.c + dc}]] > top.dist) {
        best[ump[{top.r + dr, top.c + dc}]] = top.dist;
        pq.push(dir{false, top.r + dr, top.c + dc, top.dist});
        pq.push(dir{true, top.r + dr, top.c + dc, top.dist + 1});
        availR[top.r + dr].erase(top.c + dc);
        availC[top.c + dc].erase(top.r + dr);
      }
      dr = -1;
      dc = 0;
      if (ump.count({top.r + dr, top.c + dc}) &&
          best[ump[{top.r + dr, top.c + dc}]] > top.dist) {
        best[ump[{top.r + dr, top.c + dc}]] = top.dist;
        pq.push(dir{false, top.r + dr, top.c + dc, top.dist});
        pq.push(dir{true, top.r + dr, top.c + dc, top.dist + 1});
        availR[top.r + dr].erase(top.c + dc);
        availC[top.c + dc].erase(top.r + dr);
      }
      dr = 0;
      dc = 1;
      if (ump.count({top.r + dr, top.c + dc}) &&
          best[ump[{top.r + dr, top.c + dc}]] > top.dist) {
        best[ump[{top.r + dr, top.c + dc}]] = top.dist;
        pq.push(dir{false, top.r + dr, top.c + dc, top.dist});
        pq.push(dir{true, top.r + dr, top.c + dc, top.dist + 1});
        availR[top.r + dr].erase(top.c + dc);
        availC[top.c + dc].erase(top.r + dr);
      }
      dr = 0;
      dc = -1;
      if (ump.count({top.r + dr, top.c + dc}) &&
          best[ump[{top.r + dr, top.c + dc}]] > top.dist) {
        best[ump[{top.r + dr, top.c + dc}]] = top.dist;
        pq.push(dir{false, top.r + dr, top.c + dc, top.dist});
        pq.push(dir{true, top.r + dr, top.c + dc, top.dist + 1});
        availR[top.r + dr].erase(top.c + dc);
        availC[top.c + dc].erase(top.r + dr);
      }
    }
  }
  int ans = INF;
  for (auto au : ump) {
    if (au.first == dpair<int>{N, M}) {
      ans = min(ans, best[au.second]);
    }
    if (abs(au.first.first - N) <= 1 || abs(au.first.second - M) <= 1) {
      ans = min(ans, best[au.second] + 1);
    }
  }
  if (ans > 10000000) {
    cout << -1;
  } else {
    cout << ans;
  }
}
