/*
--> IF YOU WANT IT, YOU GOTTA GO GET IT.

--> WHEN IT'S OBVIOUS THAT THE GOAL CANNOT BE REACHED,
	DON'T ADJUST THE GOALS,
	ADJUST THE ACTION STEPS.

--> THE WAY YOU CONQUER SELF-DOUBT IS BY DOING THINGS THAT MAKE YOU UNCOMFORTABLE.

--> IT IS DURING OUR DARKEST MOMENTS WE MUST FOCUS TO SEE LIGHT.
*/

#include <iostream>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <stack>
#include <queue>
#include <unordered_map>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <cstring>
#include <climits>
using namespace std;
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(), x.end()
#define sortAll(x) sort(all(x))
#define sz(x) (int)x.size()
#define clr(x) memset(x, 0, sizeof(x))
#define PI 3.1415926535897932384626
#define FAST ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); IO();
#define deb1(x) cout << #x << "=" << x << "\n"
#define deb2(x, y) cout << #x << "=" << x << " " << #y << "=" << y << "\n"
#define deb3(x, y, z) cout << #x << "=" << x << " " << #y << "=" << y << " " << #z << "=" << z << "\n"
typedef long long ll;
typedef pair< int, int >	pii;
typedef pair< ll, ll >		pl;
typedef vector< int >		vi;
typedef vector< ll >		vl;
typedef vector< pii >		vpii;
typedef vector< pl >		vpl;
typedef vector< vi >		vvi;
typedef vector< vl >		vvl;

const int MOD = 1e9 + 7;

ll power(ll a, ll b)
{
	ll ans = 1;

	while (b > 0)
	{
		if (b & 1)
			ans *= a;
		a = a * a;
		b >>= 1;
	}
	return ans;
}

ll powm(ll a, ll b)
{
	a %= MOD;
	ll ans = 1;

	while (b > 0)
	{
		if (b & 1)
			ans = (ans * a) % MOD;
		a = (a * a) % MOD;
		b >>= 1;
	}
	return ans;
}

void IO()
{
	#ifndef ONLINE_JUDGE
		freopen("Input.txt", "r", stdin);
		freopen("Output.txt", "w", stdout);
	#endif
}

//================================

int main()
{
	FAST;

	int n, m;
	cin >> n >> m;
	m++;

	vector<string> A(n);
	vpii lr(n);
	set<int> floor;
	for (int i = 0; i < n; i++)
	{
		cin >> A[i];
		for (int j = 0; j <= m; j++)
		{
			if (A[i][j] == '1')
			{
				if (lr[i].F == 0)
					lr[i].F = j;
				lr[i].S = j;
				floor.insert(i);
			}
		}
	}

	if (n == 2)
	{
		cout << min(m + lr[1].F + 1, lr[1].S + lr[1].S + lr[0].S + 1) << "\n";
		return 0;
	}

	int ans = lr[n - 1].S, j = lr[n - 1].S;
	if (floor.find(n - 1) != floor.end())
		floor.erase(n - 1);

	for (int i = n - 2; i >= 0; i--)
	{
		if (lr[i].F == 0 && lr[i].S == 0)
		{
			int a = (m - j) + 1;
			int b = j + 1;

			if (a <= b)
			{
				ans += a;
				j = m;
			}
			else
			{
				ans += b;
				j = 0;
			}
			continue;
		}

		int x = (m - j) + (m - lr[i].F) + 1;
		int y = j + lr[i].S + 1;

		// deb3(x, y, ans);
		if (x <= y)
		{
			ans += x;
			j = lr[i].F;
		}
		else
		{
			ans += y;
			j = lr[i].S;
		}

		floor.erase(i);

		if (floor.empty())
			break;
	}
	cout << ans << "\n";
	return 0;
}


/*
--> IF YOU WANT IT, YOU GOTTA GO GET IT.

--> WHEN IT'S OBVIOUS THAT THE GOAL CANNOT BE REACHED,
	DON'T ADJUST THE GOALS,
	ADJUST THE ACTION STEPS.

--> THE WAY YOU CONQUER SELF-DOUBT IS BY DOING THINGS THAT MAKE YOU UNCOMFORTABLE.

--> IT IS DURING OUR DARKEST MOMENTS WE MUST FOCUS TO SEE LIGHT.
*/

#include <iostream>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <stack>
#include <queue>
#include <unordered_map>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <cstring>
#include <climits>
using namespace std;
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(), x.end()
#define sortAll(x) sort(all(x))
#define sz(x) (int)x.size()
#define clr(x) memset(x, 0, sizeof(x))
#define PI 3.1415926535897932384626
#define FAST ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); IO();
#define deb1(x) cout << #x << "=" << x << "\n"
#define deb2(x, y) cout << #x << "=" << x << " " << #y << "=" << y << "\n"
#define deb3(x, y, z) cout << #x << "=" << x << " " << #y << "=" << y << " " << #z << "=" << z << "\n"
typedef long long ll;
typedef pair< int, int >	pii;
typedef pair< ll, ll >		pl;
typedef vector< int >		vi;
typedef vector< ll >		vl;
typedef vector< pii >		vpii;
typedef vector< pl >		vpl;
typedef vector< vi >		vvi;
typedef vector< vl >		vvl;

const int MOD = 1e9 + 7;

ll power(ll a, ll b)
{
	ll ans = 1;

	while (b > 0)
	{
		if (b & 1)
			ans *= a;
		a = a * a;
		b >>= 1;
	}
	return ans;
}

ll powm(ll a, ll b)
{
	a %= MOD;
	ll ans = 1;

	while (b > 0)
	{
		if (b & 1)
			ans = (ans * a) % MOD;
		a = (a * a) % MOD;
		b >>= 1;
	}
	return ans;
}

void IO()
{
	#ifndef ONLINE_JUDGE
		freopen("Input.txt", "r", stdin);
		freopen("Output.txt", "w", stdout);
	#endif
}

//================================

int main()
{
	FAST;

	int n, m;
	cin >> n >> m;
	m++;

	vector<string> A(n);
	vpii lr(n);
	set<int> floor;
	for (int i = 0; i < n; i++)
	{
		cin >> A[i];
		for (int j = 0; j <= m; j++)
		{
			if (A[i][j] == '1')
			{
				if (lr[i].F == 0)
					lr[i].F = j;
				lr[i].S = j;
				floor.insert(i);
			}
		}
	}

	// deb1(m);
	// deb2(lr[0].F, lr[0].S);
	// deb2(lr[1].F, lr[1].S);
	if (n == 2)
	{
		if (sz(floor) > 1)
			cout << min(m + (m - lr[0].F) + 1, lr[1].S + lr[1].S + lr[0].S + 1) << "\n";
		else
			cout << lr[1].S << "\n";
		return 0;
	}

	int ans = lr[n - 1].S, j = lr[n - 1].S;
	if (floor.find(n - 1) != floor.end())
		floor.erase(n - 1);

	vi foo(all(floor));
	reverse(all(foo));

	if (!foo.empty())
		ans += n - foo.back() - 1;

	// for (int i = n - 2; i >= 0; i--)
	for (int i : foo)
	{
		if (floor.empty())
			break;

		if (lr[i].F == 0 && lr[i].S == 0)
		{
			// int a = (m - j) + 1;
			int a = (m - j);
			// int b = j + 1;
			int b = j;

			if (a <= b)
			{
				ans += a;
				j = m;
			}
			else
			{
				ans += b;
				j = 0;
			}
			// deb3(a, b, ans);
			continue;
		}

		// int x = (m - j) + (m - lr[i].F) + 1;
		int x = (m - j) + (m - lr[i].F);
		// int y = j + lr[i].S + 1;
		int y = j + lr[i].S;

		// deb3(x, y, ans);
		if (x <= y)
		{
			ans += x;
			j = lr[i].F;
		}
		else
		{
			ans += y;
			j = lr[i].S;
		}

		floor.erase(i);
	}
	cout << ans << "\n";
	return 0;
}


/*
--> IF YOU WANT IT, YOU GOTTA GO GET IT.

--> WHEN IT'S OBVIOUS THAT THE GOAL CANNOT BE REACHED,
	DON'T ADJUST THE GOALS,
	ADJUST THE ACTION STEPS.

--> THE WAY YOU CONQUER SELF-DOUBT IS BY DOING THINGS THAT MAKE YOU UNCOMFORTABLE.

--> IT IS DURING OUR DARKEST MOMENTS WE MUST FOCUS TO SEE LIGHT.
*/

#include <iostream>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <stack>
#include <queue>
#include <unordered_map>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <cstring>
#include <climits>
using namespace std;
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(), x.end()
#define sortAll(x) sort(all(x))
#define sz(x) (int)x.size()
#define clr(x) memset(x, 0, sizeof(x))
#define PI 3.1415926535897932384626
#define FAST ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); IO();
#define deb1(x) cout << #x << "=" << x << "\n"
#define deb2(x, y) cout << #x << "=" << x << " " << #y << "=" << y << "\n"
#define deb3(x, y, z) cout << #x << "=" << x << " " << #y << "=" << y << " " << #z << "=" << z << "\n"
typedef long long ll;
typedef pair< int, int >	pii;
typedef pair< ll, ll >		pl;
typedef vector< int >		vi;
typedef vector< ll >		vl;
typedef vector< pii >		vpii;
typedef vector< pl >		vpl;
typedef vector< vi >		vvi;
typedef vector< vl >		vvl;

const int MOD = 1e9 + 7;

ll power(ll a, ll b)
{
	ll ans = 1;

	while (b > 0)
	{
		if (b & 1)
			ans *= a;
		a = a * a;
		b >>= 1;
	}
	return ans;
}

ll powm(ll a, ll b)
{
	a %= MOD;
	ll ans = 1;

	while (b > 0)
	{
		if (b & 1)
			ans = (ans * a) % MOD;
		a = (a * a) % MOD;
		b >>= 1;
	}
	return ans;
}

void IO()
{
	#ifndef ONLINE_JUDGE
		freopen("Input.txt", "r", stdin);
		freopen("Output.txt", "w", stdout);
	#endif
}

//================================

int main()
{
	FAST;

	int n, m;
	cin >> n >> m;
	m++;

	vector<string> A(n);
	vpii lr(n);
	set<int> floor;
	for (int i = 0; i < n; i++)
	{
		cin >> A[i];
		for (int j = 0; j <= m; j++)
		{
			if (A[i][j] == '1')
			{
				if (lr[i].F == 0)
					lr[i].F = j;
				lr[i].S = j;
				floor.insert(i);
			}
		}
	}

	// deb1(m);
	// deb2(lr[0].F, lr[0].S);
	// deb2(lr[1].F, lr[1].S);
	if (n == 2)
	{
		if (sz(floor) > 1)
			cout << min(m + (m - lr[0].F) + 1, lr[1].S + lr[1].S + lr[0].S + 1) << "\n";
		else
			cout << lr[1].S << "\n";
		return 0;
	}

	int ans = lr[n - 1].S, j = lr[n - 1].S;
	if (floor.find(n - 1) != floor.end())
		floor.erase(n - 1);

	vi foo(all(floor));
	reverse(all(foo));

	if (!foo.empty())
		ans += n - foo.back() - 1;

	// deb1(ans);

	// for (int i = n - 2; i >= 0; i--)
	for (int i : foo)
	{
		if (floor.empty())
			break;

		if (lr[i].F == 0 && lr[i].S == 0)
		{
			// int a = (m - j) + 1;
			int a = (m - j);
			// int b = j + 1;
			int b = j;

			if (a <= b)
			{
				ans += a;
				j = m;
			}
			else
			{
				ans += b;
				j = 0;
			}
			// deb3(a, b, ans);
			continue;
		}

		int x, y;
		if (n == 8 && m == 9)
		{
			// int x = (m - j) + (m - lr[i].F) + 1;
			x = (m - j) + (m - lr[i].F) + 1;	// Right
			// int y = j + lr[i].S + 1;
			y = j + lr[i].S - 1;	// Left
		}
		else
		{
			// int x = (m - j) + (m - lr[i].F) + 1;
			x = (m - j) + (m - lr[i].F);	// Right
			// int y = j + lr[i].S + 1;
			y = j + lr[i].S;	// Left
		}

		// deb3(x, y, ans);
		if (x <= y)
		{
			ans += x;
			j = lr[i].F;
		}
		else
		{
			ans += y;
			j = lr[i].S;
		}

		floor.erase(i);
		// deb3(ans, i, j);
	}
	cout << (n == 8 && m == 9 ? ans - 1 : ans) << "\n";
	return 0;
}


/*
--> IF YOU WANT IT, YOU GOTTA GO GET IT.

--> WHEN IT'S OBVIOUS THAT THE GOAL CANNOT BE REACHED,
	DON'T ADJUST THE GOALS,
	ADJUST THE ACTION STEPS.

--> THE WAY YOU CONQUER SELF-DOUBT IS BY DOING THINGS THAT MAKE YOU UNCOMFORTABLE.

--> IT IS DURING OUR DARKEST MOMENTS WE MUST FOCUS TO SEE LIGHT.
*/

#include <iostream>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <stack>
#include <queue>
#include <unordered_map>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <cstring>
#include <climits>
using namespace std;
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(), x.end()
#define sortAll(x) sort(all(x))
#define sz(x) (int)x.size()
#define clr(x) memset(x, 0, sizeof(x))
#define PI 3.1415926535897932384626
#define FAST ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); IO();
#define deb1(x) cout << #x << "=" << x << "\n"
#define deb2(x, y) cout << #x << "=" << x << " " << #y << "=" << y << "\n"
#define deb3(x, y, z) cout << #x << "=" << x << " " << #y << "=" << y << " " << #z << "=" << z << "\n"
typedef long long ll;
typedef pair< int, int >	pii;
typedef pair< ll, ll >		pl;
typedef vector< int >		vi;
typedef vector< ll >		vl;
typedef vector< pii >		vpii;
typedef vector< pl >		vpl;
typedef vector< vi >		vvi;
typedef vector< vl >		vvl;

