#include <bits/stdc++.h>
using namespace std;
const int Maxn = 1000010, Maxk = 100010;
const int inf = 2147483647;
const int mod = 1000000007;
int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9')
    x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar();
  return x * f;
}
int n, m, k;
struct Seg {
  int l, r, lc, rc, tag, c;
} tr[Maxn << 1];
int tot = 0;
void build(int l, int r) {
  int x = ++tot;
  tr[x].l = l;
  tr[x].r = r;
  tr[x].tag = -1;
  tr[x].c = 0;
  if (l == r) return;
  int mid = l + r >> 1;
  tr[x].lc = tot + 1, build(l, mid);
  tr[x].rc = tot + 1, build(mid + 1, r);
}
void w(int x, int v) {
  tr[x].tag = v;
  tr[x].c = (long long)v * (tr[x].r - tr[x].l + 1) % mod;
}
void down(int x) {
  if (tr[x].tag == -1) return;
  int lc = tr[x].lc, rc = tr[x].rc, t = tr[x].tag;
  w(lc, t), w(rc, t);
  tr[x].tag = -1;
}
void up(int x) { tr[x].c = (tr[tr[x].lc].c + tr[tr[x].rc].c) % mod; }
void modify(int x, int l, int r, int v) {
  if (tr[x].l == l && tr[x].r == r) {
    w(x, v);
    return;
  }
  int lc = tr[x].lc, rc = tr[x].rc, mid = tr[x].l + tr[x].r >> 1;
  down(x);
  if (r <= mid)
    modify(lc, l, r, v);
  else if (l > mid)
    modify(rc, l, r, v);
  else
    modify(lc, l, mid, v), modify(rc, mid + 1, r, v);
  up(x);
}
int query(int x, int l, int r) {
  if (tr[x].l == l && tr[x].r == r) return tr[x].c;
  int lc = tr[x].lc, rc = tr[x].rc, mid = tr[x].l + tr[x].r >> 1;
  down(x);
  if (r <= mid) return query(lc, l, r);
  if (l > mid) return query(rc, l, r);
  return (query(lc, l, mid) + query(rc, mid + 1, r)) % mod;
}
void add(int x, int p, int v) {
  if (tr[x].l == tr[x].r) {
    tr[x].c = (tr[x].c + v) % mod;
    return;
  }
  int lc = tr[x].lc, rc = tr[x].rc, mid = tr[x].l + tr[x].r >> 1;
  down(x);
  if (p <= mid)
    add(lc, p, v);
  else
    add(rc, p, v);
  up(x);
}
struct P {
  int x, l, r, op;
  P(int _x = 0, int _l = 0, int _r = 0, int _op = 0) {
    x = _x, l = _l, r = _r, op = _op;
  }
} a[Maxk << 1];
int la = 0;
bool cmp(P a, P b) {
  if (a.x != b.x) return a.x < b.x;
  if (a.op != b.op) return a.op > b.op;
  return a.l > b.l;
}
multiset<int> S;
int main() {
  n = read(), m = read(), k = read();
  for (int i = 1; i <= k; i++) {
    int X1 = read(), Y1 = read(), X2 = read(), Y2 = read();
    a[++la] = P(X1, Y1, Y2, 1), a[++la] = P(X2 + 1, Y1, Y2, -1);
  }
  sort(a + 1, a + 1 + la, cmp);
  build(1, m);
  add(1, 1, 1);
  S.insert(0);
  S.insert(m + 1);
  int o;
  for (int i = 1; i <= la; i++) {
    if (a[i].x != 1) {
      o = i;
      break;
    }
    S.insert(a[i].l), S.insert(a[i].r);
  }
  for (int i = 2; i <= n; i++) {
    while (o <= la && a[o].x == i) {
      multiset<int>::iterator it;
      if (a[o].op == 1) {
        it = S.upper_bound(a[o].r);
        int nxt = (*it);
        int L = (*(--it)) + 1, R = a[o].r;
        if (L <= R && a[o].r < m && nxt != a[o].r + 1)
          add(1, a[o].r + 1, query(1, L, R));
        modify(1, a[o].l, a[o].r, 0);
        S.insert(a[o].l), S.insert(a[o].r);
      } else
        S.erase(S.lower_bound(a[o].l)), S.erase(S.lower_bound(a[o].r));
      o++;
    }
  }
  multiset<int>::iterator it = S.end();
  it--;
  it--;
  if ((*it) == m) return puts("0"), 0;
  printf("%d", query(1, (*it) + 1, m));
}
