There are $n$ robbers at coordinates $(a_1, b_1)$, $(a_2, b_2)$, ..., $(a_n, b_n)$ and $m$ searchlight at coordinates $(c_1, d_1)$, $(c_2, d_2)$, ..., $(c_m, d_m)$. 

In one move you can move each robber to the right (increase $a_i$ of each robber by one) or move each robber up (increase $b_i$ of each robber by one). Note that you should either increase all $a_i$ or all $b_i$, you can't increase $a_i$ for some points and $b_i$ for some other points.

Searchlight $j$ can see a robber $i$ if $a_i \leq c_j$ and $b_i \leq d_j$. 

A configuration of robbers is safe if no searchlight can see a robber (i.e. if there is no pair $i,j$ such that searchlight $j$ can see a robber $i$).

What is the minimum number of moves you need to perform to reach a safe configuration?


-----Input-----

The first line of input contains two integers $n$ and $m$ ($1 \leq n, m \leq 2000$): the number of robbers and the number of searchlight.

Each of the next $n$ lines contains two integers $a_i$, $b_i$ ($0 \leq a_i, b_i \leq 10^6$), coordinates of robbers.

Each of the next $m$ lines contains two integers $c_i$, $d_i$ ($0 \leq c_i, d_i \leq 10^6$), coordinates of searchlights.


-----Output-----

Print one integer: the minimum number of moves you need to perform to reach a safe configuration.


-----Examples-----
Input
1 1
0 0
2 3

Output
3

Input
2 3
1 6
6 1
10 1
1 10
7 7

Output
4

Input
1 2
0 0
0 0
0 0

Output
1

Input
7 3
0 8
3 8
2 7
0 10
5 5
7 0
3 5
6 6
3 11
11 5

Output
6



-----Note-----

In the first test, you can move each robber to the right three times. After that there will be one robber in the coordinates $(3, 0)$.

The configuration of the robbers is safe, because the only searchlight can't see the robber, because it is in the coordinates $(2, 3)$ and $3 > 2$.

In the second test, you can move each robber to the right two times and two times up. After that robbers will be in the coordinates $(3, 8)$, $(8, 3)$.

It's easy the see that the configuration of the robbers is safe.

It can be proved that you can't reach a safe configuration using no more than $3$ moves.

Difficulty: MEDIUM

Starter code:

Solutions:
import sys
input = lambda : sys.stdin.readline().rstrip()
(N, M) = map(int, input().split())
X = []
for _ in range(N):
	(a, b) = map(int, input().split())
	X.append((a, b))
Y = []
for _ in range(M):
	(c, d) = map(int, input().split())
	(c, d) = (c, d + 1)
	Y.append((c, d))
Y.sort(key=lambda x: -x[0])
Z = [0] * 1001001
for (a, b) in X:
	for (c, d) in Y:
		if c >= a:
			Z[c - a] = max(Z[c - a], d - b)
ans = 1 << 30
ma = 0
for i in range(1001000)[::-1]:
	ma = max(ma, Z[i])
	ans = min(ans, ma + i)
print(ans)


from sys import stdin
tt = 1
for loop in range(tt):
	(n, m) = map(int, stdin.readline().split())
	ab = []
	cd = []
	tcd = []
	for i in range(n):
		(A, B) = map(int, stdin.readline().split())
		ab.append((A, B))
	for i in range(m):
		(C, D) = map(int, stdin.readline().split())
		tcd.append((C, D))
	tcd.sort()
	cd = []
	cd.append(tcd[0])
	for i in range(1, m):
		while len(cd) > 0 and tcd[i][1] >= cd[-1][1]:
			del cd[-1]
		cd.append(tcd[i])
	ymax = [0] * (10 ** 6 + 10)
	for (A, B) in ab:
		for j in range(len(cd)):
			(C, D) = cd[j]
			if A <= C and B <= D:
				ymax[C - A] = max(ymax[C - A], D - B + 1)
	ans = float('inf')
	Y = 0
	for i in range(10 ** 6 + 9, -1, -1):
		Y = max(Y, ymax[i])
		ans = min(ans, i + Y)
	print(ans)


import sys
reader = (s.rstrip() for s in sys.stdin)
input = reader.__next__
from collections import defaultdict
(n, m) = list(map(int, input().split()))
robbers = []
searchers = []
for i in range(n):
	cord = list(map(int, input().split()))
	robbers.append(cord)
for i in range(m):
	cord = list(map(int, input().split()))
	searchers.append(cord)
(xMax, yMax) = (0, 0)
tou = defaultdict(lambda : 0)
maxIt = 0
for robber in robbers:
	(rx, ry) = robber
	for searcher in searchers:
		(sx, sy) = searcher
		(dx, dy) = (sx - rx, sy - ry)
		if dx >= 0 and dy >= 0:
			tou[dx + 1] = max(tou[dx + 1], dy + 1)
if len(tou) == 0:
	print(0)
