#include <bits/stdc++.h>
using namespace std;
const int RLEN = 1 << 18 | 1;
inline char nc() {
  static char ibuf[RLEN], *ib, *ob;
  (ib == ob) && (ob = (ib = ibuf) + fread(ibuf, 1, RLEN, stdin));
  return (ib == ob) ? -1 : *ib++;
}
inline int rd() {
  char ch = nc();
  int i = 0, f = 1;
  while (!isdigit(ch)) {
    if (ch == '-') f = -1;
    ch = nc();
  }
  while (isdigit(ch)) {
    i = (i << 1) + (i << 3) + ch - '0';
    ch = nc();
  }
  return i * f;
}
const int N = 4e5 + 50, mod = 1e9 + 7;
inline int add(int x, int y) {
  return (x + y >= mod) ? (x + y - mod) : (x + y);
}
inline int dec(int x, int y) { return (x - y < 0) ? (x - y + mod) : (x - y); }
inline int mul(int x, int y) { return (long long)x * y % mod; }
inline int power(int a, int b, int rs = 1) {
  for (; b; b >>= 1, a = mul(a, a))
    if (b & 1) rs = mul(rs, a);
  return rs;
}
int n, m, k, l[2][N], r[2][N], p[2][N];
vector<int> pos;
struct SegmentTree {
  struct node {
    int sum, tag;
    node() : sum(0), tag(-1) {}
    inline void cov(int v, int l, int r) {
      sum = mul(v, r - l + 1);
      tag = v;
    }
  } tr[N * 4];
  inline void pushdown(int k, int l, int r) {
    int mid = (l + r) >> 1;
    tr[k << 1].cov(tr[k].tag, l, mid);
    tr[k << 1 | 1].cov(tr[k].tag, mid + 1, r);
    tr[k].tag = -1;
  }
  inline void upt(int k) {
    tr[k].sum = add(tr[k << 1].sum, tr[k << 1 | 1].sum);
  }
  inline void cov(int k, int l, int r, int L, int R, int v) {
    if (L <= l && r <= R) return tr[k].cov(v, l, r);
    if (~tr[k].tag) pushdown(k, l, r);
    int mid = (l + r) >> 1;
    if (R <= mid)
      cov(k << 1, l, mid, L, R, v);
    else if (L > mid)
      cov(k << 1 | 1, mid + 1, r, L, R, v);
    else
      cov(k << 1, l, mid, L, R, v), cov(k << 1 | 1, mid + 1, r, L, R, v);
    upt(k);
  }
} st[2];
int main() {
  k = rd(), n = rd(), m = rd();
  pos.push_back(1);
  pos.push_back(k + 1);
  for (int i = 1; i <= n; i++)
    pos.push_back((l[0][i] = rd())), pos.push_back((r[0][i] = rd() + 1));
  for (int i = 1; i <= m; i++)
    pos.push_back((l[1][i] = rd())), pos.push_back((r[1][i] = rd() + 1));
  sort(pos.begin(), pos.end());
  pos.erase(unique(pos.begin(), pos.end()), pos.end());
  memset(p, -1, sizeof(p));
  for (int i = 1; i <= n; i++) {
    int tl = lower_bound(pos.begin(), pos.end(), l[0][i]) - pos.begin();
    int tr = lower_bound(pos.begin(), pos.end(), r[0][i]) - pos.begin();
    p[0][tr] = max(p[0][tr], tl);
  }
  for (int i = 1; i <= m; i++) {
    int tl = lower_bound(pos.begin(), pos.end(), l[1][i]) - pos.begin();
    int tr = lower_bound(pos.begin(), pos.end(), r[1][i]) - pos.begin();
    p[1][tr] = max(p[1][tr], tl);
  }
  int ans = 1;
  for (int i = 0; i < pos.size() - 1; ++i) {
    int t1 = dec(power(2, (pos[i + 1] - pos[i])), 2);
    int t2 = add(ans, add(st[0].tr[1].sum, st[1].tr[1].sum));
    int s0 = st[0].tr[1].sum, s1 = st[1].tr[1].sum;
    st[0].cov(1, 0, pos.size(), i + 1, i + 1, add(ans, s1));
    st[1].cov(1, 0, pos.size(), i + 1, i + 1, add(ans, s0));
    ans = mul(t1, t2);
    st[0].cov(1, 0, pos.size(), 0, p[1][i + 1] + 1, 0);
    st[1].cov(1, 0, pos.size(), 0, p[0][i + 1] + 1, 0);
  }
  cout << add(ans, add(st[0].tr[1].sum, st[1].tr[1].sum)) << '\n';
}
