#include <bits/stdc++.h>   #pragma GCC optimize( Ofast )   using namespace std;   const long long mod = 1000000007;   void solve() {     int n, m, u, v;     cin >> n >> m;     vector<int> adj[n + 1];     for (int i = 0; i < m; i++) {       cin >> u >> v;       adj[u].push_back(v);       adj[v].push_back(u);     }     vector<pair<long long, long long> > hash, hash_orig;     hash.reserve(n);     long long p1 = 31, p2 = 53, h1, h2;     long long pow_p1[n + 1], pow_p2[n + 1];     pow_p1[0] = pow_p2[0] = 1;     for (int i = 1; i <= n; i++) {       pow_p1[i] = pow_p1[i - 1] * p1 % mod;       pow_p2[i] = pow_p2[i - 1] * p2 % mod;     }     for (int i = 1; i <= n; i++) {       h1 = 0;       h2 = 0;       for (int &j : adj[i]) {         h1 += pow_p1[j];         h2 += pow_p2[j];       }       hash.push_back({h1, h2});     }     hash_orig = hash;     sort((hash).begin(), (hash).end());     long long ans = 0;     int cnt = 1;     for (int i = 1; i < n; i++) {       if (hash[i] != hash[i - 1]) {         ans += 1ll * cnt * (cnt - 1) / 2;         cnt = 1;       } else         cnt++;     }     ans += 1ll * cnt * (cnt - 1) / 2;     for (int i = 1; i <= n; i++) {       hash_orig[i - 1].first += pow_p1[i];       hash_orig[i - 1].second += pow_p2[i];     }     for (int i = 1; i <= n; i++) {       for (int &j : adj[i]) {         if (j < i || adj[i].size() != adj[j].size()) continue;         if (hash_orig[i - 1] == hash_orig[j - 1]) ans++;       }     }     cout << ans <<   n ;   }   signed main() {     ios_base::sync_with_stdio(false);     cin.tie(NULL);     cout.tie(NULL);     int t = 1;     while (t--) {       solve();     }   }   