#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 10;
const int INF = 2e9 + 10;
const int BASE = 1e9 + 7;
int h, w, n;
int dp[N];
map<int, int> idx;
struct FenwickTree {
  int n;
  vector<int> fw;
  void Init(int _n) {
    n = _n;
    fw.resize(n + 2);
    for (int i = 1; i <= n; ++i) fw[i] = 0;
  }
  void Update(int i, int v) {
    for (i; i > 0; i -= i & -i) fw[i] = max(fw[i], v);
  }
  int Query(int i) {
    int ans = 0;
    for (i; i <= n; i += i & -i) ans = max(ans, fw[i]);
    return ans;
  }
};
struct SegmentTree {
  static const int N = 1e5 + 10;
  FenwickTree st[4 * N];
  vector<int> val[4 * N];
  void fakeNode(int k, int l, int r, int i, int j, int v) {
    if (l > j || r < i) return;
    if (i <= l && r <= j) {
      val[k].push_back(v);
      return;
    }
    fakeNode(k << 1, l, ((l + r) >> 1), i, j, v);
    fakeNode(k << 1 | 1, ((l + r) >> 1) + 1, r, i, j, v);
  }
  int Pos(int k, int v) {
    return lower_bound(val[k].begin(), val[k].end(), v) - val[k].begin() + 1;
  }
  void Init(int k, int l, int r) {
    sort(val[k].begin(), val[k].end());
    val[k].resize(unique(val[k].begin(), val[k].end()) - val[k].begin());
    st[k].Init(val[k].size());
    if (l == r) return;
    Init(k << 1, l, ((l + r) >> 1));
    Init(k << 1 | 1, ((l + r) >> 1) + 1, r);
  }
  void Update(int k, int l, int r, int i, int j, pair<int, int> v) {
    if (l > j || r < i) return;
    if (i <= l && r <= j) {
      int p = Pos(k, v.first);
      st[k].Update(p, v.second);
      return;
    }
    Update(k << 1, l, ((l + r) >> 1), i, j, v);
    Update(k << 1 | 1, ((l + r) >> 1) + 1, r, i, j, v);
  }
  int Query(int k, int l, int r, int i, int v) {
    if (l > i || r < i) return 0;
    int ans = st[k].Query(Pos(k, v));
    if (l == r) return ans;
    ans = max(ans, Query(k << 1, l, ((l + r) >> 1), i, v));
    ans = max(ans, Query(k << 1 | 1, ((l + r) >> 1) + 1, r, i, v));
    return ans;
  }
} ST;
struct Barrier {
  int l, r, u, s;
  Barrier() {}
  Barrier(int l, int r, int u, int s) : l(l), r(r), u(u), s(s) {}
  bool operator<(const Barrier &that) const { return u < that.u; }
} B[N];
void Add(int &a, int b) {
  a += b;
  if (a >= BASE) a -= BASE;
}
int Mul(int a, int b) { return 1LL * a * b % BASE; }
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> h >> w >> n;
  for (int i = 1; i <= n; ++i) {
    int l, r, u, s;
    cin >> u >> l >> r >> s;
    B[i] = Barrier(l, r, u, s);
  }
  sort(B + 1, B + n + 1);
  for (int i = 1; i <= n; ++i) {
    int l = B[i].l, r = B[i].r, u = B[i].u, s = B[i].s;
    idx[u] = i;
    ST.fakeNode(1, 1, w, l, r, u + s);
    if (l - 1 >= 1) ST.fakeNode(1, 1, w, l - 1, l - 1, u);
    if (r + 1 <= w) ST.fakeNode(1, 1, w, r + 1, r + 1, u);
  }
  idx[0] = 0;
  dp[0] = 1;
  ST.Init(1, 1, w);
  for (int i = 1; i <= n; ++i) {
    int l = B[i].l, r = B[i].r, u = B[i].u, s = B[i].s;
    if (l - 1 >= 1 && r + 1 <= w) {
      int x = ST.Query(1, 1, w, l - 1, u);
      Add(dp[idx[u]], dp[idx[x]]);
      x = ST.Query(1, 1, w, r + 1, u);
      Add(dp[idx[u]], dp[idx[x]]);
    } else if (l - 1 >= 1) {
      int x = ST.Query(1, 1, w, l - 1, u);
      Add(dp[idx[u]], Mul(2, dp[idx[x]]));
    } else {
      assert(r + 1 <= w);
      int x = ST.Query(1, 1, w, r + 1, u);
      Add(dp[idx[u]], Mul(2, dp[idx[x]]));
    }
    ST.Update(1, 1, w, l, r, pair<int, int>(u + s, u));
  }
  int ans = 0;
  for (int i = 1; i <= w; ++i) {
    int x = ST.Query(1, 1, w, i, h + 1);
    Add(ans, dp[idx[x]]);
  }
  cout << ans << '\n';
  return 0;
}
