#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define START 200000
#define GOAL  200001
#define HUGE_NUM 9999999999999999


enum DIR{
	TATE,
	YOKO,
};


struct Info{
	int col,row;
};

struct Data{
	Data(){
		info_id = 0;
		loc = 0;
	}
	Data(int arg_info_id,int arg_loc){
		info_id = arg_info_id;
		loc = arg_loc;
	}
	bool operator<(const struct Data &arg) const{
		return loc < arg.loc;
	}
	int info_id,loc;
};

struct STATE{
	STATE(int arg_node_id,ll arg_cost,DIR arg_dir){
		node_id = arg_node_id;
		cost = arg_cost;
		dir = arg_dir;
	}
	bool operator<(const struct STATE &arg) const{
		return cost > arg.cost;
	}
	int node_id;
	ll cost;
	DIR dir;
};

int W,H,K;
vector<Data> COL[100000],ROW[100000];
Info info[200002];
vector<int> G[200002];
ll min_cost[200002][2];

int main(){

	scanf("%d %d %d",&W,&H,&K);

	COL[0].push_back(Data(START,0));
	ROW[0].push_back(Data(START,0));
	info[START].row = 0;
	info[START].col = 0;

	COL[W-1].push_back(Data(GOAL,H-1));
	ROW[H-1].push_back(Data(GOAL,W-1));
	info[GOAL].row = H-1;
	info[GOAL].col = W-1;

	bool start_switch = false;

	int tmp_row,tmp_col;
	for(int i = 0; i < K; i++){
		scanf("%d %d",&tmp_col,&tmp_row);
		tmp_row--;
		tmp_col--;
		if(tmp_row == 0 && tmp_col == 0){
			start_switch = true;
			continue;
		}
		info[i].row = tmp_row;
		info[i].col = tmp_col;
 		COL[info[i].col].push_back(Data(i,info[i].row));
		ROW[info[i].row].push_back(Data(i,info[i].col));
	}


	for(int row = 0; row < H; row++){
		sort(ROW[row].begin(),ROW[row].end());
	}

	for(int col = 0; col < W; col++){
		sort(COL[col].begin(),COL[col].end());
	}

	for(int row = 0; row < H; row++){
		if(ROW[row].size() <= 1)continue;

		for(int i = 0; i < ROW[row].size()-1; i++){
			G[ROW[row][i].info_id].push_back(ROW[row][i+1].info_id);
			G[ROW[row][i+1].info_id].push_back(ROW[row][i].info_id);
		}
	}

	for(int col = 0; col < W; col++){
		if(COL[col].size() <= 1)continue;

		for(int i = 0; i < COL[col].size()-1; i++){
			G[COL[col][i].info_id].push_back(COL[col][i+1].info_id);
			G[COL[col][i+1].info_id].push_back(COL[col][i].info_id);
		}
	}

	for(int i = 0; i <= GOAL; i++){
		min_cost[i][TATE] = HUGE_NUM;
		min_cost[i][YOKO] = HUGE_NUM;
	}

	priority_queue<STATE> Q;

	min_cost[START][TATE] = 0;
	Q.push(STATE(START,0,TATE));

	if(start_switch){
		min_cost[START][YOKO] = 1;
		Q.push(STATE(START,1,YOKO));
	}

	int next_node;
	ll next_cost;

	while(!Q.empty()){

		if(Q.top().node_id == GOAL){
			printf("%lld\n",Q.top().cost);
			return 0;
		}else if(Q.top().cost > min_cost[Q.top().node_id][Q.top().dir]){
			Q.pop();
		}else{

			for(int i = 0; i < G[Q.top().node_id].size(); i++){
				next_node = G[Q.top().node_id][i];

				next_cost = Q.top().cost;

				if(info[Q.top().node_id].row == info[next_node].row){
					next_cost += abs(info[Q.top().node_id].col-info[next_node].col);

					if(Q.top().dir == TATE && Q.top().node_id == START && start_switch == false)continue;
					if(Q.top().dir == TATE)next_cost += 1;

					if(min_cost[next_node][YOKO] > next_cost){
						min_cost[next_node][YOKO] = next_cost;
						Q.push(STATE(next_node,next_cost,YOKO));
					}

				}else{
					next_cost += abs(info[Q.top().node_id].row-info[next_node].row);

					if(Q.top().dir == YOKO && Q.top().node_id == START && start_switch == false)continue;
					if(Q.top().dir == YOKO)next_cost += 1;

					if(min_cost[next_node][TATE] > next_cost){
						min_cost[next_node][TATE] = next_cost;
						Q.push(STATE(next_node,next_cost,TATE));
					}
				}
			}
			Q.pop();
		}
	}

	printf("-1\n");

	return 0;
}



Measured memory_bytes: 32460