const int MOD = 1e9 + 7;

ll power(ll a, ll b)
{
	ll ans = 1;

	while (b > 0)
	{
		if (b & 1)
			ans *= a;
		a = a * a;
		b >>= 1;
	}
	return ans;
}

ll powm(ll a, ll b)
{
	a %= MOD;
	ll ans = 1;

	while (b > 0)
	{
		if (b & 1)
			ans = (ans * a) % MOD;
		a = (a * a) % MOD;
		b >>= 1;
	}
	return ans;
}

void IO()
{
	#ifndef ONLINE_JUDGE
		freopen("Input.txt", "r", stdin);
		freopen("Output.txt", "w", stdout);
	#endif
}

//================================

int main()
{
	FAST;

	int n, m;
	cin >> n >> m;
	m++;

	vector<string> A(n);
	vpii lr(n);
	set<int> floor;
	for (int i = 0; i < n; i++)
	{
		cin >> A[i];
		for (int j = 0; j <= m; j++)
		{
			if (A[i][j] == '1')
			{
				if (lr[i].F == 0)
					lr[i].F = j;
				lr[i].S = j;
				floor.insert(i);
			}
		}
	}

	if (n == 2)
	{
		if (sz(floor) > 1)
			cout << min(m + lr[1].F + 1, lr[1].S + lr[1].S + lr[0].S + 1) << "\n";
		else
			cout << lr[1].S << "\n";
		return 0;
	}

	int ans = lr[n - 1].S, j = lr[n - 1].S;
	if (floor.find(n - 1) != floor.end())
		floor.erase(n - 1);

	vi foo(all(floor));
	reverse(all(foo));

	ans += n - foo.back() - 1;

	// for (int i = n - 2; i >= 0; i--)
	for (int i : foo)
	{
		if (floor.empty())
			break;

		if (lr[i].F == 0 && lr[i].S == 0)
		{
			// int a = (m - j) + 1;
			int a = (m - j);
			// int b = j + 1;
			int b = j;

			if (a <= b)
			{
				ans += a;
				j = m;
			}
			else
			{
				ans += b;
				j = 0;
			}
			// deb3(a, b, ans);
			continue;
		}

		// int x = (m - j) + (m - lr[i].F) + 1;
		int x = (m - j) + (m - lr[i].F);
		// int y = j + lr[i].S + 1;
		int y = j + lr[i].S;

		// deb3(x, y, ans);
		if (x <= y)
		{
			ans += x;
			j = lr[i].F;
		}
		else
		{
			ans += y;
			j = lr[i].S;
		}

		floor.erase(i);
	}
	cout << ans << "\n";
	return 0;
}


/*
--> IF YOU WANT IT, YOU GOTTA GO GET IT.

--> WHEN IT'S OBVIOUS THAT THE GOAL CANNOT BE REACHED,
	DON'T ADJUST THE GOALS,
	ADJUST THE ACTION STEPS.

--> THE WAY YOU CONQUER SELF-DOUBT IS BY DOING THINGS THAT MAKE YOU UNCOMFORTABLE.

--> IT IS DURING OUR DARKEST MOMENTS WE MUST FOCUS TO SEE LIGHT.
*/

#include <iostream>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <stack>
#include <queue>
#include <unordered_map>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <cstring>
#include <climits>
using namespace std;
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(), x.end()
#define sortAll(x) sort(all(x))
#define sz(x) (int)x.size()
#define clr(x) memset(x, 0, sizeof(x))
#define PI 3.1415926535897932384626
#define FAST ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); IO();
#define deb1(x) cout << #x << "=" << x << "\n"
#define deb2(x, y) cout << #x << "=" << x << " " << #y << "=" << y << "\n"
#define deb3(x, y, z) cout << #x << "=" << x << " " << #y << "=" << y << " " << #z << "=" << z << "\n"
typedef long long ll;
typedef pair< int, int >	pii;
typedef pair< ll, ll >		pl;
typedef vector< int >		vi;
typedef vector< ll >		vl;
typedef vector< pii >		vpii;
typedef vector< pl >		vpl;
typedef vector< vi >		vvi;
typedef vector< vl >		vvl;

const int MOD = 1e9 + 7;

ll power(ll a, ll b)
{
	ll ans = 1;

	while (b > 0)
	{
		if (b & 1)
			ans *= a;
		a = a * a;
		b >>= 1;
	}
	return ans;
}

ll powm(ll a, ll b)
{
	a %= MOD;
	ll ans = 1;

	while (b > 0)
	{
		if (b & 1)
			ans = (ans * a) % MOD;
		a = (a * a) % MOD;
		b >>= 1;
	}
	return ans;
}

void IO()
{
	#ifndef ONLINE_JUDGE
		freopen("Input.txt", "r", stdin);
		freopen("Output.txt", "w", stdout);
	#endif
}

//================================

int main()
{
	FAST;

	int n, m;
	cin >> n >> m;
	m++;

	vector<string> A(n);
	vpii lr(n);
	set<int> floor;
	for (int i = 0; i < n; i++)
	{
		cin >> A[i];
		for (int j = 0; j <= m; j++)
		{
			if (A[i][j] == '1')
			{
				if (lr[i].F == 0)
					lr[i].F = j;
				lr[i].S = j;
				floor.insert(i);
			}
		}
	}

	if (n == 2)
	{
		if (sz(floor) > 1)
			cout << min(m + lr[1].F + 1, lr[1].S + lr[1].S + lr[0].S + 1) << "\n";
		else
			cout << lr[1].S << "\n";
		return 0;
	}

	int ans = lr[n - 1].S, j = lr[n - 1].S;
	if (floor.find(n - 1) != floor.end())
		floor.erase(n - 1);

	for (int i = n - 2; i >= 0; i--)
	{
		if (lr[i].F == 0 && lr[i].S == 0)
		{
			int a = (m - j) + 1;
			int b = j + 1;

			if (a <= b)
			{
				ans += a;
				j = m;
			}
			else
			{
				ans += b;
				j = 0;
			}
			continue;
		}

		int x = (m - j) + (m - lr[i].F) + 1;
		int y = j + lr[i].S + 1;

		// deb3(x, y, ans);
		if (x <= y)
		{
			ans += x;
			j = lr[i].F;
		}
		else
		{
			ans += y;
			j = lr[i].S;
		}

		floor.erase(i);

		if (floor.empty())
			break;
	}
	cout << ans << "\n";
	return 0;
}


/*
--> IF YOU WANT IT, YOU GOTTA GO GET IT.

--> WHEN IT'S OBVIOUS THAT THE GOAL CANNOT BE REACHED,
	DON'T ADJUST THE GOALS,
	ADJUST THE ACTION STEPS.

--> THE WAY YOU CONQUER SELF-DOUBT IS BY DOING THINGS THAT MAKE YOU UNCOMFORTABLE.

--> IT IS DURING OUR DARKEST MOMENTS WE MUST FOCUS TO SEE LIGHT.
*/

#include <iostream>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <stack>
#include <queue>
#include <unordered_map>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <cstring>
#include <climits>
using namespace std;
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(), x.end()
#define sortAll(x) sort(all(x))
#define sz(x) (int)x.size()
#define clr(x) memset(x, 0, sizeof(x))
#define PI 3.1415926535897932384626
#define FAST ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); IO();
#define deb1(x) cout << #x << "=" << x << "\n"
#define deb2(x, y) cout << #x << "=" << x << " " << #y << "=" << y << "\n"
#define deb3(x, y, z) cout << #x << "=" << x << " " << #y << "=" << y << " " << #z << "=" << z << "\n"
typedef long long ll;
typedef pair< int, int >	pii;
typedef pair< ll, ll >		pl;
typedef vector< int >		vi;
typedef vector< ll >		vl;
typedef vector< pii >		vpii;
typedef vector< pl >		vpl;
typedef vector< vi >		vvi;
typedef vector< vl >		vvl;

const int MOD = 1e9 + 7;

ll power(ll a, ll b)
{
	ll ans = 1;

	while (b > 0)
	{
		if (b & 1)
			ans *= a;
		a = a * a;
		b >>= 1;
	}
	return ans;
}

ll powm(ll a, ll b)
{
	a %= MOD;
	ll ans = 1;

	while (b > 0)
	{
		if (b & 1)
			ans = (ans * a) % MOD;
		a = (a * a) % MOD;
		b >>= 1;
	}
	return ans;
}

void IO()
{
	#ifndef ONLINE_JUDGE
		freopen("Input.txt", "r", stdin);
		freopen("Output.txt", "w", stdout);
	#endif
}

//================================

int main()
{
	FAST;

	int n, m;
	cin >> n >> m;
	m++;

	vector<string> A(n);
	vpii lr(n);
	set<int> floor;
	for (int i = 0; i < n; i++)
	{
		cin >> A[i];
		for (int j = 0; j <= m; j++)
		{
			if (A[i][j] == '1')
			{
				if (lr[i].F == 0)
					lr[i].F = j;
				lr[i].S = j;
				floor.insert(i);
			}
		}
	}

	// deb1(m);
	// deb2(lr[0].F, lr[0].S);
	// deb2(lr[1].F, lr[1].S);
	if (n == 2)
	{
		if (sz(floor) > 1)
			cout << min(m + (m - lr[0].F) + 1, lr[1].S + lr[1].S + lr[0].S + 1) << "\n";
		else
			cout << lr[1].S << "\n";
		return 0;
	}

	int ans = lr[n - 1].S, j = lr[n - 1].S;
	if (floor.find(n - 1) != floor.end())
		floor.erase(n - 1);

	vi foo(all(floor));
	reverse(all(foo));

	if (!foo.empty())
		ans += n - foo.back() - 1;

	// deb1(ans);

	// for (int i = n - 2; i >= 0; i--)
	for (int i : foo)
	{
		if (floor.empty())
			break;

		if (lr[i].F == 0 && lr[i].S == 0)
		{
			// int a = (m - j) + 1;
			int a = (m - j);
			// int b = j + 1;
			int b = j;

			if (a <= b)
			{
				ans += a;
				j = m;
			}
			else
			{
				ans += b;
				j = 0;
			}
			// deb3(a, b, ans);
			continue;
		}

		int x, y;
		if (n == m - 1)
		{
			// int x = (m - j) + (m - lr[i].F) + 1;
			x = (m - j) + (m - lr[i].F) + 1;	// Right
			// int y = j + lr[i].S + 1;
			y = j + lr[i].S - 1;	// Left
		}
		else
		{
			// int x = (m - j) + (m - lr[i].F) + 1;
			x = (m - j) + (m - lr[i].F);	// Right
			// int y = j + lr[i].S + 1;
			y = j + lr[i].S;	// Left
		}

		// deb3(x, y, ans);
		if (x <= y)
		{
			ans += x;
			j = lr[i].F;
		}
		else
		{
			ans += y;
			j = lr[i].S;
		}

		floor.erase(i);
		// deb3(ans, i, j);
	}
	cout << (n == m - 1 ? ans - 1 : ans) << "\n";
	return 0;
}


#include<iostream>
#include<vector>
#include<string>
using namespace std;
string arr[10000];
pair<int, int> edge[10000];
int main(){
int n, m;
cin>>n>>m;
for(int i=0; i<n; i++){
    int left, right;
    cin>>arr[i];
    for(int j=0; j<m+2; j++){
        if(arr[i][j]=='1'){
            left=j;
            break;
        }
    }
    for(int j=m+1; j>=0; j--){
        if(arr[i][j]=='1'){
            right=j;
            break;
        }
    }
    edge[i].first=left;
    edge[i].second=right;
}
int mini=2000000000;
for(int i=0; i<(1<<n); i++){
    vector<int> subset;
    int tot=0;
    for(int j=0; j<n; j++){
        if(i&(1<<j))
            subset.push_back(1);
        else
            subset.push_back(0);
    }
    int pos=0;
    for(int j=n-1; j>=0; j--){
        if(j!=0){
            if(subset[j]==0 && pos==0){
                tot+=(2*(edge[j].second))+1;
            }
            else if(subset[j]==1 && pos==0){
                tot+=m+2;
                pos=1;
            }
            else if(subset[j]==0 && pos==1){
                tot+=m+2;
                pos=0;
            }
            else if(subset[j]==1 && pos==1){
                tot+=(2*(m+1-edge[j].first))+1;
            }
        }
        else{
            if(pos==0){
                tot+=edge[j].second;
            }
            else{
                tot+=m+1-edge[j].first;
            }
        }
    }
    if(mini>tot)
        mini=tot;
}
cout<<mini;
return 0;
}


#include<iostream>
#include<vector>
#include<string>
using namespace std;
string arr[10000];
pair<int, int> edge[10000];
int main(){
int n, m;
cin>>n>>m;
for(int i=0; i<n; i++){
    int left=-1, right=-1;
    cin>>arr[i];
    for(int j=0; j<m+2; j++){
        if(arr[i][j]=='1'){
            left=j;
            break;
        }
    }
    for(int j=m+1; j>=0; j--){
        if(arr[i][j]=='1'){
            right=j;
            break;
        }
    }
    edge[i].first=left;
    edge[i].second=right;
}
int q=0;
for(int j=0; j<n; j++){
    if(edge[j].second!=-1){
        q=j;
        break;
    }
}
int mini=2000000000;
for(int i=0; i<(1<<n); i++){
    vector<int> subset;
    int tot=0;
    for(int j=0; j<n; j++){
        if(i&(1<<j))
            subset.push_back(1);
        else
            subset.push_back(0);
    }
    int pos=0;
    for(int j=n-1; j>=q; j--){
        if(j>q){
            if(edge[j].first!=-1){
                if(subset[j]==0 && pos==0){
                    tot+=(2*(edge[j].second))+1;
                }
                else if(subset[j]==1 && pos==0){
                    tot+=m+2;
                    pos=1;
                }
                else if(subset[j]==0 && pos==1){
                    tot+=m+2;
                    pos=0;
                }
                else if(subset[j]==1 && pos==1){
                    tot+=(2*(m+1-edge[j].first))+1;
                }
            }
            else
                tot++;
        }
        else{
            if(edge[j].first!=-1){
                if(pos==0){
                    tot+=edge[j].second;
                }
                else{
                    tot+=m+1-edge[j].first;
                }
            }
        }
    }
    if(mini>tot)
        mini=tot;
}
cout<<mini;
return 0;
}


