#include <bits/stdc++.h>
using namespace std;
const int MAXN = 50000 + 10;
struct Event {
  bool operator<(const Event& b) const { return x == b.x ? t < b.t : x < b.x; }
  int t, x, y;
} ev[MAXN * 5];
struct Ver {
  int x, a, b;
} ver[MAXN];
struct Hor {
  int y, a, b;
} hor[MAXN];
int n, m, maxl;
int cnt;
inline bool check(int mid) {
  cnt = 0;
  int i;
  for (i = 1; i <= m; i++) {
    if (hor[i].b - hor[i].a >= 2 * mid) {
      ev[++cnt] = (Event){0, hor[i].a + mid, hor[i].y};
      ev[++cnt] = (Event){2, hor[i].b - mid, hor[i].y};
    }
  }
  for (i = 1; i <= n; i++) {
    ev[++cnt] = (Event){1, ver[i].x, i};
  }
  sort(ev + 1, ev + cnt + 1);
  multiset<int> s;
  for (i = 1; i <= cnt; i++) {
    if (ev[i].t == 0) {
      s.insert(ev[i].y);
    } else if (ev[i].t == 1) {
      if (ver[ev[i].y].b - ver[ev[i].y].a >= mid * 2 &&
          s.lower_bound(ver[ev[i].y].a + mid) !=
              s.upper_bound(ver[ev[i].y].b - mid)) {
        return true;
      }
    } else {
      s.erase(s.find(ev[i].y));
    }
  }
  return false;
}
void solve() {
  int L = 0, R = maxl / 2 + 1, M;
  int ans = 0;
  while (L < R) {
    M = (L + R + 1) >> 1;
    if (check(M)) {
      ans = L = M;
    } else {
      R = M - 1;
    }
  }
  printf("%d\n", ans);
}
void read() {
  scanf("%d%d", &n, &m);
  int i, x, y, l;
  for (i = 1; i <= n; i++) {
    scanf("%d%d%d", &x, &y, &l);
    ver[i] = (Ver){x, y, y + l};
    maxl = max(maxl, l);
  }
  for (i = 1; i <= m; i++) {
    scanf("%d%d%d", &x, &y, &l);
    hor[i] = (Hor){y, x, x + l};
  }
}
int main() {
  read();
  solve();
  return 0;
}
