#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;     }   }