else:
	dingDong = sorted(tou.items())
	dingDongBack = sorted(tou.items(), key=lambda x: x[1])
	m = len(dingDong)
	if m == 1:
		print(min(dingDong[-1][0], dingDong[-1][1]))
	else:
		maxSofarBack = 0
		maxSofarFront = 0
		minAns = min(dingDong[-1][0], dingDongBack[-1][1])
		for i in range(1, m):
			maxSofarBack = max(maxSofarBack, dingDong[m - i][1])
			minAns = min(minAns, maxSofarBack + dingDong[m - 1 - i][0])
			maxSofarFront = max(maxSofarFront, dingDongBack[m - i][0])
			minAns = min(minAns, maxSofarFront + dingDongBack[m - 1 - i][1])
		print(minAns)


(n, m) = map(int, input().split())
AB = []
for i in range(n):
	(a, b) = map(int, input().split())
	AB.append((a, b))
CD = []
for i in range(m):
	(c, d) = map(int, input().split())
	CD.append((c, d))
flag = True
for (a, b) in AB:
	for (c, d) in CD:
		if c < a or d < b:
			continue
		else:
			flag = False
if flag:
	print(0)
	exit()
from itertools import accumulate

def is_ok(x):
	imos = [0] * (x + 2)
	for (a, b) in AB:
		for (c, d) in CD:
			if c < a or d < b:
				continue
			l = x - (d - b)
			r = c - a
			if r < l:
				continue
			else:
				imos[max(0, l)] += 1
				imos[min(x + 1, r + 1)] -= 1
	imos = list(accumulate(imos))
	for i in range(x + 1):
		if imos[i] == 0:
			return True
	else:
		return False
ng = 0
ok = 2 * 10 ** 6 + 1
while ng + 1 < ok:
	c = (ng + ok) // 2
	if is_ok(c):
		ok = c
	else:
		ng = c
print(ok)


import sys, math
from collections import Counter, deque, defaultdict
from bisect import bisect_left, bisect_right
mod = 10 ** 9 + 7
INF = float('inf')

def inp():
	return int(sys.stdin.readline())

def inpl():
	return list(map(int, sys.stdin.readline().split()))
(n, m) = inpl()
ab = [inpl() for _ in range(n)]
cd = [inpl() for _ in range(m)]
up = [0] * 1000010
for (a, b) in ab:
	for (c, d) in cd:
		if a > c:
			continue
		up[c - a] = max(up[c - a], d - b + 1)
mx = 0
res = INF
for right in range(1000010)[::-1]:
	mx = max(mx, up[right])
	res = min(res, right + mx)
print(res)


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def RL():
	return map(int, sys.stdin.readline().rstrip().split())

def RLL():
	return list(map(int, sys.stdin.readline().rstrip().split()))

def N():
	return int(input())

def print_list(l):
	print(' '.join(map(str, l)))
from collections import defaultdict as dc
(n, m) = RL()
r = []
s = []
for _ in range(n):
	r.append(tuple(map(int, sys.stdin.readline().rstrip().split())))
for _ in range(m):
	s.append(tuple(map(int, sys.stdin.readline().rstrip().split())))
r.sort()
rr = [r[0]]
for i in range(1, n):
	if r[i][0] > rr[-1][0] and r[i][1] < rr[-1][1]:
		rr.append(r[i])
s.sort()
ss = []
for i in range(m):
	while ss and s[i][1] >= ss[-1][1]:
		ss.pop()
	ss.append(s[i])
line = [-1] * 3000001
ls = len(ss)
last = 0
for now in range(ls):
	for i in range(last, ss[now][0] + 1):
		line[i] = ss[now][1]
	last = ss[now][0] + 1
lr = len(rr)
dic = dc(int)
last = 0
for i in range(lr):
	(x, y) = (rr[i][0], rr[i][1])
	dic[0] = max(dic[0], line[x] - y + 1)
	for j in range(last, ls):
		if ss[j][0] <= x:
			last += 1
			continue
		if ss[j][1] >= y:
			dic[ss[j][0] - x + 1] = max(dic[ss[j][0] - x + 1], line[ss[j][0] + 1] - y + 1)
			dic[ss[j][0] - x] = max(dic[ss[j][0] - x], line[ss[j][0]] - y + 1)
		else:
			break
res = []
for c in dic:
	res.append((c, dic[c]))
res.sort()
ans = []
for tmp in res:
	while ans and tmp[1] >= ans[-1][1]:
		ans.pop()
	ans.append(tmp)
k = dic[0]
last = 0
for tmp in ans:
	k = min(k, last + 1 + tmp[1])
	last = tmp[0]
print(k)


(n, m) = map(int, input().split())
rob = []
spot = []
for i in range(n):
	rob.append(list(map(int, input().split())))
for i in range(m):
	spot.append(list(map(int, input().split())))
d = {}
for i in range(n):
	for j in range(m):
		(x, y) = (rob[i], spot[j])
		if x[0] <= y[0]:
			if y[0] - x[0] in d:
				d[y[0] - x[0]] = max(d[y[0] - x[0]], y[1] - x[1] + 1)
			else:
				d[y[0] - x[0]] = y[1] - x[1] + 1
