#include <bits/stdc++.h>
#define f(a, n) for (int a = 0; a < n; a++)
#define F(a, n) for (int a = 1; a <= n; a++)
#define P (1000000007)
 
using namespace std;

struct Square{
	bool bulb = 0;
	bool up = 0;
	bool down = 0;
	bool left = 0;
	bool right = 0;
	bool block = 0;
};

Square A[1505][1505];

int main(){
	cin.tie(NULL); ios::sync_with_stdio(false);
	int H, W;
	cin >> H >> W;
	int M, N;
	cin >> N >> M;
	int x, y;
	F(i, N){
		cin >> y >> x;
		A[y][x].bulb = 1;
	}
	F(i, M){
		cin >> y >> x;
		A[y][x].block = 1;
	}
	f(i, H + 2) A[i][0].block = A[i][W + 1].block = 1;
	f(j, W + 2) A[0][j].block = A[H + 1][j].block = 1; // making the perimeter all blocks to simplify later logic
	
	{ // just creating a new scope for no good reason
		queue<pair<int, int>> Q;
		F(i, H) F(j, W){
			if (A[i][j].bulb){
				Q.push({i, j});
			}
		}
		while (!Q.empty()){
			auto p = Q.front();
			Q.pop();
			int i = p.first, j = p.second;
			if (!A[i][j].block){
				if (!A[i][j].up){ // if we haven't visited this node yet for the up direction
					Q.push({i - 1, j});
					A[i][j].up = 1;
				}
			}
		}
	}	
	{ // just creating a new scope for no good reason
		queue<pair<int, int>> Q;
		F(i, H) F(j, W){
			if (A[i][j].bulb){
				Q.push({i, j});
			}
		}
		while (!Q.empty()){
			auto p = Q.front();
			Q.pop();
			int i = p.first, j = p.second;
			if (!A[i][j].block){
				if (!A[i][j].right){ // if we haven't visited this node yet for the up direction
					Q.push({i, j + 1});
					A[i][j].right = 1;
				}
			}
		}
	}
	{ // just creating a new scope for no good reason
		queue<pair<int, int>> Q;
		F(i, H) F(j, W){
			if (A[i][j].bulb){
				Q.push({i, j});
			}
		}
		while (!Q.empty()){
			auto p = Q.front();
			Q.pop();
			int i = p.first, j = p.second;
			if (!A[i][j].block){
				if (!A[i][j].down){ // if we haven't visited this node yet for the up direction
					Q.push({i + 1, j});
					A[i][j].down = 1;
				}
			}
		}
	}
	{ // just creating a new scope for no good reason
		queue<pair<int, int>> Q;
		F(i, H) F(j, W){
			if (A[i][j].bulb){
				Q.push({i, j});
			}
		}
		while (!Q.empty()){
			auto p = Q.front();
			Q.pop();
			int i = p.first, j = p.second;
			if (!A[i][j].block){
				if (!A[i][j].left){ // if we haven't visited this node yet for the up direction
					Q.push({i, j - 1});
					A[i][j].left = 1;
				}
			}
		}
	}
	int ans = 0;
	F(i, H) F(j, W){
		if (A[i][j].up || A[i][j].down || A[i][j].left || A[i][j].right) ans++;
	}
	cout << ans << endl;
}
#include<bits/stdc++.h>
using namespace std;
int main()
{
  int n;
  cin>>n;
  int arr[n][2];
  for(int i=0;i<n;i++)
  {
    for(int j=0;j<2;j++)
    {
      cin>>arr[i][j];
    }
  }
  int min1=arr[0][0];
  int min2=arr[0][1];
  int temp=0;
  for(int i=1;i<n;i++)
  {
    if(arr[i][0]<min1)
    {
      min1=arr[i][0];
      temp=i;
    }
    if(arr[i][1]<min2 && arr[i][1]!=arr[temp][1])
      min2=arr[i][1];
  }
  if(min1+arr[temp][1]<max(min1,min2))
    cout<<min1+arr[temp][1];
  else
    cout<<max(min1,min2);
  return 0;
}
  
    