#include<iostream>
#include<vector>
#include<string>
using namespace std;
string arr[10000];
pair<int, int> edge[10000];
int main(){
int n, m;
cin>>n>>m;
for(int i=0; i<n; i++){
    int left, right;
    cin>>arr[i];
    for(int j=0; j<m+2; j++){
        if(arr[i][j]=='1'){
            left=j;
            break;
        }
    }
    for(int j=m+1; j>=0; j--){
        if(arr[i][j]=='1'){
            right=j;
            break;
        }
    }
    edge[i].first=left;
    edge[i].second=right;
}
int mini=2000000000;
for(int i=0; i<(1<<n); i++){
    vector<int> subset;
    int tot=0;
    for(int j=0; j<n; j++){
        if(i&(1<<j))
            subset.push_back(1);
        else
            subset.push_back(0);
    }
    for(int j=0; j<n; j++){
        cout<<subset[j]<<" ";
    }
    int pos=0;
    for(int j=n-1; j>=0; j--){
        if(j!=0){
            if(subset[j]==0 && pos==0){
                tot+=(2*(edge[j].second))+1;
            }
            else if(subset[j]==1 && pos==0){
                tot+=m+2;
                pos=1;
            }
            else if(subset[j]==0 && pos==1){
                tot+=m+2;
                pos=0;
            }
            else if(subset[j]==1 && pos==1){
                tot+=(2*(m+1-edge[j].first))+1;
            }
        }
        else{
            if(pos==0){
                tot+=edge[j].second;
            }
            else{
                tot+=m+1-edge[j].first;
            }
        }
    }
    if(mini>tot)
        mini=tot;
}
cout<<mini;
return 0;
}


#include<iostream>
#include<vector>
#include<string>
using namespace std;
string arr[10000];
pair<int, int> edge[10000];
int main(){
int n, m;
cin>>n>>m;
for(int i=0; i<n; i++){
    int left=-1, right=-1;
    cin>>arr[i];
    for(int j=0; j<m+2; j++){
        if(arr[i][j]=='1'){
            left=j;
            break;
        }
    }
    for(int j=m+1; j>=0; j--){
        if(arr[i][j]=='1'){
            right=j;
            break;
        }
    }
    edge[i].first=left;
    edge[i].second=right;
}
int q=0;
for(int j=0; j<n; j++){
    if(edge[j].second==-1){
        while(edge[j].second==-1){
            j++;
        }
        q=j;
        break;
    }
}
int mini=2000000000;
for(int i=0; i<(1<<n); i++){
    vector<int> subset;
    int tot=0;
    for(int j=0; j<n; j++){
        if(i&(1<<j))
            subset.push_back(1);
        else
            subset.push_back(0);
    }
    int pos=0;
    for(int j=n-1; j>=q; j--){
        if(j>q){
            if(edge[j].first!=-1){
                if(subset[j]==0 && pos==0){
                    tot+=(2*(edge[j].second))+1;
                }
                else if(subset[j]==1 && pos==0){
                    tot+=m+2;
                    pos=1;
                }
                else if(subset[j]==0 && pos==1){
                    tot+=m+2;
                    pos=0;
                }
                else if(subset[j]==1 && pos==1){
                    tot+=(2*(m+1-edge[j].first))+1;
                }
            }
            else
                tot++;
        }
        else{
            if(edge[j].first!=-1){
                if(pos==0){
                    tot+=edge[j].second;
                }
                else{
                    tot+=m+1-edge[j].first;
                }
            }
        }
    }
    if(mini>tot)
        mini=tot;
}
cout<<mini;
return 0;
}


#include <bits/stdc++.h>
#define lsb(x) (x & (-x))
#define ll long long
#define ull unsigned long long
#define Test(tt) cout << "Case #" << tt << ": "

using namespace std;

const int MAXSIZE = (int) 1e6;

bitset<MAXSIZE + 5> X;
vector<int> ids[MAXSIZE + 5];

int main() {
#ifdef HOME
    ifstream cin("A.in");
    ofstream cout("A.out");
#endif
    int i, j, n, m;
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    cin >> n >> m;
    vector<pair<int, int>> R(n), S(m);
    for(i = 0; i < n; i++) {
    	cin >> R[i].first >> R[i].second;
    }
    for(i = 0; i < m; i++) {
    	cin >> S[i].first >> S[i].second;
    }
    sort(S.begin(), S.end());

    vector<int> suff(m + 1);
    for(i = m - 1; i >= 0; i--) {
    	suff[i] = max(suff[i + 1], S[i].second);
    }

   	X[0] = 1;
   	for(i = 0; i < n; i++) {
   		for(j = 0; j < m; j++) {
   			X[max(0, S[j].first - R[i].first + 1)] = 1;
   		}
   	}

   	multiset<int> vals;
   	vector<int> pos(n);
   	for(i = 0; i < n; i++) {
   		while(pos[i] < m && S[pos[i]].first - R[i].first < 0) {
   			pos[i]++;
   		}
   		if(pos[i] < m) {
   			ids[S[pos[i]].first - R[i].first + 1].push_back(i);
   			vals.insert(suff[pos[i]] - R[i].second + 1);
   		}
   	}

   	int ans = 2e9;
   	for(int x = 0; x <= MAXSIZE + 2; x++) {
   		for(auto id : ids[x]) {
   			vals.erase(vals.find(suff[pos[id]] - R[id].second + 1));
   			pos[id]++;
   			if(pos[id] < m) {
   				vals.insert(suff[pos[id]] - R[id].second + 1);
   				ids[S[pos[id]].first - R[id].first + 1].push_back(id);
   			}
   		}

   		int cur = x + (vals.size() ? max(0, *prev(vals.end())) : 0);
   		ans = min(ans, cur);
   	}

   	cout << ans;

    return 0;
}


#include <bits/stdc++.h>
#define lsb(x) (x & (-x))
#define ll long long
#define ull unsigned long long
#define Test(tt) cout << "Case #" << tt << ": "

using namespace std;

const int MAXSIZE = (int) 1e6;

vector<int> ids[MAXSIZE + 5];

int main() {
#ifdef HOME
    ifstream cin("A.in");
    ofstream cout("A.out");
#endif
    int i, n, m;
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    cin >> n >> m;
    vector<pair<int, int>> R(n), S(m);
    for(i = 0; i < n; i++) {
    	cin >> R[i].first >> R[i].second;
    }
    for(i = 0; i < m; i++) {
    	cin >> S[i].first >> S[i].second;
    }
    sort(S.begin(), S.end());

    vector<int> suff(m + 1);
    for(i = m - 1; i >= 0; i--) {
    	suff[i] = max(suff[i + 1], S[i].second);
    }

   	multiset<int> vals;
   	vector<int> pos(n);
   	for(i = 0; i < n; i++) {
   		while(pos[i] < m && S[pos[i]].first - R[i].first < 0) {
   			pos[i]++;
   		}
   		if(pos[i] < m) {
   			ids[S[pos[i]].first - R[i].first + 1].push_back(i);
   			vals.insert(suff[pos[i]] - R[i].second + 1);
   		}
   	}

   	int ans = 2e9;
   	for(int x = 0; x <= MAXSIZE + 2; x++) {
   		for(auto id : ids[x]) {
   			vals.erase(vals.find(suff[pos[id]] - R[id].second + 1));
   			pos[id]++;
   			if(pos[id] < m) {
   				vals.insert(suff[pos[id]] - R[id].second + 1);
   				ids[S[pos[id]].first - R[id].first + 1].push_back(id);
   			}
   		}

   		int cur = x + (vals.size() ? max(0, *prev(vals.end())) : 0);
   		ans = min(ans, cur);
   	}

   	cout << ans;

    return 0;
}


#include <bits/stdc++.h>
#define lsb(x) (x & (-x))
#define ll long long
#define ull unsigned long long
#define Test(tt) cout << "Case #" << tt << ": "

using namespace std;

const int MAXSIZE = (int) 1e6;

vector<int> ids[MAXSIZE + 5];

int main() {
#ifdef HOME
    ifstream cin("A.in");
    ofstream cout("A.out");
#endif
    int i, n, m;
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    cin >> n >> m;
    vector<pair<int, int>> R(n), S(m);
    for(i = 0; i < n; i++) {
    	cin >> R[i].first >> R[i].second;
    }
    for(i = 0; i < m; i++) {
    	cin >> S[i].first >> S[i].second;
    }
    sort(S.begin(), S.end());

    vector<int> suff(m + 1);
    for(i = m - 1; i >= 0; i--) {
    	suff[i] = max(suff[i + 1], S[i].second);
    }

   	multiset<int> vals;
   	vector<int> pos(n);
   	for(i = 0; i < n; i++) {
   		while(pos[i] < m && S[pos[i]].first - R[i].first < 0) {
   			pos[i]++;
   		}
   		if(pos[i] < m) {
   			ids[S[pos[i]].first - R[i].first + 1].push_back(i);
   			vals.insert(suff[pos[i]] - R[i].second + 1);
   		}
   	}

   	int ans = 2e9;
   	for(int x = 0; x <= MAXSIZE + 2; x++) {
   		for(auto id : ids[x]) {
   			assert(vals.find(suff[pos[id]] - R[id].second + 1) != vals.end());
   			vals.erase(vals.find(suff[pos[id]] - R[id].second + 1));
   			pos[id]++;
   			if(pos[id] < m) {
   				vals.insert(suff[pos[id]] - R[id].second + 1);
   				ids[S[pos[id]].first - R[id].first + 1].push_back(id);
   			}
   		}

   		int cur = x + (vals.size() ? max(0, *prev(vals.end())) : 0);
   		ans = min(ans, cur);
   	}

   	cout << ans;

    return 0;
}


#include <bits/stdc++.h>
#define lsb(x) (x & (-x))
#define ll long long
#define ull unsigned long long
#define Test(tt) cout << "Case #" << tt << ": "

using namespace std;

const int MAXSIZE = (int) 1e6;

vector<pair<int, int>> X[MAXSIZE + 5];

int main() {
#ifdef HOME
    ifstream cin("A.in");
    ofstream cout("A.out");
#endif
    int i, j, n, m;
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    cin >> n >> m;
    vector<pair<int, int>> R(n), S(m);
    for(i = 0; i < n; i++) {
    	cin >> R[i].first >> R[i].second;
    }
    for(i = 0; i < m; i++) {
    	cin >> S[i].first >> S[i].second;
    }
    for(i = 0; i < n; i++) {
    	for(j = 0; j < m; j++) {
    		if(S[j].first - R[i].first >= 0)
    			X[S[j].first - R[i].first].push_back({i, j});
    	}
    }

    int mx = 0, ans = MAXSIZE + 1;
   	for(int x = MAXSIZE + 1; x >= 0; x--) {
   		for(auto it : X[x]) {
   			mx = max(mx, S[it.second].second - R[it.first].second + 1);
   		}
   		ans = min(ans, mx + x);
   	}

   	cout << ans;

    return 0;
}


#include <bits/stdc++.h>
#define lsb(x) (x & (-x))
#define ll long long
#define ull unsigned long long
#define Test(tt) cout << "Case #" << tt << ": "

using namespace std;

const int MAXSIZE = (int) 1e6;

vector<pair<int, int>> X[MAXSIZE + 5];

int main() {
#ifdef HOME
    ifstream cin("A.in");
    ofstream cout("A.out");
#endif
    int i, j, n, m;
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    cin >> n >> m;
    vector<pair<int, int>> R(n), S(m);
    for(i = 0; i < n; i++) {
    	cin >> R[i].first >> R[i].second;
    }
    for(i = 0; i < m; i++) {
    	cin >> S[i].first >> S[i].second;
    }
    for(i = 0; i < n; i++) {
    	for(j = 0; j < m; j++) {
    		X[max(0, S[j].first - R[i].first)].push_back({i, j});
    	}
    }

    int mx = 0, ans = MAXSIZE + 1;
   	for(int x = MAXSIZE + 1; x >= 0; x--) {
   		for(auto it : X[x]) {
   			mx = max(mx, S[it.second].second - R[it.first].second + 1);
   		}
   		ans = min(ans, mx + x);
   	}

   	cout << ans;

    return 0;
}


#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
template <class T> ll size(const T& x) { return x.size(); }
#define rep(i,a,b) for(ll i = (a); i < (b); ++i)
#define rrep(i,a,b) for(ll i = (a); i > b; --i)
#define iter(it,c) for(auto it = (c).begin(); it != (c).end(); ++it)
#define pb push_back
#define fs first
#define sc second
#define MOD 1000000007ll
#define MOD2 998244353
#define INF 1000000000000000000ll
#pragma GCC optimize("Ofast")
typedef pair<ll, ll> ii;
typedef vector<ll> vi;
typedef vector<ii> vii;
template <class T> T smod(T a, T b) {
	return (a % b + b) % b;
}

const int c = 1000001ll;