x = [0] * (10 ** 6 + 2)
for i in range(len(x) - 2, -1, -1):
	if i in d:
		x[i] = max(x[i + 1], d[i])
	else:
		x[i] = x[i + 1]
ans = 10 ** 6 + 1
for i in range(len(x)):
	ans = min(ans, i + x[i])
print(ans)


def main():
	(n, m) = [int(x) for x in input().split()]
	robbers = []
	searchLights = []
	for _ in range(n):
		robbers.append([int(x) for x in input().split()])
	for _ in range(m):
		searchLights.append([int(x) for x in input().split()])
	minY = [0 for _ in range(10 ** 6 + 1)]
	for (a, b) in robbers:
		for (c, d) in searchLights:
			x = c - a
			y = d - b + 1
			if x >= 0:
				minY[x] = max(minY[x], y)
	for i in range(10 ** 6 - 1, -1, -1):
		minY[i] = max(minY[i], minY[i + 1])
	ans = float('inf')
	for (x, y) in enumerate(minY):
		ans = min(ans, x + y)
	print(ans)
	return
import sys
input = sys.stdin.buffer.readline

def oneLineArrayPrint(arr):
	print(' '.join([str(x) for x in arr]))

def multiLineArrayPrint(arr):
	print('\n'.join([str(x) for x in arr]))

def multiLineArrayOfArraysPrint(arr):
	print('\n'.join([' '.join([str(x) for x in y]) for y in arr]))
main()


(N, M) = map(int, input().split())
X = []
for _ in range(N):
	(a, b) = map(int, input().split())
	X.append((a, b))
Y = []
for _ in range(M):
	(a, b) = map(int, input().split())
	Y.append((a, b))
R = [0] * (10 ** 6 + 1)
for i in range(N):
	(a, b) = X[i]
	for j in range(M):
		(x, y) = Y[j]
		if x - a < 0:
			continue
		k = x - a
		R[k] = max(R[k], max(y - b + 1, 0))
r = 10 ** 18
mx = 0
for i in range(10 ** 6, -1, -1):
	mx = max(mx, R[i])
	r = min(r, i + mx)
print(r)


from sys import stdin, stdout
input = stdin.readline
(n, m) = map(int, input().split())
a = []
b = []
for _ in range(n):
	(x, y) = map(int, input().split())
	a.append((x, y))
for _ in range(m):
	(x, y) = map(int, input().split())
	b.append((x, y))
all = []
dict = {}
for j in range(m):
	for i in range(n):
		if b[j][0] - a[i][0] >= 0 and b[j][1] - a[i][1] >= 0:
			if b[j][0] - a[i][0] in dict:
				dict[b[j][0] - a[i][0]] = max(dict[b[j][0] - a[i][0]], b[j][1] - a[i][1])
			else:
				dict[b[j][0] - a[i][0]] = b[j][1] - a[i][1]
ans = float('inf')
all = sorted(dict.keys(), reverse=True)
y_max = -1
for i in all:
	ans = min(ans, i + 1 + y_max + 1)
	y_max = max(y_max, dict[i])
ans = min(ans, y_max + 1)
if ans == float('inf'):
	ans = 0
stdout.write(str(ans) + '\n')


from __future__ import division, print_function
from fractions import Fraction
import sys
import os
from io import BytesIO, IOBase
from heapq import *
from math import gcd, factorial, floor, ceil
from copy import deepcopy
from collections import deque
from bisect import bisect_left as bl
from bisect import bisect_right as br
from bisect import bisect
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
from types import GeneratorType

