rt
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
constexpr ll N = 4e5 + 5;
// 手写哈希函数 (和+平方和)
ll make2(ll a, ll b) { return a * a + b * b + a + b; }
ll make3(ll a, ll b, ll c) { return make2(a, b) + c * c + c; }
ll make4(ll a, ll b, ll c, ll d) { return make3(a, b, c) + d * d + d; }
// 三元组
struct node {
ll u, v, w;
// 字典序
friend bool operator<(const node &a, const node &b) {
if (a.u != b.u) return a.u < b.u;
if (a.v != b.v) return a.v < b.v;
return a.w < b.w;
}
} a[N];
// mp: 三元组标记, mp4: 四元组标记
unordered_map<ll, bool> mp, mp4;
// 判断四元组 a,b,c,d 是否满足题目要求
bool judge(ll a, ll b, ll c, ll d) {
if (!(a < b && b < c && c < d)) return 0;
if (mp[make3(a, b, c)] == 0) return 0;
if (mp[make3(a, b, d)] == 0) return 0;
if (mp[make3(a, c, d)] == 0) return 0;
if (mp[make3(b, c, d)] == 0) return 0;
return 1;
}
// 从 二元组(三元组的前两个数) 到 三元组下标 的映射, st 表示开始下标, ed 表示结束下标
unordered_map<ll, ll> st, ed;
ll n, m, ans;
int main(void) {
ios::sync_with_stdio(0), cin.tie(nullptr);
cin >> n >> m;
for (ll i = 1, u, v, w; i <= m; i++) {
cin >> u >> v >> w;
mp[make3(u, v, w)] = 1;
a[i] = {u, v, w};
}
sort(a + 1, a + 1 + m);
// 把每个三元组的前两个数构成的二元组的下标范围求出来, 方便后续查找
for (ll i = 1; i <= m; i++) {
ll t = make2(a[i].u, a[i].v);
if (st[t] == 0) st[t] = i;
ed[t] = i;
}
// 枚举三元组 (u,v,w)
for (ll i = 1; i <= m; i++) {
ll tc = make2(a[i].u, a[i].v); // 三元组的前两个数 (u,v)
ll ta = make2(a[i].v, a[i].w); // 三元组的后两个数 (v,w)
if (st[ta] == 0) continue; // (v,w) 不存在直接跳过
ll tb = make2(a[i].u, a[i].w); // 三元组的首尾两个数 (u,w)
if (st[tb] == 0) continue; // (u,w) 不存在直接跳过
ll flag = tc; // 找范围最小的那一段
if (ed[flag] - st[flag] > ed[ta] - st[ta]) flag = ta;
if (ed[flag] - st[flag] > ed[tb] - st[tb]) flag = tb;
// 枚举范围最小的那一段
for (ll j = st[flag]; j <= ed[flag]; j++) {
if (flag == tc && i == j) continue; // 最小的那一段就是 (u,v) 即三元组本身所在段, 需要跳过本身
if (a[j].w <= a[i].w) continue; // 保证四元组递增
if (judge(a[i].u, a[i].v, a[i].w, a[j].w)) {
// // 去重, 统计
// if (!mp4[make4(a[i].u, a[i].v, a[i].w, a[j].w)]) {
// mp4[make4(a[i].u, a[i].v, a[i].w, a[j].w)] = 1;
ans++;
// }
}
}
}
printf("%lld\n", ans);
return 0;
}