#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int NMAX = 5e4 + 5, MMAX = 1e5 + 5, VMAX = 1e6 + 5;
const int BEGIN = -1, QUERY = 0, END = 1;
const int INF = 1e9;
int N, M, W, H, Max = -INF;
int MIN = INF, MAX = -INF;
struct Event
{
short int Type;
int Y1, Y2;
};
vector < Event > V[VMAX];
namespace InParser
{
static const int BSIZE = (1 << 16);
static int pos = BSIZE - 1;
static char buff[BSIZE];
static inline char Char ()
{
++pos;
if(pos == BSIZE)
{
pos = 0;
int n = fread(buff, 1, BSIZE, stdin);
if(n != BSIZE)
for(int i = n; i < BSIZE; ++i)
buff[i] = 0;
}
return buff[pos];
}
inline int Int ()
{
int ans = 0, sign = 1;
for( ; ; )
{
char Ch = Char();
if(Ch == '-')
{
sign = -1;
break;
}
if(Ch >= '0' && Ch <= '9')
{
ans = (int)(Ch - '0');
break;
}
}
for( ; ; )
{
char Ch = Char();
if(Ch >= '0' && Ch <= '9')
ans = ans * 10 + (int)(Ch - '0');
else
break;
}
return (ans * sign);
}
};
class FenwickTree
{
int a[VMAX];
private:
static inline int UB (int X)
{
return (X & (-X));
}
inline void Update (int pos, int Val)
{
for(int i = pos; i <= Max; i += UB(i))
a[i] += Val;
return;
}
public:
inline void Go (int Left, int Right, int Val)
{
Update(Left, Val);
Update(Right + 1, -Val);
return;
}
inline int Query (int pos)
{
int ans = 0;
for(int i = pos; i >= 1; i -= UB(i))
ans += a[i];
return ans;
}
} AIB;
static inline void Read ()
{
ios_base :: sync_with_stdio(false);
cin.tie(nullptr);
freopen("ograzi.in", "r", stdin);
freopen("ograzi.out", "w", stdout);
N = InParser :: Int(), M = InParser :: Int();
W = InParser :: Int(), H = InParser :: Int();
for(int i = 1; i <= N; ++i)
{
int X1 = InParser :: Int(), Y1 = InParser :: Int();
int X2 = X1 + W, Y2 = Y1 + H;
Max = max(Max, (Y2 + 1));
MIN = min(MIN, X1);
MAX = max(MAX, X2);
V[X1].push_back({BEGIN, Y1, Y2});
V[X2].push_back({END, Y1, Y2});
}
for(int i = 1; i <= M; ++i)
{
int X = InParser :: Int(), Y1 = InParser :: Int();
Max = max(Max, (Y1 + 1));
MIN = min(MIN, X);
MAX = max(MAX, X);
V[X].push_back({QUERY, Y1, Y1});
}
return;
}
auto cmp = [] (Event A, Event B)
{
if(A.Type < B.Type)
return 1;
return 0;
};
static inline void Solve ()
{
int ans = 0;
for(int X = MIN; X <= MAX; ++X)
if(!V[X].empty())
{
sort(V[X].begin(), V[X].end(), cmp);
for(auto it : V[X])
if(it.Type == BEGIN)
AIB.Go(it.Y1, it.Y2, 1);
else if(it.Type == END)
{
if(X == MAX)
break;
AIB.Go(it.Y1, it.Y2, -1);
}
else
{
if(AIB.Query(it.Y1))
++ans;
}
}
printf("%d\n", ans);
return;
}
int main()
{
Read();
Solve();
return 0;
}