def iterative(f, stack=[]):

	def wrapped_func(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		to = f(*args, **kwargs)
		while True:
			if type(to) is GeneratorType:
				stack.append(to)
				to = next(to)
				continue
			stack.pop()
			if not stack:
				break
			to = stack[-1].send(to)
		return to
	return wrapped_func
mod = 10 ** 9 + 7

def inp():
	return sys.stdin.readline().rstrip('\r\n')

def out(var):
	sys.stdout.write(str(var))

def lis():
	return list(map(int, inp().split()))

def stringlis():
	return list(map(str, inp().split()))

def sep():
	return map(int, inp().split())

def strsep():
	return map(str, inp().split())

def zerolist(n):
	return [0] * n

def nextline():
	out('\n')

def testcase(t):
	for pp in range(t):
		solve(pp)

def printlist(a):
	for p in range(0, len(a)):
		out(str(a[p]) + ' ')

def google(p):
	print('Case #' + str(p) + ': ', end='')

def lcm(a, b):
	return a * b // gcd(a, b)

def power(x, y, p):
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res

def ncr(n, r):
	return factorial(n) // (factorial(r) * factorial(max(n - r, 1)))

def isPrime(n):
	if n <= 1:
		return False
	if n <= 3:
		return True
	if n % 2 == 0 or n % 3 == 0:
		return False
	i = 5
	while i * i <= n:
		if n % i == 0 or n % (i + 2) == 0:
			return False
		i = i + 6
	return True

def bucketsort(order, seq):
	buckets = [0] * (max(seq) + 1)
	for x in seq:
		buckets[x] += 1
	for i in range(len(buckets) - 1):
		buckets[i + 1] += buckets[i]
	new_order = [-1] * len(seq)
	for i in reversed(order):
		x = seq[i]
		idx = buckets[x] = buckets[x] - 1
		new_order[idx] = i
	return new_order

def ordersort(order, seq, reverse=False):
	bit = max(seq).bit_length() >> 1
	mask = (1 << bit) - 1
	order = bucketsort(order, [x & mask for x in seq])
	order = bucketsort(order, [x >> bit for x in seq])
	if reverse:
		order.reverse()
	return order

def long_ordersort(order, seq):
	order = ordersort(order, [int(i & 2147483647) for i in seq])
	return ordersort(order, [int(i >> 31) for i in seq])

def multikey_ordersort(order, *seqs, sort=ordersort):
	for i in reversed(range(len(seqs))):
		order = sort(order, seqs[i])
	return order

def man(a, b, x, y):
	return abs(a - x) + abs(b - y)

def solve(case):
	(n, m) = sep()
	rob = []
	for i in range(n):
		(a, b) = sep()
		rob.append((a, b))
	coor = []
	for i in range(m):
		(a, b) = sep()
		coor.append((a, b))
	curr = [0] * (10 ** 6 + 1)
	for i in range(len(rob)):
		for j in range(len(coor)):
			if rob[i][0] <= coor[j][0]:
				curr[coor[j][0] - rob[i][0]] = max(curr[coor[j][0] - rob[i][0]], max(0, coor[j][1] - rob[i][1] + 1))
	ans = 10 ** 10
	mx = 0
	for i in range(10 ** 6, -1, -1):
		mx = max(mx, curr[i])
		ans = min(ans, i + mx)
	print(ans)
testcase(1)


(n, m) = map(int, input().split())
g = []
c = []
for i in range(n):
	(x, y) = map(int, input().split())
	g.append((x, y))
for i in range(m):
	(x, y) = map(int, input().split())
	c.append((x, y))
g.sort()
c.sort()
kek = []
mi = 10000000000.0
mx = 0
for i in range(n):
	buf1 = 10000000000.0
	buf2 = 10000000000.0
	for j in range(m):
		if c[j][0] - g[i][0] < 0 or c[j][1] - g[i][1] < 0:
			continue
		mx = max(mx, c[j][1] - g[i][1])
		mi = min(mi, c[j][0] - g[i][0])
		kek.append((c[j][0] - g[i][0], c[j][1] - g[i][1]))
if len(kek) > 0:
	kek.sort()
	res = min(kek[-1][0], mx) + 1
	buf = kek[0][0]
	pref = [0] * (len(kek) + 1)
	for i in range(len(kek) - 1, -1, -1):
		pref[i] = max(pref[i + 1], kek[i][1] + 1)
	for i in range(len(kek)):
		if kek[i][0] == buf:
			continue
		res = min(res, buf + 1 + pref[i])
		buf = kek[i][0]
	print(res)
else:
	print(0)


import sys
import math
input = sys.stdin.readline
(r, s) = list(map(int, input().split()))
robbers = []
ligths = []
for _ in range(r):
	(x, y) = list(map(int, input().split()))
	robbers.append((x, y))
for _ in range(s):
	(x, y) = list(map(int, input().split()))
	ligths.append((x, y))
mm = {}
move = []
for r in robbers:
	for l in ligths:
		a = max(0, l[0] - r[0] + 1)
		b = max(0, l[1] - r[1] + 1)
		if a not in mm:
			mm[a] = b
		else:
			mm[a] = max(mm[a], b)
for j in range(10 ** 6 + 100):
	if j in mm:
		move.append((j, mm[j]))
A = [0] * len(move)
cur = 0
for i in range(len(move) - 1, -1, -1):
	cur = max(cur, move[i][1])
	A[i] = cur
A.append(0)
best = 9999999999999999999
for i in range(len(move)):
	best = min(best, move[i][0] + A[i + 1])
best = min(best, A[0])
print(best)


import sys
sys.setrecursionlimit(10 ** 5)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep='\n')

def II():
	return int(sys.stdin.readline())

def MI():
	return map(int, sys.stdin.readline().split())

def LI():
	return list(map(int, sys.stdin.readline().split()))

def LLI(rows_number):
	return [LI() for _ in range(rows_number)]

def SI():
	return sys.stdin.readline()[:-1]
(n, m) = MI()
ab = LLI(n)
cd = LLI(m)
cd.sort()
ncd = []
for (c, d) in cd:
	while ncd and ncd[-1][1] <= d:
		ncd.pop()
	ncd.append((c, d))
cd = ncd
ab.sort()
nab = []
for (a, b) in ab:
	while nab and nab[-1][1] <= b:
		nab.pop()
	nab.append((a, b))
ab = nab

def chmax(i, val):
	if val > dp[i]:
		dp[i] = val
mx = 10 ** 6 + 5
dp = [0] * mx
for (a, b) in ab:
	for (c, d) in cd:
		if d < b:
			break
		if c < a:
			continue
		chmax(c - a, d - b + 1)