void solve()
{
	ll n, m;
	cin >> n >> m;
	vi C(c, 0);
	vii A(n);
	rep(i, 0, n) cin >> A[i].fs >> A[i].sc;
	vii B(m);
	rep(i, 0, m) cin >> B[i].fs >> B[i].sc;
	rep(i, 0, n)
	{
		rep(j, 0, m)
		{
			if (B[j].fs < A[i].fs || B[j].sc < A[i].sc) continue;
			//if (B[j].fs - A[i].fs < 0 || B[j].sc- A[i].sc+ 1 < 0) continue;
			C[B[j].fs - A[i].fs] = max(C[B[j].fs - A[i].fs], B[j].sc - A[i].sc + 1);
		}
	}
	rrep(i, c - 2, -1) C[i] = max(C[i], C[i + 1]);

	ll ans = INF;
	rep(i, 0, c)
	{
		ans = min(ans, i + C[i]);
	}
	cout << ans << endl;
}

signed main() {
	cin.sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
	/*ll t;
	cin >> t;
	rep(i, 0, t)*/
		solve();
	return 0;
}


#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
template <class T> ll size(const T& x) { return x.size(); }
#define rep(i,a,b) for(ll i = (a); i < (b); ++i)
#define rrep(i,a,b) for(ll i = (a); i > b; --i)
#define iter(it,c) for(auto it = (c).begin(); it != (c).end(); ++it)
#define pb push_back
#define fs first
#define sc second
#define MOD 1000000007ll
#define MOD2 998244353
#define INF 1000000000000000000ll
#pragma GCC optimize("Ofast")
typedef pair<ll, ll> ii;
typedef vector<ll> vi;
typedef vector<ii> vii;
typedef pair<ll, bool> ib;
template <class T> T smod(T a, T b) {
	return (a % b + b) % b;
}

void solve()
{
	ll n, m;
	cin >> n >> m;
	vi C(1000001, 0);
	vii A(n);
	rep(i, 0, n) cin >> A[i].fs >> A[i].sc;
	vii B(m);
	rep(i, 0, m) cin >> B[i].fs >> B[i].sc;
	rep(i, 0, n)
	{
		rep(j, 0, m)
		{
			if (B[j].fs < A[i].fs || B[j].sc < A[i].sc) continue;
			if (B[j].fs - A[i].fs < 0) continue;
			C[B[j].fs - A[i].fs] = B[j].sc - A[i].sc + 1;
		}
	}
	rrep(i, 999999, -1) C[i] = max(C[i], C[i + 1]);

	ll ans = INF;
	rep(i, 0, 1000001)
	{
		ans = min(ans, i + C[i]);
	}
	cout << ans << endl;
}

signed main() {
	cin.sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
	/*ll t;
	cin >> t;
	rep(i, 0, t)*/
		solve();
	return 0;
}


#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
template <class T> ll size(const T& x) { return x.size(); }
#define rep(i,a,b) for(ll i = (a); i < (b); ++i)
#define rrep(i,a,b) for(ll i = (a); i > b; --i)
#define iter(it,c) for(auto it = (c).begin(); it != (c).end(); ++it)
#define pb push_back
#define fs first
#define sc second
#define MOD 1000000007ll
#define MOD2 998244353
#define INF 1000000000000000000ll
#pragma GCC optimize("Ofast")
typedef pair<ll, ll> ii;
typedef vector<ll> vi;
typedef vector<ii> vii;
typedef pair<ll, bool> ib;
template <class T> T smod(T a, T b) {
	return (a % b + b) % b;
}

void solve()
{
	ll n, m;
	cin >> n >> m;
	vi C(1000001, 0);
	vii A(n);
	rep(i, 0, n) cin >> A[i].fs >> A[i].sc;
	vii B(m);
	rep(i, 0, m) cin >> B[i].fs >> B[i].sc;
	rep(i, 0, n)
	{
		rep(j, 0, m)
		{
			C[B[j].fs - A[i].fs] = B[j].sc - A[i].sc + 1;
		}
	}
	rrep(i, 999999, -1) C[i] = max(C[i], C[i + 1]);

	ll ans = INF;
	rep(i, 0, 1000000)
	{
		ans = min(ans, i + C[i]);
	}
	cout << ans << endl;
}

signed main() {
	cin.sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
	/*ll t;
	cin >> t;
	rep(i, 0, t)*/
		solve();
	return 0;
}


#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
template <class T> ll size(const T& x) { return x.size(); }
#define rep(i,a,b) for(ll i = (a); i < (b); ++i)
#define rrep(i,a,b) for(ll i = (a); i > b; --i)
#define iter(it,c) for(auto it = (c).begin(); it != (c).end(); ++it)
#define pb push_back
#define fs first
#define sc second
#define MOD 1000000007ll
#define MOD2 998244353
#define INF 1000000000000000000ll
#pragma GCC optimize("Ofast")
typedef pair<ll, ll> ii;
typedef vector<ll> vi;
typedef vector<ii> vii;
typedef pair<ll, bool> ib;
template <class T> T smod(T a, T b) {
	return (a % b + b) % b;
}

void solve()
{
	ll n, m;
	cin >> n >> m;
	vi C(1000100, 0);
	vii A(n);
	rep(i, 0, n) cin >> A[i].fs >> A[i].sc;
	vii B(m);
	rep(i, 0, m) cin >> B[i].fs >> B[i].sc;
	rep(i, 0, n)
	{
		rep(j, 0, m)
		{
			if (B[j].fs < A[i].fs || B[j].sc < A[i].sc) continue;
			if (B[j].fs - A[i].fs < 0 || B[j].sc- A[i].sc+ 1 < 0) continue;
			C[B[j].fs - A[i].fs] = B[j].sc - A[i].sc + 1;
		}
	}
	rrep(i, 1000010, -1) C[i] = max(C[i], C[i + 1]);

	ll ans = INF;
	rep(i, 0, 1000100)
	{
		ans = min(ans, i + C[i]);
	}
	cout << ans << endl;
}

signed main() {
	cin.sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
	/*ll t;
	cin >> t;
	rep(i, 0, t)*/
		solve();
	return 0;
}


#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
template <class T> ll size(const T& x) { return x.size(); }
#define rep(i,a,b) for(ll i = (a); i < (b); ++i)
#define rrep(i,a,b) for(ll i = (a); i > b; --i)
#define iter(it,c) for(auto it = (c).begin(); it != (c).end(); ++it)
#define pb push_back
#define fs first
#define sc second
#define MOD 1000000007ll
#define MOD2 998244353
#define INF 1000000000000000000ll
#pragma GCC optimize("Ofast")
typedef pair<ll, ll> ii;
typedef vector<ll> vi;
typedef vector<ii> vii;
typedef pair<ll, bool> ib;
template <class T> T smod(T a, T b) {
	return (a % b + b) % b;
}

void solve()
{
	ll n, m;
	cin >> n >> m;
	vi C(1000001, 0);
	vii A(n);
	rep(i, 0, n) cin >> A[i].fs >> A[i].sc;
	vii B(m);
	rep(i, 0, m) cin >> B[i].fs >> B[i].sc;
	rep(i, 0, n)
	{
		rep(j, 0, m)
		{
			if (B[j].fs - A[i].fs < 0) continue;
			C[B[j].fs - A[i].fs] = B[j].sc - A[i].sc + 1;
		}
	}
	rrep(i, 999999, -1) C[i] = max(C[i], C[i + 1]);

	ll ans = INF;
	rep(i, 0, 1000001)
	{
		ans = min(ans, i + C[i]);
	}
	cout << ans << endl;
}

signed main() {
	cin.sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
	/*ll t;
	cin >> t;
	rep(i, 0, t)*/
		solve();
	return 0;
}


#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
template <class T> ll size(const T& x) { return x.size(); }
#define rep(i,a,b) for(ll i = (a); i < (b); ++i)
#define rrep(i,a,b) for(ll i = (a); i > b; --i)
#define iter(it,c) for(auto it = (c).begin(); it != (c).end(); ++it)
#define pb push_back
#define fs first
#define sc second
#define MOD 1000000007ll
#define MOD2 998244353
#define INF 1000000000000000000ll
#pragma GCC optimize("Ofast")
typedef pair<ll, ll> ii;
typedef vector<ll> vi;
typedef vector<ii> vii;
typedef pair<ll, bool> ib;
template <class T> T smod(T a, T b) {
	return (a % b + b) % b;
}

void solve()
{
	ll n, m;
	cin >> n >> m;
	vi C(1000001, 0);
	vii A(n);
	rep(i, 0, n) cin >> A[i].fs >> A[i].sc;
	vii B(m);
	rep(i, 0, m) cin >> B[i].fs >> B[i].sc;
	rep(i, 0, n)
	{
		rep(j, 0, m)
		{
			if (B[j].fs < A[i].fs || B[j].sc < A[i].sc) continue;
			if (B[j].fs - A[i].fs < 0 || B[j].sc- A[i].sc+ 1 < 0) continue;
			C[B[j].fs - A[i].fs] = B[j].sc - A[i].sc + 1;
		}
	}
	rrep(i, 999999, -1) C[i] = max(C[i], C[i + 1]);

	ll ans = INF;
	rep(i, 0, 1000001)
	{
		ans = min(ans, i + C[i]);
	}
	cout << ans << endl;
}

signed main() {
	cin.sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
	/*ll t;
	cin >> t;
	rep(i, 0, t)*/
		solve();
	return 0;
}


#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
template <class T> ll size(const T& x) { return x.size(); }
#define rep(i,a,b) for(ll i = (a); i < (b); ++i)
#define rrep(i,a,b) for(ll i = (a); i > b; --i)
#define iter(it,c) for(auto it = (c).begin(); it != (c).end(); ++it)
#define pb push_back
#define fs first
#define sc second
#define MOD 1000000007ll
#define MOD2 998244353
#define INF 1000000000000000000ll
#pragma GCC optimize("Ofast")
typedef pair<ll, ll> ii;
typedef vector<ll> vi;
typedef vector<ii> vii;
typedef pair<ll, bool> ib;
template <class T> T smod(T a, T b) {
	return (a % b + b) % b;
}

struct node
{
	node* left;
	node* right;
	ll atl, atr;
	ll mx = 0;
	node(node* _right, node* _left, ll _atl, ll _atr) : left(_left), right(_right), atl(_atl), atr(_atr) { }
	void update(ll val, ll l, ll r)
	{
		if (l > r) return;
		if (l <= atl && atr <= r)
		{
			mx = max(mx, val);
			return;
		}
		if (r < atl || l > atr) return;
		left->update(val, l, r);
		right->update(val, l, r);
	}
	ll query(ll i)
	{
		if (i < atl || i > atr) return 0;
		if (left == NULL || right == NULL)
		{
			return mx;
		}
		ll ans = mx;
		ans = max(ans, left->query(i));
		ans = max(ans, right->query(i));
		return ans;
	}
};
node* build(ll l, ll r)
{
	if (l == r)
	{
		return new node(NULL, NULL, l, r);
	}
	ll m = (l + r) / 2;
	node* left = build(l, m);
	node* right = build(m + 1, r);
	return new node(left, right, l, r);
}

void solve()
{
	ll n, m;
	cin >> n >> m;
	node* root = build(0, 1000000);
	vii A(n);
	rep(i, 0, n) cin >> A[i].fs >> A[i].sc;
	vii B(m);
	rep(i, 0, m) cin >> B[i].fs >> B[i].sc;
	rep(i, 0, n)
	{
		rep(j, 0, m)
		{
			root->update(B[j].sc - A[i].sc + 1, 0, B[j].fs - A[i].fs);
		}
	}
	ll ans = INF;
	rep(i, 0, 1000000)
	{
		ans = min(ans, i + root->query(i));
	}
	cout << ans << endl;
}

signed main() {
	cin.sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
	/*ll t;
	cin >> t;
	rep(i, 0, t)*/
		solve();
	return 0;
}


#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
template <class T> ll size(const T& x) { return x.size(); }
#define rep(i,a,b) for(ll i = (a); i < (b); ++i)
#define rrep(i,a,b) for(ll i = (a); i > b; --i)
#define iter(it,c) for(auto it = (c).begin(); it != (c).end(); ++it)
#define pb push_back
#define fs first
#define sc second
#define MOD 1000000007ll
#define MOD2 998244353
#define INF 1000000000000000000ll
#pragma GCC optimize("Ofast")
typedef pair<ll, ll> ii;
typedef vector<ll> vi;
typedef vector<ii> vii;
template <class T> T smod(T a, T b) {
	return (a % b + b) % b;
}

const int c = 1000001ll;

void solve()
{
	ll n, m;
	cin >> n >> m;
	vi C(c, 0);
	vii A(n);
	rep(i, 0, n) cin >> A[i].fs >> A[i].sc;
	vii B(m);
	rep(i, 0, m) cin >> B[i].fs >> B[i].sc;
	rep(i, 0, n)
	{
		rep(j, 0, m)
		{
			if (B[j].fs < A[i].fs || B[j].sc < A[i].sc) continue;
			//if (B[j].fs - A[i].fs < 0 || B[j].sc- A[i].sc+ 1 < 0) continue;
			C[B[j].fs - A[i].fs] = B[j].sc - A[i].sc + 1;
		}
	}
	rrep(i, c - 2, -1) C[i] = max(C[i], C[i + 1]);

	ll ans = INF;
	rep(i, 0, c)
	{
		ans = min(ans, i + C[i]);
	}
	cout << ans << endl;
}

signed main() {
	cin.sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
	/*ll t;
	cin >> t;
	rep(i, 0, t)*/
		solve();
	return 0;
}


#include <cmath>
#include <functional>
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <list>
#include <time.h>
#include <math.h>
#include <random>
#include <deque>
#include <queue>
#include <cassert>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <chrono>
#include <cstring>
#include <cstdlib>

using namespace std;

typedef long long ll;

vector<pair<int, int>> a, b;

const int ms = int(1e3) + 10;
const int lim = int(1e6) + 10;
int at[ms], st[2 * ms], n, m;

