#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cstring>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <memory>
#include <queue>
#include <random>
 
 
using namespace std;
 
template<class T>
using vec = std::vector<T>;
 
 
#define FOR(i, n) for (int i = 0; i < (n); ++i)
#define FORA(i, a, n) for (int i = (a); i < (n); ++i)
 
 
#define all(c) c.begin(), c.end()
 
 
// TC_REMOVE_BEGIN
/// caide keep
bool __hack = std::ios::sync_with_stdio(false);
/// caide keep
auto __hack1 = cin.tie(nullptr);
// TC_REMOVE_END
 
 
// Section with adoption of array and vector algorithms.
 
 
//#include <ext/pb_ds/tree_policy.hpp>
//#include <ext/pb_ds/assoc_container.hpp>
//
//template <class T> using StdTree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;
 
 
namespace template_util {
    
 
    constexpr int bytecount(uint64_t x) {
        return x ? 1 + bytecount(x >> 8) : 0;
    }
 
    template<int N>
    struct bytetype {
        
    };
 
    
    /// caide keep
    template<uint64_t N>
    struct minimal_uint : bytetype<bytecount(N)> {
    };
}
 
 
template<class T>
T next(istream& in) {
    T ret;
    in >> ret;
    return ret;
}
 
 
template<typename T> static constexpr T wrap_pos(T a, T m) { return a < 0 ? a + m : a; }
 
// m must be positive
template<typename T> static constexpr T mod(T a, T m) { return wrap_pos(a % m, m); }
 
template<typename T>
static constexpr T inverse2(T a, T m) { return a <= 1 ? a : mod((1 - inverse2(m % a, a) * m) / a, m); }
 
template<typename T>
static constexpr T inverse(T a, T m) { return inverse2(mod(a, m), m); }
 
template<typename T, typename C, T Modulus>
class MR
{
 private:
   // indicates value is in range [0, 2 * Modulus)
  struct tag_minus {}; // indicates value is in range (-Modulus, Modulus)
  struct tag_good {}; // indicates value is in range
 
//  T value;
 
  static_assert(std::numeric_limits<C>::max() / Modulus / Modulus > 0, "compute type is too small");
  static_assert(Modulus < std::numeric_limits<T>::max() / 2, "storage type is too small");
 
  
  static constexpr T reduce(T value, tag_minus)
  {
    return value < 0 ? value + Modulus : value;
  }
 
  static constexpr T reduce(T value, tag_good) { return value; }
 
 public:
  T value;
  
  
  constexpr MR() : value(0) {}
  constexpr MR(C value) : value(reduce(value % Modulus, tag_minus())) {}
  template<typename tag_t>
  constexpr MR(T value, tag_t tag) : value(reduce(value, tag)) {}
 
  
  constexpr MR operator -(MR b) const { return MR(value - b.value, tag_minus()); }
  constexpr MR operator *(MR b) const { return MR(C(value) * C(b.value) % Modulus, tag_good()); }
  
 
  constexpr T get() const { return value; }
 
  // These are only valid if the dividend is relatively prime to the modulus
  constexpr MR inverse() const
  {
    return MR(::inverse(C(value), C(Modulus)), tag_good());
  }
  constexpr MR operator /(MR b) const { return *this * b.inverse(); }
  
};
 
template<typename T, typename C, T Modulus>
static inline std::ostream &operator<<(std::ostream &o, MR<T, C, Modulus> mr)
{
  return o << mr.get();
}
 
 
//template <class T>
//T gcd(T a, T b) {
//    return b == 0 ? a : gcd(b, a % b);
//}
 
//TODO extended gcd
 
 
// MD implementation of factorials and binomial
 
template<class T>
vector<T> getFactorials(int n) {
  vector<T> res(n);
  res[0] = T(1);
  for (int i = 1; i < n; ++i) {
    res[i] = res[i-1] * i;
  }
  return res;
}
 
 
// TODO(alf): Tests
 
 
//
//int64_t lcm(const vector<int64_t>& a) {
//    int64_t res = a[0];
//    for (int i = 1; i < (int)a.size(); ++i) {
//        int64_t g = gcd(res, a[i]);
//        res *= a[i];
//        res /= g;
//    }
//    return res;
//}
//
//int64_t lcm(int64_t a, int64_t b) {
//    return (a * b / gcd(a, b));
//}
 
 
// TODO: test on timus problem
// vector<double> polynomeEquationSolve() {}
 
 
// Algorithms
 
 
typedef MR<int, int64_t, 1000000007> md;
 
void solve(istream& in, ostream& out) {
//  auto tests = next<int>(in);
//  while (tests--) {
    auto h = next<int>(in);
    auto w = next<int>(in);
    auto n = next<int>(in);
    vec<pair<int, int>> ps(n);
    FOR(i, n) {
      ps[i] = {next<int>(in), next<int>(in)};
    }
    ps.push_back({h, w});
    sort(all(ps));
    ++n;
 
    auto fs = getFactorials<md>(h + w + 1);
    auto rfs = fs;
    FOR(i, rfs.size()) {
      rfs[i] = md(1) / fs[i];
    }
 
    auto get = [&] (int dx, int dy) -> md {
      return fs[dx + dy] * rfs[dx] * rfs[dy];
    };
 
    vec<md> res(n);
    FOR(i, n) {
      res[i] = get(ps[i].first - 1, ps[i].second - 1);
    }
    FOR(i, n) {
      FORA(j, i + 1, n) {
        if (ps[j].first < ps[i].first || ps[j].second < ps[i].second) {
          continue;
        }
        res[j] = res[j] - res[i] * get( ( ps[j].first - ps[i].first ), ( ps[j].second - ps[i].second) );
      }
    }
 
    out << res[n-1] << "\n";
  }

 
int main() {
    solve(cin, cout);

    return 0;
}

Measured memory_bytes: 1920