now = 0
ans = 10 ** 9
for i in range(mx - 1, -1, -1):
	if dp[i] > now:
		now = dp[i]
	ans = min(ans, i + now)
print(ans)


import os
import sys
from io import BytesIO, IOBase

def main():
	(n, m) = map(int, input().split())
	robbers = []
	rect = []
	for _ in range(n):
		robbers.append(list(map(int, input().split())))
	for _ in range(m):
		rect.append(list(map(int, input().split())))
	ls = [0] * 1000005
	for (a, b) in robbers:
		for (c, d) in rect:
			if a <= c:
				ls[c - a] = max(ls[c - a], d - b + 1)
	ans = float('inf')
	maxi = 0
	for i in range(1000001, -1, -1):
		maxi = max(maxi, ls[i])
		ans = min(ans, i + maxi)
	print(ans)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


from sys import stdin, stdout

def search_lights(n, m, ab, cd):
	y_a = [0] * (10 ** 6 + 1)
	for i in range(n):
		for j in range(m):
			if ab[i][0] > cd[j][0] or ab[i][1] > cd[j][1]:
				continue
			x = cd[j][0] - ab[i][0]
			y = cd[j][1] - ab[i][1] + 1
			y_a[x] = max(y_a[x], y)
	r = 10 ** 9
	mx = 0
	for i in range(10 ** 6, -1, -1):
		mx = max(mx, y_a[i])
		r = min(r, mx + i)
	return r
(n, m) = map(int, stdin.readline().split())
ab = []
cd = []
for _ in range(n):
	ab.append(list(map(int, stdin.readline().split())))
for _ in range(m):
	cd.append(list(map(int, stdin.readline().split())))
res = search_lights(n, m, ab, cd)
stdout.write(str(res) + '\n')


import sys, io, os
BUFSIZE = 8192

