#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
struct p1 {
	int idx, x, y;
};
bool operator<(const p1& r1, const p1& r2) {
	if (r1.y != r2.y) return r1.y < r2.y;
	return r1.x < r2.x;
}
struct edge {
	int to; long long cost; int type;
};
bool operator<(const edge& e1, const edge& e2) {
	return e1.cost < e2.cost;
}
int H, W, N;
int main() {
	cin >> W >> H >> N;
	vector<p1> p(N);
	for (int i = 0; i < N; i++) cin >> p[i].x >> p[i].y, p[i].x--, p[i].y--, p[i].idx = i;
	p.push_back(p1{ N, W - 1, H - 1 }); N++;
	vector<vector<p1> > ex(W), ey(H);
	for (int i = 0; i < N; i++) {
		ex[p[i].x].push_back(p[i]);
		ey[p[i].y].push_back(p[i]);
	}
	for (int i = 0; i < W; i++) sort(ex[i].begin(), ex[i].end());
	for (int i = 0; i < H; i++) sort(ey[i].begin(), ey[i].end());
	vector<vector<edge> > G(N);
	for (int i = 0; i < W; i++) {
		for (int j = 1; j < ex[i].size(); j++) {
			int d = ex[i][j].y - ex[i][j - 1].y;
			G[ex[i][j - 1].idx].push_back(edge{ ex[i][j].idx, d, 0 });
			G[ex[i][j].idx].push_back(edge{ ex[i][j - 1].idx, d, 0 });
		}
	}
	for (int i = 0; i < H; i++) {
		for (int j = 1; j < ey[i].size(); j++) {
			int d = ey[i][j].x - ey[i][j - 1].x;
			G[ey[i][j - 1].idx].push_back(edge{ ey[i][j].idx, d, 1 });
			G[ey[i][j].idx].push_back(edge{ ey[i][j - 1].idx, d, 1 });
		}
	}
	priority_queue<edge> que;
	vector<vector<long long> > dist(N, vector<long long>(2, 1LL << 60));
	if (ex[0].size()) {
		que.push(edge{ ex[0][0].idx, ex[0][0].y, 0 });
		dist[ex[0][0].idx][0] = ex[0][0].y;
	}
	while (!que.empty()) {
		edge u = que.top(); que.pop();
		for (edge e : G[u.to]) {
			long long d = dist[u.to][u.type];
			if (e.type == 0) d += abs(p[u.to].y - p[e.to].y);
			else d += abs(p[u.to].x - p[e.to].x);
			if (u.type != e.type) d++;
			if (dist[e.to][e.type] > d) {
				dist[e.to][e.type] = d;
				que.push(edge{ e.to, -d, e.type });
			}
		}
	}
	long long ret = min(dist[N - 1][0], dist[N - 1][1]);
	if (ret == (1LL << 60)) cout << -1 << endl;
	else cout << ret << endl;
	return 0;
}