#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
#define DEBUG
#ifdef DEBUG
#define debug(...) __f(#__VA_ARGS__, __VA_ARGS__)
	template <typename Arg1>
	void __f(const char* name, Arg1&& arg1){
		cerr << name << " : " << arg1 << std::endl;
	}
	template <typename Arg1, typename... Args>
	void __f(const char* names, Arg1&& arg1, Args&&... args){
		const char* comma = strchr(names + 1, ','); cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
	}
#else
#define debug(...)
#endif
#define FOR(i,a,b) 	for(int i=a;i<b;++i)
#define RFOR(i,a,b) 	for(int i=a;i>=b;--i)
#define ln 		"\n"
#define mp make_pair
#define pb push_back
#define sz(a)	ll(a.size())
#define F first
#define S second
#define all(c)	c.begin(),c.end()
#define trace(c,x) for(auto &x:c)
#define pii pair<ll,ll>
typedef long long ll;
typedef long double ld;
typedef	priority_queue<pii,std::vector<pii>,greater<pii> > revpr;

typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> pbds;
// ordered_set X
//K-th smallest
//*X.find_by_order(k-1)
//NO OF ELEMENTS < A
//X.order_of_key(A)

const int L=1e6+7;
int m, d, mod = 1e9+7;
string a, b;
int lena, lenb;
ll dp[2002][2002][2][2][2];
ll solve(int sofar,int i, int gr,int fl, int cur)
{
	ll ans = 0;
	if(i > lenb)return 0;
	sofar%=m;
	int tr = gr, tl = fl ;
	if(i == lenb)
	{
		if(sofar == 0 && gr && fl)return 1LL;
		return 0LL;
	}
	if(dp[sofar][i][gr][fl][cur] != -1)return dp[sofar][i][gr][fl][cur];
	if(cur&1)
	{
		if(d < b[i] - '0')tl = 1;
		if(!fl && d > b[i] - '0')return 0LL;
		if(!gr && d < a[i] - '0')return 0LL;
		if(d > (a[i]-'0'))tr = 1;
		ans = (ans%mod + solve(sofar*10+d, i + 1, tr,tl, 1 - cur)%mod)%mod;
		ans %= mod;
	}
	else
	{
		FOR(j,0,10)
		{
			tl = fl, tr = gr;
			if(!fl && j > b[i]-'0')continue;
			if(!gr && j < a[i]-'0')continue;
			if(j == d)continue;
			if(j>a[i]-'0')tr = 1;
			if(j<b[i] - '0')tl = 1;
			ans = (ans%mod +  solve((sofar*10)+j, i + 1, tr,tl, 1-cur)%mod)%mod;
		}
	}
	return dp[sofar][i][gr][fl][cur] = ans;
}
int main()
{
		ios_base::sync_with_stdio(false);
	 	cin.tie(NULL);
	 	string ta = "";
	 	cin >> m >> d;
	 	cin >> ta >> b;
	 	lena = ta.length();
	 	lenb = b.length();
	 	FOR(i,0,2001)FOR(j,0,2001)FOR(k,0,2)FOR(l,0,2)FOR(z,0,2)dp[i][j][k][l][z]=-1;
	 	a = "";
	 	FOR(i,0,lenb-lena)a+="0";
	 	a += ta;
	 	ll tmp = solve(0,0,0,0,0);
	 	int f =0, vl = 0;
	 	for (int i = 1; i < lena; i += 2)
	 	{
	 		if(ta[i]-'0' != d)
	 		{
	 			f = 1;
	 			break;
	 		}
	 	}
	 	FOR(i,0,lena)
	 		vl = (vl*10 + (ta[i] - '0'))%m;

	 	for (int i = 0; i < lena; i += 2)
	 	{
	 		if(ta[i]-'0' == d)
	 		{
	 			f = 1;
	 			break;
	 		}
	 	}
	 	if(!f && !vl)tmp++;
	 	vl = 0;
	 	for (int i = 1; i < lenb; i += 2)
	 	{
	 		if(b[i]-'0' != d)
	 		{
	 			f = 1;
	 			break;
	 		}
	 	}
	 	FOR(i,0,lenb)
	 		vl = (vl*10 + (b[i] - '0'))%m;
	 	for (int i = 0; i < lenb; i += 2)
	 	{
	 		if(b[i]-'0' == d)
	 		{
	 			f = 1;
	 			break;
	 		}
	 	}
	 	if(!f && ta != b && !vl)tmp++;
	 	cout<<tmp%mod;
		return 0;
}


#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
#define DEBUG
#ifdef DEBUG
#define debug(...) __f(#__VA_ARGS__, __VA_ARGS__)
	template <typename Arg1>
	void __f(const char* name, Arg1&& arg1){
		cerr << name << " : " << arg1 << std::endl;
	}
	template <typename Arg1, typename... Args>
	void __f(const char* names, Arg1&& arg1, Args&&... args){
		const char* comma = strchr(names + 1, ','); cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
	}
#else
#define debug(...)
#endif
#define FOR(i,a,b) 	for(int i=a;i<b;++i)
#define RFOR(i,a,b) 	for(int i=a;i>=b;--i)
#define ln 		"\n"
#define mp make_pair
#define pb push_back
#define sz(a)	ll(a.size())
#define F first
#define S second
#define all(c)	c.begin(),c.end()
#define trace(c,x) for(auto &x:c)
#define pii pair<ll,ll>
typedef long long ll;
typedef long double ld;
typedef	priority_queue<pii,std::vector<pii>,greater<pii> > revpr;

typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> pbds;
// ordered_set X
//K-th smallest
//*X.find_by_order(k-1)
//NO OF ELEMENTS < A
//X.order_of_key(A)

const int L=1e6+7;
int m, d, mod = 1e9+7;
string a, b;
int lena, lenb;
int dp[2002][2002][2][2][2];
int solve(int sofar,int i, int gr,int fl, int cur)
{
	int ans = 0;
	if(i > lenb)return 0;
	sofar%=m;
	int tr = gr, tl = fl ;
	if(i == lenb)
	{
		if(sofar == 0 && gr && fl)return 1;
		return 0;
	}
	if(dp[sofar][i][gr][fl][cur] != -1)return dp[sofar][i][gr][fl][cur];
	if(cur&1)
	{
		if(d < b[i] - '0')tl = 1;
		if(!fl && d > b[i] - '0')return 0;
		if(!gr && d < a[i] - '0')return 0;
		if(d > (a[i]-'0'))tr = 1;
		ans = (ans%mod + solve(sofar*10+d, i + 1, tr,tl, 1 - cur)%mod)%mod;
	}
	else
	{
		FOR(j,0,10)
		{
			tl = fl, tr = gr;
			if(!fl && j > b[i]-'0')continue;
			if(!gr && j < a[i]-'0')continue;
			if(j == d)continue;
			if(j>a[i]-'0')tr = 1;
			if(j<b[i] - '0')tl = 1;
			ans = (ans%mod +  solve((sofar*10)+j, i + 1, tr,tl, 1-cur)%mod)%mod;
		}
	}
	return dp[sofar][i][gr][fl][cur] = ans;
}
int main()
{
		ios_base::sync_with_stdio(false);
	 	cin.tie(NULL);
	 	string ta = "";
	 	cin >> m >> d;
	 	cin >> ta >> b;
	 	lena = ta.length();
	 	lenb = b.length();
	 	FOR(i,0,2001)FOR(j,0,2001)FOR(k,0,2)FOR(l,0,2)FOR(z,0,2)dp[i][j][k][l][z]=-1;
	 	a = "";
	 	FOR(i,0,lenb-lena)a+="0";
	 	a += ta;
	 	int tmp = solve(0,0,0,0,0);
	 	int f =0, vl = 0;
	 	for (int i = 1; i < lena; i += 2)
	 	{
	 		if(ta[i]-'0' != d)
	 		{
	 			f = 1;
	 			break;
	 		}
	 	}
	 	FOR(i,0,lena)
	 		vl = (vl*10 + (ta[i] - '0'))%m;

	 	for (int i = 0; i < lena; i += 2)
	 	{
	 		if(ta[i]-'0' == d)
	 		{
	 			f = 1;
	 			break;
	 		}
	 	}
	 	if(!f && !vl)tmp++;
	 	vl = 0, f=0;
	 	for (int i = 1; i < lenb; i += 2)
	 	{
	 		if(b[i]-'0' != d)
	 		{
	 			f = 1;
	 			break;
	 		}
	 	}
	 	FOR(i,0,lenb)
	 		vl = (vl*10 + (b[i] - '0'))%m;
	 	for (int i = 0; i < lenb; i += 2)
	 	{
	 		if(b[i]-'0' == d)
	 		{
	 			f = 1;
	 			break;
	 		}
	 	}
	 	if(!f && ta != b && !vl)tmp++;
	 	cout<<tmp%mod;
		return 0;
}


#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
#define DEBUG
#ifdef DEBUG
#define debug(...) __f(#__VA_ARGS__, __VA_ARGS__)
	template <typename Arg1>
	void __f(const char* name, Arg1&& arg1){
		cerr << name << " : " << arg1 << std::endl;
	}
	template <typename Arg1, typename... Args>
	void __f(const char* names, Arg1&& arg1, Args&&... args){
		const char* comma = strchr(names + 1, ','); cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
	}
#else
#define debug(...)
#endif
#define FOR(i,a,b) 	for(int i=a;i<b;++i)
#define RFOR(i,a,b) 	for(int i=a;i>=b;--i)
#define ln 		"\n"
#define mp make_pair
#define pb push_back
#define sz(a)	ll(a.size())
#define F first
#define S second
#define all(c)	c.begin(),c.end()
#define trace(c,x) for(auto &x:c)
#define pii pair<ll,ll>
typedef long long ll;
typedef long double ld;
typedef	priority_queue<pii,std::vector<pii>,greater<pii> > revpr;

typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> pbds;
// ordered_set X
//K-th smallest
//*X.find_by_order(k-1)
//NO OF ELEMENTS < A
//X.order_of_key(A)

const int L=1e6+7;
int m, d, mod = 1e9+7;
string a, b;
int lena, lenb;
ll dp[2002][2002][2][2];
ll solve(int sofar,int i, int gr, int cur)
{
	ll ans = 0;
	if(i > lenb)return 0;
	// debug(i,num);
	sofar%=m;
	if(i == lenb)
	{
		// debug(i,num, gr,sofar);
		if(sofar%m == 0 && gr)return 1LL;
		return 0LL;
	}
	if(dp[sofar][i][gr][cur] != -1)return dp[sofar][i][gr][cur];
	if(cur&1)
	{
		sofar*=10;
		sofar+=d;
		sofar%=m;
		if(d > a[i]-'0')gr = 1;
		ans += solve(sofar*10+d, i + 1, gr, 1 - cur);
		ans %= m;
	}
	else
	{
		int f = gr;
		FOR(j,a[i]-'0', 10)
		{
			if(j == d)continue;
			if(j>a[i]-'0')gr = 1;
			ans += solve(((sofar*10)+j)%m, i + 1, gr, 1-cur);
			ans %= mod;
		}
		if(f)
		{
			RFOR(j,a[i]-'0'-1,0)
			{
				if(j == d)continue;
				ans += solve(((sofar*10)+j)%m, i + 1, gr, 1-cur);
				ans %= mod;
			}
		}
	}
	return dp[sofar][i][gr][cur] = ans;
}
int main()
{
		ios_base::sync_with_stdio(false);
	 	cin.tie(NULL);
	 	string ta = "";
	 	cin >> m >> d;
	 	cin >> ta >> b;
	 	lena = ta.length();
	 	lenb = b.length();
	 	FOR(i,0,2001)FOR(j,0,2001)FOR(k,0,2)FOR(l,0,2)dp[i][j][k][l]=-1;
	 	a = "";
	 	FOR(i,0,lenb-lena)a+="0";
	 	a += ta;
	 	cout<<solve(0,0,0,0);
		return 0;
}


#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
#define DEBUG
#ifdef DEBUG
#define debug(...) __f(#__VA_ARGS__, __VA_ARGS__)
	template <typename Arg1>
	void __f(const char* name, Arg1&& arg1){
		cerr << name << " : " << arg1 << std::endl;
	}
	template <typename Arg1, typename... Args>
	void __f(const char* names, Arg1&& arg1, Args&&... args){
		const char* comma = strchr(names + 1, ','); cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
	}
#else
#define debug(...)
#endif
#define FOR(i,a,b) 	for(int i=a;i<b;++i)
#define RFOR(i,a,b) 	for(int i=a;i>=b;--i)
#define ln 		"\n"
#define mp make_pair
#define pb push_back
#define sz(a)	ll(a.size())
#define F first
#define S second
#define all(c)	c.begin(),c.end()
#define trace(c,x) for(auto &x:c)
#define pii pair<ll,ll>
typedef long long ll;
typedef long double ld;
typedef	priority_queue<pii,std::vector<pii>,greater<pii> > revpr;

typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> pbds;
// ordered_set X
//K-th smallest
//*X.find_by_order(k-1)
//NO OF ELEMENTS < A
//X.order_of_key(A)