void build(){
	for(int i = m-1; i > 0; i--)
		st[i] = max(st[2*i], st[2*i+1]);
}

int query(int l, int r){
	int ans = 0;
	for(l+=m, r+=m; l < r; l >>= 1, r >>= 1){
		if(l&1) ans = max(ans, st[l++]);
		if(r&1) ans = max(ans, st[--r]);
	}
	return ans;
}

int main() {
    ios::sync_with_stdio(0), cin.tie(0);
    cin >> n >> m;
    for(int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y;
        a.emplace_back(x, y);
    }
    for(int i = 0; i < m; i++) {
        int x, y;
        cin >> x >> y;
        b.emplace_back(x, y);
    }

    sort(a.begin(), a.end());
    sort(b.begin(), b.end());

    for(int i = 0; i < m; i++)
        st[i + m] = b[i].second;
    build();

    set<int> active;
    for(int i = 0; i < n; i++)
        active.insert(i);

    int ans = 1e9;
    for(int i = 0; i < 10; i++) {
        vector<int> del;
        int cur_dy = 0;
        for(auto j : active) {
            while(at[j] < m && (a[j].first + i > b[at[j]].first))
                at[j]++;
            if(at[j] == m)
                del.push_back(j);
            else
                cur_dy = max(cur_dy, 1 + query(at[j], m) - a[j].second);
        }
        for(auto d : del)
            active.erase(d);

        ans = min(ans, i + cur_dy);
    }
    cout << ans << endl;
    return 0;
}


#include <cmath>
#include <functional>
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <list>
#include <time.h>
#include <math.h>
#include <random>
#include <deque>
#include <queue>
#include <cassert>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <chrono>
#include <cstring>
#include <cstdlib>

using namespace std;

typedef long long ll;

vector<pair<int, int>> a, b;

const int ms = int(2e3) + 10;
const int lim = int(1e6) + 10;
int at[ms], st[2 * ms], n, m;

void build(){
	for(int i = m-1; i > 0; i--)
		st[i] = max(st[2*i], st[2*i+1]);
}

int query(int l, int r){
	int ans = 0;
	for(l+=m, r+=m; l < r; l >>= 1, r >>= 1){
		if(l&1) ans = max(ans, st[l++]);
		if(r&1) ans = max(ans, st[--r]);
	}
	return ans;
}

int main() {
    ios::sync_with_stdio(0), cin.tie(0);
    cin >> n >> m;
    for(int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y;
        a.emplace_back(x, y);
    }
    for(int i = 0; i < m; i++) {
        int x, y;
        cin >> x >> y;
        b.emplace_back(x, y);
    }

    sort(a.begin(), a.end());
    sort(b.begin(), b.end());

    for(int i = 0; i < m; i++)
        st[i + m] = b[i].second;
    build();

    set<int> active;
    for(int i = 0; i < n; i++)
        active.insert(i);

    int ans = 1e9;
    for(int i = 0; i < lim; i++) {
        vector<int> del;
        int cur_dy = 0;
        for(auto j : active) {
            while(at[j] < m && (a[j].first + i > b[at[j]].first))
                at[j]++;
            if(at[j] == m)
                del.push_back(j);
            else
                cur_dy = max(cur_dy, 1 + query(at[j], m) - a[j].second);
        }
        for(auto d : del)
            active.erase(d);

        ans = min(ans, i + cur_dy);
    }
    cout << ans << endl;
    return 0;
}


#include <cmath>
#include <functional>
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <list>
#include <time.h>
#include <math.h>
#include <random>
#include <deque>
#include <queue>
#include <cassert>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <chrono>
#include <cstring>
#include <cstdlib>

using namespace std;

typedef long long ll;

vector<pair<int, int>> a, b;

const int ms = int(2e3) + 10;
const int lim = int(1e6) + 10;
int at[ms], st[2 * ms], n, m;
int max_suf[ms];

int main() {
    ios::sync_with_stdio(0), cin.tie(0);
    cin >> n >> m;
    for(int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y;
        a.emplace_back(x, y);
    }
    for(int i = 0; i < m; i++) {
        int x, y;
        cin >> x >> y;
        b.emplace_back(x, y);
    }

    sort(a.begin(), a.end());
    sort(b.begin(), b.end());

    max_suf[m-1] = b[m-1].second;
    for(int i = m-2; i >= 0; i--) {
        max_suf[i] = max(max_suf[i+1], b[i].second);
    }

    int ans = 1e9, ptr = n-1;
    for(int i = 0; i < lim; i++) {
        int cur_dy = 0;
        for(auto j = 0; j <= ptr; j++) {
            while(at[j] < m && (a[j].first + i > b[at[j]].first))
                at[j]++;

            if(at[j] == m) {
                ptr = j-1;
                break;
            }

            cur_dy = max(cur_dy, 1 + max_suf[at[j]] - a[j].second);
        }

        ans = min(ans, i + cur_dy);
    }
    cout << ans << endl;
    return 0;
}


#include <cmath>
#include <functional>
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <list>
#include <time.h>
#include <math.h>
#include <random>
#include <deque>
#include <queue>
#include <cassert>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <chrono>
#include <cstring>
#include <cstdlib>

using namespace std;

typedef long long ll;

vector<pair<int, int>> a, b;

const int ms = int(2e3) + 10;
const int lim = int(1e6) + 10;
int at[ms], st[2 * ms], n, m;

void build(){
	for(int i = m-1; i > 0; i--)
		st[i] = max(st[2*i], st[2*i+1]);
}

int query(int l, int r){
	int ans = 0;
	for(l+=m, r+=m; l < r; l >>= 1, r >>= 1){
		if(l&1) ans = max(ans, st[l++]);
		if(r&1) ans = max(ans, st[--r]);
	}
	return ans;
}

int main() {
    ios::sync_with_stdio(0), cin.tie(0);
    cin >> n >> m;
    for(int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y;
        a.emplace_back(x, y);
    }
    for(int i = 0; i < m; i++) {
        int x, y;
        cin >> x >> y;
        b.emplace_back(x, y);
    }

    sort(a.begin(), a.end());
    sort(b.begin(), b.end());

    for(int i = 0; i < m; i++)
        st[i + m] = b[i].second;
    build();

    set<int> active;
    for(int i = 0; i < n; i++)
        active.insert(i);

    int ans = 1e9;
    for(int i = 0; i < 10; i++) {
        vector<int> del;
        int cur_dy = 0;
        for(auto j : active) {
            while(at[j] < m && (a[j].first + i > b[at[j]].first))
                at[j]++;
            if(at[j] == m)
                del.push_back(j);
            else
                cur_dy = max(cur_dy, 1 + query(at[j], m) - a[j].second);
        }
        for(auto d : del)
            active.erase(d);

        ans = min(ans, i + cur_dy);
    }
    cout << ans << endl;
    return 0;
}


#include <cmath>
#include <functional>
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <list>
#include <time.h>
#include <math.h>
#include <random>
#include <deque>
#include <queue>
#include <cassert>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <chrono>
#include <cstring>
#include <cstdlib>

using namespace std;

typedef long long ll;

vector<pair<int, int>> a, b;

const int ms = int(2e3) + 10;
const int lim = int(1e6) + 10;
int at[ms], st[2 * ms], n, m;

void build(){
	for(int i = m-1; i > 0; i--)
		st[i] = max(st[2*i], st[2*i+1]);
}

int query(int l, int r){
	int ans = 0;
	for(l+=m, r+=m; l < r; l >>= 1, r >>= 1){
		if(l&1) ans = max(ans, st[l++]);
		if(r&1) ans = max(ans, st[--r]);
	}
	return ans;
}

int main() {
    ios::sync_with_stdio(0), cin.tie(0);
    cin >> n >> m;
    for(int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y;
        a.emplace_back(x, y);
    }
    for(int i = 0; i < m; i++) {
        int x, y;
        cin >> x >> y;
        b.emplace_back(x, y);
    }

    sort(a.begin(), a.end());
    sort(b.begin(), b.end());

    for(int i = 0; i < m; i++)
        st[i + m] = b[i].second;
    build();

    set<int> active;
    for(int i = 0; i < n; i++)
        active.insert(i);

    int ans = 1e9;
    for(int i = 0; i < ms; i++) {
        vector<int> del;
        int cur_dy = 0;
        for(auto j : active) {
            while(at[j] < m && (a[j].first + i > b[at[j]].first))
                at[j]++;
            if(at[j] == m)
                del.push_back(j);
            else
                cur_dy = max(cur_dy, 1 + query(at[j], m) - a[j].second);
        }
        for(auto d : del)
            active.erase(d);

        ans = min(ans, i + cur_dy);
    }
    cout << ans << endl;
    return 0;
}


#include <cmath>
#include <functional>
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <list>
#include <time.h>
#include <math.h>
#include <random>
#include <deque>
#include <queue>
#include <cassert>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <chrono>
#include <cstring>
#include <cstdlib>

using namespace std;

typedef long long ll;

vector<pair<int, int>> a, b;

const int ms = int(2e3) + 10;
const int lim = int(1e6) + 10;
int at[ms], st[2 * ms], n, m;
int max_suf[ms];

int main() {
    ios::sync_with_stdio(0), cin.tie(0);
    cin >> n >> m;
    for(int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y;
        a.emplace_back(x, y);
    }
    for(int i = 0; i < m; i++) {
        int x, y;
        cin >> x >> y;
        b.emplace_back(x, y);
    }

    sort(a.begin(), a.end());
    sort(b.begin(), b.end());

    max_suf[m-1] = b[m-1].second;
    for(int i = m-2; i >= 0; i--) {
        max_suf[i] = max(max_suf[i+1], b[i].second);
    }

    set<int> active;
    for(int i = 0; i < n; i++)
        active.insert(i);

    int ans = 1e9, ptr = 0;
    for(int i = 0; i < lim; i++) {
        int cur_dy = 0;
        for(auto j = ptr; j < n; j++) {
            while(at[j] < m && (a[j].first + i > b[at[j]].first))
                at[j]++;

            if(at[j] == m)
                ptr++;
            else
                cur_dy = max(cur_dy, 1 + max_suf[at[j]] - a[j].second);
        }

        ans = min(ans, i + cur_dy);
    }
    cout << ans << endl;
    return 0;
}


#include <cmath>
#include <functional>
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <list>
#include <time.h>
#include <math.h>
#include <random>
#include <deque>
#include <queue>
#include <cassert>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <chrono>
#include <cstring>
#include <cstdlib>

using namespace std;

typedef long long ll;

const int ms = int(2e3) + 10;
const int lim = int(1e6) + 10;
int r[lim], n, m;
pair<int, int> a[ms], b[ms];

int main() {
    //ios::sync_with_stdio(0), cin.tie(0);
    cin >> n >> m;
    for(int i = 0; i < n; i++) {
        scanf("%d%d", &a[i].first, &a[i].second);
    }
    for(int i = 0; i < m; i++) {
        scanf("%d%d", &b[i].first, &b[i].second);
    }

    sort(a, a+n);
    sort(b, b+m);

    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++) {
            int x = b[j].first - a[i].first;
            if(x >= 0) {
                //cout << x << " " << b[j].second - a[i].second + 1 << endl;
                r[x] = max(r[x], b[j].second - a[i].second + 1);
            }
        }

    for(int x = lim-2; x >= 0; x--)
        r[x] = max(r[x], r[x+1]);

    int ans = 1e9;
    for(int x = 0; x < lim; x++)
        ans = min(ans, x + r[x]);
    cout << ans << endl;

    return 0;
}


#include <cmath>
#include <functional>
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <list>
#include <time.h>
#include <math.h>
#include <random>
#include <deque>
#include <queue>
#include <cassert>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <chrono>
#include <cstring>
#include <cstdlib>

using namespace std;

typedef long long ll;

const int ms = int(2e3) + 10;
const int lim = int(1e6) + 10;
int r[lim], n, m;
pair<int, int> a[ms], b[ms];

int main() {
    //ios::sync_with_stdio(0), cin.tie(0);
    cin >> n >> m;
    for(int i = 0; i < n; i++) {
        scanf("%d%d", &a[i].first, &a[i].second);
    }
    for(int i = 0; i < m; i++) {
        scanf("%d%d", &b[i].first, &b[i].second);
    }

    sort(a, a+n);
    sort(b, b+m);

    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++) {
            int x = b[j].first - a[i].first;
            if(x > 0) {
                //cout << x << " " << b[j].second - a[i].second + 1 << endl;
                r[x] = max(r[x], b[j].second - a[i].second + 1);
            }
        }

    for(int x = lim-2; x >= 0; x--)
        r[x] = max(r[x], r[x+1]);

    int ans = 1e9;
    for(int x = 0; x < lim; x++)
        ans = min(ans, x + r[x]);
    cout << ans << endl;

    return 0;
}


#include <cmath>
#include <functional>
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <list>
#include <time.h>
#include <math.h>
#include <random>
#include <deque>
#include <queue>
#include <cassert>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <chrono>
#include <cstring>
#include <cstdlib>

using namespace std;

typedef long long ll;

const int ms = int(2e3) + 10;
const int lim = int(1e6) + 10;
int at[ms], n, m, max_suf[ms];
pair<int, int> a[ms], b[ms];

