#include <bits/stdc++.h>
using namespace std;
template <class T>
inline void upmax(T &a, T b) {
  if (a < b) a = b;
}
template <class T>
inline void upmin(T &a, T b) {
  if (a > b) a = b;
}
const int maxn = 100007;
const int maxm = 200007;
const int mod = 1000000007;
const int inf = 0x7fffffff;
const double eps = 1e-7;
typedef int arr[maxn];
typedef int adj[maxm];
inline int fcmp(double a, double b) {
  if (fabs(a - b) <= eps) return 0;
  if (a < b - eps) return -1;
  return 1;
}
inline int add(int a, int b) { return (a + b) % mod; }
inline int mul(int a, int b) { return ((long long)a * b) % mod; }
inline int dec(int a, int b) { return add(a, mod - b % mod); }
inline int Pow(int a, int b) {
  int t = 1;
  while (b) {
    if (b & 1) t = mul(t, a);
    a = mul(a, a), b >>= 1;
  }
  return t;
}
template <typename Type>
inline Type RD() {
  char c = getchar();
  Type x = 0, flag = 1;
  while (!isdigit(c) && c != '-') c = getchar();
  if (c == '-')
    flag = -1;
  else
    x = c - '0';
  while (isdigit(c = getchar())) x = x * 10 + c - '0';
  return x * flag;
}
inline char rdch() {
  char c = getchar();
  while (!isalpha(c)) c = getchar();
  return c;
}
struct Event {
  int x, id;
  Event(int x = 0, int id = 0) : x(x), id(id) {}
};
arr _y1, _y2;
vector<Event> ScanLine;
inline bool cmp_e(const Event a, const Event b) {
  if (a.x != b.x) return a.x < b.x;
  if (a.id < 0) return b.id > 0 || (_y1[-a.id] < _y1[-b.id]);
  if (b.id < 0) return 0;
  return _y1[a.id] < _y1[b.id];
}
int n, m, q;
void input() {
  n = RD<int>(), m = RD<int>(), q = RD<int>();
  for (int i = 1, _ = q; i <= _; i++) {
    int x1, x2;
    x1 = RD<int>(), _y1[i] = RD<int>(), x2 = RD<int>(), _y2[i] = RD<int>();
    ScanLine.push_back(Event(x1, i));
    ScanLine.push_back(Event(x2 + 1, -i));
  }
  sort(ScanLine.begin(), ScanLine.end(), cmp_e);
}
namespace ST {
const int maxs = (1 << 21) + 7;
typedef int seg[maxs];
seg cv, sum, ls, rs;
int rt, tot, ql, qr, p, v;
inline void tag(int u) { cv[u] = 1, sum[u] = 0; }
inline void push(int u) {
  if (ls[u]) tag(ls[u]);
  if (rs[u]) tag(rs[u]);
  cv[u] = 0;
}
void add(int &u, int l = 1, int r = m) {
  if (!u) u = ++tot;
  sum[u] = ::add(sum[u], v);
  if (l == r) return;
  if (cv[u]) push(u);
  int m = (l + r) >> 1;
  if (p <= m)
    add(ls[u], l, m);
  else
    add(rs[u], m + 1, r);
}
void clr(int &u, int l = 1, int r = m) {
  if (!u) return;
  if (ql <= l && r <= qr) return (void)tag(u);
  if (cv[u]) push(u);
  int m = (l + r) >> 1;
  if (ql <= m) clr(ls[u], l, m);
  if (qr > m) clr(rs[u], m + 1, r);
  sum[u] = ::add(sum[ls[u]], sum[rs[u]]);
}
int que(int &u, int l = 1, int r = m) {
  if (!u) return 0;
  if (ql <= l && r <= qr) return sum[u];
  if (cv[u]) push(u);
  int m = (l + r) >> 1, t = 0;
  if (ql <= m) t = que(ls[u], l, m);
  if (qr > m) t = ::add(t, que(rs[u], m + 1, r));
  return t;
}
inline void A(int _p, int s) {
  p = _p, v = s;
  if (p < 1 || p > m) return;
  add(rt);
}
inline void C(int l, int r) {
  if (l > r) return;
  ql = l, qr = r;
  clr(rt);
}
inline int Q(int l, int r) {
  if (l > r) return 0;
  ql = l, qr = r;
  return que(rt);
}
}  // namespace ST
set<pair<int, int> > S, pre_s;
set<pair<int, int> >::iterator iter_up[maxn], iter_dn[maxn];
stack<int> to_ins;
stack<pair<int, int> > to_add, to_clr;
int cur;
inline void print_set(set<pair<int, int> > s) {
  for (pair<int, int> x : s) fprintf(stderr, "%d %d\n", x.first, x.second);
}
inline void insert(int id) {
  int up_bound = _y2[id], dn_bound = 1;
  to_ins.push(id);
  auto it = S.lower_bound(make_pair(_y2[id], 1));
  if (it == S.end() || it->first != up_bound + 1) {
    it = S.lower_bound(make_pair(_y1[id], 0));
    if (it != S.begin() && !S.empty()) --it, dn_bound = it->first + 1;
    auto it_s = pre_s.lower_bound(make_pair(_y2[id], 1));
    if (cur != 1 &&
        (it_s == pre_s.end() || (!it_s->second && it_s->first > _y2[id] + 1))) {
      if (it_s != pre_s.begin()) {
        if (it_s == pre_s.end() || !it_s->second) --it_s;
        upmax(dn_bound, it_s->first + 1);
      }
      int sum = ST::Q(dn_bound, up_bound);
      if (up_bound != m) to_add.push(make_pair(up_bound + 1, sum));
    }
  }
  to_clr.push(make_pair(_y1[id], _y2[id]));
}
stack<pair<int, int> > sta;
inline void erase(int id) {
  sta.push(*iter_up[id]);
  sta.push(*iter_dn[id]);
  S.erase(iter_up[id]);
  S.erase(iter_dn[id]);
}
inline void push_sta() {
  pre_s.clear();
  while (!sta.empty()) pre_s.insert(sta.top()), sta.pop();
}
inline void clear_sta() {
  pre_s.clear();
  while (!sta.empty()) sta.pop();
  while (!to_add.empty()) {
    ST::A(to_add.top().first, to_add.top().second), to_add.pop();
  }
  while (!to_clr.empty())
    ST::C(to_clr.top().first, to_clr.top().second), to_clr.pop();
  while (!to_ins.empty()) {
    int id = to_ins.top();
    to_ins.pop();
    iter_up[id] = S.insert(make_pair(_y2[id], 1)).first;
    iter_dn[id] = S.insert(make_pair(_y1[id], 0)).first;
  }
}
void solve() {
  ST::A(1, 1);
  pair<int, int> pre(0, 0), pre_pre(0, 0);
  for (Event e : ScanLine) {
    int i = e.id;
    cur = e.x;
    if (cur > n) break;
    if (pre.first == cur && pre.second != (i > 0))
      push_sta();
    else if (pre.first != cur)
      clear_sta();
    if (i > 0)
      insert(i);
    else
      erase(-i);
    if (cur != pre.first || (cur == pre.first && (i > 0) != pre.second))
      pre_pre = pre;
    pre = make_pair(cur, i > 0);
  }
  clear_sta();
  int l = 1;
  if (!S.empty()) {
    auto it = --S.end();
    l = it->first + 1;
  }
  int ans = ST::Q(l, m);
  printf("%d\n", ans);
}
int main() {
  input();
  solve();
  return 0;
}
