#include <bits/stdc++.h>
using namespace std;
const double EPS = 1e-10;
const double PI = acos(-1.0);
template <class T>
T gcd(T a, T b) {
  for (T c; b; c = a, a = b, b = c % b)
    ;
  return a;
}
template <class T>
void out(const vector<T> &a) {
  for (int i = 0; i < ((int)(a).size()); ++i) cout << a[i] << " ";
  cout << endl;
}
int countbit(int n) { return n == 0 ? 0 : 1 + countbit(n & (n - 1)); }
const int d8[8][2] = {{1, 0}, {-1, 0},  {0, 1},  {0, -1},
                      {1, 1}, {-1, -1}, {1, -1}, {-1, 1}};
const int d4[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
inline long long cross(const complex<long long> &a,
                       const complex<long long> &b) {
  return (conj(a) * b).imag();
}
inline long long cross(const complex<long long> &a, const complex<long long> &b,
                       const complex<long long> &c) {
  return cross(b - a, c - a);
}
inline long long dot(const complex<long long> &a, const complex<long long> &b) {
  return (conj(a) * b).real();
}
inline bool which_part(const complex<long long> &p) {
  return p.imag() > 0 || p.imag() == 0 && p.real() > 0;
}
namespace std {
bool operator<(const complex<long long> &a, const complex<long long> &b) {
  int flag_a = which_part(a);
  int flag_b = which_part(b);
  if (flag_a != flag_b) return flag_a < flag_b;
  return cross(a, b) > 0;
}
}  // namespace std
struct node {
  complex<long long> p;
  int color;
};
struct cmp {
  complex<long long> p;
  cmp(const complex<long long> &p) : p(p) {}
  bool operator()(const node &a, const node &b) { return a.p - p < b.p - p; }
};
node a[1000], b[2000];
int main() {
  int n, m;
  scanf("%d %d", &n, &m);
  for (int i = 0; i < n; ++i) {
    long long x, y;
    scanf("%I64d %I64d", &x, &y);
    a[i].p = complex<long long>(x, y);
    a[i].color = 0;
  }
  for (int i = 0; i < m; ++i) {
    long long x, y;
    scanf("%I64d %I64d", &x, &y);
    a[n + i].p = complex<long long>(x, y);
    a[n + i].color = 1;
  }
  long long ret = 0;
  for (int i = 0; i < n; ++i) {
    int L = 0;
    for (int j = i + 1; j < n + m; ++j) {
      if (j == i) continue;
      b[L++] = a[j];
    }
    sort(b, b + L, cmp(a[i].p));
    for (int j = 0; j < L; ++j) b[L + j] = b[j];
    int u;
    for (u = 1; cross(a[i].p, b[0].p, b[u].p) > 0; ++u)
      ;
    for (int j = 0; j < L; ++j) {
      if (b[j].color == 1) continue;
      bool found = false;
      complex<long long> p;
      for (u = max(u, j + 1); cross(a[i].p, b[j].p, b[u].p) > 0; ++u)
        ;
      for (int k = j + 1; k != u; ++k) {
        if (b[k].color == 1) {
          if (!found || cross(b[j].p, p, b[k].p) > 0) {
            found = true;
            p = b[k].p;
          }
        } else {
          if (!found || cross(b[j].p, p, b[k].p) > 0) {
            ++ret;
          }
        }
      }
    }
  }
  printf("%I64d\n", ret);
  return 0;
}
