#include <bits/stdc++.h>
using namespace std;
const long long inf = 4e18;
struct xxx {
  long long x;
  int flag, ip;
  bool operator<(const xxx &temp) const {
    if (x == temp.x) return flag > temp.flag;
    return x < temp.x;
  }
};
xxx x[801000], bs[2][401000];
int cnt, mf[801000], cnt_bs[2];
long long dp[2][801000], c, sum[801000], dc, dx, sum_list[801000], cl[801000],
    vl[801000], pref, ans;
int cnt_sum;
struct segment {
  long long l, r;
};
segment sg[2][201000];
int n[2];
struct segment_tree {
  long long max_vl[4], lazy[2];
};
segment_tree tree[1 << 21];
void build(int left, int right, int id) {
  int l = 2 * id + 1, r = 2 * id + 2, mid = (left + right) >> 1;
  for (int i = 0; i < 4; i++) {
    tree[id].max_vl[i] = -inf;
    if (i < 2) tree[id].lazy[i] = 0;
  }
  if (left == right) return;
  build(left, mid, l);
  build(mid + 1, right, r);
}
void zz(int id, int ll, int rr) {
  int l = 2 * id + 1, r = 2 * id + 2;
  for (int i = 0; i < 2; i++) {
    if (tree[id].lazy[i] != 0 &&
        (tree[id].max_vl[2 * i] > -inf || tree[id].max_vl[2 * i + 1] > -inf)) {
      if (ll != rr) {
        tree[l].lazy[i] += tree[id].lazy[i];
        tree[r].lazy[i] += tree[id].lazy[i];
      }
      if (tree[id].max_vl[2 * i] > -inf)
        tree[id].max_vl[2 * i] += tree[id].lazy[i];
      if (tree[id].max_vl[2 * i + 1] > -inf)
        tree[id].max_vl[2 * i + 1] += tree[id].lazy[i];
    }
    tree[id].lazy[i] = 0;
  }
}
long long query(int ip, long long left, long long right, long long mc, int ll,
                int rr, int id) {
  int l = 2 * id + 1, r = 2 * id + 2, mm = (ll + rr) >> 1;
  if (sum_list[ll] > right || sum_list[rr] < left) return -inf;
  zz(id, ll, rr);
  if (tree[id].max_vl[ip] <= mc) return -inf;
  if (sum_list[ll] >= left && sum_list[rr] <= right) return tree[id].max_vl[ip];
  return max(query(ip, left, right, mc, ll, mm, l),
             query(ip, left, right, mc, mm + 1, rr, r));
}
void insert(int ip, long long pos, long long vl, int ll, int rr, int id) {
  int l = 2 * id + 1, r = 2 * id + 2, mm = (ll + rr) >> 1;
  zz(id, ll, rr);
  if (ll == rr) {
    tree[id].max_vl[ip] = max(tree[id].max_vl[ip], vl);
    return;
  }
  if (sum_list[mm] < pos) {
    insert(ip, pos, vl, mm + 1, rr, r);
    zz(l, ll, mm);
  } else {
    insert(ip, pos, vl, ll, mm, l);
    zz(r, mm + 1, rr);
  }
  tree[id].max_vl[ip] = max(tree[l].max_vl[ip], tree[r].max_vl[ip]);
}
void update(int ip, long long left, long long right, long long vl, int ll,
            int rr, int id) {
  int l = 2 * id + 1, r = 2 * id + 2, mm = (ll + rr) >> 1;
  zz(id, ll, rr);
  if (sum_list[ll] > right || sum_list[rr] < left ||
      tree[id].max_vl[ip] == -inf)
    return;
  if (sum_list[ll] >= left && sum_list[rr] <= right) {
    tree[id].lazy[ip] += vl;
    zz(id, ll, rr);
    return;
  }
  update(ip, left, right, vl, ll, mm, l);
  update(ip, left, right, vl, mm + 1, rr, r);
  tree[id].max_vl[2 * ip] = max(tree[l].max_vl[2 * ip], tree[r].max_vl[2 * ip]);
  tree[id].max_vl[2 * ip + 1] =
      max(tree[l].max_vl[2 * ip + 1], tree[r].max_vl[2 * ip + 1]);
}
int main() {
  scanf("%d%d%lld", &n[0], &n[1], &c);
  int i, j, s, p, q, nc = 0, ch;
  cnt = 0;
  cnt_bs[0] = cnt_bs[1] = 0;
  for (i = 0; i < 2; i++)
    for (j = 0; j < n[i]; j++) {
      scanf("%lld%lld", &sg[i][j].l, &sg[i][j].r);
      bs[i][cnt_bs[i]].x = sg[i][j].l;
      bs[i][cnt_bs[i]].flag = -1;
      bs[i][cnt_bs[i]++].ip = i;
      bs[i][cnt_bs[i]].x = sg[i][j].r;
      bs[i][cnt_bs[i]].flag = 1;
      bs[i][cnt_bs[i]++].ip = i;
    }
  int u = 0, v = 0;
  while (u < cnt_bs[0] && v < cnt_bs[1]) {
    if (bs[0][u] < bs[1][v]) {
      x[cnt++] = bs[0][u];
      u++;
    } else {
      x[cnt++] = bs[1][v];
      v++;
    }
  }
  while (u < cnt_bs[0]) {
    x[cnt++] = bs[0][u];
    u++;
  }
  while (v < cnt_bs[1]) {
    x[cnt++] = bs[1][v];
    v++;
  }
  sum[0] = 0;
  cnt_sum = 0;
  sum_list[0] = 0;
  cl[0] = vl[0] = 0;
  for (i = 0; i < cnt; i++) {
    if (i) {
      cl[i - 1] = vl[i] = x[i].x - x[i - 1].x;
      if (ch == 1 && nc == 1) {
        cl[i - 1] = 0;
        vl[i] *= -1;
      }
      if (nc == 0) cl[i - 1] = vl[i] = 0;
      if (nc == 2) vl[i] = 0;
      sum[i] = sum[i - 1] + vl[i];
    }
    if (x[i].flag < 0) {
      nc++;
      ch = x[i].ip;
    } else
      nc--;
    if (nc == 1 && x[i].flag > 0) ch = 1 - x[i].ip;
    mf[i] = nc;
    sum_list[i] = sum[i];
  }
  cl[cnt - 1] = 0;
  mf[cnt] = vl[cnt] = 0;
  sort(sum_list, sum_list + cnt);
  cnt_sum = 0;
  for (i = 0; i < cnt; i++) {
    if (cnt_sum == 0 || sum_list[cnt_sum - 1] < sum_list[i])
      sum_list[cnt_sum++] = sum_list[i];
  }
  build(0, cnt_sum - 1, 0);
  for (i = 0; i < cnt; i++)
    for (j = 0; j < 2; j++) dp[j][i + 1] = -inf;
  long long dx = 0, cm = 0, npref, tl = 0, tot = 0;
  ans = 0;
  for (i = 0; i + 1 < cnt; i++) {
    dx += vl[i];
    if (abs(dx) <= c && mf[i] == 2)
      cm = 2 * cl[i];
    else
      cm = cl[i];
    ans = ans + cm;
    tot += cl[i];
  }
  pref = 0;
  dx = 0;
  cm = 0;
  for (i = 0; i + 1 < cnt; i++) {
    long long mv;
    if (mf[i] == 2)
      mv = cl[i];
    else
      mv = 0;
    dx += vl[i];
    if (abs(dx) <= c && mf[i] == 2)
      cm = 2 * cl[i];
    else
      cm = cl[i];
    npref = pref + cm;
    tl += cl[i];
    if (mf[i] != 2) {
      pref = npref;
      continue;
    }
    if (sum[i] >= c)
      dp[0][i + 1] = max(dp[0][i + 1], pref - sum[i] + c + mv + cl[i]);
    if (sum[i] <= -c) dp[1][i + 1] = max(dp[1][i + 1], pref + mv + cl[i]);
    dp[0][i + 1] = max(
        dp[0][i + 1], query(0, -inf, sum[i], dp[0][i + 1] - mv + sum[i] - tl, 0,
                            cnt_sum - 1, 0) -
                          sum[i] + mv + tl);
    dp[0][i + 1] =
        max(dp[0][i + 1],
            query(2, -inf, sum[i] - 2 * c,
                  dp[0][i + 1] - mv - 2 * c + sum[i] - tl, 0, cnt_sum - 1, 0) -
                sum[i] + 2 * c + mv + tl);
    dp[1][i + 1] =
        max(dp[1][i + 1], query(1, sum[i] + 2 * c, inf, dp[1][i + 1] - mv - tl,
                                0, cnt_sum - 1, 0) +
                              mv + tl);
    dp[1][i + 1] =
        max(dp[1][i + 1],
            query(3, sum[i], inf, dp[1][i + 1] - mv - tl, 0, cnt_sum - 1, 0) +
                mv + tl);
    pref = npref;
    if (cl[i] != 0) {
      update(0, sum[i], sum[i] + 2 * c, cl[i], 0, cnt_sum - 1, 0);
      update(1, sum[i] - 2 * c, sum[i], cl[i], 0, cnt_sum - 1, 0);
    }
    insert(0, sum[i], dp[0][i + 1] + sum[i] - tl, 0, cnt_sum - 1, 0);
    insert(1, sum[i], dp[0][i + 1] - tl, 0, cnt_sum - 1, 0);
    insert(2, sum[i], dp[1][i + 1] + sum[i] - tl, 0, cnt_sum - 1, 0);
    insert(3, sum[i], dp[1][i + 1] - tl, 0, cnt_sum - 1, 0);
    zz(0, 0, cnt_sum - 1);
    ans = max(ans, tot + max(tree[0].max_vl[1], tree[0].max_vl[3]));
  }
  printf("%lld\n", ans);
  return 0;
}
