import std.stdio, std.conv, std.string, std.bigint;
import std.math, std.random, std.datetime;
import std.array, std.range, std.algorithm, std.container, std.format;
string read(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }

/*

【Ｙ】

包除の原理 包除原理 経路 二項係数 階乗

--------------------------------------------------------------------------------

求めるものは
C(H, W) - sum(k)((-1)**k x[k])
ただし
x[k] はk個のNGな点を通る経路の数
 ※k+1個以上のNGな点を通る場合、k個の選び方ごとに重複して数える

である。

--------------------------------------------------------------------------------

NGな点は、①x座標の順 ②y座標の順 でソートしておく
（「P[j]からP[i]に行けるならばj < i」を確保する）

x[i][k]は、k個のNGな点を通ってP[i]に到達する経路の数

x[i][k] = sum(j; 0 .. i, P[j] < P[i])(x[j][k - 1] C(P[j] -> P[i]))

この C は、あらかじめperm[]とinvperm[]を計算しておけば定数時間になる
（実装としてはperm()とinvperm()がメモを持つ）

x[k] = sum(i; 0 .. n) (x[i][k] C(P[i] -> HW - 1)

求めるものは
C(H, W) - sum(k)((-1)**k x[k])

--------------------------------------------------------------------------------

*/

const long mod = 1_000_000_007;

void main(){
	long h = read.to!long;
	long w = read.to!long;
	long n = read.to!long;
	
	Cell[] cells;
	foreach(i; 0 .. n){
		long r = read.to!long - 1;
		long c = read.to!long - 1;
		cells ~= new Cell(r, c);
	}
	debug writeln("cells:", cells);
	
	cells.sort!"a.value<b.value"();
	debug writeln("cells:", cells);
	
	long[][] xs = new long[][](n, n);
	foreach(i; 0 .. n){
		foreach(k; 0 .. i + 1){
			long x;
			if(k == 0) x = pascal(cells[i].r, cells[i].c);
			else foreach(j; 0 .. i){
				if(cells[j].r <= cells[i].r && cells[j].c <= cells[i].c){
					long tmp = xs[j][k - 1] * pascal(cells[i].r - cells[j].r, cells[i].c - cells[j].c) % mod;
					x += tmp, x %= mod;
				}
			}
			debug writeln("i:", i, " k:", k, " x:", x);
			xs[i][k] = x;
		}
	}
	debug writeln("xs:", xs);
	
	long[] ys = new long[](n);
	foreach(k; 0 .. n){
		long y;
		foreach(i; 0 .. n){
			y += xs[i][k] * pascal(h - 1 - cells[i].r, w  - 1 - cells[i].c) % mod, y %= mod;
			debug writeln("k:", k, " i:", i, " x:", xs[i][k], " h-1-r:", h - 1 - cells[i].r, " w-1-c:", w - 1 - cells[i].c);
		}
		ys[k] = y;
	}
	debug writeln("ys:", ys);
	
	long ans = pascal(h - 1, w - 1);
	foreach(k; 0 .. n){
		if(k % 2 == 0) ans += mod - ys[k], ans %= mod;
		else ans += ys[k], ans %= mod;
	}
	ans.writeln;
	
}

// mod p における乗法逆元
long inv(long x){
	assert(x > 0);
	assert(x < mod);
	static long[] _inv = [0, 1];
	while(x >= _inv.length){
		_inv ~= _inv[mod % $] * (mod - mod / _inv.length) % mod;
	}
	return _inv[x];
}

// mod p における階乗
long perm(long x){
	assert(x >= 0);
	assert(x < mod);
	static long[] _perm = [1];
	while(x >= _perm.length){
		_perm ~= _perm[$ - 1] * _perm.length % mod;
	}
	return _perm[x];
}

// mod p における階乗の逆元
long invperm(long x){
	assert(x >= 0);
	assert(x < mod);
	static long[] _invperm = [1];
	while(x >= _invperm.length){
		_invperm ~= _invperm[$ - 1] * inv(_invperm.length) % mod;
	}
	return _invperm[x];
}

// mod p における二項係数（定義に注意：(a + b)! / a! / b! ）
long pascal(long a, long b){
	assert(a >= 0 && b >= 0);
	assert(a < mod && b < mod);
	long res = perm((a + b) % mod);
	res *= invperm(a), res %= mod;
	res *= invperm(b), res %= mod;
	return res;
}


class Cell{
	long r, c;
	long value;
	this(long r, long c){
		this.r = r;
		this.c = c;
		this.value = r * mod + c;
	}
	override string toString(){
		return [r, c].to!string;
	}
}

