#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;
  });

  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;
  };

  vector<vector<int>> distToTower(1 << n, vector<int>(n, INF));
  vector<vector<int>> distToQuest(1 << n, vector<int>(m, INF));
  for (int mask = 1; mask < (1 << n); ++mask) {
    for (int i = 0; i < n; ++i) {
      if (mask & (1 << i)) { continue; }
      distToTower[mask][i] = calcMinDist(mask, tower[i]);
    }
    for (int i = 0; i < m; ++i) {
      distToQuest[mask][i] = calcMinDist(mask, quest[i].p);
    }
  }


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

  auto updateDpTowers = [&](int active_tower_mask, int done_quests, int min_time) {
    if (dpTowers[active_tower_mask][done_quests] > min_time) {
      dpTowers[active_tower_mask][done_quests] = min_time;
    }
  };

  auto updateDpLastQuest = [&](int active_mask_tower, int last_quest, int done_quests) {
    if (dpLastQuest[active_mask_tower][last_quest] < done_quests) {
      dpLastQuest[active_mask_tower][last_quest] = done_quests;
    }
  };

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

  for (int i = 0; i < m; ++i) {
    updateDpLastQuest(0, i, 1);
  }

  for (int active_tower_mask = 0; active_tower_mask < (1 << n); ++active_tower_mask) {
    for (int done_quests = 0; done_quests <= m; ++done_quests) {
      if (dpTowers[active_tower_mask][done_quests] == INF) { continue; }
      eprintf("mask %d done %d => time %d\n", active_tower_mask, done_quests, dpTowers[active_tower_mask][done_quests]);
      for (int new_tower = 0; new_tower < n; ++new_tower) {
        if (active_tower_mask & (1 << new_tower)) { continue; }
        updateDpTowers(active_tower_mask | (1 << new_tower), done_quests,
                       dpTowers[active_tower_mask][done_quests] + distToTower[active_tower_mask][new_tower]);
      }
      for (int last_quest = 0; last_quest < m; ++last_quest) {
        if (dpTowers[active_tower_mask][done_quests] + distToQuest[active_tower_mask][last_quest] <= quest[last_quest].t) {
          updateDpLastQuest(active_tower_mask, last_quest, done_quests + 1);
        }
      }
    }

    for (int last_quest = 0; last_quest < m; ++last_quest) {
      if (dpLastQuest[active_tower_mask][last_quest] < 0) { continue; }
      eprintf("mask %d last %d => done %d\n", active_tower_mask, last_quest, dpLastQuest[active_tower_mask][last_quest]);
      for (int new_tower = 0; new_tower < n; ++new_tower) {
        if (active_tower_mask & (1 << new_tower)) { continue; }
        auto need_time = min(distToTower[active_tower_mask][new_tower], quest[last_quest].p.distTo(tower[new_tower]));
        updateDpTowers(active_tower_mask | (1 << new_tower), dpLastQuest[active_tower_mask][last_quest],
                       quest[last_quest].t + need_time);
      }
      for (int next_quest = last_quest + 1; next_quest < m; ++next_quest) {
        auto need_time = min(distToQuest[active_tower_mask][next_quest], quest[last_quest].p.distTo(quest[next_quest].p));
        if (quest[last_quest].t + need_time <= quest[next_quest].t) {
          updateDpLastQuest(active_tower_mask, next_quest, dpLastQuest[active_tower_mask][last_quest] + 1);
        }
      }
    }
  }

  int ans = 0;
  for (int active_tower_mask = 0; active_tower_mask < (1 << n); ++active_tower_mask) {
    for (int last_quest = 0; last_quest < m; ++last_quest) {
      ans = max(ans, dpLastQuest[active_tower_mask][last_quest]);
    }
  }
  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;
}
