#include <bits/stdc++.h>
using std::map;
using std::max;
using std::min;
using std::priority_queue;
using std::queue;
using std::set;
using std::sort;
using std::swap;
using std::vector;
inline int readInt() {
  int ans = 0;
  char c;
  do c = getchar();
  while (!isdigit(c));
  while (isdigit(c)) {
    ans = ans * 10 + c - '0';
    c = getchar();
  }
  return ans;
}
const int N = 30050;
const int M = 300050;
int pre[N], nxt[M], to[M], cost[M];
int cnt = 0;
inline void addEdge(int u, int v, int c) {
  cost[cnt] = c;
  to[cnt] = v;
  nxt[cnt] = pre[u];
  pre[u] = cnt++;
  cost[cnt] = c;
  to[cnt] = u;
  nxt[cnt] = pre[v];
  pre[v] = cnt++;
}
struct Cell {
  int r, c, i;
};
bool cmprc(const Cell &a, const Cell &b) {
  if (a.r != b.r) return a.r < b.r;
  return a.c < b.c;
}
bool cmpcr(const Cell &a, const Cell &b) {
  if (a.c != b.c) return a.c < b.c;
  return a.r < b.r;
}
Cell cells[N];
struct HeapNode {
  int x, d;
  HeapNode(int x, int d) : x(x), d(d) {}
  bool operator<(const HeapNode &l) const { return d > l.d; }
};
int dis[N];
priority_queue<HeapNode> Q;
void Dijkstra(int s) {
  memset(dis, -1, sizeof dis);
  Q.push(HeapNode(s, dis[s] = 0));
  while (!Q.empty()) {
    HeapNode xx = Q.top();
    Q.pop();
    if (dis[xx.x] != xx.d) continue;
    int x = xx.x;
    for (int i = pre[x]; ~i; i = nxt[i])
      if (dis[to[i]] == -1 || dis[to[i]] > dis[xx.x] + cost[i])
        Q.push(HeapNode(to[i], dis[to[i]] = dis[xx.x] + cost[i]));
  }
}
int main() {
  int n = readInt();
  int m = readInt();
  int k = readInt();
  int t0 = -1, t1 = -1;
  memset(pre, -1, sizeof pre);
  for (int i = 0; i < k; ++i) {
    int &r = cells[i].r = readInt();
    int &c = cells[i].c = readInt();
    if (r == 1 && c == 1) t0 = i;
    if (r == n && c == m) t1 = i;
    cells[i].i = i;
    for (int l = -1; l <= 1; ++l) {
      addEdge(i, (k + r + l), 1);
      addEdge(i, (k + n + 2 + c + l), 1);
    }
  }
  sort(cells, cells + k, cmprc);
  for (int i = 1; i < k; ++i)
    if (cells[i].r == cells[i - 1].r && cells[i].c == cells[i - 1].c + 1)
      addEdge(cells[i - 1].i, cells[i].i, 0);
  sort(cells, cells + k, cmpcr);
  for (int i = 1; i < k; ++i)
    if (cells[i].r == cells[i - 1].r + 1 && cells[i].c == cells[i - 1].c)
      addEdge(cells[i - 1].i, cells[i].i, 0);
  Dijkstra(t0);
  if (!(~dis[(k + n)] || ~dis[(k + n + 2 + m)] || (~t1 && ~dis[t1])))
    return puts("-1"), 0;
  int ans = 1000000000;
  if (~dis[(k + n)]) ans = min(ans, (dis[(k + n)] + 1) / 2);
  if (~dis[(k + n + 2 + m)]) ans = min(ans, (dis[(k + n + 2 + m)] + 1) / 2);
  if (~t1 && ~dis[t1]) ans = min(ans, dis[t1] / 2);
  printf("%d\n", ans);
  return 0;
}
