#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
const int INF = 1e9;
const ll LINF = 1e18;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
const int p = 1e6 + 3;
const int N = 1e6 + 5;
int n, m;
vector<int> adj[N];
vector<ii> edges;
ll h_val[N];
ll h_xor_adj[N];
void precompute() {
for (int u = 1; u <= n; u++) {
h_val[u] = rng();
}
for (int u = 1; u <= n; u++) {
for (int v : adj[u]) {
h_xor_adj[u] ^= h_val[v];
}
}
}
map<ll, int> cnt[N];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m;
for (int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
edges.push_back({u, v});
}
precompute();
ll ans = 0;
// Xét các cặp (u, v) mà u, v không phải là bạn của nhau
for (int u = 1; u <= n; u++) {
ans += cnt[adj[u].size()][h_xor_adj[u]];
cnt[adj[u].size()][h_xor_adj[u]]++;
}
// Xét các cặp (u, v) mà u, v là bạn của nhau
for (ii e : edges) {
int u = e.first, v = e.second;
if (adj[u].size() != adj[v].size()) continue;
h_xor_adj[u] ^= h_val[v], h_xor_adj[v] ^= h_val[u];
ans += (h_xor_adj[u] == h_xor_adj[v]);
h_xor_adj[u] ^= h_val[v], h_xor_adj[v] ^= h_val[u];
}
cout << ans << '\n';
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+IAoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsgIAoKdHlwZWRlZiBsb25nIGxvbmcgbGw7ICAKdHlwZWRlZiBwYWlyPGludCwgaW50PiBpaTsgIAoKY29uc3QgaW50IElORiA9IDFlOTsgIApjb25zdCBsbCBMSU5GID0gMWUxODsgIAoKbXQxOTkzN182NCBybmcoY2hyb25vOjpzdGVhZHlfY2xvY2s6Om5vdygpLnRpbWVfc2luY2VfZXBvY2goKS5jb3VudCgpKTsgICAKCmNvbnN0IGludCBwID0gMWU2ICsgMzsgCmNvbnN0IGludCBOID0gMWU2ICsgNTsgCgppbnQgbiwgbTsgIAp2ZWN0b3I8aW50PiBhZGpbTl07IAp2ZWN0b3I8aWk+IGVkZ2VzOyAKCmxsIGhfdmFsW05dOyAKbGwgaF94b3JfYWRqW05dOyAKCnZvaWQgcHJlY29tcHV0ZSgpIHsKCWZvciAoaW50IHUgPSAxOyB1IDw9IG47IHUrKykgewoJCWhfdmFsW3VdID0gcm5nKCk7ICAKCX0KCglmb3IgKGludCB1ID0gMTsgdSA8PSBuOyB1KyspIHsKCQlmb3IgKGludCB2IDogYWRqW3VdKSB7CgkJCWhfeG9yX2Fkalt1XSBePSBoX3ZhbFt2XTsKCQl9Cgl9Cn0KCm1hcDxsbCwgaW50PiBjbnRbTl07IAoKaW50IG1haW4oKSB7Cglpb3M6OnN5bmNfd2l0aF9zdGRpbyhmYWxzZSk7IAoJY2luLnRpZShudWxscHRyKTsgCQoJY2luID4+IG4gPj4gbTsgCglmb3IgKGludCBpID0gMTsgaSA8PSBtOyBpKyspIHsKCQlpbnQgdSwgdjsgCgkJY2luID4+IHUgPj4gdjsgCgkJYWRqW3VdLnB1c2hfYmFjayh2KTsgCgkJYWRqW3ZdLnB1c2hfYmFjayh1KTsgCQkKCQllZGdlcy5wdXNoX2JhY2soe3UsIHZ9KTsgCgl9CgoJcHJlY29tcHV0ZSgpOyAgCgoJbGwgYW5zID0gMDsgIAoJLy8gWMOpdCBjw6FjIGPhurdwICh1LCB2KSBtw6AgdSwgdiBraMO0bmcgcGjhuqNpIGzDoCBi4bqhbiBj4bunYSBuaGF1Cglmb3IgKGludCB1ID0gMTsgdSA8PSBuOyB1KyspIHsKCQlhbnMgKz0gY250W2Fkalt1XS5zaXplKCldW2hfeG9yX2Fkalt1XV07ICAKCQljbnRbYWRqW3VdLnNpemUoKV1baF94b3JfYWRqW3VdXSsrOyAKCX0KCgkvLyBYw6l0IGPDoWMgY+G6t3AgKHUsIHYpIG3DoCB1LCB2IGzDoCBi4bqhbiBj4bunYSBuaGF1CQoJZm9yIChpaSBlIDogZWRnZXMpIHsKCQlpbnQgdSA9IGUuZmlyc3QsIHYgPSBlLnNlY29uZDsgCgkJaWYgKGFkalt1XS5zaXplKCkgIT0gYWRqW3ZdLnNpemUoKSkgY29udGludWU7IAoJCWhfeG9yX2Fkalt1XSBePSBoX3ZhbFt2XSwgaF94b3JfYWRqW3ZdIF49IGhfdmFsW3VdOyAgCgkJYW5zICs9IChoX3hvcl9hZGpbdV0gPT0gaF94b3JfYWRqW3ZdKTsgCgkJaF94b3JfYWRqW3VdIF49IGhfdmFsW3ZdLCBoX3hvcl9hZGpbdl0gXj0gaF92YWxbdV07ICAKCX0KCgljb3V0IDw8IGFucyA8PCAnXG4nOyAKfQ==