#include<cstdio>
#include<vector>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
using namespace std;

namespace Elaina{
    // #define NDEBUG
    #include<cassert>

    #define rep(i, l, r) for(int i=(l), i##_end_=(r); i<=i##_end_; ++i)
    #define drep(i, l, r) for(int i=(l), i##_end_=(r); i>=i##_end_; --i)
    #define fi first
    #define se second
    #define mp(a, b) make_pair(a, b)
    #define Endl putchar('\n')
    #define mmset(a, b) memset(a, b, sizeof a)
    typedef long long ll;
    typedef pair<int, int> pii;
    typedef pair<ll, ll> pll;
    template<class T>inline T fab(T x){ return x<0? -x: x; }
    template<class T>inline void getmin(T& x, const T rhs){ x=min(x, rhs); }
    template<class T>inline void getmax(T& x, const T rhs){ x=max(x, rhs); }
    template<class T>inline T readin(T x){
        x=0; int f=0; char c;
        while((c=getchar())<'0' || '9'<c) if(c=='-') f=1;
        for(x=(c^48); '0'<=(c=getchar()) && c<='9'; x=(x<<1)+(x<<3)+(c^48));
        return f? -x: x;
    }
    template<class T>inline void writc(T x, char s='\n'){
        static int fwri_sta[1005], fwri_ed=0;
        if(x<0) putchar('-'), x=-x;
        do fwri_sta[++fwri_ed]=x%10, x/=10; while(x);
        while(putchar(fwri_sta[fwri_ed--]^48), fwri_ed);
        putchar(s);
    }
}
using namespace Elaina;


const int maxm=100;
const int maxs=1<<14;
const int maxn=14;
const int inf=0x3f3f3f3f;
const int maxt=1e9;

struct spot{
    int x, y, t;
    spot(){}
    spot(int X, int Y, int T): x(X), y(Y), t(T){}
    inline int operator <(const spot rhs) const{
        return t<rhs.t;
    }
}a[maxm+maxn+5];

int n, m, U;

inline void input(){
    n=readin(1), m=readin(1), U=1<<n;
    int x, y, t;
    for(int i=0; i<n; ++i){
        x=readin(1), y=readin(1);
        a[i]=spot(x, y, -1);
    }
    for(int i=n; i<n+m; ++i){
        x=readin(1), y=readin(1), t=readin(1);
        a[i]=spot(x, y, t);
    }
    sort(a+n, a+n+m);
}

inline int getdis(int i, int j){
    return fab(a[i].x-a[j].x)+fab(a[i].y-a[j].y);
}

int w[maxs+5][maxn+maxm+5];

inline void getw(){
    for(int i=0; i<U; ++i){
        for(int j=0; j<n+m; ++j){
            w[i][j]=inf;
            for(int k=0; k<n; ++k) if((i>>k)&1)
                getmin(w[i][j], getdis(k, j));
        }
    }
}

/**
 * @brief the set of revived tower is @p i , and have finished @p j tasks, now is at a tower, the minimum time
*/
int f[maxs+5][maxn+maxm+5];
/**
 * @brief the set of rivived tower is @p i , and now is at landmark(except tower) @p j , the maximum number of finished tasks
*/
int g[maxs+5][maxn+maxm+5];

inline void transDP(){
    mmset(f, 0x3f); mmset(g, -1);
    // spawn at a tower
    for(int i=0; i<n; ++i) f[1<<i][0]=0;
    // spawn at a landmark
    for(int i=n; i<n+m; ++i) g[0][i]=1;
    int ans=0;
    for(int s=0; s<U; ++s){
        for(int j=0; j<=m; ++j) if(f[s][j]<=maxt){
            // from tower set to tower @p i
            for(int i=0; i<n; ++i) if(!((s>>i)&1))
                getmin(f[s^(1<<i)][j], f[s][j]+w[s][i]);
            // from tower set to landmark @p i
            for(int i=n; i<n+m; ++i) if(f[s][j]+w[s][i]<=a[i].t)
                getmax(g[s][i], j+1);
        }
        for(int j=n; j<n+m; ++j) if(g[s][j]>=0){
            // from landmark @p j to tower @p i
            for(int i=0; i<n; ++i) if(!((s>>i)&1))
                getmin(f[s^(1<<i)][g[s][j]], a[j].t+min(w[s][i], getdis(j, i)));
            // from landmark @p j to landmark @p i
            for(int i=j+1; i<n+m; ++i)
                if(a[j].t+min(getdis(j, i), w[s][i])<=a[i].t)
                getmax(g[s][i], g[s][j]+1);
            ans=max(ans, g[s][j]);
        }
    }
    writc(ans);
}

signed main(){
    input();
    getw();
    transDP();
    return 0;
}