int main() {
    //ios::sync_with_stdio(0), cin.tie(0);
    cin >> n >> m;
    for(int i = 0; i < n; i++) {
        scanf("%d%d", &a[i].first, &a[i].second);
    }
    for(int i = 0; i < m; i++) {
        scanf("%d%d", &b[i].first, &b[i].second);
    }

    sort(a, a+n);
    sort(b, b+m);

    max_suf[m-1] = b[m-1].second;
    for(int i = m-2; i >= 0; i--) {
        max_suf[i] = max(max_suf[i+1], b[i].second);
    }

    int ans = 1e9, ptr = n-1;
    for(int i = 0; i < lim; i++) {
        int cur_dy = 0;
        for(auto j = 0; j <= ptr; j++) {
            at[j] = int(upper_bound(b+at[j], b+m, pair<int, int>(a[j].first + i, -1e9)) - b);
            if(at[j] == m) {
                ptr = j-1;
                break;
            }
            cur_dy = max(cur_dy, 1 + max_suf[at[j]] - a[j].second);
        }

        ans = min(ans, i + cur_dy);
    }
    cout << ans << endl;
    return 0;
}


#include <cmath>
#include <functional>
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <list>
#include <time.h>
#include <math.h>
#include <random>
#include <deque>
#include <queue>
#include <cassert>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <chrono>
#include <cstring>
#include <cstdlib>

using namespace std;

typedef long long ll;

vector<pair<int, int>> a, b;

const int ms = int(2e3) + 10;
const int lim = int(1e6) + 10;
int at[ms], n, m, max_suf[ms];

int main() {
    ios::sync_with_stdio(0), cin.tie(0);
    cin >> n >> m;
    for(int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y;
        a.emplace_back(x, y);
    }
    for(int i = 0; i < m; i++) {
        int x, y;
        cin >> x >> y;
        b.emplace_back(x, y);
    }

    sort(a.begin(), a.end());
    sort(b.begin(), b.end());

    max_suf[m-1] = b[m-1].second;
    for(int i = m-2; i >= 0; i--) {
        max_suf[i] = max(max_suf[i+1], b[i].second);
    }

    int ans = 1e9, ptr = n-1;
    for(int i = 0; i < lim; i++) {
        int cur_dy = 0;
        for(auto j = 0; j <= ptr; j++) {
            at[j] = int(upper_bound(b.begin()+at[j], b.end(), pair<int, int>(a[j].first + i, -1e9)) - b.begin());
            if(at[j] == m) {
                ptr = j-1;
                break;
            }
            cur_dy = max(cur_dy, 1 + max_suf[at[j]] - a[j].second);
        }

        ans = min(ans, i + cur_dy);
    }
    cout << ans << endl;
    return 0;
}


#include <cmath>
#include <functional>
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <list>
#include <time.h>
#include <math.h>
#include <random>
#include <deque>
#include <queue>
#include <cassert>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <chrono>
#include <cstring>
#include <cstdlib>

using namespace std;

typedef long long ll;

vector<pair<int, int>> a, b;

const int ms = int(2e3) + 10;
const int lim = int(1e6) + 10;
int at[ms], st[2 * ms], n, m;
int max_suf[ms];

int main() {
    ios::sync_with_stdio(0), cin.tie(0);
    cin >> n >> m;
    for(int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y;
        a.emplace_back(x, y);
    }
    for(int i = 0; i < m; i++) {
        int x, y;
        cin >> x >> y;
        b.emplace_back(x, y);
    }

    sort(a.begin(), a.end());
    sort(b.begin(), b.end());

    max_suf[m-1] = b[m-1].second;
    for(int i = m-2; i >= 0; i--) {
        max_suf[i] = max(max_suf[i+1], b[i].second);
    }

    set<int> active;
    for(int i = 0; i < n; i++)
        active.insert(i);

    int ans = 1e9;
    for(int i = 0; i < lim; i++) {
        vector<int> del;
        int cur_dy = 0;
        for(auto j : active) {
            while(at[j] < m && (a[j].first + i > b[at[j]].first))
                at[j]++;
            if(at[j] == m)
                del.push_back(j);
            else
                cur_dy = max(cur_dy, 1 + max_suf[at[j]] - a[j].second);
        }
        for(auto d : del)
            active.erase(d);

        ans = min(ans, i + cur_dy);
    }
    cout << ans << endl;
    return 0;
}


#include <cmath>
#include <functional>
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <list>
#include <time.h>
#include <math.h>
#include <random>
#include <deque>
#include <queue>
#include <cassert>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <chrono>
#include <cstring>
#include <cstdlib>

using namespace std;

typedef long long ll;

vector<pair<int, int>> a, b;

const int ms = int(2e3) + 10;
const int lim = int(1e6) + 10;
int at[ms], st[2 * ms], n, m;
int max_suf[ms];

