#ifdef LOCAL
#define _GLIBCXX_DEBUG
#endif

#include <cassert>
#include <cstring>
#include <cstdint>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <string>
#include <random>
#include <queue>

using namespace std;


#ifdef LOCAL
#define eprintf(...) fprintf(stderr,__VA_ARGS__)
clock_t __my_start_clock = clock();
#else
#define eprintf(...)
#endif

#define TIMESTAMP(x) eprintf("["#x"] Time : %.3lf s.\n", (clock() - __my_start_clock)*1.0/CLOCKS_PER_SEC)
#define TIMESTAMPf(x, ...) eprintf("[" x "] Time : %.3lf s.\n", __VA_ARGS__, (clock() - __my_start_clock)*1.0/CLOCKS_PER_SEC)

#ifdef LOCAL
#define DBG if (1) cerr
#else
#define DBG if (0) cerr
#endif

template<typename T>
bool update_max(T &a, T b) {
  if (a <= b) {
    a = b;
    return true;
  } else {
    return false;
  }
}

template<typename T>
bool update_min(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  } else {
    return false;
  }
}

template<typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << "[";
  for (const auto &x : v) {
    out << x << " ";
  }
  out << "]";
  return out;
}

#ifdef LOCAL
static struct __timestamper {
  string what;
  __timestamper(const char* what) : what(what){};
  __timestamper(const string& what) : what(what){};
  ~__timestamper(){
    TIMESTAMPf("%s", what.data());
  }
} __TIMESTAMPER("end");
#else
struct __timestamper {
};
#endif

using ll = long long;

const int P = int(1e9) + 7;

int sum(int a, int b) {
  a += b;
  if (a >= P) {
    a -= P;
  }
  return a;
}

int &add(int &a, int b) {
  return a = sum(a, b);
}

int diff(int a, int b) {
  a -= b;
  if (a < 0) {
    a += P;
  }
  return a;
}

int prod(int a, int b) {
  return ll(a) * b % P;
}

int power(int a, int n) {
  int b = 1;
  while (n) {
    if (n & 1) {
      b = prod(a, b);
    }
    a = prod(a, a);
    n /= 2;
  }
  return b;
}

int inv(int a) {
  return power(a, P - 2);
}

int divide(int a, int b) {
  return prod(a, inv(b));
}

using pii = std::pair<int, int>;

#ifdef LOCAL
//#define GEN
#define INTERACT
#endif

struct Point {
  int x, y;

  int distTo(const Point &p) const {
    return abs(x - p.x) + abs(y - p.y);
  }
};

struct Quest {
  Point p;
  int t;
};

struct State {
  int time;
  int cnt;
  int mask;

  bool operator < (const State &st) const {
    if (time != st.time) {
      return time < st.time;
    }
    if (cnt != st.cnt) {
      return cnt < st.cnt;
    }
    return mask < st.mask;
  }
};

const int INF = (1 << 30);

