#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e9 + 7;
const double PI = acos(-1.0);
const double EPS = 1e-10;
inline int readint() {
  int sum = 0;
  char c = getchar();
  bool f = 0;
  while (c < '0' || c > '9') {
    if (c == '-') f = 1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    sum = sum * 10 + c - '0';
    c = getchar();
  }
  if (f) return -sum;
  return sum;
}
inline long long readLL() {
  long long sum = 0;
  char c = getchar();
  bool f = 0;
  while (c < '0' || c > '9') {
    if (c == '-') f = 1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    sum = sum * 10 + c - '0';
    c = getchar();
  }
  if (f) return -sum;
  return sum;
}
const int maxn = 3e4 + 5;
struct Edge {
  int from, to, weight;
  Edge(int from, int to, int weight) : from(from), to(to), weight(weight) {}
};
struct HeapNode {
  int u, dist;
  HeapNode(int u, int d) : u(u), dist(d) {}
  bool operator<(const HeapNode& h) const { return dist > h.dist; }
};
struct Dijkstra {
  int n, m;
  vector<Edge> edges;
  vector<int> G[maxn];
  bool done[maxn];
  int dist[maxn];
  int p[maxn];
  Dijkstra(int n) : n(n) {
    for (int i = 0; i < n; i++) G[i].clear();
    edges.clear();
  }
  void AddEdge(int from, int to, int weight) {
    edges.push_back(Edge(from, to, weight));
    m = edges.size();
    G[from].push_back(m - 1);
  }
  void dijkstra(int s) {
    priority_queue<HeapNode> Q;
    memset(dist, 0x3f3f3f3f, sizeof(dist));
    memset(done, false, sizeof(false));
    dist[s] = 0;
    Q.push(HeapNode(s, 0));
    while (!Q.empty()) {
      int u = Q.top().u;
      Q.pop();
      if (done[u]) continue;
      done[u] = true;
      for (int i = 0; i < G[u].size(); i++) {
        Edge& e = edges[G[u][i]];
        int v = e.to, w = e.weight;
        if (dist[v] > dist[u] + w) {
          dist[v] = dist[u] + w;
          p[v] = G[u][i];
          Q.push(HeapNode(v, dist[v]));
        }
      }
    }
  }
};
Dijkstra d(maxn);
map<pair<int, int>, int> ss;
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n, m, k, x, y, s, e = 0;
  cin >> n >> m >> k;
  for (int i = 1; i <= k; i++) {
    cin >> x >> y;
    ss[make_pair(x, y)] = i + n + m;
    if (x == 1 && y == 1) {
      s = i + n + m;
    }
    if (x == n && y == m) {
      e = i + n + m;
    }
    int t = i + n + m;
    int ny = n + y;
    if (x > 1) {
      if (ss[make_pair(x - 1, y)] != 0) {
        d.AddEdge(ss[make_pair(x - 1, y)], t, 0);
        d.AddEdge(t, ss[make_pair(x - 1, y)], 0);
      }
      d.AddEdge(x - 1, t, 0);
      d.AddEdge(t, x - 1, 1);
    }
    if (x < n) {
      if (ss[make_pair(x + 1, y)] != 0) {
        d.AddEdge(ss[make_pair(x + 1, y)], t, 0);
        d.AddEdge(t, ss[make_pair(x + 1, y)], 0);
      }
      d.AddEdge(x + 1, t, 0);
      d.AddEdge(t, x + 1, 1);
    }
    if (y > 1) {
      if (ss[make_pair(x, y - 1)] != 0) {
        d.AddEdge(ss[make_pair(x, y - 1)], t, 0);
        d.AddEdge(t, ss[make_pair(x, y - 1)], 0);
      }
      d.AddEdge(ny - 1, t, 0);
      d.AddEdge(t, ny - 1, 1);
    }
    if (y < m) {
      if (ss[make_pair(x, y + 1)] != 0) {
        d.AddEdge(ss[make_pair(x, y + 1)], t, 0);
        d.AddEdge(t, ss[make_pair(x, y + 1)], 0);
      }
      d.AddEdge(ny + 1, t, 0);
      d.AddEdge(t, ny + 1, 1);
    }
    d.AddEdge(x, t, 0), d.AddEdge(t, x, 1);
    d.AddEdge(ny, t, 0), d.AddEdge(t, ny, 1);
  }
  if (!e) {
    d.AddEdge(n, n + m + k + 1, 0);
    d.AddEdge(n + m, n + m + k + 1, 0);
    if (ss[make_pair(n, m - 1)] != 0) {
      d.AddEdge(ss[make_pair(n, m - 1)], n + m + k + 1, e ? 0 : 1);
    }
    if (ss[make_pair(n - 1, m)] != 0) {
      d.AddEdge(ss[make_pair(n - 1, m)], n + m + k + 1, e ? 0 : 1);
    }
  }
  d.dijkstra(s);
  if (d.dist[e ? e : n + m + k + 1] == 0x3f3f3f3f) {
    cout << "-1" << endl;
  } else {
    cout << d.dist[e ? e : n + m + k + 1] << endl;
  }
  return 0;
}
