#include <bits/stdc++.h>
using namespace std;
const int N = 1<<17;
const int LOG = 18;
vector < int > v[N],digit[N];
namespace cd {
int sz[N];
bool used[N];
int parent[N];
int link[N];
#define cd_parent parent
void cd_dfs(int node, vector < int > &path) {
used[node]=true;
path.push_back(node);
sz[node]=1;
int i;
for(i=0;i<(int)(v[node].size());i++) if(!used[v[node][i]]) {
cd_dfs(v[node][i],path);
sz[node]+=sz[v[node][i]];
}
}
int get_centroid(int node, int cnt) {
int i,max_size=-1,who;
used[node]=true;
for(i=0;i<(int)(v[node].size());i++) if(!used[v[node][i]]) {
if(sz[v[node][i]]>max_size) max_size=sz[v[node][i]],who=v[node][i];
}
if(max_size<=(cnt>>1)) return node;
else return get_centroid(who,cnt);
}
int centroid_decomposition(int node) {
int i,ans;
vector < int > nodes;
cd_dfs(node,nodes);
for(i=0;i<(int)(nodes.size());i++) used[nodes[i]]=false;
ans=get_centroid(node,(int)(nodes.size()));
for(i=0;i<(int)(nodes.size());i++) used[nodes[i]]=false;
used[ans]=true;
for(i=0;i<(int)(v[ans].size());i++) if(!used[v[ans][i]]) cd_parent[centroid_decomposition(v[ans][i])]=ans;
return ans;
}
}
#define pow oaighkjqghja
#define pow10 pow
int n,m;
int pow[N];
map < int, int > cnt[N];
map < pair < int, int >, int > cnt2[N];
long long ans;
int root;
bool used[N];
int parent[N],level[N];
int link[N];
int jump[N][LOG];
int jump_value[N][LOG];
int partial_reversed_value[N];
int fpow(int a, int b) {
if(a==0) return 0;
if(b==0) return 1;
int p=fpow(a,b>>1);
p=(p*1ll*p)%m;
if(b&1) p=(p*1ll*a)%m;
return p;
}
int div_mod(int a, int b) {
return (a*1ll*fpow(b,m-2))%m;
}
void dfs(int node) {
partial_reversed_value[node]=(partial_reversed_value[parent[node]]*1ll*10)%m;
partial_reversed_value[node]=(partial_reversed_value[node]+link[node])%m;
used[node]=true;
int i;
for(i=0;i<(int)(v[node].size());i++) if(!used[v[node][i]]) parent[v[node][i]]=node,level[v[node][i]]=level[node]+1,link[v[node][i]]=digit[node][i],dfs(v[node][i]);
}
int walk_up(int node, int lvl) {
int i;
for(i=16;i>=0;i--) if(jump[node][i]>=lvl) node=jump[node][i];
return node;
}
int get_lca(int a, int b) {
if(level[a]>level[b]) swap(a,b);
b=walk_up(b,level[a]);
if(a==b) return a;
int i;
for(i=16;i>=0;i--) if(jump[a][i]!=jump[b][i]) a=jump[a][i],b=jump[b][i];
return parent[a];
}
int get_distance(int a, int b) {
return level[a]+level[b]-(level[get_lca(a,b)]<<1);
}
int get_jump_value(int a, int b) {
int ans=0,i;
for(i=16;i>=0;i--) {
if(level[jump[a][i]]>=level[b]) {
ans=(ans*1ll*pow[1<<i])%m;
ans=(ans+jump_value[a][i])%m;
a=jump[a][i];
}
}
return ans;
}
int get_reversed_value(int a, int b) {
int ans=(partial_reversed_value[a]-(pow[level[a]-level[b]]*1ll*partial_reversed_value[b])%m+m)%m;
//ans=div_mod(ans,pow[level[b]-level[a]]);
return ans;
}
int get_value(int a, int b) {
int their_lca=get_lca(a,b),dist1=level[a]-level[their_lca],dist2=level[b]-level[their_lca],ans;
ans=(get_jump_value(a,their_lca)*1ll*pow[dist2])%m;
ans=(ans+get_reversed_value(b,their_lca))%m;
return ans;
}
void update(int node) {
int value,from=-1,where=node;
while(where) {
value=get_value(node,where);
++cnt[where][value];
++cnt2[where][make_pair(value,from)];
from=where;
where=cd::parent[where];
}
}
int query(int node) {
int value,ans=0,length,need,from=-1,where=node;
while(where) {
value=get_value(where,node);
need=(0-value+m)%m;
length=get_distance(where,node);
need=div_mod(need,pow[length]);
ans+=cnt[where][need]-cnt2[where][make_pair(need,from)];
from=where;
where=cd::parent[where];
}
return ans;
}
int main() {
int i,j,x,y,z;
scanf("%d %d", &n, &m);
pow[0]=1;
for(i=1;i<N;i++) pow[i]=(pow[i-1]*1ll*10)%m;
for(i=1;i<n;i++) scanf("%d %d %d", &x, &y, &z),++x,++y,v[x].push_back(y),v[y].push_back(x),digit[x].push_back(z),digit[y].push_back(z);
level[1]=1;
dfs(1);
for(i=1;i<=n;i++) jump[i][0]=parent[i],jump_value[i][0]=link[i];
for(j=1;j<=16;j++) for(i=1;i<=n;i++) {
jump[i][j]=jump[jump[i][j-1]][j-1];
jump_value[i][j]=jump_value[i][j-1];
jump_value[i][j]=(jump_value[i][j]*1ll*pow[1<<(j-1)])%m;
jump_value[i][j]=(jump_value[i][j]+jump_value[jump[i][j-1]][j-1])%m;
}
root=cd::centroid_decomposition(1);
for(i=1;i<=n;i++) update(i);
for(i=1;i<=n;i++) ans+=query(i);
printf("%lld\n", ans);
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY29uc3QgaW50IE4gPSAxPDwxNzsKY29uc3QgaW50IExPRyA9IDE4OwoKdmVjdG9yIDwgaW50ID4gdltOXSxkaWdpdFtOXTsKCm5hbWVzcGFjZSBjZCB7CiAgICBpbnQgc3pbTl07CiAgICBib29sIHVzZWRbTl07CiAgICBpbnQgcGFyZW50W05dOwogICAgaW50IGxpbmtbTl07CiAgICAjZGVmaW5lIGNkX3BhcmVudCBwYXJlbnQKICAgIHZvaWQgY2RfZGZzKGludCBub2RlLCB2ZWN0b3IgPCBpbnQgPiAmcGF0aCkgewogICAgICAgIHVzZWRbbm9kZV09dHJ1ZTsKICAgICAgICBwYXRoLnB1c2hfYmFjayhub2RlKTsKICAgICAgICBzeltub2RlXT0xOwogICAgICAgIGludCBpOwogICAgICAgIGZvcihpPTA7aTwoaW50KSh2W25vZGVdLnNpemUoKSk7aSsrKSBpZighdXNlZFt2W25vZGVdW2ldXSkgewogICAgICAgICAgICBjZF9kZnModltub2RlXVtpXSxwYXRoKTsKICAgICAgICAgICAgc3pbbm9kZV0rPXN6W3Zbbm9kZV1baV1dOwogICAgICAgIH0KICAgIH0KCiAgICBpbnQgZ2V0X2NlbnRyb2lkKGludCBub2RlLCBpbnQgY250KSB7CiAgICAgICAgaW50IGksbWF4X3NpemU9LTEsd2hvOwogICAgICAgIHVzZWRbbm9kZV09dHJ1ZTsKICAgICAgICBmb3IoaT0wO2k8KGludCkodltub2RlXS5zaXplKCkpO2krKykgaWYoIXVzZWRbdltub2RlXVtpXV0pIHsKICAgICAgICAgICAgaWYoc3pbdltub2RlXVtpXV0+bWF4X3NpemUpIG1heF9zaXplPXN6W3Zbbm9kZV1baV1dLHdobz12W25vZGVdW2ldOwogICAgICAgIH0KICAgICAgICBpZihtYXhfc2l6ZTw9KGNudD4+MSkpIHJldHVybiBub2RlOwogICAgICAgIGVsc2UgcmV0dXJuIGdldF9jZW50cm9pZCh3aG8sY250KTsKICAgIH0KCiAgICBpbnQgY2VudHJvaWRfZGVjb21wb3NpdGlvbihpbnQgbm9kZSkgewogICAgICAgIGludCBpLGFuczsKICAgICAgICB2ZWN0b3IgPCBpbnQgPiBub2RlczsKICAgICAgICBjZF9kZnMobm9kZSxub2Rlcyk7CiAgICAgICAgZm9yKGk9MDtpPChpbnQpKG5vZGVzLnNpemUoKSk7aSsrKSB1c2VkW25vZGVzW2ldXT1mYWxzZTsKICAgICAgICBhbnM9Z2V0X2NlbnRyb2lkKG5vZGUsKGludCkobm9kZXMuc2l6ZSgpKSk7CiAgICAgICAgZm9yKGk9MDtpPChpbnQpKG5vZGVzLnNpemUoKSk7aSsrKSB1c2VkW25vZGVzW2ldXT1mYWxzZTsKICAgICAgICB1c2VkW2Fuc109dHJ1ZTsKICAgICAgICBmb3IoaT0wO2k8KGludCkodlthbnNdLnNpemUoKSk7aSsrKSBpZighdXNlZFt2W2Fuc11baV1dKSBjZF9wYXJlbnRbY2VudHJvaWRfZGVjb21wb3NpdGlvbih2W2Fuc11baV0pXT1hbnM7CiAgICAgICAgcmV0dXJuIGFuczsKICAgIH0KfQoKI2RlZmluZSBwb3cgb2FpZ2hranFnaGphCiNkZWZpbmUgcG93MTAgcG93CgppbnQgbixtOwppbnQgcG93W05dOwptYXAgPCBpbnQsIGludCA+IGNudFtOXTsKbWFwIDwgcGFpciA8IGludCwgaW50ID4sIGludCA+IGNudDJbTl07CmxvbmcgbG9uZyBhbnM7CmludCByb290Owpib29sIHVzZWRbTl07CmludCBwYXJlbnRbTl0sbGV2ZWxbTl07CmludCBsaW5rW05dOwppbnQganVtcFtOXVtMT0ddOwppbnQganVtcF92YWx1ZVtOXVtMT0ddOwppbnQgcGFydGlhbF9yZXZlcnNlZF92YWx1ZVtOXTsKCmludCBmcG93KGludCBhLCBpbnQgYikgewogICAgaWYoYT09MCkgcmV0dXJuIDA7CiAgICBpZihiPT0wKSByZXR1cm4gMTsKICAgIGludCBwPWZwb3coYSxiPj4xKTsKICAgIHA9KHAqMWxsKnApJW07CiAgICBpZihiJjEpIHA9KHAqMWxsKmEpJW07CiAgICByZXR1cm4gcDsKfQoKaW50IGRpdl9tb2QoaW50IGEsIGludCBiKSB7CiAgICByZXR1cm4gKGEqMWxsKmZwb3coYixtLTIpKSVtOwp9Cgp2b2lkIGRmcyhpbnQgbm9kZSkgewogICAgcGFydGlhbF9yZXZlcnNlZF92YWx1ZVtub2RlXT0ocGFydGlhbF9yZXZlcnNlZF92YWx1ZVtwYXJlbnRbbm9kZV1dKjFsbCoxMCklbTsKICAgIHBhcnRpYWxfcmV2ZXJzZWRfdmFsdWVbbm9kZV09KHBhcnRpYWxfcmV2ZXJzZWRfdmFsdWVbbm9kZV0rbGlua1tub2RlXSklbTsKICAgIHVzZWRbbm9kZV09dHJ1ZTsKICAgIGludCBpOwogICAgZm9yKGk9MDtpPChpbnQpKHZbbm9kZV0uc2l6ZSgpKTtpKyspIGlmKCF1c2VkW3Zbbm9kZV1baV1dKSBwYXJlbnRbdltub2RlXVtpXV09bm9kZSxsZXZlbFt2W25vZGVdW2ldXT1sZXZlbFtub2RlXSsxLGxpbmtbdltub2RlXVtpXV09ZGlnaXRbbm9kZV1baV0sZGZzKHZbbm9kZV1baV0pOwp9CgppbnQgd2Fsa191cChpbnQgbm9kZSwgaW50IGx2bCkgewogICAgaW50IGk7CiAgICBmb3IoaT0xNjtpPj0wO2ktLSkgaWYoanVtcFtub2RlXVtpXT49bHZsKSBub2RlPWp1bXBbbm9kZV1baV07CiAgICByZXR1cm4gbm9kZTsKfQoKaW50IGdldF9sY2EoaW50IGEsIGludCBiKSB7CiAgICBpZihsZXZlbFthXT5sZXZlbFtiXSkgc3dhcChhLGIpOwogICAgYj13YWxrX3VwKGIsbGV2ZWxbYV0pOwogICAgaWYoYT09YikgcmV0dXJuIGE7CiAgICBpbnQgaTsKICAgIGZvcihpPTE2O2k+PTA7aS0tKSBpZihqdW1wW2FdW2ldIT1qdW1wW2JdW2ldKSBhPWp1bXBbYV1baV0sYj1qdW1wW2JdW2ldOwogICAgcmV0dXJuIHBhcmVudFthXTsKfQoKaW50IGdldF9kaXN0YW5jZShpbnQgYSwgaW50IGIpIHsKICAgIHJldHVybiBsZXZlbFthXStsZXZlbFtiXS0obGV2ZWxbZ2V0X2xjYShhLGIpXTw8MSk7Cn0KCmludCBnZXRfanVtcF92YWx1ZShpbnQgYSwgaW50IGIpIHsKICAgIGludCBhbnM9MCxpOwogICAgZm9yKGk9MTY7aT49MDtpLS0pIHsKICAgICAgICBpZihsZXZlbFtqdW1wW2FdW2ldXT49bGV2ZWxbYl0pIHsKICAgICAgICAgICAgYW5zPShhbnMqMWxsKnBvd1sxPDxpXSklbTsKICAgICAgICAgICAgYW5zPShhbnMranVtcF92YWx1ZVthXVtpXSklbTsKICAgICAgICAgICAgYT1qdW1wW2FdW2ldOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBhbnM7Cn0KCmludCBnZXRfcmV2ZXJzZWRfdmFsdWUoaW50IGEsIGludCBiKSB7CiAgICBpbnQgYW5zPShwYXJ0aWFsX3JldmVyc2VkX3ZhbHVlW2FdLShwb3dbbGV2ZWxbYV0tbGV2ZWxbYl1dKjFsbCpwYXJ0aWFsX3JldmVyc2VkX3ZhbHVlW2JdKSVtK20pJW07CiAgICAvL2Fucz1kaXZfbW9kKGFucyxwb3dbbGV2ZWxbYl0tbGV2ZWxbYV1dKTsKICAgIHJldHVybiBhbnM7Cn0KCmludCBnZXRfdmFsdWUoaW50IGEsIGludCBiKSB7CiAgICBpbnQgdGhlaXJfbGNhPWdldF9sY2EoYSxiKSxkaXN0MT1sZXZlbFthXS1sZXZlbFt0aGVpcl9sY2FdLGRpc3QyPWxldmVsW2JdLWxldmVsW3RoZWlyX2xjYV0sYW5zOwogICAgYW5zPShnZXRfanVtcF92YWx1ZShhLHRoZWlyX2xjYSkqMWxsKnBvd1tkaXN0Ml0pJW07CiAgICBhbnM9KGFucytnZXRfcmV2ZXJzZWRfdmFsdWUoYix0aGVpcl9sY2EpKSVtOwogICAgcmV0dXJuIGFuczsKfQoKdm9pZCB1cGRhdGUoaW50IG5vZGUpIHsKICAgIGludCB2YWx1ZSxmcm9tPS0xLHdoZXJlPW5vZGU7CiAgICB3aGlsZSh3aGVyZSkgewogICAgICAgIHZhbHVlPWdldF92YWx1ZShub2RlLHdoZXJlKTsKICAgICAgICArK2NudFt3aGVyZV1bdmFsdWVdOwogICAgICAgICsrY250Mlt3aGVyZV1bbWFrZV9wYWlyKHZhbHVlLGZyb20pXTsKICAgICAgICBmcm9tPXdoZXJlOwogICAgICAgIHdoZXJlPWNkOjpwYXJlbnRbd2hlcmVdOwogICAgfQp9CgppbnQgcXVlcnkoaW50IG5vZGUpIHsKICAgIGludCB2YWx1ZSxhbnM9MCxsZW5ndGgsbmVlZCxmcm9tPS0xLHdoZXJlPW5vZGU7CiAgICB3aGlsZSh3aGVyZSkgewogICAgICAgIHZhbHVlPWdldF92YWx1ZSh3aGVyZSxub2RlKTsKICAgICAgICBuZWVkPSgwLXZhbHVlK20pJW07CiAgICAgICAgbGVuZ3RoPWdldF9kaXN0YW5jZSh3aGVyZSxub2RlKTsKICAgICAgICBuZWVkPWRpdl9tb2QobmVlZCxwb3dbbGVuZ3RoXSk7CiAgICAgICAgYW5zKz1jbnRbd2hlcmVdW25lZWRdLWNudDJbd2hlcmVdW21ha2VfcGFpcihuZWVkLGZyb20pXTsKICAgICAgICBmcm9tPXdoZXJlOwogICAgICAgIHdoZXJlPWNkOjpwYXJlbnRbd2hlcmVdOwogICAgfQogICAgcmV0dXJuIGFuczsKfQoKaW50IG1haW4oKSB7CiAgICBpbnQgaSxqLHgseSx6OwoKICAgIHNjYW5mKCIlZCAlZCIsICZuLCAmbSk7CiAgICBwb3dbMF09MTsKICAgIGZvcihpPTE7aTxOO2krKykgcG93W2ldPShwb3dbaS0xXSoxbGwqMTApJW07CiAgICBmb3IoaT0xO2k8bjtpKyspIHNjYW5mKCIlZCAlZCAlZCIsICZ4LCAmeSwgJnopLCsreCwrK3ksdlt4XS5wdXNoX2JhY2soeSksdlt5XS5wdXNoX2JhY2soeCksZGlnaXRbeF0ucHVzaF9iYWNrKHopLGRpZ2l0W3ldLnB1c2hfYmFjayh6KTsKICAgIGxldmVsWzFdPTE7CiAgICBkZnMoMSk7CiAgICBmb3IoaT0xO2k8PW47aSsrKSBqdW1wW2ldWzBdPXBhcmVudFtpXSxqdW1wX3ZhbHVlW2ldWzBdPWxpbmtbaV07CiAgICBmb3Ioaj0xO2o8PTE2O2orKykgZm9yKGk9MTtpPD1uO2krKykgewogICAgICAgIGp1bXBbaV1bal09anVtcFtqdW1wW2ldW2otMV1dW2otMV07CiAgICAgICAganVtcF92YWx1ZVtpXVtqXT1qdW1wX3ZhbHVlW2ldW2otMV07CiAgICAgICAganVtcF92YWx1ZVtpXVtqXT0oanVtcF92YWx1ZVtpXVtqXSoxbGwqcG93WzE8PChqLTEpXSklbTsKICAgICAgICBqdW1wX3ZhbHVlW2ldW2pdPShqdW1wX3ZhbHVlW2ldW2pdK2p1bXBfdmFsdWVbanVtcFtpXVtqLTFdXVtqLTFdKSVtOwogICAgfQogICAgcm9vdD1jZDo6Y2VudHJvaWRfZGVjb21wb3NpdGlvbigxKTsKICAgIGZvcihpPTE7aTw9bjtpKyspIHVwZGF0ZShpKTsKICAgIGZvcihpPTE7aTw9bjtpKyspIGFucys9cXVlcnkoaSk7CiAgICBwcmludGYoIiVsbGRcbiIsIGFucyk7CgogICAgcmV0dXJuIDA7Cn0K