const int L=1e6+7;
int m, d, mod = 1e9+7;
string a, b;
int lena, lenb;
ll dp[2002][2002][2][2][2];
ll solve(int sofar,int i, int gr,int fl, int cur)
{
	ll ans = 0;
	if(i > lenb)return 0;
	sofar%=m;
	int tr = gr, tl = fl ;
	if(i == lenb)
	{
		if(sofar == 0 && gr && fl)return 1LL;
		return 0LL;
	}
	if(dp[sofar][i][gr][fl][cur] != -1)return dp[sofar][i][gr][fl][cur];
	if(cur&1)
	{
		if(d < b[i] - '0')tl = 1;
		if(!fl && d > b[i] - '0')return 0LL;
		if(!gr && d < a[i] - '0')return 0LL;
		if(d > (a[i]-'0'))tr = 1;
		ans = (ans%mod + solve(sofar*10+d, i + 1, tr,tl, 1 - cur)%mod)%mod;
		ans %= mod;
	}
	else
	{
		FOR(j,0,10)
		{
			tl = fl, tr = gr;
			if(!fl && j > b[i]-'0')continue;
			if(!gr && j < a[i]-'0')continue;
			if(j == d)continue;
			if(j>a[i]-'0')tr = 1;
			if(j<b[i] - '0')tl = 1;
			ans = (ans%mod +  solve((sofar*10)+j, i + 1, tr,tl, 1-cur)%mod)%mod;
		}
	}
	return dp[sofar][i][gr][fl][cur] = ans;
}
int main()
{
		ios_base::sync_with_stdio(false);
	 	cin.tie(NULL);
	 	string ta = "";
	 	cin >> m >> d;
	 	cin >> ta >> b;
	 	lena = ta.length();
	 	lenb = b.length();
	 	FOR(i,0,2001)FOR(j,0,2001)FOR(k,0,2)FOR(l,0,2)FOR(z,0,2)dp[i][j][k][l][z]=-1;
	 	a = "";
	 	FOR(i,0,lenb-lena)a+="0";
	 	a += ta;
	 	ll tmp = solve(0,0,0,0,0);
	 	int f =0, vl = 0;
	 	for (int i = 1; i < lena; i += 2)
	 	{
	 		if(ta[i]-'0' != d)
	 		{
	 			f = 1;
	 			break;
	 		}
	 	}
	 	FOR(i,0,lena)
	 		vl = (vl*10 + (ta[i] - '0'))%m;

	 	for (int i = 0; i < lena; i += 2)
	 	{
	 		if(ta[i]-'0' == d)
	 		{
	 			f = 1;
	 			break;
	 		}
	 	}
	 	// debug(f,vl);
	 	if(!f && !vl)tmp++;
	 	vl = 0;
	 	f=0;
	 	for (int i = 1; i < lenb; i += 2)
	 	{
	 		if(b[i]-'0' != d)
	 		{
	 			f = 1;
	 			break;
	 		}
	 	}
	 	FOR(i,0,lenb)
	 		vl = (vl*10 + (b[i] - '0'))%m;
	 	for (int i = 0; i < lenb; i += 2)
	 	{
	 		if(b[i]-'0' == d)
	 		{
	 			f = 1;
	 			break;
	 		}
	 	}
	 	// debug(f,ta,b,vl);
	 	if(!f && ta != b && !vl)tmp++;
	 	cout<<tmp%mod;
		return 0;
}


#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
#define DEBUG
#ifdef DEBUG
#define debug(...) __f(#__VA_ARGS__, __VA_ARGS__)
	template <typename Arg1>
	void __f(const char* name, Arg1&& arg1){
		cerr << name << " : " << arg1 << std::endl;
	}
	template <typename Arg1, typename... Args>
	void __f(const char* names, Arg1&& arg1, Args&&... args){
		const char* comma = strchr(names + 1, ','); cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
	}
#else
#define debug(...)
#endif
#define FOR(i,a,b) 	for(int i=a;i<b;++i)
#define RFOR(i,a,b) 	for(int i=a;i>=b;--i)
#define ln 		"\n"
#define mp make_pair
#define pb push_back
#define sz(a)	ll(a.size())
#define F first
#define S second
#define all(c)	c.begin(),c.end()
#define trace(c,x) for(auto &x:c)
#define pii pair<ll,ll>
typedef long long ll;
typedef long double ld;
typedef	priority_queue<pii,std::vector<pii>,greater<pii> > revpr;

typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> pbds;
// ordered_set X
//K-th smallest
//*X.find_by_order(k-1)
//NO OF ELEMENTS < A
//X.order_of_key(A)