class FastIO(io.IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = io.BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(io.IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from heapq import heapify, heappop, heappush
(N, M) = map(int, input().split())
AB = [list(map(int, input().split())) for _ in range(N)]
CD_ = [list(map(int, input().split())) for _ in range(M)]
L = [0 for _ in range(10 ** 6 + 1)]
maxs = [0] * N
for (i, (a, b)) in enumerate(AB):
	for (c, d) in CD_:
		dx = c - a
		dy = d - b + 1
		if dx < 0 or dy < 0:
			continue
		L[dx] = max(L[dx], dy)
max_dy = 0
ans = 1 << 60
for (dx, dy) in zip(range(10 ** 6, -1, -1), L[::-1]):
	if max_dy < dy:
		max_dy = dy
	if max_dy + dx < ans:
		ans = max_dy + dx
print(ans)
exit()


import os
import sys
from io import BytesIO, IOBase
import threading
from bisect import bisect_right, bisect_left
from math import gcd, log
from collections import defaultdict
from pprint import pprint
from math import ceil

def main():
	(n, m) = map(int, input().split())
	arr = []
	for i in range(n):
		arr.append(tuple(map(int, input().split())))
	brr = []
	for i in range(m):
		brr.append(tuple(map(int, input().split())))
	prev = 0
	brr.sort(key=lambda x: -x[1])
	chx = [0] * (10 ** 6 + 5)
	mx = 0
	dx = []
	for i in range(n):
		for j in range(m):
			if arr[i][0] <= brr[j][0] and arr[i][1] <= brr[j][1]:
				chx[brr[j][0] - arr[i][0] + 1] = max(chx[brr[j][0] - arr[i][0] + 1], brr[j][1] - arr[i][1] + 1)
				mx = max(mx, brr[j][0] - arr[i][0] + 1)
	maxy = 0
	ptr = 0
	ans = float('inf')
	for dx in range(mx + 1, -1, -1):
		ans = min(ans, dx + maxy)
		maxy = max(maxy, chx[dx])
	ans = min(ans, maxy)
	print(ans)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
for _ in range(1):
	main()


import os
from sys import stdin, stdout

class Input:

	def __init__(self):
		self.lines = stdin.readlines()
		self.idx = 0

	def line(self):
		try:
			return self.lines[self.idx].strip()
		finally:
			self.idx += 1

	def array(self, sep=' ', cast=int):
		return list(map(cast, self.line().split(sep=sep)))

	def known_tests(self):
		(num_of_cases,) = self.array()
		for case in range(num_of_cases):
			yield self

	def unknown_tests(self):
		while self.idx < len(self.lines):
			yield self

def problem_solver():

	def solver(inpt):
		(n, m) = inpt.array()
		robs = [inpt.array() for i in range(n)]
		lights = [inpt.array() for i in range(m)]
		N = 1000006
		d = [0 for i in range(N)]
		for r in robs:
			for l in lights:
				if r[0] <= l[0]:
					d[l[0] - r[0]] = max(d[l[0] - r[0]], l[1] - r[1] + 1)
		ans = N << 1
		dmax = 0
		for i in range(N):
			dx = N - 1 - i
			dmax = max(dmax, d[dx])
			ans = min(ans, dx + dmax)
		print(ans)
	return solver
try:
	solver = problem_solver()
	for tc in Input().unknown_tests():
		solver(tc)
except Exception as e:
	import traceback
	traceback.print_exc(file=stdout)


(n, m) = map(int, input().split())
(rob, ser) = ([], [])
maxis = [(0, 0)]
for i in range(n):
	(a, b) = map(int, input().split())
	rob.append((a, b))
for i in range(m):
	(c, d) = map(int, input().split())
	ser.append((c, d))
for i in range(n):
	for j in range(m):
		if rob[i][0] <= ser[j][0] and rob[i][1] <= ser[j][1]:
			(tmx, tmy) = (0, 0)
			tmx = ser[j][0] - rob[i][0] + 1
			tmy = ser[j][1] - rob[i][1] + 1
			maxis.append((tmx, tmy))
maxis.sort()
tot = len(maxis)
pmax = [0] * tot
pmax[-1] = maxis[-1][1]
for i in range(1, tot):
	pmax[tot - i - 1] = max(pmax[tot - i], maxis[tot - i - 1][1])
pmax += [0]
ans = 1000000000000000
for i in range(tot):
	ans = min(ans, pmax[i + 1] + maxis[i][0])
if len(maxis) == 1:
	ans = 0
print(ans)


(n, m) = map(int, input().split())
robbers = []
lights = []
for i in range(n):
	(a, b) = map(int, input().split())
	robbers.append((a, b))
for i in range(m):
	(c, d) = map(int, input().split())
	lights.append((c, d))
C = [0] * 1000002
for (a, b) in robbers:
	for (c, d) in lights:
		if a <= c:
			C[c - a] = max(C[c - a], d - b + 1)
result = 1000001
max_value = 0
for i in range(1000001, -1, -1):
	max_value = max(max_value, C[i])
	result = min(result, i + max_value)
print(result)


(n, m) = map(int, input().split())
rob = [list(map(int, input().split())) for _ in range(n)]
lig = [list(map(int, input().split())) for _ in range(m)]
d = {}
for (x, y) in lig:
	if x not in d:
		d[x] = y
	else:
		d[x] = max(d[x], y)
X = list(d.keys())
Y = list(d.values())
idx = sorted(range(len(X)), key=lambda i: -X[i])
X = [X[i] for i in idx]
Y = [Y[i] for i in idx]
D = [0] * 1000003
for (x, y) in rob:
	for (a, b) in zip(X, Y):
		if x > a:
			break
		D[a - x] = max(D[a - x], b + 1 - y)
num = float('inf')
max_ = 0
for i in range(1000001, -1, -1):
	max_ = max(max_, D[i])
	num = min(num, i + max_)
print(num)


from bisect import *
from collections import *
from math import *
from heapq import *
from typing import List
from itertools import *
from operator import *
from functools import *
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def RL():
	return map(int, sys.stdin.readline().rstrip().split())

def RLL():
	return list(map(int, sys.stdin.readline().rstrip().split()))

def N():
	return int(input())

@lru_cache(None)
def fact(x):
	if x < 2:
		return 1
	return fact(x - 1) * x

@lru_cache(None)
def per(i, j):
	return fact(i) // fact(i - j)

@lru_cache(None)
def com(i, j):
	return per(i, j) // fact(j)

def linc(f, t, l, r):
	while l < r:
		mid = (l + r) // 2
		if t > f(mid):
			l = mid + 1
		else:
			r = mid
	return l

def rinc(f, t, l, r):
	while l < r:
		mid = (l + r + 1) // 2
		if t < f(mid):
			r = mid - 1
		else:
			l = mid
	return l

def ldec(f, t, l, r):
	while l < r:
		mid = (l + r) // 2
		if t < f(mid):
			l = mid + 1
		else:
			r = mid
	return l

def rdec(f, t, l, r):
	while l < r:
		mid = (l + r + 1) // 2
		if t > f(mid):
			r = mid - 1
		else:
			l = mid
	return l

def isprime(n):
	for i in range(2, int(n ** 0.5) + 1):
		if n % i == 0:
			return False
	return True

def binfun(x):
	c = 1
	res = 0
	for w in arr:
		res += w
		if res > x:
			res = w
		c += 1
	return c

def lowbit(n):
	return n & -n

class BIT:

	def __init__(self, arr):
		self.arr = arr
		self.n = len(arr) - 1

	def update(self, x, v):
		while x <= self.n:
			self.arr[x] += v
			x += x & -x

	def query(self, x):
		ans = 0
		while x:
			ans += self.arr[x]
			x &= x - 1
		return ans

class smt:

	def __init__(self, l, r, arr):
		self.l = l
		self.r = r
		self.value = (1 << 31) - 1 if l < r else arr[l]
		mid = (l + r) // 2
		if l < r:
			self.left = smt(l, mid, arr)
			self.right = smt(mid + 1, r, arr)
			self.value &= self.left.value & self.right.value

	def setvalue(self, x, val):
		if self.l == self.r:
			self.value = val
			return
		mid = (self.l + self.r) // 2
		if x <= mid:
			self.left.setvalue(x, val)
		else:
			self.right.setvalue(x, val)
		self.value = self.left.value & self.right.value

	def ask(self, l, r):
		if l <= self.l and r >= self.r:
			return self.value
		val = (1 << 31) - 1
		mid = (self.l + self.r) // 2
		if l <= mid:
			val &= self.left.ask(l, r)
		if r > mid:
			val &= self.right.ask(l, r)
		return val

class UFS:

	def __init__(self, n):
		self.parent = [i for i in range(n)]
		self.ranks = [0] * n

	def find(self, x):
		if x != self.parent[x]:
			self.parent[x] = self.find(self.parent[x])
		return self.parent[x]

	def union(self, u, v):
		(pu, pv) = (self.find(u), self.find(v))
		if pu == pv:
			return False
		if self.ranks[pu] >= self.ranks[pv]:
			self.parent[pv] = pu
			if self.ranks[pv] == self.ranks[pu]:
				self.ranks[pu] += 1
		else:
			self.parent[pu] = pv

def Prime(n):
	c = 0
	prime = []
	flag = [0] * (n + 1)
	for i in range(2, n + 1):
		if not flag[i]:
			prime.append(i)
			c += 1
		for j in range(c):
			if i * prime[j] > n:
				break
			flag[i * prime[j]] = prime[j]
			if i % prime[j] == 0:
				break
	return prime

def dij(s, graph):
	d = {}
	d[s] = 0
	heap = [(0, s)]
	seen = set()
	while heap:
		(dis, u) = heappop(heap)
		if u in seen:
			continue
		for v in graph[u]:
			if v not in d or d[v] > d[u] + graph[u][v]:
				d[v] = d[u] + graph[u][v]
				heappush(heap, (d[v], v))
	return d
(n, m) = RL()
arr1 = []
arr2 = []
for i in range(n):
	arr1.append(RLL())
for i in range(m):
	arr2.append(RLL())
x = [0] * (10 ** 6 + 2)
for i in range(n):
	for j in range(m):
		(a, b) = arr1[i]
		(c, d) = arr2[j]
		if a > c or b > d:
			continue
		x[c - a + 1] = max(x[c - a + 1], d - b + 1)
y = 0
ans = inf
for i in range(10 ** 6 + 1, -1, -1):
	ans = min(ans, i + y)
	y = max(y, x[i])
print(ans)


import io
import os

def solve(N, M, R, S):
	yNeeded = [0 for x in range(10 ** 6 + 1)]
	for r in R:
		for s in S:
			if r[0] <= s[0]:
				x = max(s[0] - r[0] + 1, 0)
				y = max(s[1] - r[1] + 1, 0)
				yNeeded[x - 1] = max(yNeeded[x - 1], y)
	for i in reversed(range(1, len(yNeeded))):
		yNeeded[i - 1] = max(yNeeded[i - 1], yNeeded[i])
	best = 2 * 10 ** 9
	for (x, y) in enumerate(yNeeded):
		best = min(best, x + y)
	return best
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
(N, M) = [int(x) for x in input().split()]
R = [[int(x) for x in input().split()] for i in range(N)]
S = [[int(x) for x in input().split()] for i in range(M)]
ans = solve(N, M, R, S)
print(ans)


import sys
from itertools import accumulate

def input():
	return sys.stdin.readline().strip()

def list2d(a, b, c):
	return [[c for j in range(b)] for i in range(a)]

def list3d(a, b, c, d):
	return [[[d for k in range(c)] for j in range(b)] for i in range(a)]

def list4d(a, b, c, d, e):
	return [[[[e for l in range(d)] for k in range(c)] for j in range(b)] for i in range(a)]

def ceil(x, y=1):
	return int(-(-x // y))

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST(N=None):
	return list(MAP()) if N is None else [INT() for i in range(N)]

def Yes():
	print('Yes')

def No():
	print('No')

def YES():
	print('YES')

def NO():
	print('NO')
INF = 10 ** 18
MOD = 10 ** 9 + 7
EPS = 10 ** (-10)
(N, M) = MAP()
AB = []
for i in range(N):
	(a, b) = MAP()
	AB.append((a, b))
CD = []
for i in range(M):
	(c, d) = MAP()
	CD.append((c, d))
(C, D) = zip(*CD)
L = max(C)
acc = [0] * (L + 2)
for (a, b) in AB:
	for (c, d) in CD:
		if c - a >= 0:
			acc[c - a] = max(acc[c - a], d - b + 1)
acc = list(accumulate(acc[::-1], max))[::-1]
ans = INF
for x in range(L + 2):
	y = acc[x]
	ans = min(ans, x + y)
print(ans)


(n, m) = map(int, input().split())
robs = [tuple(map(int, input().split())) for i in range(n)]
light = [tuple(map(int, input().split())) for i in range(m)]
limitation = [0] * (10 ** 6 + 10)
for i in range(n):
	for j in range(m):
		(a, b) = robs[i]
		(c, d) = light[j]
		(x, y) = (c - a, d - b)
		if x >= 0:
			limitation[x] = max(limitation[x], y + 1)
for i in range(10 ** 6, -1, -1):
	limitation[i] = max(limitation[i + 1], limitation[i])
ans = min((i + limitation[i] for i in range(10 ** 6 + 1)))
print(ans)


import sys
import heapq, functools, collections
import math, random
from collections import Counter, defaultdict

def solve(arr, brr):
	console('----- solving ------')
	arr = sorted(arr, key=lambda x: x[1])
	arr = sorted(arr, key=lambda x: x[0])
	brr = sorted(brr, key=lambda x: x[1])[::-1]
	brr = sorted(brr, key=lambda x: x[0])
	console(arr)
	console(brr)
	arr2 = [arr[0]]
	miny = arr[0][1]
	for (x, y) in arr[1:]:
		if y >= miny:
			continue
		arr2.append([x, y])
		miny = min(miny, y)
	brr2 = [brr[-1]]
	maxy = brr[-1][1]
	for (x, y) in brr[::-1][1:]:
		if y <= maxy:
			continue
		brr2.append([x, y])
		maxy = max(maxy, y)
	brr2 = brr2[::-1]
	brr2 = [[-1, brr2[0][1] + 1]] + brr2 + [[brr2[-1][0] + 1, -1]]
	del arr, brr
	limits = {}
	for (robx, roby) in arr2:
		cur = []
		for ((x1, y1), (x2, y2)) in zip(brr2, brr2[1:]):
			if x2 < robx:
				continue
			if y1 < roby:
				continue
			dx = max(0, x1 + 1 - robx)
			dy = max(0, y2 + 1 - roby)
			cur.append([dx, dy])
		console('cur', cur)
		for ((dx1, dy1), (dx2, dy2)) in zip(cur, cur[1:]):
			console(dx2, dy1)
			if dx2 in limits:
				limits[dx2] = max(limits[dx2], dy1)
			else:
				limits[dx2] = dy1
		if cur:
			(dx2, dy1) = cur[0]
			if dx2 in limits:
				limits[dx2] = max(limits[dx2], dy1)
			else:
				limits[dx2] = dy1
			(dx2, dy1) = cur[-1]
			if dx2 in limits:
				limits[dx2] = max(limits[dx2], dy1)
			else:
				limits[dx2] = dy1
	if not limits:
		return 0
	del arr2, brr2
	limits = sorted(limits.items())
	console('limits', limits)
	limits = sorted(limits, key=lambda x: x[1])[::-1]
	limits = sorted(limits, key=lambda x: x[0])
	brr = limits
	brr2 = [limits[-1]]
	maxy = brr[-1][1]
	for (x, y) in brr[::-1][1:]:
		if y <= maxy:
			continue
		brr2.append((x, y))
		maxy = max(maxy, y)
	brr2 = brr2[::-1]
	console('limits', brr2)
	console('result', brr2)
	limits = brr2
	minres = min(limits[0][1], limits[-1][0])
	for ((k1, v1), (k2, v2)) in zip(limits, limits[1:]):
		minres = min(minres, k1 + v2)
	return minres

def console(*args):
	return
for case_num in [1]:
	(a, b) = list(map(int, input().split()))
	arr = []
	for _ in range(a):
		arr.append(list(map(int, input().split())))
	brr = []
	for _ in range(b):
		brr.append(list(map(int, input().split())))
	res = solve(arr, brr)
	print(res)


(N, M) = map(int, input().split())
R = []
for _ in range(N):
	R.append(tuple(map(int, input().split())))
P = []
for _ in range(M):
	P.append(tuple(map(int, input().split())))
D = [0] * (10 ** 6 + 1)
for (rx, ry) in R:
	for (px, py) in P:
		if px >= rx and py >= ry:
			D[px - rx] = max(D[px - rx], py - ry + 1)
result = 10 ** 7
my = 0
for x in range(len(D) - 1, -1, -1):
	my = max(my, D[x])
	result = min(result, my + x)
print(result)


import os
from sys import stdin, stdout

class Input:

	def __init__(self):
		self.lines = stdin.readlines()
		self.idx = 0

	def line(self):
		try:
			return self.lines[self.idx].strip()
		finally:
			self.idx += 1

	def array(self, sep=' ', cast=int):
		return list(map(cast, self.line().split(sep=sep)))

	def is_next(self):
		return self.idx < len(self.lines)

def known_cases(func):
	inpt = Input()
	(num_of_cases,) = inpt.array()
	for case in range(num_of_cases):
		func(inpt)

def unknown_cases(func):
	inpt = Input()
	while inpt.is_next():
		func(inpt)

@unknown_cases
def solve(inpt):
	(n, m) = inpt.array()
	robs = [inpt.array() for i in range(n)]
	lights = [inpt.array() for i in range(m)]
	N = 1000006
	d = [0 for i in range(N)]
	for r in robs:
		for l in lights:
			if r[0] <= l[0]:
				d[l[0] - r[0]] = max(d[l[0] - r[0]], l[1] - r[1] + 1)
	ans = N << 1
	dmax = 0
	for i in range(N):
		dx = N - 1 - i
		dmax = max(dmax, d[dx])
		ans = min(ans, dx + dmax)
	print(ans)