bool solve() {
  int n, m;
  if (scanf("%d%d", &n, &m) != 2) {
    return false;
  }

  vector<Point> tower(n);
  for (int i = 0; i < n; ++i) {
    scanf("%d%d", &tower[i].x, &tower[i].y);
  }
  vector<Quest> quest(m);
  for (int i = 0; i < m; ++i) {
    scanf("%d%d%d", &quest[i].p.x, &quest[i].p.y, &quest[i].t);
  }

  sort(quest.begin(), quest.end(), [](const Quest &q1, const Quest &q2) {
    return q1.t < q2.t;
  });

  set<State> q;
  vector<vector<int>> dpTowers(1 << n, vector<int>(m + 1, INF));
  vector<vector<int>> dpLastQuest(m + 1, vector<int>(1 << n, -1));

  auto updateDpTowers = [&](int cnt, int mask, int minT) {
    if (dpTowers[mask][cnt] > minT) {
      eprintf("update mask %d cnt %d = dpTowers %d\n", mask, cnt, minT);
      q.erase({dpTowers[mask][cnt], cnt, mask});
      dpTowers[mask][cnt] = minT;
      q.insert({dpTowers[mask][cnt], cnt, mask});
    }
  };

  auto calcMinDist = [&](int mask, const Point &p) {
    int minD = INF;
    for (int k = 0; k < n; ++k) {
      if (mask & (1 << k)) {
        minD = min(minD, p.distTo(tower[k]));
      }
    }
    return minD;
  };

  auto updateDpLastQuest = [&](int num, int mask, int cnt) {
    if (dpLastQuest[num][mask] < cnt) {
      dpLastQuest[num][mask] = cnt;
    }
  };

  for (int i = 0; i < n; ++i) {
    updateDpTowers(0, (1 << i), 0);
  }

  for (int last = 0; last < m; ++last) {
    while (!q.empty()) {
      auto it = q.begin();
      auto cur = *it;
      if (cur.time >= quest[last].t) {
        break;
      }

      eprintf("mask %d cnt %d = dpTowers %d\n", cur.mask, cur.cnt, cur.time);

      q.erase(it);
      for (int j = 0; j < n; ++j) {
        if (cur.mask & (1 << j)) continue;
        auto minD = calcMinDist(cur.mask, tower[j]);
        updateDpTowers(cur.cnt, cur.mask | (1 << j), cur.time + minD);
      }
    }

    updateDpLastQuest(last, 0, 1);
    for (int prev_last = 0; prev_last < last; ++prev_last) {
      if (quest[prev_last].t + quest[prev_last].p.distTo(quest[last].p) <= quest[last].t) {
        for (int mask = 0; mask < (1 << n); ++mask) {
          if (dpLastQuest[prev_last][mask] != -1) {
            updateDpLastQuest(last, mask, dpLastQuest[prev_last][mask] + 1);
          }
        }
      }
    }
    for (int mask = 1; mask < (1 << n); ++mask) {
      int minD = calcMinDist(mask, quest[last].p);
      auto it = upper_bound(dpTowers[mask].begin(), dpTowers[mask].end(), quest[last].t - minD);
      if (it == dpTowers[mask].begin()) {
        continue;
      }
      it--;
      updateDpLastQuest(last, mask, (it - dpTowers[mask].begin()) + 1);

//      assert(is_sorted(dpTowers[mask].begin(), dpTowers[mask].end()));
//
//      int cnt = -1;
//      while (cnt < m && dpTowers[mask][cnt + 1] + minD <= quest[last].t) {
//        cnt++;
//      }
//      if (cnt != -1) {
////        assert(it - dpTowers[mask].begin() == cnt);
//        updateDpLastQuest(last, mask, cnt + 1);
//      }
    }
    for (int mask = 0; mask < (1 << n); ++mask) {
      if (dpLastQuest[last][mask] != -1) {
        eprintf("last %d mask %d = dpLastQuest %d\n", last, mask, dpLastQuest[last][mask]);
        for (int j = 0; j < n; ++j) {
          if (mask & (1 << j)) {
            updateDpTowers(dpLastQuest[last][mask], mask, quest[last].t);
          } else {
            updateDpTowers(dpLastQuest[last][mask], mask | (1 << j), quest[last].t + quest[last].p.distTo(tower[j]));
          }
        }
      }
    }
  }

  int ans = 0;
  for (int i = 0; i < m; ++i) {
    for (int mask = 0; mask < (1 << n); ++mask) {
      ans = max(ans, dpLastQuest[i][mask]);
    }
  }
  printf("%d\n", ans);

  return true;
}

int main() {
#ifdef LOCAL
  freopen("../sample.txt", "r", stdin);
#endif

#ifdef GEN
  int tt = 100;
#else
  int tt = -1;
//  scanf("%d", &tt);
#endif
  for (int ii = 1; ii <= tt || tt == -1; ++ii) {
    if (!solve()) {
      break;
    }
    TIMESTAMPf("Case #%d", ii);
  }
  return 0;
}