const int L=1e6+7;
int m, d, mod = 1e9+7;
string a, b;
int lena, lenb;
ll dp[2002][2002][2][2][2];
ll solve(int sofar,int i, int gr,int fl, int cur)
{
	ll ans = 0;
	if(i > lenb)return 0;
	sofar%=m;
	int tr = gr, tl = fl ;
	if(i == lenb)
	{
		if(sofar == 0 && gr && fl)
		{
		// debug(i,num,fl,  gr,sofar);
			return 1LL;
		}
		return 0LL;
	}
	if(dp[sofar][i][gr][fl][cur] != -1)return dp[sofar][i][gr][fl][cur];
	if(cur&1)
	{
		if(d < b[i] - '0')tl = 1;
		if(!fl && d > b[i] - '0')return 0LL;
		if(!gr && d < a[i] - '0')return 0LL;
		if(d > (a[i]-'0'))tr = 1;
		ans += solve(sofar*10+d, i + 1, tr,tl, 1 - cur);
		ans %= m;
	}
	else
	{
		FOR(j,0,10)
		{
			tl = fl, tr = gr;
			if(!fl && j > b[i]-'0')continue;
			if(!gr && j < a[i]-'0')continue;
			if(j == d)continue;
			if(j>a[i]-'0')tr = 1;
			if(j<b[i] - '0')tl = 1;
			ans += solve((sofar*10)+j, i + 1, tr,tl, 1-cur);
			ans %= mod;
		}
	}
	return dp[sofar][i][gr][fl][cur] = ans;
}
int main()
{
		ios_base::sync_with_stdio(false);
	 	cin.tie(NULL);
	 	string ta = "";
	 	cin >> m >> d;
	 	cin >> ta >> b;
	 	lena = ta.length();
	 	lenb = b.length();
	 	FOR(i,0,2001)FOR(j,0,2001)FOR(k,0,2)FOR(l,0,2)FOR(z,0,2)dp[i][j][k][l][z]=-1;
	 	a = "";
	 	FOR(i,0,lenb-lena)a+="0";
	 	a += ta;
	 	cout<<solve(0,0,0,0,0);
		return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define ff first
#define ss second
#define endl '\n'
#define fast ios::sync_with_stdio(false); cin.tie(NULL);

/////////////////////////////////////////////

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

////////////////////////////////
const int mod = 1e9 + 7;
int m,d;
string a,b;
int dp[2000][2][2000];
int calc(int pos ,int f , int rem){

    if(pos==b.size()){

        return (rem==0);
    }

    if(dp[pos][f][rem]!=-1)
        return dp[pos][f][rem];

    long long ans = 0;

    int len;
    if(f==0)
        len = b[pos]-'0';
    else len = 9;
    if(pos&1){

        if(d < len)
            ans += calc(pos+1,1 , (rem*10 + d)%m);
        ans%=mod;

        dp[pos][f][rem] = ans;
        return ans;
    }
    for(int i = 0 ; i <= len ; ++i){

        if(i==d)
            continue;
        if(f==0 && i < len)
            ans += calc(pos+1 , 1 , (rem*10 + i)%m);
        else ans += calc(pos+1 , f , (rem*10 + i)%m);

        ans%=mod;
    }

    return dp[pos][f][rem] = ans;
}

void solve(){

    cin>>m>>d>>a>>b;

    memset(dp,-1,sizeof dp);

    int res = calc(0,0,0);

    memset(dp,-1,sizeof dp);
    b = a;
    debug(res);
    res-=calc(0,0,0);
    debug(res);
    bool ok = true;
    int val = 0;
    for(int i = 0 ; i < a.size() ; ++i){

        if(i&1 && a[i]!=d+'0')
            ok = false;

        val = val*10 + (a[i]-'0');
        val%=m;
    }
    if(ok && a.size()>1 && val==0)
        res++;
    debug(ok);
    if(res < 0)
        res+=mod;
    res%=mod;
    cout<<res<<endl;
}

signed main(){

    int t;
    t = 1;
    // cin>>t;
    while(t--)
        solve();
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define ff first
#define ss second
#define endl '\n'
#define fast ios::sync_with_stdio(false); cin.tie(NULL);

/////////////////////////////////////////////

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

////////////////////////////////
const int mod = 1e9 + 7;
int m,d;
string a,b;
int dp[2000][2][2000];
int calc(int pos ,int f , int rem){

    if(pos==b.size()){

        return (rem==0);
    }

    if(dp[pos][f][rem]!=-1)
        return dp[pos][f][rem];

    long long ans = 0;

    int len;
    if(f==0)
        len = b[pos]-'0';
    else len = 9;
    if(pos&1){

        if(d <= len)
            ans += calc(pos+1,1 , (rem*10 + d)%m);
        ans%=mod;

        dp[pos][f][rem] = ans;
        return ans;
    }
    for(int i = 0 ; i <= len ; ++i){

        if(i==d)
            continue;
        if(f==0 && i < len)
            ans += calc(pos+1 , 1 , (rem*10 + i)%m);
        else ans += calc(pos+1 , f , (rem*10 + i)%m);

        ans%=mod;
    }

    return dp[pos][f][rem] = ans;
}

void solve(){

    cin>>m>>d>>a>>b;

    memset(dp,-1,sizeof dp);

    int res = calc(0,0,0);

    memset(dp,-1,sizeof dp);
    b = a;
    debug(res);
    res-=calc(0,0,0);
    debug(res);
    bool ok = true;
    int val = 0;
    for(int i = 0 ; i < a.size() ; ++i){

        if(i&1 && a[i]!=d+'0')
            ok = false;

        val = val*10 + (a[i]-'0');
        val%=m;
    }
    if(ok && a.size()>1 && val==0)
        res++;
    debug(ok);
    cout<<res<<endl;
}

signed main(){

    int t;
    t = 1;
    // cin>>t;
    while(t--)
        solve();
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define ff first
#define ss second
#define endl '\n'
#define fast ios::sync_with_stdio(false); cin.tie(NULL);

/////////////////////////////////////////////

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

////////////////////////////////
const int mod = 1e9 + 7;
int m,d;
string a,b;
int dp[2000][2][2000];
int calc(int pos ,int f , int rem){

    if(pos==b.size()){

        return (rem==0);
    }

    if(dp[pos][f][rem]!=-1)
        return dp[pos][f][rem];

    long long ans = 0;

    int len;
    if(f==0)
        len = b[pos]-'0';
    else len = 9;
    if(pos&1){

        if(d < len)
            ans += calc(pos+1,1 , (rem*10 + d)%m);
        else if(d==len)
            ans += calc(pos+1,f, (rem*10 + d)%m);
        ans%=mod;

        dp[pos][f][rem] = ans;
        return ans;
    }
    for(int i = 0 ; i <= len ; ++i){

        if(i==d)
            continue;
        if(f==0 && i < len)
            ans += calc(pos+1 , 1 , (rem*10 + i)%m);
        else ans += calc(pos+1 , f , (rem*10 + i)%m);

        ans%=mod;
    }

    return dp[pos][f][rem] = ans;
}

void solve(){

    cin>>m>>d>>a>>b;

    memset(dp,-1,sizeof dp);

    int res = calc(0,0,0);

    memset(dp,-1,sizeof dp);
    b = a;
    debug(res);
    res-=calc(0,0,0);
    debug(res);
    bool ok = true;
    int val = 0;
    for(int i = 0 ; i < a.size() ; ++i){

        if(i&1 && a[i]!=d+'0')
            ok = false;

        val = val*10 + (a[i]-'0');
        val%=m;
    }
    if(ok && a.size()>1 && val==0)
        res++;
    debug(ok);
    if(res < 0)
        res+=mod;
    res%=mod;
    cout<<res<<endl;
}

signed main(){

    int t;
    t = 1;
    // cin>>t;
    while(t--)
        solve();
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define ff first
#define ss second
#define endl '\n'
#define fast ios::sync_with_stdio(false); cin.tie(NULL);

/////////////////////////////////////////////

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

////////////////////////////////
#define int long long
const int mod = 1e9 + 7;
int m,d;
string a,b;
int dp[2000][2][2000];
int calc(int pos ,int f , int rem){

    if(pos==b.size()){

        return (rem==0);
    }

    if(dp[pos][f][rem]!=-1)
        return dp[pos][f][rem];

    long long ans = 0;

    int len;
    if(f==0)
        len = b[pos]-'0';
    else len = 9;
    if(pos&1){

        if(d <= len)
            ans += calc(pos+1,1 , (rem*10 + d)%m);
        ans%=mod;

        dp[pos][f][rem] = ans;
        return ans;
    }
    for(int i = 0 ; i <= len ; ++i){

        if(i==d)
            continue;
        if(f==0 && i < len)
            ans += calc(pos+1 , 1 , (rem*10 + i)%m);
        else ans += calc(pos+1 , f , (rem*10 + i)%m);

        ans%=mod;
    }

    return dp[pos][f][rem] = ans;
}

void solve(){

    cin>>m>>d>>a>>b;

    memset(dp,-1,sizeof dp);

    int res = calc(0,0,0);

    memset(dp,-1,sizeof dp);
    b = a;
    debug(res);
    res-=calc(0,0,0);
    debug(res);
    bool ok = true;
    int val = 0;
    for(int i = 0 ; i < a.size() ; ++i){

        if(i&1 && a[i]!=d+'0')
            ok = false;

        val = val*10 + (a[i]-'0');
        val%=m;
    }
    if(ok && a.size()>1 && val==0)
        res++;
    debug(ok);
    cout<<res<<endl;
}

signed main(){

    int t;
    t = 1;
    // cin>>t;
    while(t--)
        solve();
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define ff first
#define ss second
#define endl '\n'
#define fast ios::sync_with_stdio(false); cin.tie(NULL);

/////////////////////////////////////////////

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

////////////////////////////////
const int mod = 1e9 + 7;
int m,d;
string a,b;
int dp[2000][2][2000];
int calc(int pos ,int f , int rem){

    if(pos==b.size()){

        return (rem==0);
    }

    if(dp[pos][f][rem]!=-1)
        return dp[pos][f][rem];

    long long ans = 0;

    int len;
    if(f==0)
        len = b[pos]-'0';
    else len = 9;
    if(pos&1){

        if(d <= len)
            ans += calc(pos+1,1 , (rem*10 + d)%m);
        ans%=mod;

        dp[pos][f][rem] = ans;
        return ans;
    }
    for(int i = 0 ; i <= len ; ++i){

        if(i==d)
            continue;
        if(f==0 && i < len)
            ans += calc(pos+1 , 1 , (rem*10 + i)%m);
        else ans += calc(pos+1 , f , (rem*10 + i)%m);

        ans%=mod;
    }

    return dp[pos][f][rem] = ans;
}

void solve(){

    cin>>m>>d>>a>>b;

    memset(dp,-1,sizeof dp);

    int res = calc(0,0,0);

    memset(dp,-1,sizeof dp);
    b = a;
    debug(res);
    res-=calc(0,0,0);
    debug(res);
    bool ok = true;
    int val = 0;
    for(int i = 0 ; i < a.size() ; ++i){

        if(i&1 && a[i]!=d+'0')
            ok = false;

        val = val*10 + (a[i]-'0');
        val%=m;
    }
    if(ok && a.size()>1 && val==0)
        res++;
    debug(ok);
    if(res < 0)
        res+=mod;
    cout<<res<<endl;
}

signed main(){

    int t;
    t = 1;
    // cin>>t;
    while(t--)
        solve();
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define ff first
#define ss second
#define endl '\n'
#define fast ios::sync_with_stdio(false); cin.tie(NULL);

/////////////////////////////////////////////

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

////////////////////////////////
const int mod = 1e9 + 7;
int m,d;
string a,b;
int dp[2000][2][2000];
int calc(int pos ,int f , int rem){

    if(pos==b.size()){

        return (rem==0);
    }

    if(dp[pos][f][rem]!=-1)
        return dp[pos][f][rem];

    long long ans = 0;

    int len;
    if(f==0)
        len = b[pos]-'0';
    else len = 9;
    if(pos&1){

        if(d <= len)
            ans += calc(pos+1,1 , (rem*10 + d)%m);
        ans%=mod;

        dp[pos][f][rem] = ans;
        return ans;
    }
    for(int i = 0 ; i <= len ; ++i){

        if(i==d)
            continue;
        if(f==0 && i < len)
            ans += calc(pos+1 , 1 , (rem*10 + i)%m);
        else ans += calc(pos+1 , f , (rem*10 + i)%m);

        ans%=mod;
    }

    return dp[pos][f][rem] = ans;
}

void solve(){

    cin>>m>>d>>a>>b;

    memset(dp,-1,sizeof dp);

    int res = calc(0,0,0);

    memset(dp,-1,sizeof dp);
    b = a;
    debug(res);
    res-=calc(0,0,0);
    debug(res);
    bool ok = true;
    for(int i = 0 ; i < a.size() ; ++i){

        if(i&1 && a[i]!=d+'0')
            ok = false;

    }
    if(ok && a.size()>1)
        res++;
    debug(ok);
    cout<<res<<endl;
}

signed main(){

    int t;
    t = 1;
    // cin>>t;
    while(t--)
        solve();
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define ff first
#define ss second
#define endl '\n'
#define fast ios::sync_with_stdio(false); cin.tie(NULL);

/////////////////////////////////////////////

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

////////////////////////////////
const int mod = 1e9 + 7;
int m,d;
string a,b;
int dp[2000][2][2000];
int calc(int pos ,int f , int rem){

    if(pos==b.size()){

        return (rem==0);
    }

    if(dp[pos][f][rem]!=-1)
        return dp[pos][f][rem];

    long long ans = 0;

    int len;
    if(f==0)
        len = b[pos]-'0';
    else len = 9;
    if(pos&1){

        if(d < len)
            ans += calc(pos+1,1 , (rem*10 + d)%m);
        else if(d==len)
            ans += calc(pos+1,f, (rem*10 + d)%m);
        ans%=mod;

        dp[pos][f][rem] = ans;
        return ans;
    }
    for(int i = 0 ; i <= len ; ++i){

        if(i==d)
            continue;

        if(f==0 && i < len)
            ans += calc(pos+1 , 1 , (rem*10 + i)%m);
        else ans += calc(pos+1 , f , (rem*10 + i)%m);

        ans%=mod;
    }

    return dp[pos][f][rem] = ans;
}

void solve(){

    cin>>m>>d>>a>>b;

    memset(dp,-1,sizeof dp);

    int res = calc(0,0,0);

    memset(dp,-1,sizeof dp);

    b = a;
    debug(res);
    res-=calc(0,0,0);
    debug(res);
    bool ok = true;
    int val = 0;
    for(int i = 0 ; i < a.size() ; ++i){

        if(i&1 && a[i]!=d+'0')
            ok = false;
        if(i%2==0 && a[i]==d+'0')
            ok = false;
        val = val*10 + (a[i]-'0');
        val%=m;
    }
    if(ok && val==0)
        res++;
    debug(ok);
    if(res < 0)
        res+=mod;
    res%=mod;
    cout<<res<<endl;
}

signed main(){

    int t;
    t = 1;
    // cin>>t;
    while(t--)
        solve();
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define ff first
#define ss second
#define endl '\n'
#define fast ios::sync_with_stdio(false); cin.tie(NULL);

/////////////////////////////////////////////

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

////////////////////////////////
const int mod = 1e9 + 7;
int m,d;
string a,b;
int dp[2000][2][2000];
int calc(int pos ,int f , int rem){

    if(pos==b.size()){

        return (rem==0);
    }

    if(dp[pos][f][rem]!=-1)
        return dp[pos][f][rem];

    long long ans = 0;

    int len;
    if(f==0)
        len = b[pos]-'0';
    else len = 9;
    if(pos&1){

        if(f==0 && d < len)
            ans += calc(pos+1,1 , (rem*10 + d)%m);
        else ans+= calc(pos+1 , f , (rem*10 + d)%m);

        ans%=mod;

        dp[pos][f][rem] = ans;
        return ans;
    }
    for(int i = 0 ; i <= len ; ++i){

        if(pos&1 && i==d)
            continue;
        if(f==0 && i < len)
            ans += calc(pos+1 , 1 , (rem*10 + i)%m);
        else ans += calc(pos+1 , f , (rem*10 + i)%m);

        ans%=mod;
    }

    return dp[pos][f][rem] = ans;
}

void solve(){

    cin>>m>>d>>a>>b;

    memset(dp,-1,sizeof dp);

    int res = calc(0,0,0);

    memset(dp,-1,sizeof dp);
    b = a;
    //cout<<res<<endl;
    res-=calc(0,0,0);

    bool ok = true;
    for(int i = 0 ; i < a.size() ; ++i){

        if(i%2==0  && a[i]==d+'0')
            ok = false;

    }

    if(ok)
        res++;

    cout<<res-1<<endl;
}

signed main(){

    int t;
    t = 1;
    // cin>>t;
    while(t--)
        solve();
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define ff first
#define ss second
#define endl '\n'
#define fast ios::sync_with_stdio(false); cin.tie(NULL);

/////////////////////////////////////////////

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

////////////////////////////////
const int mod = 1e9 + 7;
int m,d;
string a,b;
int dp[2000][2][2000];
int calc(int pos ,int f , int rem){

    if(pos==b.size()){

        return (rem==0);
    }

    if(dp[pos][f][rem]!=-1)
        return dp[pos][f][rem];

    long long ans = 0;

    int len;
    if(f==0)
        len = b[pos]-'0';
    else len = 9;
    if(pos&1){

        if(f==0 && d < len)
            ans += calc(pos+1,1 , (rem*10 + d)%m);
        else ans+= calc(pos+1 , f , (rem*10 + d)%m);

        ans%=mod;

        dp[pos][f][rem] = ans;
        return ans;
    }
    for(int i = 0 ; i <= len ; ++i){

        if(pos&1 && i==d)
            continue;
        if(f==0 && i < len)
            ans += calc(pos+1 , 1 , (rem*10 + i)%m);
        else ans += calc(pos+1 , f , (rem*10 + i)%m);

        ans%=mod;
    }

    return dp[pos][f][rem] = ans;
}

void solve(){

    cin>>m>>d>>a>>b;

    memset(dp,-1,sizeof dp);

    int res = calc(0,0,0);

    memset(dp,-1,sizeof dp);
    b = a;
   // cout<<res<<endl;
    res-=calc(0,0,0);

    bool ok = true;
    for(int i = 0 ; i < a.size() ; ++i){

        if(i&1 && a[i]!=d+'0')
            ok = false;

    }

    if(ok)
        res++;

    cout<<res-1<<endl;
}

signed main(){

    int t;
    t = 1;
    // cin>>t;
    while(t--)
        solve();
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define ff first
#define ss second
#define endl '\n'
#define fast ios::sync_with_stdio(false); cin.tie(NULL);

/////////////////////////////////////////////

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

////////////////////////////////
const int mod = 1e9 + 7;
int m,d;
string a,b;
int dp[2000][2][2000];
int calc(int pos ,int f , int rem){

    if(pos==b.size()){

        return (rem==0);
    }

    if(dp[pos][f][rem]!=-1)
        return dp[pos][f][rem];

    long long ans = 0;

    int len;
    if(f==0)
        len = b[pos]-'0';
    else len = 9;
    if(pos&1){

        if(d < len)
            ans += calc(pos+1,1 , (rem*10 + d)%m);
        else if(d==len)
            ans += calc(pos+1,f, (rem*10 + d)%m);
        ans%=mod;

        dp[pos][f][rem] = ans;
        return ans;
    }
    for(int i = 0 ; i <= len ; ++i){

        if(i==d)
            continue;

        if(f==0 && i < len)
            ans += calc(pos+1 , 1 , (rem*10 + i)%m);
        else ans += calc(pos+1 , f , (rem*10 + i)%m);

        ans%=mod;
    }

    return dp[pos][f][rem] = ans;
}

void solve(){

    cin>>m>>d>>a>>b;

    memset(dp,-1,sizeof dp);

    int res = calc(0,0,0);

    memset(dp,-1,sizeof dp);
    b = a;
    debug(res);
    res-=calc(0,0,0);
    debug(res);
    bool ok = true;
    int val = 0;
    for(int i = 0 ; i < a.size() ; ++i){

        if(i&1 && a[i]!=d+'0')
            ok = false;

        val = val*10 + (a[i]-'0');
        val%=m;
    }
    if(ok && val==0)
        res++;
    debug(ok);
    if(res < 0)
        res+=mod;
    res%=mod;
    cout<<res<<endl;
}

signed main(){

    int t;
    t = 1;
    // cin>>t;
    while(t--)
        solve();
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define ff first
#define ss second
#define endl '\n'
#define fast ios::sync_with_stdio(false); cin.tie(NULL);

/////////////////////////////////////////////

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

////////////////////////////////
const int mod = 1e9 + 7;
int m,d;
string a,b;
int dp[2000][2][2000];
int calc(int pos ,int f , int rem){

    if(pos==b.size()){

        return (rem==0);
    }

    if(dp[pos][f][rem]!=-1)
        return dp[pos][f][rem];

    long long ans = 0;

    int len;
    if(f==0)
        len = b[pos]-'0';
    else len = 9;
    if(pos&1){

        if(d < len)
            ans += calc(pos+1,1 , (rem*10 + d)%m);
        else if(d==len)
            ans += calc(pos+1,f, (rem*10 + d)%m);
        ans%=mod;

        dp[pos][f][rem] = ans;
        return ans;
    }
    for(int i = 0 ; i <= len ; ++i){

        if(i==d)
            continue;

        if(f==0 && i < len)
            ans += calc(pos+1 , 1 , (rem*10 + i)%m);
        else ans += calc(pos+1 , f , (rem*10 + i)%m);

        ans%=mod;
    }

    return dp[pos][f][rem] = ans;
}

void solve(){

    cin>>m>>d>>a>>b;

    memset(dp,-1,sizeof dp);

    int res = calc(0,0,0);

    memset(dp,-1,sizeof dp);
    string x = b;
    b = a;
    debug(res);
    res-=calc(0,0,0);
    debug(res);
    bool ok = true;
    int val = 0;
    for(int i = 0 ; i < a.size() ; ++i){

        if(i&1 && a[i]!=d+'0')
            ok = false;

        val = val*10 + (a[i]-'0');
        val%=m;
    }
    if(ok && val==0 && x!=a)
        res++;
    debug(ok);
    if(res < 0)
        res+=mod;
    res%=mod;
    cout<<res<<endl;
}

signed main(){

    int t;
    t = 1;
    // cin>>t;
    while(t--)
        solve();
}


//#include <bits/stdc++.h>

#include <iostream>//数据输入输出流
#include <string.h>//字符串操作函数
#include <stdio.h>//C的输入输出
#include <stdlib.h>//定义杂项函数及内存分配函数
#include <math.h>//C中的数学函数
#include <string.h>//c++中的string类 他不能用strcpy等c函数去操作
#include <vector>//STL vetor容器
#include <list>//STL list
#include <map>// STL map
#include <queue>// STL queue
#include <stack>//sTL stack
#include <bitset>//bitset可按位定义串
#include <algorithm>//STL各种算法 比如 swap sort merge max min 比较
#include <numeric>//常用数字操作 一般和algorithm搭配使用
#include <functional>//STL定义运算函数（代替运算符）

using namespace std;

typedef long long LL;
typedef long long ULL;
typedef pair<int, int> pr;
typedef pair<LL, LL> lpr;
typedef pair<double, double> dpr;
typedef pair<long double, long double> ldpr;
//typedef complex<double> cp;

const int next_x[8] = {0, 1, -1, 0, 1, 1, -1, -1};
const int next_y[8] = {1, 0, 0, -1, 1, -1, -1, 1};
const int inf = 2147483647;
const LL linf = 1e18 + 5;
const double PI = acos(-1.0);

// #define DEBUG 1  //调试开关
struct IO
{
#define MAXSIZE (1 << 20)
#define isdigit(x) (x >= '0' && x <= '9')
    char buf[MAXSIZE], *p1, *p2;
    char pbuf[MAXSIZE], *pp;
#if DEBUG
#else
    IO() : p1(buf), p2(buf), pp(pbuf)
    {
    }
    ~IO() { fwrite(pbuf, 1, pp - pbuf, stdout); }
#endif
    inline char gc()
    {
#if DEBUG //调试，可显示字符
        return getchar();
#endif
        if (p1 == p2)
            p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin);
        return p1 == p2 ? -1 : *p1++;
    }
    inline bool blank(char ch)
    {
        return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
    }
    template <class T>
    inline void read(T &x)
    {
        register double tmp = 1;
        register bool sign = 0;
        x = 0;
        register char ch = gc();
        for (; !isdigit(ch); ch = gc())
            if (ch == '-')
                sign = 1;
        for (; isdigit(ch); ch = gc())
            x = x * 10 + (ch - '0');
        if (ch == '.')
            for (ch = gc(); isdigit(ch); ch = gc())
                tmp /= 10.0, x += tmp * (ch - '0');
        if (sign)
            x = -x;
    }
    inline void read(char *s)
    {
        register char ch = gc();
        for (; blank(ch); ch = gc())
            ;
        for (; !blank(ch); ch = gc())
            *s++ = ch;
        *s = 0;
    }
    inline void read(char &c)
    {
        for (c = gc(); blank(c); c = gc())
            ;
    }
    inline void push(const char &c)
    {
#if DEBUG //调试，可显示字符
        putchar(c);
#else
        if (pp - pbuf == MAXSIZE)
            fwrite(pbuf, 1, MAXSIZE, stdout), pp = pbuf;
        *pp++ = c;
#endif
    }
    template <class T>
    inline void write(T x)
    {
        if (x < 0)
            x = -x, push('-'); // 负数输出
        static T sta[35];
        T top = 0;
        do
        {
            sta[top++] = x % 10, x /= 10;
        } while (x);
        while (top)
            push(sta[--top] + '0');
    }
    template <class T>
    inline void write(T x, char lastChar)
    {
        write(x), push(lastChar);
    }
} io;

#define dbgs(x) #x << " = " << x
#define dbgs2(x, y) dbgs(x) << ", " << dbgs(y)
#define dbgs3(x, y, z) dbgs2(x, y) << ", " << dbgs(z)
#define dbgs4(w, x, y, z) dbgs3(w, x, y) << ", " << dbgs(z)

#define heap priority_queue
#define mst(s, x) memset(s, x, sizeof(s))
//#define mid ((l + r) >> 1)
#define fi first
#define se second
#define pb push_back
#define pf push_front
#define ppb pop_back
#define ppf pop_front
#define mp make_pair
#define all(x) x.begin(), x.end()
#define unq(x) x.erase(unique(x.begin(), x.end()), x.end())
#define rg register
#define fp(i, a, b) for (rg int i = (a), I = (b) + 1; i < I; ++i)
#define fd(i, a, b) for (rg int i = (a), I = (b)-1; i > I; --i)
#define go(u) for (rg int i = pre[u], v = e[i].v; i; i = e[i].next, v = e[i].v)
#define gow(u) for (rg int i = pre[u], v = e[i].v, w = e[i].w; i; i = e[i].next, v = e[i].v, w = e[i].w)
#define dbga(a, len)                       \
    {                                      \
        cout << #a << ": ";                \
        fp(i, 1, len) cout << a[i] << " "; \
        cout << endl;                      \
    }
#define ub upper_bound
#define lb lower_bound

const double eps = 1e-10;
const int MAXN = 2005;
//const int N = 200 + 5;
const LL MAX = 1e10;

/*----------head----------*/

const LL MOD = 1e9+7;

int n,m,d;
int a[MAXN],b[MAXN];
LL f[MAXN][2][2][2][MAXN];
stack<int> S;

LL dfs(int len,bool limit,bool lead,bool even,int mod,int num[])
{
    if(!len)
    {
/*
        stack<int> t; t=S;
        while(!t.empty()) printf("%d",t.top()),t.pop();
        printf("\n");
*/
        if(mod) return 0;
        if(lead) return 0;
        return 1;
    }

    if(f[len][limit][lead][even][mod]!=-1)
        return f[len][limit][lead][even][mod];

    LL ans=0;
    int up=limit?num[len]:9;

    if(d&&lead&&len==1) return 0;

    fp(i,0,up)
    {
        //S.push(i);
        if(lead)
        {
            if(i==0) ans+=dfs(len-1,limit&&i==up,1,0,(mod*10+i)%m,num),ans%=MOD;
            else if(i!=d) ans+=dfs(len-1,limit&&i==up,0,1,(mod*10+i)%m,num),ans%=MOD;
        }
        else
        {
            if(!even)
            {
                if(i!=d)
                    ans+=dfs(len-1,limit&&i==up,0,1,(mod*10+i)%m,num),
                    ans%=MOD;
            }
            else
            {
                if(i==d)
                    ans+=dfs(len-1,limit&&i==up,0,0,(mod*10+i)%m,num),
                    ans%=MOD;
            }
        }
        //S.pop();
    }
    return f[len][limit][lead][even][mod]=ans;
}
LL solve(int num[],int len){mst(f,-1); return dfs(len,1,1,0,0,num);}
char s[MAXN];
void read(int a[])
{
    scanf("%s",s+1),n=strlen(s+1);
    a[0]=n; fp(i,1,n)a[n-i+1]=s[i]-'0';
    //dbga(a,n);
}
bool check()
{
    if(a[0]==1&&a[1]==0)  return 0;
    if(a[0]==1) return d==0;
    for(int i=a[0]-1;i>=1;i-=2)
        if(a[i]!=d) return 0;
    int t=0;
    fd(i,a[0],1)t=t*10+a[i],t%=m;
    return t==0;
}

int work()
{
    scanf("%d%d",&m,&d),read(a),read(b);
    //cout << dbgs(solve(b,b[0])) << endl;
    //cout << dbgs(solve(a,a[0])) << endl;
    //cout << dbgs(check()) << endl;
    LL ans=solve(b,b[0])-solve(a,a[0])+check();
    ans%=MOD,ans+=MOD,ans%=MOD;
    //cout << dbgs(check()) << endl;
    return printf("%lld\n",ans);
}

// vector+lower_bound常数 < map/set
// map.find不会创建新元素 map[]会 注意空间
// 别对指针用memset
// 用位运算表示2^n注意加LL  1LL<<20
// 注意递归爆栈
// 注意边界
// 注意memset 多组样例会T

//#define ONLINE_JUDGE

int main()
{
    //ios::sync_with_stdio(false);
    //cin.tie(0);
#ifdef ONLINE_JUDGE
    //freopen("invazia.in", "r",stdin );
    //freopen("invazia.out","w",stdout);
#endif // ONLINE_JUDGE
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#endif
    work();
#ifndef ONLINE_JUDGE
    freopen("CON", "r", stdin);
    fflush(stdout);
    system("pause");
#endif
    return 0;
}


//#include <bits/stdc++.h>

#include <iostream>//数据输入输出流
#include <string.h>//字符串操作函数
#include <stdio.h>//C的输入输出
#include <stdlib.h>//定义杂项函数及内存分配函数
#include <math.h>//C中的数学函数
#include <string.h>//c++中的string类 他不能用strcpy等c函数去操作
#include <vector>//STL vetor容器
#include <list>//STL list
#include <map>// STL map
#include <queue>// STL queue
#include <stack>//sTL stack
#include <bitset>//bitset可按位定义串
#include <algorithm>//STL各种算法 比如 swap sort merge max min 比较
#include <numeric>//常用数字操作 一般和algorithm搭配使用
#include <functional>//STL定义运算函数（代替运算符）

using namespace std;

typedef long long LL;
typedef long long ULL;
typedef pair<int, int> pr;
typedef pair<LL, LL> lpr;
typedef pair<double, double> dpr;
typedef pair<long double, long double> ldpr;
//typedef complex<double> cp;

const int next_x[8] = {0, 1, -1, 0, 1, 1, -1, -1};
const int next_y[8] = {1, 0, 0, -1, 1, -1, -1, 1};
const int inf = 2147483647;
const LL linf = 1e18 + 5;
const double PI = acos(-1.0);

// #define DEBUG 1  //调试开关
struct IO
{
#define MAXSIZE (1 << 20)
#define isdigit(x) (x >= '0' && x <= '9')
    char buf[MAXSIZE], *p1, *p2;
    char pbuf[MAXSIZE], *pp;
#if DEBUG
#else
    IO() : p1(buf), p2(buf), pp(pbuf)
    {
    }
    ~IO() { fwrite(pbuf, 1, pp - pbuf, stdout); }
#endif
    inline char gc()
    {
#if DEBUG //调试，可显示字符
        return getchar();
#endif
        if (p1 == p2)
            p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin);
        return p1 == p2 ? -1 : *p1++;
    }
    inline bool blank(char ch)
    {
        return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
    }
    template <class T>
    inline void read(T &x)
    {
        register double tmp = 1;
        register bool sign = 0;
        x = 0;
        register char ch = gc();
        for (; !isdigit(ch); ch = gc())
            if (ch == '-')
                sign = 1;
        for (; isdigit(ch); ch = gc())
            x = x * 10 + (ch - '0');
        if (ch == '.')
            for (ch = gc(); isdigit(ch); ch = gc())
                tmp /= 10.0, x += tmp * (ch - '0');
        if (sign)
            x = -x;
    }
    inline void read(char *s)
    {
        register char ch = gc();
        for (; blank(ch); ch = gc())
            ;
        for (; !blank(ch); ch = gc())
            *s++ = ch;
        *s = 0;
    }
    inline void read(char &c)
    {
        for (c = gc(); blank(c); c = gc())
            ;
    }
    inline void push(const char &c)
    {
#if DEBUG //调试，可显示字符
        putchar(c);
#else
        if (pp - pbuf == MAXSIZE)
            fwrite(pbuf, 1, MAXSIZE, stdout), pp = pbuf;
        *pp++ = c;
#endif
    }
    template <class T>
    inline void write(T x)
    {
        if (x < 0)
            x = -x, push('-'); // 负数输出
        static T sta[35];
        T top = 0;
        do
        {
            sta[top++] = x % 10, x /= 10;
        } while (x);
        while (top)
            push(sta[--top] + '0');
    }
    template <class T>
    inline void write(T x, char lastChar)
    {
        write(x), push(lastChar);
    }
} io;

#define dbgs(x) #x << " = " << x
#define dbgs2(x, y) dbgs(x) << ", " << dbgs(y)
#define dbgs3(x, y, z) dbgs2(x, y) << ", " << dbgs(z)
#define dbgs4(w, x, y, z) dbgs3(w, x, y) << ", " << dbgs(z)

#define heap priority_queue
#define mst(s, x) memset(s, x, sizeof(s))
//#define mid ((l + r) >> 1)
#define fi first
#define se second
#define pb push_back
#define pf push_front
#define ppb pop_back
#define ppf pop_front
#define mp make_pair
#define all(x) x.begin(), x.end()
#define unq(x) x.erase(unique(x.begin(), x.end()), x.end())
#define rg register
#define fp(i, a, b) for (rg int i = (a), I = (b) + 1; i < I; ++i)
#define fd(i, a, b) for (rg int i = (a), I = (b)-1; i > I; --i)
#define go(u) for (rg int i = pre[u], v = e[i].v; i; i = e[i].next, v = e[i].v)
#define gow(u) for (rg int i = pre[u], v = e[i].v, w = e[i].w; i; i = e[i].next, v = e[i].v, w = e[i].w)
#define dbga(a, len)                       \
    {                                      \
        cout << #a << ": ";                \
        fp(i, 1, len) cout << a[i] << " "; \
        cout << endl;                      \
    }
#define ub upper_bound
#define lb lower_bound

const double eps = 1e-10;
const int MAXN = 2005;
//const int N = 200 + 5;
const LL MAX = 1e10;

/*----------head----------*/

const LL MOD = 1e9+7;

int n,m,d;
int a[MAXN],b[MAXN];
LL f[MAXN][2][2][2][MAXN];
stack<int> S;

LL dfs(int len,bool limit,bool lead,bool even,int mod,int num[])
{
    if(!len)
    {
/*
        stack<int> t; t=S;
        while(!t.empty()) printf("%d",t.top()),t.pop();
        printf("\n");
*/
        if(mod) return 0;
        if(lead) return 0;
        return 1;
    }

    if(f[len][limit][lead][even][mod]!=-1)
        return f[len][limit][lead][even][mod];

    LL ans=0;
    int up=limit?num[len]:9;

    if(d&&lead&&len==1) return 0;

    fp(i,0,up)
    {
        //S.push(i);
        if(lead)
        {
            if(i==0) ans+=dfs(len-1,limit&&i==up,1,0,(mod*10+i)%m,num),ans%=MOD;
            else if(i!=d) ans+=dfs(len-1,limit&&i==up,0,1,(mod*10+i)%m,num),ans%=MOD;
        }
        else
        {
            if(!even)
            {
                if(i!=d)
                    ans+=dfs(len-1,limit&&i==up,0,1,(mod*10+i)%m,num),
                    ans%=MOD;
            }
            else
            {
                if(i==d)
                    ans+=dfs(len-1,limit&&i==up,0,0,(mod*10+i)%m,num),
                    ans%=MOD;
            }
        }
        //S.pop();
    }
    return f[len][limit][lead][even][mod]=ans;
}
LL solve(int num[],int len){mst(f,-1); return dfs(len,1,1,0,0,num);}
char s[MAXN];
void read(int a[])
{
    scanf("%s",s+1),n=strlen(s+1);
    a[0]=n; fp(i,1,n)a[n-i+1]=s[i]-'0';
    //dbga(a,n);
}
bool check()
{
    if(a[0]==1&&a[1]==0)  return 0;
    for(int i=a[0]-1;i;i-=2)
        if(a[i]!=d) return 0;
    int t=0;
    fd(i,a[0],1)t=t*10+a[i],t%=m;
    return t==0;
}

int work()
{
    scanf("%d%d",&m,&d),read(a),read(b);
    //cout << dbgs(solve(b,b[0])) << endl;
    //cout << dbgs(solve(a,a[0])) << endl;
    //cout << dbgs(check()) << endl;
    LL ans=solve(b,b[0])-solve(a,a[0])+check();
    ans%=MOD,ans+=MOD,ans%=MOD;
    return printf("%lld\n",ans);
}

// vector+lower_bound常数 < map/set
// map.find不会创建新元素 map[]会 注意空间
// 别对指针用memset
// 用位运算表示2^n注意加LL  1LL<<20
// 注意递归爆栈
// 注意边界
// 注意memset 多组样例会T

//#define ONLINE_JUDGE

int main()
{
    //ios::sync_with_stdio(false);
    //cin.tie(0);
#ifdef ONLINE_JUDGE
    //freopen("invazia.in", "r",stdin );
    //freopen("invazia.out","w",stdout);
#endif // ONLINE_JUDGE
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#endif
    work();
#ifndef ONLINE_JUDGE
    freopen("CON", "r", stdin);
    fflush(stdout);
    system("pause");
#endif
    return 0;
}


//#include <bits/stdc++.h>

#include <iostream>//数据输入输出流
#include <string.h>//字符串操作函数
#include <stdio.h>//C的输入输出
#include <stdlib.h>//定义杂项函数及内存分配函数
#include <math.h>//C中的数学函数
#include <string.h>//c++中的string类 他不能用strcpy等c函数去操作
#include <vector>//STL vetor容器
#include <list>//STL list
#include <map>// STL map
#include <queue>// STL queue
#include <stack>//sTL stack
#include <bitset>//bitset可按位定义串
#include <algorithm>//STL各种算法 比如 swap sort merge max min 比较
#include <numeric>//常用数字操作 一般和algorithm搭配使用
#include <functional>//STL定义运算函数（代替运算符）

using namespace std;

typedef long long LL;
typedef long long ULL;
typedef pair<int, int> pr;
typedef pair<LL, LL> lpr;
typedef pair<double, double> dpr;
typedef pair<long double, long double> ldpr;
//typedef complex<double> cp;

const int next_x[8] = {0, 1, -1, 0, 1, 1, -1, -1};
const int next_y[8] = {1, 0, 0, -1, 1, -1, -1, 1};
const int inf = 2147483647;
const LL linf = 1e18 + 5;
const double PI = acos(-1.0);

// #define DEBUG 1  //调试开关
struct IO
{
#define MAXSIZE (1 << 20)
#define isdigit(x) (x >= '0' && x <= '9')
    char buf[MAXSIZE], *p1, *p2;
    char pbuf[MAXSIZE], *pp;
#if DEBUG
#else
    IO() : p1(buf), p2(buf), pp(pbuf)
    {
    }
    ~IO() { fwrite(pbuf, 1, pp - pbuf, stdout); }
#endif
    inline char gc()
    {
#if DEBUG //调试，可显示字符
        return getchar();
#endif
        if (p1 == p2)
            p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin);
        return p1 == p2 ? -1 : *p1++;
    }
    inline bool blank(char ch)
    {
        return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
    }
    template <class T>
    inline void read(T &x)
    {
        register double tmp = 1;
        register bool sign = 0;
        x = 0;
        register char ch = gc();
        for (; !isdigit(ch); ch = gc())
            if (ch == '-')
                sign = 1;
        for (; isdigit(ch); ch = gc())
            x = x * 10 + (ch - '0');
        if (ch == '.')
            for (ch = gc(); isdigit(ch); ch = gc())
                tmp /= 10.0, x += tmp * (ch - '0');
        if (sign)
            x = -x;
    }
    inline void read(char *s)
    {
        register char ch = gc();
        for (; blank(ch); ch = gc())
            ;
        for (; !blank(ch); ch = gc())
            *s++ = ch;
        *s = 0;
    }
    inline void read(char &c)
    {
        for (c = gc(); blank(c); c = gc())
            ;
    }
    inline void push(const char &c)
    {
#if DEBUG //调试，可显示字符
        putchar(c);
#else
        if (pp - pbuf == MAXSIZE)
            fwrite(pbuf, 1, MAXSIZE, stdout), pp = pbuf;
        *pp++ = c;
#endif
    }
    template <class T>
    inline void write(T x)
    {
        if (x < 0)
            x = -x, push('-'); // 负数输出
        static T sta[35];
        T top = 0;
        do
        {
            sta[top++] = x % 10, x /= 10;
        } while (x);
        while (top)
            push(sta[--top] + '0');
    }
    template <class T>
    inline void write(T x, char lastChar)
    {
        write(x), push(lastChar);
    }
} io;

#define dbgs(x) #x << " = " << x
#define dbgs2(x, y) dbgs(x) << ", " << dbgs(y)
#define dbgs3(x, y, z) dbgs2(x, y) << ", " << dbgs(z)
#define dbgs4(w, x, y, z) dbgs3(w, x, y) << ", " << dbgs(z)

#define heap priority_queue
#define mst(s, x) memset(s, x, sizeof(s))
//#define mid ((l + r) >> 1)
#define fi first
#define se second
#define pb push_back
#define pf push_front
#define ppb pop_back
#define ppf pop_front
#define mp make_pair
#define all(x) x.begin(), x.end()
#define unq(x) x.erase(unique(x.begin(), x.end()), x.end())
#define rg register
#define fp(i, a, b) for (rg int i = (a), I = (b) + 1; i < I; ++i)
#define fd(i, a, b) for (rg int i = (a), I = (b)-1; i > I; --i)
#define go(u) for (rg int i = pre[u], v = e[i].v; i; i = e[i].next, v = e[i].v)
#define gow(u) for (rg int i = pre[u], v = e[i].v, w = e[i].w; i; i = e[i].next, v = e[i].v, w = e[i].w)
#define dbga(a, len)                       \
    {                                      \
        cout << #a << ": ";                \
        fp(i, 1, len) cout << a[i] << " "; \
        cout << endl;                      \
    }
#define ub upper_bound
#define lb lower_bound

const double eps = 1e-10;
const int MAXN = 2005;
//const int N = 200 + 5;
const LL MAX = 1e10;

/*----------head----------*/

const LL MOD = 1e9+7;

int n,m,d;
int a[MAXN],b[MAXN];
LL f[MAXN][2][2][2][MAXN];
stack<int> S;

LL dfs(int len,bool limit,bool lead,bool even,int mod,int num[])
{
    if(!len)
    {
/*
        stack<int> t; t=S;
        while(!t.empty()) printf("%d",t.top()),t.pop();
        printf("\n");
*/
        if(mod) return 0;
        if(lead) return d!=0;
        return 1;
    }
/*
    if(f[len][limit][lead][even][mod]!=-1)
        return f[len][limit][lead][even][mod];
*/
    LL ans=0;
    int up=limit?num[len]:9;

    //if(d&&lead&&len==1) return 0;

    fp(i,0,up)
    {
        //S.push(i);
        if(lead)
        {
            if(i==0) ans+=dfs(len-1,limit&&i==up,1,0,(mod*10+i)%m,num),ans%=MOD;
            else if(i!=d) ans+=dfs(len-1,limit&&i==up,0,1,(mod*10+i)%m,num),ans%=MOD;
        }
        else
        {
            if(!even)
            {
                if(i!=d)
                    ans+=dfs(len-1,limit&&i==up,0,1,(mod*10+i)%m,num),
                    ans%=MOD;
            }
            else
            {
                if(i==d)
                    ans+=dfs(len-1,limit&&i==up,0,0,(mod*10+i)%m,num),
                    ans%=MOD;
            }
        }
        //S.pop();
    }
    return f[len][limit][lead][even][mod]=ans;
}
LL solve(int num[],int len){mst(f,-1); return dfs(len,1,1,0,0,num);}
char s[MAXN];
void read(int a[])
{
    scanf("%s",s+1),n=strlen(s+1);
    a[0]=n; fp(i,1,n)a[n-i+1]=s[i]-'0';
    //dbga(a,n);
}
bool check()
{
    if(a[1]==0&&a[0]==1) return d!=0;
    int t=0;
    fd(i,a[0],1)
    {
        bool odd=((a[0]-i+1)&1);
        if(odd&&a[i]==d)  return 0;
        if(!odd&&a[i]!=d) return 0;
        t=t*10+a[i],t%=m;
    }
    return t==0;
}

int work()
{
    scanf("%d%d",&m,&d),read(a),read(b);
    //cout << dbgs(solve(b,b[0])) << endl;
    //cout << dbgs(solve(a,a[0])) << endl;
    //cout << dbgs(check()) << endl;
    LL ans=solve(b,b[0])-solve(a,a[0])+check();
    ans%=MOD,ans+=MOD,ans%=MOD;
    //cout << dbgs(check()) << endl;
    return printf("%lld\n",ans);
}

// vector+lower_bound常数 < map/set
// map.find不会创建新元素 map[]会 注意空间
// 别对指针用memset
// 用位运算表示2^n注意加LL  1LL<<20
// 注意递归爆栈
// 注意边界
// 注意memset 多组样例会T

//#define ONLINE_JUDGE

int main()
{
    //ios::sync_with_stdio(false);
    //cin.tie(0);
#ifdef ONLINE_JUDGE
    //freopen("invazia.in", "r",stdin );
    //freopen("invazia.out","w",stdout);
#endif // ONLINE_JUDGE
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#endif
    work();
#ifndef ONLINE_JUDGE
    freopen("CON", "r", stdin);
    fflush(stdout);
    system("pause");
#endif
    return 0;
}


//#include <bits/stdc++.h>

#include <iostream>//数据输入输出流
#include <string.h>//字符串操作函数
#include <stdio.h>//C的输入输出
#include <stdlib.h>//定义杂项函数及内存分配函数
#include <math.h>//C中的数学函数
#include <string.h>//c++中的string类 他不能用strcpy等c函数去操作
#include <vector>//STL vetor容器
#include <list>//STL list
#include <map>// STL map
#include <queue>// STL queue
#include <stack>//sTL stack
#include <bitset>//bitset可按位定义串
#include <algorithm>//STL各种算法 比如 swap sort merge max min 比较
#include <numeric>//常用数字操作 一般和algorithm搭配使用
#include <functional>//STL定义运算函数（代替运算符）

using namespace std;

typedef long long LL;
typedef long long ULL;
typedef pair<int, int> pr;
typedef pair<LL, LL> lpr;
typedef pair<double, double> dpr;
typedef pair<long double, long double> ldpr;
//typedef complex<double> cp;

const int next_x[8] = {0, 1, -1, 0, 1, 1, -1, -1};
const int next_y[8] = {1, 0, 0, -1, 1, -1, -1, 1};
const int inf = 2147483647;
const LL linf = 1e18 + 5;
const double PI = acos(-1.0);

// #define DEBUG 1  //调试开关
struct IO
{
#define MAXSIZE (1 << 20)
#define isdigit(x) (x >= '0' && x <= '9')
    char buf[MAXSIZE], *p1, *p2;
    char pbuf[MAXSIZE], *pp;
#if DEBUG
#else
    IO() : p1(buf), p2(buf), pp(pbuf)
    {
    }
    ~IO() { fwrite(pbuf, 1, pp - pbuf, stdout); }
#endif
    inline char gc()
    {
#if DEBUG //调试，可显示字符
        return getchar();
#endif
        if (p1 == p2)
            p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin);
        return p1 == p2 ? -1 : *p1++;
    }
    inline bool blank(char ch)
    {
        return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
    }
    template <class T>
    inline void read(T &x)
    {
        register double tmp = 1;
        register bool sign = 0;
        x = 0;
        register char ch = gc();
        for (; !isdigit(ch); ch = gc())
            if (ch == '-')
                sign = 1;
        for (; isdigit(ch); ch = gc())
            x = x * 10 + (ch - '0');
        if (ch == '.')
            for (ch = gc(); isdigit(ch); ch = gc())
                tmp /= 10.0, x += tmp * (ch - '0');
        if (sign)
            x = -x;
    }
    inline void read(char *s)
    {
        register char ch = gc();
        for (; blank(ch); ch = gc())
            ;
        for (; !blank(ch); ch = gc())
            *s++ = ch;
        *s = 0;
    }
    inline void read(char &c)
    {
        for (c = gc(); blank(c); c = gc())
            ;
    }
    inline void push(const char &c)
    {
#if DEBUG //调试，可显示字符
        putchar(c);
#else
        if (pp - pbuf == MAXSIZE)
            fwrite(pbuf, 1, MAXSIZE, stdout), pp = pbuf;
        *pp++ = c;
#endif
    }
    template <class T>
    inline void write(T x)
    {
        if (x < 0)
            x = -x, push('-'); // 负数输出
        static T sta[35];
        T top = 0;
        do
        {
            sta[top++] = x % 10, x /= 10;
        } while (x);
        while (top)
            push(sta[--top] + '0');
    }
    template <class T>
    inline void write(T x, char lastChar)
    {
        write(x), push(lastChar);
    }
} io;

#define dbgs(x) #x << " = " << x
#define dbgs2(x, y) dbgs(x) << ", " << dbgs(y)
#define dbgs3(x, y, z) dbgs2(x, y) << ", " << dbgs(z)
#define dbgs4(w, x, y, z) dbgs3(w, x, y) << ", " << dbgs(z)

#define heap priority_queue
#define mst(s, x) memset(s, x, sizeof(s))
//#define mid ((l + r) >> 1)
#define fi first
#define se second
#define pb push_back
#define pf push_front
#define ppb pop_back
#define ppf pop_front
#define mp make_pair
#define all(x) x.begin(), x.end()
#define unq(x) x.erase(unique(x.begin(), x.end()), x.end())
#define rg register
#define fp(i, a, b) for (rg int i = (a), I = (b) + 1; i < I; ++i)
#define fd(i, a, b) for (rg int i = (a), I = (b)-1; i > I; --i)
#define go(u) for (rg int i = pre[u], v = e[i].v; i; i = e[i].next, v = e[i].v)
#define gow(u) for (rg int i = pre[u], v = e[i].v, w = e[i].w; i; i = e[i].next, v = e[i].v, w = e[i].w)
#define dbga(a, len)                       \
    {                                      \
        cout << #a << ": ";                \
        fp(i, 1, len) cout << a[i] << " "; \
        cout << endl;                      \
    }
#define ub upper_bound
#define lb lower_bound

const double eps = 1e-10;
const int MAXN = 2005;
//const int N = 200 + 5;
const LL MAX = 1e10;

/*----------head----------*/

const LL MOD = 1e9+7;

int n,m,d;
int a[MAXN],b[MAXN];
LL f[MAXN][2][2][2][MAXN];
stack<int> S;

LL dfs(int len,bool limit,bool lead,bool even,int mod,int num[])
{
    if(!len)
    {
/*
        stack<int> t; t=S;
        while(!t.empty()) printf("%d",t.top()),t.pop();
        printf("\n");
*/
        if(mod) return 0;
        if(lead) return 0;
        return 1;
    }

    if(f[len][limit][lead][even][mod]!=-1)
        return f[len][limit][lead][even][mod];

    LL ans=0;
    int up=limit?num[len]:9;

    if(d&&lead&&len==1) return 0;

    fp(i,0,up)
    {
        //S.push(i);
        if(lead)
        {
            if(i==0) ans+=dfs(len-1,limit&&i==up,1,0,(mod*10+i)%m,num),ans%=MOD;
            else if(i!=d) ans+=dfs(len-1,limit&&i==up,0,1,(mod*10+i)%m,num),ans%=MOD;
        }
        else
        {
            if(!even)
            {
                if(i!=d)
                    ans+=dfs(len-1,limit&&i==up,0,1,(mod*10+i)%m,num),
                    ans%=MOD;
            }
            else
            {
                if(i==d)
                    ans+=dfs(len-1,limit&&i==up,0,0,(mod*10+i)%m,num),
                    ans%=MOD;
            }
        }
        //S.pop();
    }
    return f[len][limit][lead][even][mod]=ans;
}
LL solve(int num[],int len){mst(f,-1); return dfs(len,1,1,0,0,num);}
char s[MAXN];
void read(int a[])
{
    scanf("%s",s+1),n=strlen(s+1);
    a[0]=n; fp(i,1,n)a[n-i+1]=s[i]-'0';
    //dbga(a,n);
}
bool check()
{
    if(a[0]==1&&a[1]==0)  return 0;
    if(a[0]==1)
    {
        if(d==0) return a[1]%m==0;
        else return 0;
    }
    for(int i=a[0]-1;i>=1;i-=2)
        if(a[i]!=d) return 0;
    int t=0;
    fd(i,a[0],1)t=t*10+a[i],t%=m;
    return t==0;
}

int work()
{
    scanf("%d%d",&m,&d),read(a),read(b);
    //cout << dbgs(solve(b,b[0])) << endl;
    //cout << dbgs(solve(a,a[0])) << endl;
    //cout << dbgs(check()) << endl;
    LL ans=solve(b,b[0])-solve(a,a[0])+check();
    ans%=MOD,ans+=MOD,ans%=MOD;
    //cout << dbgs(check()) << endl;
    return printf("%lld\n",ans);
}

// vector+lower_bound常数 < map/set
// map.find不会创建新元素 map[]会 注意空间
// 别对指针用memset
// 用位运算表示2^n注意加LL  1LL<<20
// 注意递归爆栈
// 注意边界
// 注意memset 多组样例会T

//#define ONLINE_JUDGE

int main()
{
    //ios::sync_with_stdio(false);
    //cin.tie(0);
#ifdef ONLINE_JUDGE
    //freopen("invazia.in", "r",stdin );
    //freopen("invazia.out","w",stdout);
#endif // ONLINE_JUDGE
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#endif
    work();
#ifndef ONLINE_JUDGE
    freopen("CON", "r", stdin);
    fflush(stdout);
    system("pause");
#endif
    return 0;
}


#include <bits/stdc++.h>

#define F first
#define S second
#define mp make_pair
#define pb push_back
#define sz(x) x.size()
#define all(x) x.begin(), x.end()
#define pii pair < int , int >
#define task ""

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

const int N = 1e5 + 123;
const int mod = 1e9 + 7;
const int INF = 1e9 + 1;
const ll INFL = 3e18 + 1;
const double pi = acos(-1.0);

int n, k;

struct node {
	int l, r, val;
	node () {
		l = r = val = 0;
	}
};
struct st {
	int x, r, f;
} a[N];
node t[N][N];
int sz = 1;
int id[N];

void upd (int f, int pos, int v = 1, int tl = 1, int tr = INF) {
	if (tl == tr) {
		t[f][v].val ++;
		return;
	}
	int tm = (tl + tr) / 2;
	if (pos <= tm) {
		if (!t[f][v].l) t[f][v].l = ++ 	sz;
		upd (f, pos, t[f][v].l, tl, tm);
	}
	else {
		if (!t[f][v].r) t[f][v].r = ++ sz;
		upd (f, pos, t[f][v].r, tm + 1, tr);
	}
	t[f][v].val = t[f][t[f][v].l].val + t[f][t[f][v].r].val;
}
int get (int f, int l, int r, int v = 1, int tl = 1, int tr = INF) {
	if (tl > r || tr < l || l > r || tl > tr) return 0;
	if (l <= tl && tr <= r) return t[f][v].val;
	int tm = (tl +  tr) / 2;
	int ans = 0;
	if (t[f][v].l) ans += get (f, l, r, t[f][v].l, tl, tm);
	if (t[f][v].r) ans += get (f, l, r, t[f][v].r, tm + 1, tr);
	return ans;
}
bool cmp (st a, st b) {
	return a.r > b.r;
}
int main () {

	scanf ("%d%d", &n, &k);
	for (int i = 1;i <= n;i ++) {
		scanf ("%d%d%d", &a[i].x, &a[i].r, &a[i].f);
		id[a[i].f] = i;
	}
	sort (a + 1, a + n + 1, &cmp);
	int ans = 0;
	for (int i = 1;i <= n;i ++) {
		//cout << "i = " << i << endl;
		for (int j = a[i].f - k;j <= a[i].f + k;j ++) {
			//cout << "get (" << j << ") = " << get (j, max (1, a[i].x - a[i].r), a[i].x + a[i].r) << endl;
		    if (id[j])
				ans += get (id[j], max (1, a[i].x - a[i].r), a[i].x + a[i].r);
		}
		//cout << "after " << i << "'th " << ans << endl;
		upd (id[a[i].f], a[i].x);
	}
	printf ("%d", ans);
return 0;
}


#include <bits/stdc++.h>

#define F first
#define S second
#define mp make_pair
#define pb push_back
#define sz(x) x.size()
#define all(x) x.begin(), x.end()
#define pii pair < int , int >
#define task ""

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

const int N = 1e5 + 123;
const int mod = 1e9 + 7;
const int INF = 1e9 + 1213;
const ll INFL = 3e18 + 1;
const double pi = acos(-1.0);

int n, k;

struct node {
	int l, r;
	ll val;
	node () {
		l = r = val = 0;
	}
};
struct st {
	ll x, r, f;
} a[N];

vector < node > t[N];
int id[(int)1e4];

void upd (int f, ll pos, int v = 0, ll tl = 1, ll tr = INF) {
	if (tl == tr) {
		t[f][v].val ++;
		return;
	}
	ll tm = (tl + tr) / 2;
	if (pos <= tm) {
		if (!t[f][v].l) {
			t[f][v].l = t[f].size ();
			t[f].pb (node ());
		}
		upd (f, pos, t[f][v].l, tl, tm);
	}
	else {
		if (!t[f][v].r) {
			t[f][v].r = t[f].size ();
			t[f].pb (node ());
		}
		upd (f, pos, t[f][v].r, tm + 1, tr);
	}
	t[f][v].val = t[f][t[f][v].l].val + t[f][t[f][v].r].val;
}
ll get (int f, int l, int r, int v = 0, ll tl = 1, ll tr = INF) {
	if (tl > r || tr < l || l > r || tl > tr) return 0;
	if (l <= tl && tr <= r) return t[f][v].val;
	ll tm = (tl + tr) / 2;
	ll ans = 0;
	if (t[f][v].l) ans += get (f, l, r, t[f][v].l, tl, tm);
	if (t[f][v].r) ans += get (f, l, r, t[f][v].r, tm + 1, tr);
	return ans;
}
bool cmp (st a, st b) {
	return a.r > b.r;
}
int main () {

	ios_base::sync_with_stdio (0);
	cin.tie (0); cout.tie (0);
	cin >> n >> k;
	for (int i = 1;i <= n;i ++) {
		cin >> a[i].x >> a[i].r >> a[i].f;
		id[a[i].f] = i;
		t[i].pb (node ());
		if (a[i].x < 1) {
			cout << 10 / 0;
			return 0;
		}
	}
	sort (a + 1, a + n + 1, &cmp);
	ll ans = 0;
	for (int i = 1;i <= n;i ++) {
		for (ll j = a[i].f - k;j <= a[i].f + k;j ++) {
		    if (j < 1) continue;
		    if (id[j])
				ans += get (id[j], max (1ll, a[i].x - a[i].r), a[i].x + a[i].r);
		}
		upd (id[a[i].f], a[i].x);
	}
	cout << ans;
return 0;
}


#include <bits/stdc++.h>

#define F first
#define S second
#define mp make_pair
#define pb push_back
#define sz(x) x.size()
#define all(x) x.begin(), x.end()
#define pii pair < int , int >
#define task ""
#define int long long

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

const int N = 2e5 + 123;
const int mod = 1e9 + 7;
const int INF = 1e9 + 1213;
const ll INFL = 3e18 + 1;
const double pi = acos(-1.0);

int n, k;

struct node {
	int l, r;
	int val;
	node () {
		l = r = -1;
		val = 0;
	}
};
struct st {
	int x, r, f;
} a[N];

vector < node > t[N];

void upd (int f, int pos, int v = 0, int tl = 1, int tr = INF - 1212) {
	if (tl == tr) {
		t[f][v].val ++;
		return;
	}
	int tm = (tl + tr) / 2;
	if (pos <= tm) {
		if (t[f][v].l < 0) {
			t[f][v].l = t[f].size ();
			t[f].pb (node ());
		}
		upd (f, pos, t[f][v].l, tl, tm);
	}
	else {
		if (t[f][v].r < 0) {
			t[f][v].r = t[f].size ();
			t[f].pb (node ());
		}
		upd (f, pos, t[f][v].r, tm + 1, tr);
	}
	if (t[f][v].l > 0)
		t[f][v].val += t[f][t[f][v].l].val;
	if (t[f][v].r > 0)
		t[f][v].val += t[f][t[f][v].r].val;
}
int get (int f, int l, int r, int v = 0, int tl = 1, int tr = INF - 1212) {
	if (v < 0 || tl > r || tr < l || l > r || tl > tr) return 0;
	if (l <= tl && tr <= r) return t[f][v].val;
	int tm = (tl + tr) / 2;
	int ans = 0;
	if (t[f][v].l > 0) ans += get (f, l, r, t[f][v].l, tl, tm);
	if (t[f][v].r > 0) ans += get (f, l, r, t[f][v].r, tm + 1, tr);
	return ans;
}
inline bool cmp (st a, st b) {
	return a.r > b.r;
}
main () {

	ios_base::sync_with_stdio (0);
	cin.tie (0); cout.tie (0);
	cin >> n >> k;
	for (int i = 1;i <= n;i ++) {
		cin >> a[i].x >> a[i].r >> a[i].f;
		t[a[i].f].pb (node ());
	}
	sort (a + 1, a + n + 1, &cmp);
	int ans = 0;
	for (int i = 1;i <= n;i ++) {
		for (int j = max(1ll, a[i].f - k);j <= min(10000ll, a[i].f + k);j ++) {
			if(!sz(t[j]))
				continue;
			ans += get (j, max (1ll, a[i].x - a[i].r), min(1000000000ll, a[i].x + a[i].r));
		}
		upd (a[i].f, a[i].x);
	}
	cout << ans;
	return 0;
}


#include <bits/stdc++.h>

#define F first
#define S second
#define mp make_pair
#define pb push_back
#define sz(x) x.size()
#define all(x) x.begin(), x.end()
#define pii pair < int , int >
#define task ""

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

const int N = 1e5 + 123;
const int mod = 1e9 + 7;
const int INF = 1e9 + 1;
const ll INFL = 3e18 + 1;
const double pi = acos(-1.0);

int n, k;

struct node {
	int l, r, val;
	node () {
		l = r = val = 0;
	}
};
struct st {
	int x, r, f;
} a[N];
vector < node > t[N];

void upd (int f, int pos, int v = 0, int tl = 1, int tr = INF) {
	//cerr << v << endl;
	if (tl == tr) {
		t[f][v].val ++;
		return;
	}
	int tm = (tl + tr) / 2;
	if (pos <= tm) {
		//cerr << "l = " << t[f][v].l << endl;
		if (!t[f][v].l) {
			//cerr << "yes" << endl;
			t[f][v].l = t[f].size ();
			t[f].pb (node ());
		}
		upd (f, pos, t[f][v].l, tl, tm);
	}
	else {
		//cerr << "no" << endl;
		if (!t[f][v].r) {
			t[f][v].r = t[f].size ();
			t[f].pb (node ());
		}
		upd (f, pos, t[f][v].r, tm + 1, tr);
	}
	t[f][v].val = t[f][t[f][v].l].val + t[f][t[f][v].r].val;
}
int get (int f, int l, int r, int v = 0, int tl = 1, int tr = INF) {
	if (tl > r || tr < l || l > r || tl > tr) return 0;
	if (l <= tl && tr <= r) return t[f][v].val;
	int tm = (tl + tr) / 2;
	int ans = 0;
	if (t[f][v].l) ans += get (f, l, r, t[f][v].l, tl, tm);
	if (t[f][v].r) ans += get (f, l, r, t[f][v].r, tm + 1, tr);
	return ans;
}
bool cmp (st a, st b) {
	return a.r > b.r;
}
int main () {

	scanf ("%d%d", &n, &k);
	for (int i = 1;i <= n;i ++) {
		scanf ("%d%d%d", &a[i].x, &a[i].r, &a[i].f);
		t[a[i].f].pb (node ());
	}
	sort (a + 1, a + n + 1, &cmp);
	int ans = 0;
	for (int i = 1;i <= n;i ++) {
		for (int j = a[i].f - k;j <= a[i].f + k;j ++) {
		    if (t[j].size ())
				ans += get (j, max (1, a[i].x - a[i].r), a[i].x + a[i].r);
		}
		upd (a[i].f, a[i].x);
	}
	printf ("%d", ans);
return 0;
}


#include <bits/stdc++.h>

#define F first
#define S second
#define mp make_pair
#define pb push_back
#define sz(x) x.size()
#define all(x) x.begin(), x.end()
#define pii pair < int , int >
#define task ""
#define int long long

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

const int N = 1e5 + 123;
const int mod = 1e9 + 7;
const int INF = 1e9 + 1;
const ll INFL = 3e18 + 1;
const double pi = acos(-1.0);

int n, k;

struct node {
	int l, r, val;
	node () {
		l = r = val = 0;
	}
};
struct st {
	int x, r, f;
} a[N];

vector < node > t[N];
int id[N];

void upd (int f, int pos, int v = 0, int tl = 1, int tr = INF) {
	if (tl == tr) {
		t[f][v].val ++;
		return;
	}
	int tm = (tl + tr) / 2;
	if (pos <= tm) {
		if (!t[f][v].l) {
			t[f][v].l = t[f].size ();
			t[f].pb (node ());
		}
		upd (f, pos, t[f][v].l, tl, tm);
	}
	else {
		if (!t[f][v].r) {
			t[f][v].r = t[f].size ();
			t[f].pb (node ());
		}
		upd (f, pos, t[f][v].r, tm + 1, tr);
	}
	t[f][v].val = t[f][t[f][v].l].val + t[f][t[f][v].r].val;
}
int get (int f, int l, int r, int v = 0, int tl = 1, int tr = INF) {
	if (tl > r || tr < l || l > r || tl > tr) return 0;
	if (l <= tl && tr <= r) return t[f][v].val;
	int tm = (tl + tr) / 2;
	int ans = 0;
	if (t[f][v].l) ans += get (f, l, r, t[f][v].l, tl, tm);
	if (t[f][v].r) ans += get (f, l, r, t[f][v].r, tm + 1, tr);
	return ans;
}
bool cmp (st a, st b) {
	return a.r > b.r;
}
main () {

	ios_base::sync_with_stdio (0);
	cin.tie (0); cout.tie (0);
	cin >> n >> k;
	for (int i = 1;i <= n;i ++) {
		cin >> a[i].x >> a[i].r >> a[i].f;
		id[a[i].f] = i;
		t[i].pb (node ());
	}
	sort (a + 1, a + n + 1, &cmp);
	int ans = 0;
	for (int i = 1;i <= n;i ++) {
		for (int j = a[i].f - k;j <= a[i].f + k;j ++) {
		    if (id[j])
				ans += get (id[j], max (1ll, a[i].x - a[i].r), a[i].x + a[i].r);
		}
		upd (id[a[i].f], a[i].x);
	}
	cout << ans;
return 0;
}


#include <bits/stdc++.h>
#define mp make_pair
#define fi first
#define se second

using namespace std;
typedef long long ll;
const int N = 2e4;

struct Treap{
    Treap *l, *r;
    int key, y, sz;

    Treap() : l(NULL), r(NULL), y(rand()), sz(1){}

    Treap(int x){
        l = r = NULL;
        key = x;
        y = rand();
        sz = 1;
    }
};

struct Node{
    int r, x, f;
    Node(){}
    Node(int r, int x, int f): r(r), x(x), f(f){}

    bool operator<(const Node & t) const
    {
        return r < t.r;
    }
};

vector <Treap *> root(N);

void recalc(Treap & *t){
    if (t == NULL)
        return;
    t->sz = (t->l != NULL ? t->l->sz : 0) + 1 + (t->r != NULL ? t->r->sz : NULL);
}

pair <Treap *, Treap *> split(Treap & *t, int x){
    if (t == NULL)
        return {NULL, NULL};
    if (t->key <= x){
        auto tmp = split(t->r, x);
        t->r = tmp.first;
        recalc(t);
        return {t, tmp.second};
    }
    else{
        auto tmp = split(t->l, x);
        t->l = tmp.second;
        recalc(t);
        return {tmp.first, t};
    }
}

Treap * merge(Treap *&l, Treap *&r){
    if (l == NULL)
        return r;
    if (r == NULL)
        return l;
    if (l->y >= r->y){
        l->l = merge(l->l, r);
        recalc(l);
        return l;
    }
    else{
        r->l = merge(l, r->l);
        recalc(r);
        return r;
    }
}

int getsize(Treap *& t){
    if (t == NULL)
        return 0;
    return t->sz;
}

void insert(Treap * &t, int x){
    auto tmp = split(t, x);

    t = merge(merge(tmp.first, new Treap(x)), tmp.second);
}

void erase(Treap * &t, int x){
    auto tmp = split(t, x);
    auto tmp1 = split(t, x - 1);
    t = merge(tmp1.first, tmp.second);
}

int get(Treap * &t, int l, int r){
    auto tmp = split(t, r);
    auto tmp1 = split(tmp.first, l - 1);

    int res = getsize(tmp1.second);

    t = merge(merge(tmp1.first, tmp1.second), tmp.second);

    return res;
}

int main()
{
    srand(time(NULL));

    int n, k;
    cin >> n >> k;

    ll ans = 0;

    vector <Node> p(n);

    for (int i = 0; i < n; i++){
        cin >> p[i].x >> p[i].r >> p[i].f;
        insert(root[p[i].f], p[i].x);
    }

    sort(p.begin(), p.end());

    for (int i = 0; i < n; i++){
        erase(root[p[i].f], p[i].x);

        for (int j = p[i].f - k; j <= p[i].f + k; j++){
            if (j < 1 || j >= N)
                continue;
            ans += get(root[j], p[i].x - p[i].r, p[i].x + p[i].r);
        }
    }

    cout << ans;
}


#include <bits/stdc++.h>
#define mp make_pair
#define fi first
#define se second

using namespace std;
typedef long long ll;
const int N = 2e4;

struct Treap{
    Treap *l, *r;
    int key, y, sz;

    Treap() : l(NULL), r(NULL), y(rand()), sz(1){}

    Treap(int x){
        l = r = NULL;
        key = x;
        y = rand();
        sz = 1;
    }
};

struct Node{
    int r, x, f;
    Node(){}
    Node(int r, int x, int f): r(r), x(x), f(f){}

    bool operator<(const Node & t) const
    {
        return r < t.r;
    }
};

vector <Treap *> root(N);

void recalc(Treap *t){
    if (t == NULL)
        return;
    t->sz = (t->l != NULL ? t->l->sz : 0) + 1 + (t->r != NULL ? t->r->sz : NULL);
}

pair <Treap *, Treap *> split(Treap *t, int x){
    if (t == NULL)
        return {NULL, NULL};
    if (t->key <= x){
        auto tmp = split(t->r, x);
        t->r = tmp.first;
        recalc(t);
        return {t, tmp.second};
    }
    else{
        auto tmp = split(t->l, x);
        t->l = tmp.second;
        recalc(t);
        return {tmp.first, t};
    }
}

Treap * merge(Treap *l, Treap *r){
    if (l == NULL)
        return r;
    if (r == NULL)
        return l;
    if (l->y >= r->y){
        l->l = merge(l->l, r);
        recalc(l);
        return l;
    }
    else{
        r->l = merge(l, r->l);
        recalc(r);
        return r;
    }
}

int getsize(Treap *t){
    if (t == NULL)
        return 0;
    return t->sz;
}

void insert(Treap * &t, int x){
    auto tmp = split(t, x);

    t = merge(merge(tmp.first, new Treap(x)), tmp.second);
}

void erase(Treap * &t, int x){
    auto tmp = split(t, x);
    auto tmp1 = split(t, x - 1);
    t = merge(tmp1.first, tmp.second);
}

int get(Treap * &t, int l, int r){
    auto tmp = split(t, r);
    auto tmp1 = split(tmp.first, l - 1);
    int res = getsize(tmp1.second);

    t = merge(merge(tmp1.first, tmp1.second), tmp.second);

    return res;
}

int main()
{
    srand(time(NULL));

    int n, k;
    cin >> n >> k;

    ll ans = 0;

    vector <Node> p(n);

    for (int i = 0; i < n; i++){
        cin >> p[i].x >> p[i].r >> p[i].f;
        insert(root[p[i].f], p[i].x);
    }

    sort(p.begin(), p.end());

    for (int i = 0; i < n; i++){
        erase(root[p[i].f], p[i].x);

        for (int j = p[i].f - k; j <= p[i].f + k; j++){
            if (p[i].f - k < 1 || p[i].f + k >= N)
                continue;
            ans += get(root[j], p[i].x - p[i].r, p[i].x + p[i].r);
        }
    }

    cout << ans;
}


#include <bits/stdc++.h>
#define mp make_pair
#define fi first
#define se second

using namespace std;
typedef long long ll;
const int N = 2e4;

struct Treap{
    Treap *l, *r;
    int key, y, sz;

    Treap() : l(NULL), r(NULL), y(rand()), sz(1){}

    Treap(int x){
        l = r = NULL;
        key = x;
        y = rand();
        sz = 1;
    }
};

struct Node{
    int r, x, f;
    Node(){}
    Node(int r, int x, int f): r(r), x(x), f(f){}

    bool operator<(const Node & t) const
    {
        return r < t.r;
    }
};

vector <Treap *> root(N);

void recalc(Treap *t){
    if (t == NULL)
        return;
    t->sz = (t->l != NULL ? t->l->sz : 0) + 1 + (t->r != NULL ? t->r->sz : NULL);
}

pair <Treap *, Treap *> split(Treap *t, int x){
    if (t == NULL)
        return {NULL, NULL};
    if (t->key <= x){
        auto tmp = split(t->r, x);
        t->r = tmp.first;
        recalc(t);
        return {t, tmp.second};
    }
    else{
        auto tmp = split(t->l, x);
        t->l = tmp.second;
        recalc(t);
        return {tmp.first, t};
    }
}

Treap * merge(Treap *l, Treap *r){
    if (l == NULL)
        return r;
    if (r == NULL)
        return l;
    if (l->y >= r->y){
        l->r = merge(l->r, r);
        recalc(l);
        return l;
    }
    else{
        r->l = merge(l, r->l);
        recalc(r);
        return r;
    }
}

int getsize(Treap *t){
    if (t == NULL)
        return 0;
    return t->sz;
}

void insert(Treap * &t, int x){
    auto tmp = split(t, x);

    t = merge(merge(tmp.first, new Treap(x)), tmp.second);
}

void erase(Treap * &t, int x){
    auto tmp = split(t, x);
    auto tmp1 = split(tmp.first, x - 1);
    t = merge(tmp1.first, tmp.second);
}

int get(Treap * &t, int l, int r){
    auto tmp = split(t, r);
    auto tmp1 = split(tmp.first, l - 1);
    recalc(tmp1.second);
    int res = getsize(tmp1.second);

    t = merge(merge(tmp1.first, tmp1.second), tmp.second);

    return res;
}

bool cmp(Node a, Node b){
    return a.r < b.r;
}

int main()
{
    srand(time(NULL));

    int n, k;
    cin >> n >> k;

    ll ans = 0;

    vector <Node> p(n);

    for (int i = 0; i < n; i++){
        cin >> p[i].x >> p[i].r >> p[i].f;
        insert(root[p[i].f], p[i].x);
    }

    sort(p.begin(), p.end(), cmp);

    for (int i = 0; i < n; i++){
        erase(root[p[i].f], p[i].x);

        for (int j = p[i].f - k; j <= p[i].f + k; j++){
            if (j < 1 || j >= N)
                continue;
            ans += get(root[j], p[i].x - p[i].r, p[i].x + p[i].r);
        }
    }

    cout << ans;
}


#include <bits/stdc++.h>
#define mp make_pair
#define fi first
#define se second

using namespace std;
typedef long long ll;
const int N = 2e4;

struct Treap{
    Treap *l, *r;
    int key, y, sz;

    Treap() : l(NULL), r(NULL), y(rand()), sz(1){}

    Treap(int x){
        l = r = NULL;
        key = x;
        y = rand();
        sz = 1;
    }
};

struct Node{
    int r, x, f;
    Node(){}
    Node(int r, int x, int f): r(r), x(x), f(f){}

    bool operator<(const Node & t) const
    {
        return r < t.r;
    }
};

vector <Treap *> root(N);

void recalc(Treap *t){
    if (t == NULL)
        return;
    t->sz = (t->l != NULL ? t->l->sz : 0) + 1 + (t->r != NULL ? t->r->sz : NULL);
}

pair <Treap *, Treap *> split(Treap *t, int x){
    if (t == NULL)
        return {NULL, NULL};
    if (t->key <= x){
        auto tmp = split(t->r, x);
        t->r = tmp.first;
        recalc(t);
        return {t, tmp.second};
    }
    else{
        auto tmp = split(t->l, x);
        t->l = tmp.second;
        recalc(t);
        return {tmp.first, t};
    }
}

Treap * merge(Treap *l, Treap *r){
    if (l == NULL)
        return r;
    if (r == NULL)
        return l;
    if (l->y >= r->y){
        l->l = merge(l->l, r);
        recalc(l);
        return l;
    }
    else{
        r->l = merge(l, r->l);
        recalc(r);
        return r;
    }
}

int getsize(Treap *t){
    if (t == NULL)
        return 0;
    return t->sz;
}

void insert(Treap * &t, int x){
    auto tmp = split(t, x);

    t = merge(merge(tmp.first, new Treap(x)), tmp.second);
}

void erase(Treap * &t, int x){
    auto tmp = split(t, x);
    auto tmp1 = split(t, x - 1);
    t = merge(tmp1.first, tmp.second);
}

int get(Treap * &t, int l, int r){
    auto tmp = split(t, r);
    auto tmp1 = split(tmp.first, l - 1);
    int res = getsize(tmp1.second);

    t = merge(merge(tmp1.first, tmp1.second), tmp.second);

    return res;
}

int main()
{
    srand(time(NULL));

    int n, k;
    cin >> n >> k;

    ll ans = 0;

    vector <Node> p(n);

    for (int i = 0; i < n; i++){
        cin >> p[i].x >> p[i].r >> p[i].f;
        insert(root[p[i].f], p[i].x);
    }

    sort(p.begin(), p.end());

    for (int i = 0; i < n; i++){
        erase(root[p[i].f], p[i].x);

        for (int j = p[i].f - k; j <= p[i].f + k; j++){
            if (j < 1 || j >= N)
                continue;
            ans += get(root[j], p[i].x - p[i].r, p[i].x + p[i].r);
        }
    }

    cout << ans;
}


#include <bits/stdc++.h>
#define mp make_pair
#define fi first
#define se second

using namespace std;
typedef long long ll;
const int N = 2e4;

struct Treap{
    Treap *l, *r;
    int key, y, sz;

    Treap() : l(NULL), r(NULL), y(rand()), sz(1){}

    Treap(int x){
        l = r = NULL;
        key = x;
        y = rand();
        sz = 1;
    }
};

struct Node{
    int r, x, f;
    Node(){}
    Node(int r, int x, int f): r(r), x(x), f(f){}

    bool operator<(const Node & t) const
    {
        return r < t.r;
    }
};

vector <Treap *> root(N);

void recalc(Treap *t){
    if (t == NULL)
        return;
    t->sz = (t->l != NULL ? t->l->sz : 0) + 1 + (t->r != NULL ? t->r->sz : NULL);
}

pair <Treap *, Treap *> split(Treap *t, int x){
    if (t == NULL)
        return {NULL, NULL};
    if (t->key <= x){
        auto tmp = split(t->r, x);
        t->r = tmp.first;
        recalc(t);
        return {t, tmp.second};
    }
    else{
        auto tmp = split(t->l, x);
        t->l = tmp.second;
        recalc(t);
        return {tmp.first, t};
    }
}

Treap * merge(Treap *l, Treap *r){
    if (l == NULL)
        return r;
    if (r == NULL)
        return l;
    if (l->y >= r->y){
        l->l = merge(l->l, r);
        recalc(l);
        return l;
    }
    else{
        r->l = merge(l, r->l);
        recalc(r);
        return r;
    }
}

int getsize(Treap *t){
    if (t == NULL)
        return 0;
    return t->sz;
}

void insert(Treap * &t, int x){
    auto tmp = split(t, x);

    t = merge(merge(tmp.first, new Treap(x)), tmp.second);
}

void erase(Treap * &t, int x){
    auto tmp = split(t, x);
    auto tmp1 = split(t, x - 1);
    t = merge(tmp1.first, tmp.second);
}

int get(Treap * &t, int l, int r){
    auto tmp = split(t, r);
    auto tmp1 = split(tmp.first, l - 1);
    recalc(tmp1.second);
    int res = getsize(tmp1.second);

    t = merge(merge(tmp1.first, tmp1.second), tmp.second);

    return res;
}

int main()
{//dsdsad
    srand(time(NULL));

    int n, k;
    cin >> n >> k;

    ll ans = 0;

    vector <Node> p(n);

    for (int i = 0; i < n; i++){
        cin >> p[i].x >> p[i].r >> p[i].f;
        insert(root[p[i].f], p[i].x);
    }

    sort(p.begin(), p.end());

    for (int i = 0; i < n; i++){
        erase(root[p[i].f], p[i].x);

        for (int j = p[i].f - k; j <= p[i].f + k; j++){
            if (j < 1 || j >= N)
                continue;
            ans += get(root[j], p[i].x - p[i].r, p[i].x + p[i].r);
        }
    }

    cout << ans;
}


#include <bits/stdc++.h>
#define mp make_pair
#define fi first
#define se second

using namespace std;
typedef long long ll;
const int N = 2e4;

struct Treap{
    Treap *l, *r;
    int key, y, sz;

    Treap() : l(NULL), r(NULL), y(rand()), sz(1){}

    Treap(int x){
        l = r = NULL;
        key = x;
        y = rand();
        sz = 1;
    }
};

struct Node{
    int r, x, f;
    Node(){}
    Node(int r, int x, int f): r(r), x(x), f(f){}

    bool operator<(const Node & t) const
    {
        return r < t.r;
    }
};

vector <Treap *> root(N);

void recalc(Treap *t){
    if (t == NULL)
        return;
    t->sz = (t->l != NULL ? t->l->sz : 0) + 1 + (t->r != NULL ? t->r->sz : NULL);
}

pair <Treap *, Treap *> split(Treap *t, int x){
    if (t == NULL)
        return {NULL, NULL};
    if (t->key <= x){
        auto tmp = split(t->r, x);
        t->r = tmp.first;
        recalc(t);
        return {t, tmp.second};
    }
    else{
        auto tmp = split(t->l, x);
        t->l = tmp.second;
        recalc(t);
        return {tmp.first, t};
    }
}

Treap * merge(Treap *l, Treap *r){
    if (l == NULL)
        return r;
    if (r == NULL)
        return l;
    if (l->y >= r->y){
        l->l = merge(l->l, r);
        recalc(l);
        return l;
    }
    else{
        r->l = merge(l, r->l);
        recalc(r);
        return r;
    }
}

int getsize(Treap *t){
    if (t == NULL)
        return 0;
    return t->sz;
}

void insert(Treap * &t, int x){
    auto tmp = split(t, x);

    t = merge(merge(tmp.first, new Treap(x)), tmp.second);
}

void erase(Treap * &t, int x){
    auto tmp = split(t, x);
    auto tmp1 = split(t, x - 1);
    t = merge(tmp1.first, tmp.second);
}

int get(Treap * &t, int l, int r){
    auto tmp = split(t, r);
    auto tmp1 = split(tmp.first, l - 1);
    int res = getsize(tmp1.second);

    t = merge(merge(tmp1.first, tmp1.second), tmp.second);

    return res;
}

int main()
{
    srand(time(NULL));

    int n, k;
    cin >> n >> k;

    ll ans = 0;

    vector <Node> p(n);

    for (int i = 0; i < n; i++){
        cin >> p[i].x >> p[i].r >> p[i].f;
        insert(root[p[i].f], p[i].x);
    }

    sort(p.begin(), p.end());

    for (int i = 0; i < n; i++){
        erase(root[p[i].f], p[i].x);

        for (int j = max(1, p[i].f - k); j <= min(N - 1, p[i].f + k); j++)
            ans += get(root[j], p[i].x - p[i].r, p[i].x + p[i].r);
    }

    cout << ans;
}


#include <bits/stdc++.h>
#define mp make_pair
#define fi first
#define se second

using namespace std;
typedef long long ll;
const int N = 2e4;

struct Treap{
    Treap *l, *r;
    int key, y, sz;

    Treap() : l(NULL), r(NULL), y(rand()), sz(1){}

    Treap(int x){
        l = r = NULL;
        key = x;
        y = rand();
        sz = 1;
    }
};

struct Node{
    int r, x, f;
    Node(){}
    Node(int r, int x, int f): r(r), x(x), f(f){}

    bool operator<(const Node & t) const
    {
        return r < t.r;
    }
};

vector <Treap *> root(N);

void recalc(Treap *t){
    if (t == NULL)
        return;
    t->sz = (t->l != NULL ? t->l->sz : 0) + 1 + (t->r != NULL ? t->r->sz : NULL);
}

pair <Treap *, Treap *> split(Treap *t, int x){
    if (t == NULL)
        return {NULL, NULL};
    if (t->key <= x){
        auto tmp = split(t->r, x);
        t->r = tmp.first;
        recalc(t);
        return {t, tmp.second};
    }
    else{
        auto tmp = split(t->l, x);
        t->l = tmp.second;
        recalc(t);
        return {tmp.first, t};
    }
}

Treap * merge(Treap *l, Treap *r){
    if (l == NULL)
        return r;
    if (r == NULL)
        return l;
    if (l->y >= r->y){
        l->l = merge(l->l, r);
        recalc(l);
        return l;
    }
    else{
        r->l = merge(l, r->l);
        recalc(r);
        return r;
    }
}

int getsize(Treap *t){
    if (t == NULL)
        return 0;
    return t->sz;
}

void insert(Treap * &t, int x){
    auto tmp = split(t, x);

    t = merge(merge(tmp.first, new Treap(x)), tmp.second);
}

void erase(Treap * &t, int x){
    auto tmp = split(t, x);
    auto tmp1 = split(t, x - 1);
    t = merge(tmp1.first, tmp.second);
}

int get(Treap * &t, int l, int r){
    auto tmp = split(t, r);
    auto tmp1 = split(tmp.first, l - 1);

    int res = getsize(tmp1.second);

    t = merge(merge(tmp1.first, tmp1.second), tmp.second);

    return res;
}

int main()
{
    srand(time(NULL));

    int n, k;
    cin >> n >> k;

    ll ans = 0;

    vector <Node> p(n);

    for (int i = 0; i < n; i++){
        cin >> p[i].x >> p[i].r >> p[i].f;
        insert(root[p[i].f], p[i].x);
    }

    sort(p.begin(), p.end());

    for (int i = 0; i < n; i++){
        erase(root[p[i].f], p[i].x);

        for (int j = p[i].f - k; j <= p[i].f + k; j++){
            if (j < 1 || j >= N)
                continue;
            ans += get(root[j], p[i].x - p[i].r, p[i].x + p[i].r);
        }
    }

    cout << ans;
}