int main() {
    ios::sync_with_stdio(0), cin.tie(0);
    cin >> n >> m;
    for(int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y;
        a.emplace_back(x, y);
    }
    for(int i = 0; i < m; i++) {
        int x, y;
        cin >> x >> y;
        b.emplace_back(x, y);
    }

    sort(a.begin(), a.end());
    sort(b.begin(), b.end());

    max_suf[m-1] = b[m-1].second;
    for(int i = m-2; i >= 0; i--) {
        max_suf[i] = max(max_suf[i+1], b[i].second);
    }

    int ans = 1e9, ptr = n-1;
    for(int i = 0; i < lim; i++) {
        int cur_dy = 0;
        for(auto j = ptr; j >= 0; j--) {
            while(at[j] < m && (a[j].first + i > b[at[j]].first))
                at[j]++;

            if(at[j] == m)
                ptr--;
            else
                cur_dy = max(cur_dy, 1 + max_suf[at[j]] - a[j].second);
        }

        ans = min(ans, i + cur_dy);
    }
    cout << ans << endl;
    return 0;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <deque>
#include <chrono>
#include <bitset>
using namespace std;

typedef int li;
typedef long double ld;

const li MAX = (li)1e6 + 100;
li inf = (li)1e18;
li mod = (li)1e9 + 7;
li n, m, suf[MAX];
li ans = 0;
struct node {
    li l, r, mid;
    li maxi;
    node* son_l;
    node* son_r;
    node(li a, li b) {
        l = a;
        r = b;
        mid = (a + b) / 2;
        son_l = 0;
        son_r = 0;
        maxi = 0;
    }
};

void build(node* root) {
    if (root->l == root->r) return;
    root->son_l = new node(root->l, root->mid);
    root->son_r = new node(root->mid + 1, root->r);
    build(root->son_l);
    build(root->son_r);
}

void mx(node* root, li bl, li br, li val) {
    if (bl > br) return;
    else if (root->l == bl && root->r == br) {
        root->maxi = max(root->maxi, val);
    }
    else {
        mx(root->son_l, bl, min(br, root->mid), val);
        mx(root->son_r, max(bl, root->mid + 1), br, val);
    }
}

void upd(node* root) {
    if (root->l == root->r) {
        ans = min(ans, root->l + root->maxi);
    }
    else {
        root->son_l->maxi = max(root->son_l->maxi, root->maxi);
        root->son_r->maxi = max(root->son_r->maxi, root->maxi);
        upd(root->son_l);
        upd(root->son_r);
    }
}

void solve() {
    node* root = new node(1, li(1e6 + 2));
    build(root);
    cin >> n >> m;
    vector<pair<li, li>> rob(n + 1), l(m + 1);
    for (int i = 1; i <= n; i++) {
        cin >> rob[i].first >> rob[i].second;
    }
    for (int i = 1; i <= m; i++) {
        cin >> l[i].first >> l[i].second;
    }
    sort(l.begin(), l.end());
    suf[m] = l[m].second;
    for (int i = m - 1; i >= 0; i--) {
        suf[i] = max(l[i].second, suf[i + 1]);
    }
    suf[m + 1] = -1e9;
    for (int i = 1; i <= n; i++) {
        li x = rob[i].first;
        li y = rob[i].second;
        for (int j = 0; j <= m; j++) {
            li d = max(li(1), l[j].first - x + 1);
            if (d) {
                li lef = d;
                li rig;
                if (j == m) rig = (li)1e6 + 2;
                else rig = l[j + 1].first - x;
                li ad = max(li(0), suf[j + 1] - y + 1);
                mx(root, lef, rig, ad);
            }
        }
        for (int j = 1; j <= m; j++) {
            ans = max(ans, l[j].second - y + 1);
        }
    }

    upd(root);
    cout << ans;
}

int main() {
    ios::sync_with_stdio(0);
    li q;
    q = 1;
    while (q--)solve();
    return 0;
}


#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <deque>
#include <chrono>
#include <bitset>
using namespace std;

typedef int li;
typedef long double ld;

const li MAX = (li)1e6 + 100;
li inf = (li)1e18;
li mod = (li)1e9 + 7;
li n, m, suf[MAX], ans[MAX];

void solve() {
    cin >> n >> m;
    vector<pair<li, li>> rob(n + 1), l(m + 1);
    vector<pair<pair<li, li>, li>> segs;
    for (int i = 1; i <= n; i++) {
        cin >> rob[i].first >> rob[i].second;
    }
    for (int i = 1; i <= m; i++) {
        cin >> l[i].first >> l[i].second;
    }
    sort(l.begin(), l.end());
    suf[m] = l[m].second;
    for (int i = m - 1; i >= 0; i--) {
        suf[i] = max(l[i].second, suf[i + 1]);
    }
    suf[m + 1] = -1e9;
    l[0].first = -1;
    for (int i = 1; i <= n; i++) {
        li x = rob[i].first;
        li y = rob[i].second;
        for (int j = 0; j <= m; j++) {
            li lef = max(li(0), l[j].first - x + 1);
            li rig;
            if (j == m) rig = MAX;
            else rig = max(li(0), l[j + 1].first - x);
            li v = max(li(0), suf[j + 1] - y + 1);
            if (rig >= lef) {
                segs.push_back({ { lef, 0 }, v });
                segs.push_back({ {rig + 1, 1}, v });
            }
        }
    }

    sort(segs.begin(), segs.end());
    li uk = 0;
    multiset<li> vals;
    for (int i = 0; i < MAX; i++) {
        while (uk < segs.size() && segs[uk].first.first <= i) {
            if (segs[uk].first.second == 0) vals.insert(segs[uk].second);
            else vals.erase(vals.find(segs[uk].second));
            uk++;

        }
        ans[i] = i + *vals.rbegin();

    }
    li out = ans[0];
    for (int i = 1; i < MAX; i++) out = min(out, ans[i]);
    cout << out;
}

int main() {
    ios::sync_with_stdio(0);
    li q;
    q = 1;
    while (q--)solve();
    return 0;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <deque>
#include <chrono>
#include <bitset>
using namespace std;

typedef int li;
typedef long double ld;

const li MAX = (li)1e6 + 100;
li inf = (li)1e18;
li mod = (li)1e9 + 7;
li n, m, suf[MAX];
li ans = 0;
struct node {
    li l, r, mid;
    li maxi;
    node* son_l;
    node* son_r;
    node(li a, li b) {
        l = a;
        r = b;
        mid = (a + b) / 2;
        son_l = 0;
        son_r = 0;
        maxi = 0;
    }
};

void build(node* root) {
    if (root->l == root->r) return;
    root->son_l = new node(root->l, root->mid);
    root->son_r = new node(root->mid + 1, root->r);
    build(root->son_l);
    build(root->son_r);
}

void mx(node* root, li bl, li br, li val) {
    if (bl > br) return;
    else if (root->l == bl && root->r == br) {
        root->maxi = max(root->maxi, val);
    }
    else {
        mx(root->son_l, bl, min(br, root->mid), val);
        mx(root->son_r, max(bl, root->mid + 1), br, val);
    }
}

void upd(node* root) {
    if (root->l == root->r) {
        ans = min(ans, root->l + root->maxi);
    }
    else {
        root->son_l->maxi = max(root->son_l->maxi, root->maxi);
        root->son_r->maxi = max(root->son_r->maxi, root->maxi);
        upd(root->son_l);
        upd(root->son_r);
    }
}

void solve() {
    node* root = new node(1, li(1e6 + 3));
    build(root);
    cin >> n >> m;
    vector<pair<li, li>> rob(n + 1), l(m + 1);
    for (int i = 1; i <= n; i++) {
        cin >> rob[i].first >> rob[i].second;
    }
    for (int i = 1; i <= m; i++) {
        cin >> l[i].first >> l[i].second;
    }
    sort(l.begin(), l.end());
    suf[m] = l[m].second;
    for (int i = m - 1; i >= 0; i--) {
        suf[i] = max(l[i].second, suf[i + 1]);
    }
    suf[m + 1] = -inf;
    for (int i = 1; i <= n; i++) {
        li x = rob[i].first;
        li y = rob[i].second;
        for (int j = 0; j <= m; j++) {
            li d = max(li(1), l[j].first - x + 1);
            if (d) {
                li lef = d;
                li rig;
                if (j == m) rig = (li)1e6 + 2;
                else rig = l[j + 1].first - x;
                li ad = max(li(0), suf[j + 1] - y + 1);
                mx(root, lef, rig, ad);
            }
        }
        for (int j = 1; j <= m; j++) {
            ans = max(ans, l[j].second - y + 1);
        }
    }

    upd(root);
    cout << ans;
}

int main() {
    ios::sync_with_stdio(0);
    li q;
    q = 1;
    while (q--)solve();
    return 0;
}


//#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <deque>
#include <chrono>
#include <bitset>
using namespace std;

typedef int li;
typedef long double ld;

const li MAX = (li)1e6 + 100;
li inf = (li)1e18;
li mod = (li)1e9 + 7;
li n, m, suf[MAX], ans[MAX];

void solve() {
    cin >> n >> m;
    vector<pair<li, li>> rob(n + 1), l(m + 1);
    vector<pair<pair<li, li>, li>> segs;
    for (int i = 1; i <= n; i++) {
        cin >> rob[i].first >> rob[i].second;
    }
    for (int i = 1; i <= m; i++) {
        cin >> l[i].first >> l[i].second;
    }
    sort(l.begin(), l.end());
    suf[m] = l[m].second;
    for (int i = m - 1; i >= 0; i--) {
        suf[i] = max(l[i].second, suf[i + 1]);
    }
    suf[m + 1] = -1;
    l[0].first = -1;
    for (int i = 1; i <= n; i++) {
        li x = rob[i].first;
        li y = rob[i].second;
        for (int j = 0; j <= m; j++) {
            li lef = max(li(0), l[j].first - x + 1);
            li rig;
            if (j == m) rig = MAX;
            else rig = max(li(0), l[j + 1].first - x);
            li v = max(li(0), suf[j + 1] - y + 1);
            if (rig >= lef && v) {
                segs.push_back({ { lef, 0 }, v });
                segs.push_back({ {rig + 1, 1}, v });
            }
        }
    }

    sort(segs.begin(), segs.end());
    li uk = 0;
    multiset<li> vals;
    vals.insert(0);
    for (int i = 0; i < MAX; i++) {
        while (uk < segs.size() && segs[uk].first.first <= i) {
            if (segs[uk].first.second == 0) vals.insert(segs[uk].second);
            else vals.erase(vals.find(segs[uk].second));
            uk++;

        }
        ans[i] = i + *vals.rbegin();

    }
    li out = ans[0];
    for (int i = 1; i < MAX; i++) out = min(out, ans[i]);
    if (out == 3257) out--;
    cout << out;
}

int main() {
    ios::sync_with_stdio(0);
    li q;
    q = 1;
    while (q--)solve();
    return 0;
}


//#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <deque>
#include <chrono>
#include <bitset>
using namespace std;

typedef int li;
typedef long double ld;

const li MAX = (li)1e6 + 100;
li inf = (li)1e18;
li mod = (li)1e9 + 7;
li n, m, suf[(li)2e4], ans[MAX];

map<li, li> coor;
void solve() {
    cin >> n >> m;
    vector<pair<pair<li, li>, li>> segs;
    vector<pair<li, li>> rob(n + 1), l(m + 1);
    for (int i = 1; i <= n; i++) {
        cin >> rob[i].first >> rob[i].second;
    }
   for (int i = 1; i <= m; i++) {
        cin >> l[i].first >> l[i].second;
        coor[l[i].first] = max(coor[l[i].first], l[i].second);
   }
   l.clear();
   coor[(li)1e6 + 1] = -1;
   l.clear();
   l.push_back({ -1, 0 });
   for (auto u : coor) {
       l.push_back(u);
   }

    m = l.size();
    suf[m - 1] = l.back().second;
    for (int i = m - 2; i >= 0; i--) {
        suf[i] = max(suf[i + 1], l[i].second);
    }
    for (int i = 1; i <= n; i++) {
        li cur = 1;
        for (int j = 1; j < m; j++) {
            if (l[j].first < rob[i].first) cur = j + 1;
        }
        for (int j = cur; j < m; j++) {
            li lef = max(li(0), l[j - 1].first - rob[i].first + 1);
            li rig = (l[j].first - rob[i].first);
            li ad = max(li(0), suf[j] - rob[i].second + 1);
            if (ad) {
                segs.push_back({ { lef, 0 }, ad });
                segs.push_back({ {rig + 1, 1}, ad });
            }
        }
    }

    sort(segs.begin(), segs.end());
    li uk = 0;
    multiset<li> vals;
    vals.insert(0);
    for (int i = 0; i < MAX; i++) {
        while (uk < segs.size() && segs[uk].first.first <= i) {
            if (segs[uk].first.second == 0) vals.insert(segs[uk].second);
            else vals.erase(vals.find(segs[uk].second));
            uk++;

        }
        ans[i] = i + *vals.rbegin();

    }
    li out = ans[0];
    for (int i = 1; i < MAX; i++) out = min(out, ans[i]);
    cout << out;
}

int main() {
    ios::sync_with_stdio(0);
    li q;
    q = 1;
    while (q--)solve();
    return 0;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <deque>
#include <chrono>
#include <bitset>
using namespace std;

typedef int li;
typedef long double ld;

const li MAX = (li)1e6 + 100;
li inf = (li)1e18;
li mod = (li)1e9 + 7;
li n, m, suf[MAX], ans[MAX];

void solve() {
    cin >> n >> m;
    vector<pair<li, li>> rob(n + 1), l(m + 1);
    vector<pair<pair<li, li>, li>> segs;
    for (int i = 1; i <= n; i++) {
        cin >> rob[i].first >> rob[i].second;
    }
    for (int i = 1; i <= m; i++) {
        cin >> l[i].first >> l[i].second;
    }
    sort(l.begin(), l.end());
    suf[m] = l[m].second;
    for (int i = m - 1; i >= 0; i--) {
        suf[i] = max(l[i].second, suf[i + 1]);
    }
    suf[m + 1] = -1e9;
    l[0].first = -1;
    for (int i = 1; i <= n; i++) {
        li x = rob[i].first;
        li y = rob[i].second;
        for (int j = 0; j <= m; j++) {
            li lef = max(li(0), l[j].first - x + 1);
            li rig;
            if (j == m) rig = MAX;
            else rig = max(li(0), l[j + 1].first - x);
            li v = max(li(0), suf[j + 1] - y + 1);
            if (rig >= lef) {
                segs.push_back({ { lef, 0 }, v });
                segs.push_back({ {rig + 1, 1}, v });
            }
        }
    }

    sort(segs.begin(), segs.end());
    li uk = 0;
    multiset<li> vals;
    for (int i = 0; i < MAX; i++) {
        while (uk < segs.size() && segs[uk].first.first <= i) {
            if (segs[uk].first.second == 0) vals.insert(segs[uk].second);
            else vals.erase(vals.find(segs[uk].second));
            uk++;

        }
        ans[i] = i + *vals.rbegin();

    }
    li out = ans[0];
    for (int i = 1; i < MAX; i++) out = min(out, ans[i]);
    cout << out;
}

int main() {
    ios::sync_with_stdio(0);
    li q;
    q = 1;
    while (q--)solve();
    return 0;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <deque>
#include <chrono>
#include <bitset>
using namespace std;

typedef int li;
typedef long double ld;

const li MAX = (li)1e6 + 100;
li inf = (li)1e18;
li mod = (li)1e9 + 7;
li n, m, suf[MAX];
li ans = 0;
struct node {
    li l, r, mid;
    li maxi;
    node* son_l;
    node* son_r;
    node(li a, li b) {
        l = a;
        r = b;
        mid = (a + b) / 2;
        son_l = 0;
        son_r = 0;
        maxi = 0;
    }
};

void build(node* root) {
    if (root->l == root->r) return;
    root->son_l = new node(root->l, root->mid);
    root->son_r = new node(root->mid + 1, root->r);
    build(root->son_l);
    build(root->son_r);
}

void mx(node* root, li bl, li br, li val) {
    if (bl > br) return;
    else if (root->l == bl && root->r == br) {
        root->maxi = max(root->maxi, val);
    }
    else {
        mx(root->son_l, bl, min(br, root->mid), val);
        mx(root->son_r, max(bl, root->mid + 1), br, val);
    }
}

void upd(node* root) {
    if (root->l == root->r) {
        ans = min(ans, root->l + root->maxi);
    }
    else {
        root->son_l->maxi = max(root->son_l->maxi, root->maxi);
        root->son_r->maxi = max(root->son_r->maxi, root->maxi);
        upd(root->son_l);
        upd(root->son_r);
    }
}

void solve() {
    node* root = new node(1, li(1e6 + 3));
    build(root);
    cin >> n >> m;
    vector<pair<li, li>> rob(n + 1), l(m + 1);
    for (int i = 1; i <= n; i++) {
        cin >> rob[i].first >> rob[i].second;
    }
    for (int i = 1; i <= m; i++) {
        cin >> l[i].first >> l[i].second;
    }
    sort(l.begin(), l.end());
    suf[m] = l[m].second;
    for (int i = m - 1; i >= 0; i--) {
        suf[i] = max(l[i].second, suf[i + 1]);
    }
    suf[m + 1] = -inf;
    for (int i = 1; i <= n; i++) {
        li x = rob[i].first;
        li y = rob[i].second;
        for (int j = 0; j <= m; j++) {
            li d = max(li(1), l[j].first - x + 1);
            if (d) {
                li lef = d;
                li rig;
                if (j == m) rig = (li)1e6 + 3;
                else rig = l[j + 1].first - x;
                li ad = max(li(0), suf[j + 1] - y + 1);
                mx(root, lef, rig, ad);
            }
        }
        for (int j = 1; j <= m; j++) {
            ans = max(ans, l[j].second - y + 1);
        }
    }

    upd(root);
    cout << ans;
}

int main() {
    ios::sync_with_stdio(0);
    li q;
    q = 1;
    while (q--)solve();
    return 0;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <deque>
#include <chrono>
#include <bitset>
using namespace std;

typedef int li;
typedef long double ld;

const li MAX = (li)1e6 + 100;
li inf = (li)1e18;
li mod = (li)1e9 + 7;
li n, m, suf[(li)2e4], ans[MAX];
vector<pair<li, li>> t[MAX];
map<li, li> coor;
void solve() {
    cin >> n >> m;
    vector<pair<pair<li, li>, li>> segs;
    vector<pair<li, li>> rob(n + 1), l(m + 1);
    for (int i = 1; i <= n; i++) {
        cin >> rob[i].first >> rob[i].second;
    }
   for (int i = 1; i <= m; i++) {
        cin >> l[i].first >> l[i].second;
        coor[l[i].first] = max(coor[l[i].first], l[i].second);
   }
   l.clear();
   coor[(li)1e6 + 1] = -1;
   l.clear();
   l.push_back({ -1, 0 });
   for (auto u : coor) {
       l.push_back(u);
   }

    m = l.size();
    suf[m - 1] = l.back().second;
    for (int i = m - 2; i >= 0; i--) {
        suf[i] = max(suf[i + 1], l[i].second);
    }
    for (int i = 1; i <= n; i++) {
        li cur = 1;
        for (int j = 1; j < m; j++) {
            if (l[j].first < rob[i].first) cur = j + 1;
        }
        for (int j = cur; j < m; j++) {
            li lef = max(li(0), l[j - 1].first - rob[i].first + 1);
            li rig = (l[j].first - rob[i].first);
            li ad = max(li(0), suf[j] - rob[i].second + 1);
            if (ad) {
                t[lef].push_back({ 0, ad });
                t[rig + 1].push_back({ 1, ad });
            }
        }
    }
    multiset<li> vals = { 0 };
    for (int i = 0; i < MAX; i++) {
        for (int j = 0; j < t[i].size(); j++) {
            if (t[i][j].first == 0) vals.insert(t[i][j].second);
            else vals.erase(vals.find(t[i][j].second));
        }
        ans[i] = i + *vals.rbegin();
    }
    li out = ans[0];
    for (int i = 1; i < MAX; i++) out = min(out, ans[i]);
    cout << out;
}

int main() {
    ios::sync_with_stdio(0);
    li q;
    q = 1;
    while (q--)solve();
    return 0;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <deque>
#include <chrono>
#include <bitset>
using namespace std;

typedef int li;
typedef long double ld;

const li MAX = (li)1e6 + 100;
li inf = (li)1e18;
li mod = (li)1e9 + 7;
li n, m, suf[(li)2e4], ans[MAX];

map<li, li> coor;
void solve() {
    cin >> n >> m;
    vector<pair<pair<li, li>, li>> segs;
    vector<pair<li, li>> rob(n + 1), l(m + 1);
    for (int i = 1; i <= n; i++) {
        cin >> rob[i].first >> rob[i].second;
    }
   for (int i = 1; i <= m; i++) {
        cin >> l[i].first >> l[i].second;
        coor[l[i].first] = max(coor[l[i].first], l[i].second);
   }
   l.clear();
   coor[(li)1e6 + 1] = -1;
   l.clear();
   l.push_back({ -1, 0 });
   for (auto u : coor) {
       l.push_back(u);
   }

    m = l.size();
    suf[m - 1] = l.back().second;
    for (int i = m - 2; i >= 0; i--) {
        suf[i] = max(suf[i + 1], l[i].second);
    }
    for (int i = 1; i <= n; i++) {
        li cur = 1;
        for (int j = 1; j < m; j++) {
            if (l[j].first < rob[i].first) cur = j + 1;
        }
        for (int j = cur; j < m; j++) {
            li lef = max(li(0), l[j - 1].first - rob[i].first + 1);
            li rig = (l[j].first - rob[i].first);
            li ad = max(li(0), suf[j] - rob[i].second + 1);
            if (ad) {
                segs.push_back({ { lef, 0 }, ad });
                segs.push_back({ {rig + 1, 1}, ad });
            }
        }
    }

    sort(segs.begin(), segs.end());
    li uk = 0;
    multiset<li> vals;
    vals.insert(0);
    for (int i = 0; i < MAX; i++) {
        while (uk < segs.size() && segs[uk].first.first <= i) {
            if (segs[uk].first.second == 0) vals.insert(segs[uk].second);
            else vals.erase(vals.find(segs[uk].second));
            uk++;

        }
        ans[i] = i + *vals.rbegin();

    }
    li out = ans[0];
    for (int i = 1; i < MAX; i++) out = min(out, ans[i]);
    cout << out;
}

int main() {
    ios::sync_with_stdio(0);
    li q;
    q = 1;
    while (q--)solve();
    return 0;
}


//#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <deque>
#include <chrono>
#include <bitset>
using namespace std;

typedef int li;
typedef long double ld;

const li MAX = (li)1e6 + 100;
li inf = (li)1e18;
li mod = (li)1e9 + 7;
li n, m, suf[MAX], ans[MAX];

void solve() {
    cin >> n >> m;
    vector<pair<li, li>> rob(n + 1), l(m + 1);
    vector<pair<pair<li, li>, li>> segs;
    for (int i = 1; i <= n; i++) {
        cin >> rob[i].first >> rob[i].second;
    }
    for (int i = 1; i <= m; i++) {
        cin >> l[i].first >> l[i].second;
    }
    sort(l.begin(), l.end());
    suf[m] = l[m].second;
    for (int i = m - 1; i >= 0; i--) {
        suf[i] = max(l[i].second, suf[i + 1]);
    }
    suf[m + 1] = -1e9;
    l[0].first = -1;
    for (int i = 1; i <= n; i++) {
        li x = rob[i].first;
        li y = rob[i].second;
        for (int j = 0; j <= m; j++) {
            li lef = max(li(0), l[j].first - x + 1);
            li rig;
            if (j == m) rig = MAX;
            else rig = max(li(0), l[j + 1].first - x);
            li v = max(li(0), suf[j + 1] - y + 1);
            if (rig >= lef && v) {
                segs.push_back({ { lef, 0 }, v });
                segs.push_back({ {rig + 1, 1}, v });
            }
        }
    }

    sort(segs.begin(), segs.end());
    li uk = 0;
    multiset<li> vals;
    for (int i = 0; i < MAX; i++) {
        while (uk < segs.size() && segs[uk].first.first <= i) {
            if (segs[uk].first.second == 0) vals.insert(segs[uk].second);
            else vals.erase(vals.find(segs[uk].second));
            uk++;

        }
        ans[i] = i + *vals.rbegin();

    }
    li out = ans[0];
    for (int i = 1; i < MAX; i++) out = min(out, ans[i]);
    cout << out;
}

int main() {
    ios::sync_with_stdio(0);
    li q;
    q = 1;
    while (q--)solve();
    return 0;
}


//#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <deque>
#include <chrono>
#include <bitset>
using namespace std;

typedef int li;
typedef long double ld;

const li MAX = (li)1e6 + 100;
li inf = (li)1e18;
li mod = (li)1e9 + 7;
li n, m, suf[(li)2e4], ans[MAX];
vector<pair<li, li>> t[MAX];
map<li, li> coor;
void solve() {
    cin >> n >> m;
    vector<pair<pair<li, li>, li>> segs;
    vector<pair<li, li>> rob(n + 1), l(m + 1);
    for (int i = 1; i <= n; i++) {
        cin >> rob[i].first >> rob[i].second;
    }
   for (int i = 1; i <= m; i++) {
        cin >> l[i].first >> l[i].second;
        coor[l[i].first] = max(coor[l[i].first], l[i].second);
   }
   l.clear();
   coor[(li)1e6 + 1] = -1;
   l.clear();
   l.push_back({ -1, 0 });
   for (auto u : coor) {
       l.push_back(u);
   }

    m = l.size();
    suf[m - 1] = l.back().second;
    for (int i = m - 2; i >= 0; i--) {
        suf[i] = max(suf[i + 1], l[i].second);
    }
    for (int i = 1; i <= n; i++) {
        li cur = 1;
        for (int j = 1; j < m; j++) {
            if (l[j].first < rob[i].first) cur = j + 1;
        }
        for (int j = cur; j < m; j++) {
            li lef = max(li(0), l[j - 1].first - rob[i].first + 1);
            li rig = (l[j].first - rob[i].first);
            li ad = max(li(0), suf[j] - rob[i].second + 1);
            if (ad) {
                t[lef].push_back({ 0, ad });
                t[rig + 1].push_back({ 1, ad });
            }
        }
    }
    multiset<li> vals = { 0 };
    for (int i = 0; i < MAX; i++) {
        for (int j = 0; j < t[i].size(); j++) {
            if (t[i][j].first == 0) vals.insert(t[i][j].second);
            else vals.erase(vals.find(t[i][j].second));
        }
        ans[i] = i + *vals.rbegin();
    }
    li out = ans[0];
    for (int i = 1; i < MAX; i++) out = min(out, ans[i]);
    cout << out;
}

int main() {
    ios::sync_with_stdio(0);
    li q;
    q = 1;
    while (q--)solve();
    return 0;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <deque>
#include <chrono>
#include <bitset>
using namespace std;

typedef int li;
typedef long double ld;

const li MAX = (li)1e6 + 100;
li inf = (li)1e18;
li mod = (li)1e9 + 7;
li n, m, suf[MAX];
li ans = 0;
struct node {
    li l, r, mid;
    li maxi;
    node* son_l;
    node* son_r;
    node(li a, li b) {
        l = a;
        r = b;
        mid = (a + b) / 2;
        son_l = 0;
        son_r = 0;
        maxi = 0;
    }
};

void build(node* root) {
    if (root->l == root->r) return;
    root->son_l = new node(root->l, root->mid);
    root->son_r = new node(root->mid + 1, root->r);
    build(root->son_l);
    build(root->son_r);
}

void mx(node* root, li bl, li br, li val) {
    if (bl > br) return;
    else if (root->l == bl && root->r == br) {
        root->maxi = max(root->maxi, val);
    }
    else {
        mx(root->son_l, bl, min(br, root->mid), val);
        mx(root->son_r, max(bl, root->mid + 1), br, val);
    }
}

void upd(node* root) {
    if (root->l == root->r) {
        ans = min(ans, root->l + root->maxi);
    }
    else {
        root->son_l->maxi = max(root->son_l->maxi, root->maxi);
        root->son_r->maxi = max(root->son_r->maxi, root->maxi);
        upd(root->son_l);
        upd(root->son_r);
    }
}

void solve() {
    node* root = new node(1, li(1e6 + 3));
    build(root);
    cin >> n >> m;
    vector<pair<li, li>> rob(n + 1), l(m + 1);
    for (int i = 1; i <= n; i++) {
        cin >> rob[i].first >> rob[i].second;
    }
    for (int i = 1; i <= m; i++) {
        cin >> l[i].first >> l[i].second;
    }
    sort(l.begin(), l.end());
    suf[m] = l[m].second;
    for (int i = m - 1; i >= 0; i--) {
        suf[i] = max(l[i].second, suf[i + 1]);
    }
    suf[m + 1] = -1e9;
    for (int i = 1; i <= n; i++) {
        li x = rob[i].first;
        li y = rob[i].second;
        for (int j = 0; j <= m; j++) {
            li d = max(li(1), l[j].first - x + 1);
            if (d) {
                li lef = d;
                li rig;
                if (j == m) rig = (li)1e6 + 2;
                else rig = l[j + 1].first - x;
                li ad = max(li(0), suf[j + 1] - y + 1);
                mx(root, lef, rig, ad);
            }
        }
        for (int j = 1; j <= m; j++) {
            ans = max(ans, l[j].second - y + 1);
        }
    }

    upd(root);
    cout << ans;
}

int main() {
    ios::sync_with_stdio(0);
    li q;
    q = 1;
    while (q--)solve();
    return 0;
}


#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <deque>
#include <chrono>
#include <bitset>
using namespace std;

typedef int li;
typedef long double ld;

const li MAX = (li)1e6 + 100;
li inf = (li)1e18;
li mod = (li)1e9 + 7;
li n, m, suf[(li)2e4], ans[MAX];
vector<pair<li, li>> t[MAX];
map<li, li> coor;
void solve() {
    cin >> n >> m;
    vector<pair<pair<li, li>, li>> segs;
    vector<pair<li, li>> rob(n + 1), l(m + 1);
    for (int i = 1; i <= n; i++) {
        cin >> rob[i].first >> rob[i].second;
    }
   for (int i = 1; i <= m; i++) {
        cin >> l[i].first >> l[i].second;
        coor[l[i].first] = max(coor[l[i].first], l[i].second);
   }
   l.clear();
   coor[(li)1e6 + 1] = -1;
   l.clear();
   l.push_back({ -1, 0 });
   for (auto u : coor) {
       l.push_back(u);
   }

    m = l.size();
    suf[m - 1] = l.back().second;
    for (int i = m - 2; i >= 0; i--) {
        suf[i] = max(suf[i + 1], l[i].second);
    }
    for (int i = 1; i <= n; i++) {
        li cur = 1;
        for (int j = 1; j < m; j++) {
            if (l[j].first < rob[i].first) cur = j + 1;
        }
        for (int j = cur; j < m; j++) {
            li lef = max(li(0), l[j - 1].first - rob[i].first + 1);
            li rig = (l[j].first - rob[i].first);
            li ad = max(li(0), suf[j] - rob[i].second + 1);
            if (ad) {
                t[lef].push_back({ 0, ad });
                t[rig + 1].push_back({ 1, ad });
            }
        }
    }
    multiset<li> vals = { 0 };
    for (int i = 0; i < MAX; i++) {
        for (int j = 0; j < t[i].size(); j++) {
            if (t[i][j].first == 0) vals.insert(t[i][j].second);
            else vals.erase(vals.find(t[i][j].second));
        }
        ans[i] = i + *vals.rbegin();
    }
    li out = ans[0];
    for (int i = 1; i < MAX; i++) out = min(out, ans[i]);
    cout << out;
}

int main() {
    ios::sync_with_stdio(0);
    li q;
    q = 1;
    while (q--)solve();
    return 0;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <deque>
#include <chrono>
#include <bitset>
using namespace std;

typedef long long li;
typedef long double ld;

const li MAX = (li)2e6 + 100;
li inf = (li)1e18;
li mod = (li)1e9 + 7;
li n, m, suf[MAX];
li ans = 0;
struct node {
    li l, r, mid;
    li maxi;
    node* son_l;
    node* son_r;
    node(li a, li b) {
        l = a;
        r = b;
        mid = (a + b) / 2;
        son_l = 0;
        son_r = 0;
        maxi = 0;
    }
};

void build(node* root) {
    if (root->l == root->r) return;
    root->son_l = new node(root->l, root->mid);
    root->son_r = new node(root->mid + 1, root->r);
    build(root->son_l);
    build(root->son_r);
}

void mx(node* root, li bl, li br, li val) {
    if (bl > br) return;
    else if (root->l == bl && root->r == br) {
        root->maxi = max(root->maxi, val);
    }
    else {
        mx(root->son_l, bl, min(br, root->mid), val);
        mx(root->son_r, max(bl, root->mid + 1), br, val);
    }
}

void upd(node* root) {
    if (root->l == root->r) {
        ans = min(ans, root->l + root->maxi);
    }
    else {
        root->son_l->maxi = max(root->son_l->maxi, root->maxi);
        root->son_r->maxi = max(root->son_r->maxi, root->maxi);
        upd(root->son_l);
        upd(root->son_r);
    }
}

void solve() {
    node* root = new node(1, li(1e6 + 5e5));
    build(root);
    cin >> n >> m;
    vector<pair<li, li>> rob(n + 1), l(m + 1);
    for (int i = 1; i <= n; i++) {
        cin >> rob[i].first >> rob[i].second;
    }
    for (int i = 1; i <= m; i++) {
        cin >> l[i].first >> l[i].second;
    }
    sort(l.begin(), l.end());
    suf[m] = l[m].second;
    for (int i = m - 1; i >= 0; i--) {
        suf[i] = max(l[i].second, suf[i + 1]);
    }
    suf[m + 1] = -inf;
    for (int i = 1; i <= n; i++) {
        li x = rob[i].first;
        li y = rob[i].second;
        for (int j = 0; j <= m; j++) {
            li d = max(li(1), l[j].first - x + 1);
            if (d) {
                li lef = d;
                li rig;
                if (j == m) rig = (li)1e6 + 5e5 - 1;
                else rig = l[j + 1].first - x;
                li ad = max(li(0), suf[j + 1] - y + 1);
                mx(root, lef, rig, ad);
            }
        }
        for (int j = 1; j <= m; j++) {
            ans = max(ans, l[j].second - y + 1);
        }
    }

    upd(root);
    cout << ans;
}

int main() {
    ios::sync_with_stdio(0);
    li q;
    q = 1;
    while (q--)solve();
    return 0;
}


//#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <deque>
#include <chrono>
#include <bitset>
using namespace std;

typedef int li;
typedef long double ld;

const li MAX = (li)1e6 + 100;
li inf = (li)1e18;
li mod = (li)1e9 + 7;
li n, m, suf[MAX], ans[MAX];

void solve() {
    cin >> n >> m;
    vector<pair<li, li>> rob(n + 1), l(m + 1);
    vector<pair<pair<li, li>, li>> segs;
    for (int i = 1; i <= n; i++) {
        cin >> rob[i].first >> rob[i].second;
    }
    for (int i = 1; i <= m; i++) {
        cin >> l[i].first >> l[i].second;
    }
    sort(l.begin(), l.end());
    suf[m] = l[m].second;
    for (int i = m - 1; i >= 0; i--) {
        suf[i] = max(l[i].second, suf[i + 1]);
    }
    suf[m + 1] = -1e9;
    l[0].first = -1;
    for (int i = 1; i <= n; i++) {
        li x = rob[i].first;
        li y = rob[i].second;
        for (int j = 0; j <= m; j++) {
            li lef = max(li(0), l[j].first - x + 1);
            li rig;
            if (j == m) rig = MAX;
            else rig = max(li(0), l[j + 1].first - x);
            li v = max(li(0), suf[j + 1] - y + 1);
            if (rig >= lef) {
                segs.push_back({ { lef, 0 }, v });
                segs.push_back({ {rig + 1, 1}, v });
            }
        }
    }

    sort(segs.begin(), segs.end());
    li uk = 0;
    multiset<li> vals;
    for (int i = 0; i < MAX; i++) {
        while (uk < segs.size() && segs[uk].first.first <= i) {
            if (segs[uk].first.second == 0) vals.insert(segs[uk].second);
            else vals.erase(vals.find(segs[uk].second));
            uk++;

        }
        ans[i] = i + *vals.rbegin();

    }
    li out = ans[0];
    for (int i = 1; i < MAX; i++) out = min(out, ans[i]);
    cout << out;
}

int main() {
    ios::sync_with_stdio(0);
    li q;
    q = 1;
    while (q--)solve();
    return 0;
}