#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector < vector <long long> > g;
long long hash[1000003];
long long b[1000003];
int n,m;
long long ans;
long long coun;
long long a[1000003];
int aa[1000003];
int d[1000003];
void radixsort(int *a,int n)
{
    int k=sizeof(int);
    int i,j;
    for(i=0;i<k;i++)
    {
        int c[256]={0};
        for(j=0;j<n;j++)
            c[(a[j]>>(8*i)&255)]++;
        for(j=1;j<256;j++)
            c[j]+=c[j-1];
        for(j=n-1;j>-1;j--)
            d[--c[(a[j]>>(8*i)&255)]]=a[j];
        for(j=0;j<n;j++)
            a[j]=d[j];
    }
}
void radixsort2(long long *a,int n)
{
    int k=sizeof(long long);
    int i,j;
    for(i=0;i<k;i++)
    {
        int c[256]={0};
        for(j=0;j<n;j++)
            c[(a[j]>>(8*i)&255)]++;
        for(j=1;j<256;j++)
            c[j]+=c[j-1];
        for(j=n-1;j>-1;j--)
            b[--c[(a[j]>>(8*i)&255)]]=a[j];
        for(j=0;j<n;j++)
            a[j]=b[j];
    }
}
int main()
{
    long long mnog=37;
    scanf("%d %d",&n,&m);
    g.resize(n);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        for(j=0;j<coun;j++)
            aa[j]=(int)a[j];
        radixsort(aa,(int)coun);
        for(j=0;j<coun;j++)
            a[j]=(long long)aa[j];
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    radixsort2(hash,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        for(j=0;j<coun;j++)
            aa[j]=(int)a[j];
        radixsort(aa,(int)coun);
        for(j=0;j<coun;j++)
            a[j]=(long long)aa[j];
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    radixsort2(hash,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector < vector <int> > g;
long long hash[1000003];
long long b[1000003];
int n,m;
long long ans;
long long coun;
long long a[1000003];
int aa[1000003];
int d[1000003];
void radixsort(int *a,int n)
{
    int k=3;
    int i,j;
    for(i=0;i<k;i++)
    {
        int c[256]={0};
        for(j=0;j<n;j++)
            c[(a[j]>>(8*i)&255)]++;
        for(j=1;j<256;j++)
            c[j]+=c[j-1];
        for(j=n-1;j>-1;j--)
            d[--c[(a[j]>>(8*i)&255)]]=a[j];
        for(j=0;j<n;j++)
            a[j]=d[j];
    }
}
void radixsort2(long long *a,int n)
{
    int k=sizeof(long long);
    int i,j;
    for(i=0;i<k;i++)
    {
        int c[256]={0};
        for(j=0;j<n;j++)
            c[(a[j]>>(8*i)&255)]++;
        for(j=1;j<256;j++)
            c[j]+=c[j-1];
        for(j=n-1;j>-1;j--)
            b[--c[(a[j]>>(8*i)&255)]]=a[j];
        for(j=0;j<n;j++)
            a[j]=b[j];
    }
}
int main()
{
    long long mnog=37;
    scanf("%d %d",&n,&m);
    g.resize(n);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        for(j=0;j<coun;j++)
            aa[j]=(int)a[j];
        radixsort(aa,(int)coun);
        for(j=0;j<coun;j++)
            a[j]=(long long)aa[j];
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    radixsort2(hash,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        for(j=0;j<coun;j++)
            aa[j]=(int)a[j];
        radixsort(aa,(int)coun);
        for(j=0;j<coun;j++)
            a[j]=(long long)aa[j];
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    radixsort2(hash,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector < vector <long long> > g;
long double hash[1000003];
long double b[1000003];
int n,m;
long long ans;
long long coun;
long double a[1000003];
void mergesort(long double *a,long double *b,long long n)
{
    long long i,i0,i1,iRight,iEnd,width,j;
    for(width=1;width<n;width*=2)
        for(i=0;i<n;i+=width*2)
        {
            i0=i;
            i1=iRight=min(i+width,n);
            iEnd=min(i+width*2,n);
            for(j=i;j<iEnd;j++)
                if(i0<iRight && (i1==iEnd || a[i0]<=a[i1]))
                    b[j]=a[i0++];
                else
                    b[j]=a[i1++];
            for(j=i;j<iEnd;j++)
                a[j]=b[j];
        }
}
int main()
{
    long double mnog=(1.0*sqrt(5)+1)/2.0;
    scanf("%d %d",&n,&m);
    g.resize(n);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
            hash[i]=(hash[i]*mnog+a[j]+13.0);
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[j]>=hash[i]-0.000000000000000001 && hash[j]<=hash[i]+0.000000000000000001)
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
            hash[i]=(hash[i]*mnog+a[j]+13.0);
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[j]>=hash[i]-0.000000000000000001 && hash[j]<=hash[i]+0.000000000000000001)
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector < vector <int> > g;
long long hash[1000003];
long long b[1000003];
int n,m;
long long ans;
long long coun;
long long a[1000003];
int aa[1000003];
int d[1000003];
void radixsort(int *a,int n)
{
    int k=4;
    int i,j;
    for(i=0;i<k;i++)
    {
        int c[32]={0};
        for(j=0;j<n;j++)
            c[(a[j]>>(5*i)&255)]++;
        for(j=1;j<32;j++)
            c[j]+=c[j-1];
        for(j=n-1;j>-1;j--)
            d[--c[(a[j]>>(5*i)&255)]]=a[j];
        for(j=0;j<n;j++)
            a[j]=d[j];
    }
}
void radixsort2(long long *a,int n)
{
    int k=sizeof(long long);
    int i,j;
    for(i=0;i<k;i++)
    {
        int c[256]={0};
        for(j=0;j<n;j++)
            c[(a[j]>>(8*i)&255)]++;
        for(j=1;j<256;j++)
            c[j]+=c[j-1];
        for(j=n-1;j>-1;j--)
            b[--c[(a[j]>>(8*i)&255)]]=a[j];
        for(j=0;j<n;j++)
            a[j]=b[j];
    }
}
int main()
{
    long long mnog=37;
    scanf("%d %d",&n,&m);
    g.resize(n);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        for(j=0;j<coun;j++)
            aa[j]=(int)a[j];
        radixsort(aa,(int)coun);
        for(j=0;j<coun;j++)
            a[j]=(long long)aa[j];
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    radixsort2(hash,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        for(j=0;j<coun;j++)
            aa[j]=(int)a[j];
        radixsort(aa,(int)coun);
        for(j=0;j<coun;j++)
            a[j]=(long long)aa[j];
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    radixsort2(hash,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector < vector <long long> > g;
long double hash[1000003];
long double b[1000003];
int n,m;
long long ans;
long long coun;
long double a[1000003];
void mergesort(long double *a,long double *b,long long n)
{
    long long i,i0,i1,iRight,iEnd,width,j;
    for(width=1;width<n;width*=2)
        for(i=0;i<n;i+=width*2)
        {
            i0=i;
            i1=iRight=min(i+width,n);
            iEnd=min(i+width*2,n);
            for(j=i;j<iEnd;j++)
                if(i0<iRight && (i1==iEnd || a[i0]<=a[i1]))
                    b[j]=a[i0++];
                else
                    b[j]=a[i1++];
            for(j=i;j<iEnd;j++)
                a[j]=b[j];
        }
}
int main()
{
    long double mnog=(1.0*sqrt(5))/2.0;
    scanf("%d %d",&n,&m);
    g.resize(n);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
            hash[i]=(hash[i]*mnog+a[j]+13.0);
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[j]>=hash[i]-0.000000000000000001 && hash[j]<=hash[i]+0.000000000000000001)
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
            hash[i]=(hash[i]*mnog+a[j]+13.0);
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[j]>=hash[i]-0.000000000000000001 && hash[j]<=hash[i]+0.000000000000000001)
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector < vector <long long> > g;
long long hash[1000003];
long long b[1000003];
int n,m;
long long ans;
long long coun;
long long a[1000003];
void mergesort(long long *a,long long *b,long long n)
{
    long long i,i0,i1,iRight,iEnd,width,j;
    for(width=1;width<n;width*=2)
        for(i=0;i<n;i+=width*2)
        {
            i0=i;
            i1=iRight=min(i+width,n);
            iEnd=min(i+width*2,n);
            for(j=i;j<iEnd;j++)
                if(i0<iRight && (i1==iEnd || a[i0]<=a[i1]))
                    b[j]=a[i0++];
                else
                    b[j]=a[i1++];
            for(j=i;j<iEnd;j++)
                a[j]=b[j];
        }
}
int main()
{
    scanf("%d %d",&n,&m);
    g.resize(n);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
            hash[i]=(hash[i]*37+a[j]+1)%17397537375329787;
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[j]==hash[i])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
            hash[i]=(hash[i]*37+a[j]+1)%17397537375329787;
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[j]==hash[i])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    cout<<ans<<endl;
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector < vector <int> > g;
long long hash[1000003];
long long b[1000003];
int n,m;
long long ans;
long long coun;
long long a[1000003];
int aa[1000003];
int d[1000003];
void radixsort(int *a,int n)
{
    int k=sizeof(int);
    int i,j;
    for(i=0;i<k;i++)
    {
        int c[256]={0};
        for(j=0;j<n;j++)
            c[(a[j]>>(8*i)&255)]++;
        for(j=1;j<256;j++)
            c[j]+=c[j-1];
        for(j=n-1;j>-1;j--)
            d[--c[(a[j]>>(8*i)&255)]]=a[j];
        for(j=0;j<n;j++)
            a[j]=d[j];
    }
}
void radixsort2(long long *a,int n)
{
    int k=sizeof(long long);
    int i,j;
    for(i=0;i<k;i++)
    {
        int c[256]={0};
        for(j=0;j<n;j++)
            c[(a[j]>>(8*i)&255)]++;
        for(j=1;j<256;j++)
            c[j]+=c[j-1];
        for(j=n-1;j>-1;j--)
            b[--c[(a[j]>>(8*i)&255)]]=a[j];
        for(j=0;j<n;j++)
            a[j]=b[j];
    }
}
int main()
{
    long long mnog=37;
    scanf("%d %d",&n,&m);
    g.resize(n);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        for(j=0;j<coun;j++)
            aa[j]=(int)a[j];
        radixsort(aa,(int)coun);
        for(j=0;j<coun;j++)
            a[j]=(long long)aa[j];
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    radixsort2(hash,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        for(j=0;j<coun;j++)
            aa[j]=(int)a[j];
        radixsort(aa,(int)coun);
        for(j=0;j<coun;j++)
            a[j]=(long long)aa[j];
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    radixsort2(hash,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector < vector <long long> > g;
long long hash[1000003];
long long b[1000003];
int n,m;
long long ans;
long long coun;
long long a[1000003];
void mergesort(long long *a,long long *b,long long n)
{
    long long i,i0,i1,iRight,iEnd,width,j;
    for(width=1;width<n;width*=2)
        for(i=0;i<n;i+=width*2)
        {
            i0=i;
            i1=iRight=min(i+width,n);
            iEnd=min(i+width*2,n);
            for(j=i;j<iEnd;j++)
                if(i0<iRight && (i1==iEnd || a[i0]<=a[i1]))
                    b[j]=a[i0++];
                else
                    b[j]=a[i1++];
            for(j=i;j<iEnd;j++)
                a[j]=b[j];
        }
}
int main()
{
    scanf("%d %d",&n,&m);
    g.resize(n);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
            hash[i]=(hash[i]*29+a[j]+3)%177397537375329787;
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[j]==hash[i])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
            hash[i]=(hash[i]*29+a[j]+3)%177397537375329787;
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[j]==hash[i])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector < vector <long long> > g;
long long hash[1000003];
long long b[1000003];
int n,m;
long long ans;
long long coun;
long long a[1000003];
void radixsort(long long *a,int n)
{
    int k=sizeof(long long);
    int i,j;
    for(i=0;i<k;i++)
    {
        int c[256]={0};
        for(j=0;j<n;j++)
            c[(a[j]>>(8*i)&255)]++;
        for(j=1;j<256;j++)
            c[j]+=c[j-1];
        for(j=n-1;j>-1;j--)
            b[--c[(a[j]>>(8*i)&255)]]=a[j];
        for(j=0;j<n;j++)
            a[j]=b[j];
    }
}
int main()
{
    long long mnog=37;
    scanf("%d %d",&n,&m);
    g.resize(n);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        radixsort(a,(int)coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    radixsort(hash,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        radixsort(a,(int)coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    radixsort(hash,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector < vector <int> > g;
long long hash[1000003];
long long b[1000003];
int n,m;
long long ans;
long long coun;
long long a[1000003];
void mergesort(long long *a,long long *b,int n)
{
    int i,i0,i1,iRight,iEnd,width,j;
    for(width=1;width<n;width*=2)
        for(i=0;i<n;i+=width*2)
        {
            i0=i;
            i1=iRight=min(i+width,n);
            iEnd=min(i+width*2,n);
            for(j=i;j<iEnd;j++)
                if(i0<iRight && (i1==iEnd || a[i0]<=a[i1]))
                    b[j]=a[i0++];
                else
                    b[j]=a[i1++];
            for(j=i;j<iEnd;j++)
                a[j]=b[j];
        }
}
bool flag[1000003];
void cherpak(long long *a,int n)
{
    int cou=0;
    int i;
    for(i=0;i<1000003;i++)
        flag[i]=false;
    for(i=0;i<n;i++)
        flag[a[i]]=true;
    for(i=0;i<1000003;i++)
        if(flag[i])
            a[cou++]=i;
}
int main()
{
    long long mnog=37;
    scanf("%d %d",&n,&m);
    g.resize(n);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        cherpak(a,(int)coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        cherpak(a,(int)coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector < vector <long long> > g;
long long hash[1000003];
long long b[1000003];
int n,m;
long long ans;
long long coun;
long long a[1000003];
void mergesort(long long *a,long long *b,int n)
{
    int i,i0,i1,iRight,iEnd,width,j;
    for(width=1;width<n;width*=2)
        for(i=0;i<n;i+=width*2)
        {
            i0=i;
            i1=iRight=min(i+width,n);
            iEnd=min(i+width*2,n);
            for(j=i;j<iEnd;j++)
                if(i0<iRight && (i1==iEnd || a[i0]<=a[i1]))
                    b[j]=a[i0++];
                else
                    b[j]=a[i1++];
            for(j=i;j<iEnd;j++)
                a[j]=b[j];
        }
}
int main()
{
    long long mnog=37;
    scanf("%d %d",&n,&m);
    g.resize(n);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,(int)coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector < vector <long long> > g;
long long hash[1000003];
long long b[1000003];
int n,m;
long long ans;
int coun;
long long a[1000003];
void mergesort(long long *a,long long *b,int n)
{
    int i,i0,i1,iRight,iEnd,width,j;
    for(width=1;width<n;width*=2)
        for(i=0;i<n;i+=width*2)
        {
            i0=i;
            i1=iRight=min(i+width,n);
            iEnd=min(i+width*2,n);
            for(j=i;j<iEnd;j++)
                if(i0<iRight && (i1==iEnd || a[i0]<=a[i1]))
                    b[j]=a[i0++];
                else
                    b[j]=a[i1++];
            for(j=i;j<iEnd;j++)
                a[j]=b[j];
        }
}
int main()
{
    scanf("%d %d",&n,&m);
    g.resize(n);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
            hash[i]=(hash[i]*37+a[j]+1)%17397537375329787;
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[j]==hash[i])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)>>1);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
            hash[i]=(hash[i]*37+a[j]+1)%17397537375329787;
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[j]==hash[i])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)>>1);
    }
    cout<<ans<<endl;
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector < vector <long long> > g;
long double hash[1000003];
long double b[1000003];
int n,m;
long long ans;
long long coun;
long double a[1000003];
void mergesort(long double *a,long double *b,long long n)
{
    long long i,i0,i1,iRight,iEnd,width,j;
    for(width=1;width<n;width*=2)
        for(i=0;i<n;i+=width*2)
        {
            i0=i;
            i1=iRight=min(i+width,n);
            iEnd=min(i+width*2,n);
            for(j=i;j<iEnd;j++)
                if(i0<iRight && (i1==iEnd || a[i0]<=a[i1]))
                    b[j]=a[i0++];
                else
                    b[j]=a[i1++];
            for(j=i;j<iEnd;j++)
                a[j]=b[j];
        }
}
int main()
{
    long double mnog=(1.0*sqrt(5)-1.0)/2.0;
    scanf("%d %d",&n,&m);
    g.resize(n);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
            hash[i]=(hash[i]*mnog+a[j]+13.0);
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[j]>=hash[i]-0.0000000001 && hash[j]<=hash[i]+0.0000000001)
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
            hash[i]=(hash[i]*mnog+a[j]+13.0);
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[j]>=hash[i]-0.0000000001 && hash[j]<=hash[i]+0.0000000001)
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector < vector <long long> > g;
long long hash[1000003];
long long b[1000003];
int n,m;
long long ans;
long long coun;
long long a[1000003];
void mergesort(long long *a,long long *b,long long n)
{
    long long i,i0,i1,iRight,iEnd,width,j;
    for(width=1;width<n;width*=2)
        for(i=0;i<n;i+=width*2)
        {
            i0=i;
            i1=iRight=min(i+width,n);
            iEnd=min(i+width*2,n);
            for(j=i;j<iEnd;j++)
                if(i0<iRight && (i1==iEnd || a[i0]<=a[i1]))
                    b[j]=a[i0++];
                else
                    b[j]=a[i1++];
            for(j=i;j<iEnd;j++)
                a[j]=b[j];
        }
}
int main()
{
    long long mnog=37;
    scanf("%d %d",&n,&m);
    g.resize(n);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector <int> g[1000003];
long long hash[1000003];
long long b[1000003];
int n,m;
long long ans;
long long coun;
long long a[1000003];
int aa[1000003];
int d[1000003];
void radixsort(int *a,int n)
{
    int k=10;
    int i,j;
    for(i=0;i<k;i++)
    {
        int c[4]={0};
        for(j=0;j<n;j++)
            c[(a[j]>>(2*i)&3)]++;
        for(j=1;j<4;j++)
            c[j]+=c[j-1];
        for(j=n-1;j>-1;j--)
            d[--c[(a[j]>>(2*i)&3)]]=a[j];
        for(j=0;j<n;j++)
            a[j]=d[j];
    }
}
void radixsort2(long long *a,int n)
{
    int k=sizeof(long long);
    int i,j;
    for(i=0;i<k;i++)
    {
        int c[256]={0};
        for(j=0;j<n;j++)
            c[(a[j]>>(8*i)&255)]++;
        for(j=1;j<256;j++)
            c[j]+=c[j-1];
        for(j=n-1;j>-1;j--)
            b[--c[(a[j]>>(8*i)&255)]]=a[j];
        for(j=0;j<n;j++)
            a[j]=b[j];
    }
}
int main()
{
    long long mnog=37;
    scanf("%d %d",&n,&m);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[(int)x].push_back((int)y);
        g[(int)y].push_back((int)x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        for(j=0;j<coun;j++)
            aa[j]=(int)a[j];
        radixsort(aa,(int)coun);
        for(j=0;j<coun;j++)
            a[j]=(long long)aa[j];
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    radixsort2(hash,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        for(j=0;j<coun;j++)
            aa[j]=(int)a[j];
        radixsort(aa,(int)coun);
        for(j=0;j<coun;j++)
            a[j]=(long long)aa[j];
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    radixsort2(hash,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector < vector <long long> > g;
long long hash[1000003];
long long b[1000003];
int n,m;
long long ans;
long long coun;
long long a[1000003];
void mergesort(long long *a,long long *b,long long n)
{
    long long i,i0,i1,iRight,iEnd,width,j;
    for(width=1;width<n;width*=2)
        for(i=0;i<n;i+=width*2)
        {
            i0=i;
            i1=iRight=min(i+width,n);
            iEnd=min(i+width*2,n);
            for(j=i;j<iEnd;j++)
                if(i0<iRight && (i1==iEnd || a[i0]<=a[i1]))
                    b[j]=a[i0++];
                else
                    b[j]=a[i1++];
            for(j=i;j<iEnd;j++)
                a[j]=b[j];
        }
}
int main()
{
    scanf("%d %d",&n,&m);
    g.resize(n);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
            hash[i]=(hash[i]*13+a[j]+7)%177397537375329787;
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[j]==hash[i])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
            hash[i]=(hash[i]*13+a[j]+7)%177397537375329787;
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[j]==hash[i])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector < vector <int> > g;
long long hash[1000003];
long long b[1000003];
int n,m;
long long ans;
long long coun;
long long a[1000003];
int aa[1000003];
int d[1000003];
void radixsort(int *a,int n)
{
    int k=8;
    int i,j;
    for(i=0;i<k;i++)
    {
        int c[8]={0};
        for(j=0;j<n;j++)
            c[(a[j]>>(3*i)&7)]++;
        for(j=1;j<8;j++)
            c[j]+=c[j-1];
        for(j=n-1;j>-1;j--)
            d[--c[(a[j]>>(3*i)&7)]]=a[j];
        for(j=0;j<n;j++)
            a[j]=d[j];
    }
}
void radixsort2(long long *a,int n)
{
    int k=sizeof(long long);
    int i,j;
    for(i=0;i<k;i++)
    {
        int c[256]={0};
        for(j=0;j<n;j++)
            c[(a[j]>>(8*i)&255)]++;
        for(j=1;j<256;j++)
            c[j]+=c[j-1];
        for(j=n-1;j>-1;j--)
            b[--c[(a[j]>>(8*i)&255)]]=a[j];
        for(j=0;j<n;j++)
            a[j]=b[j];
    }
}
int main()
{
    long long mnog=37;
    scanf("%d %d",&n,&m);
    g.resize(n);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        for(j=0;j<coun;j++)
            aa[j]=(int)a[j];
        radixsort(aa,(int)coun);
        for(j=0;j<coun;j++)
            a[j]=(long long)aa[j];
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    radixsort2(hash,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        for(j=0;j<coun;j++)
            aa[j]=(int)a[j];
        radixsort(aa,(int)coun);
        for(j=0;j<coun;j++)
            a[j]=(long long)aa[j];
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    radixsort2(hash,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector < vector <int> > g;
long long hash[1000003];
long long b[1000003];
int n,m;
long long ans;
long long coun;
long long a[1000003];
void mergesort(long long *a,long long *b,int n)
{
    int i,i0,i1,iRight,iEnd,width,j;
    for(width=1;width<n;width*=2)
        for(i=0;i<n;i+=width*2)
        {
            i0=i;
            i1=iRight=min(i+width,n);
            iEnd=min(i+width*2,n);
            for(j=i;j<iEnd;j++)
                if(i0<iRight && (i1==iEnd || a[i0]<=a[i1]))
                    b[j]=a[i0++];
                else
                    b[j]=a[i1++];
            for(j=i;j<iEnd;j++)
                a[j]=b[j];
        }
}
int main()
{
    long long mnog=37;
    scanf("%d %d",&n,&m);
    g.resize(n);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,(int)coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector < vector <long long> > g;
long double hash[1000003];
long double b[1000003];
int n,m;
long long ans;
long long coun;
long double a[1000003];
void mergesort(long double *a,long double *b,long long n)
{
    long long i,i0,i1,iRight,iEnd,width,j;
    for(width=1;width<n;width*=2)
        for(i=0;i<n;i+=width*2)
        {
            i0=i;
            i1=iRight=min(i+width,n);
            iEnd=min(i+width*2,n);
            for(j=i;j<iEnd;j++)
                if(i0<iRight && (i1==iEnd || a[i0]<=a[i1]))
                    b[j]=a[i0++];
                else
                    b[j]=a[i1++];
            for(j=i;j<iEnd;j++)
                a[j]=b[j];
        }
}
int main()
{
    long double mnog=(1.0*sqrt(5)-1.0)/2.0;
    scanf("%d %d",&n,&m);
    g.resize(n);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
            hash[i]=(hash[i]*mnog+a[j]+13.0);
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[j]>=hash[i]-0.0000000000001 && hash[j]<=hash[i]+0.0000000000001)
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        mergesort(a,b,coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
            hash[i]=(hash[i]*mnog+a[j]+13.0);
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[j]>=hash[i]-0.0000000000001 && hash[j]<=hash[i]+0.0000000000001)
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
vector < vector <int> > g;
long long hash[1000003];
long long b[1000003];
int n,m;
long long ans;
long long coun;
long long a[1000003];
void mergesort(long long *a,long long *b,int n)
{
    int i,i0,i1,iRight,iEnd,width,j;
    for(width=1;width<n;width*=2)
        for(i=0;i<n;i+=width*2)
        {
            i0=i;
            i1=iRight=min(i+width,n);
            iEnd=min(i+width*2,n);
            for(j=i;j<iEnd;j++)
                if(i0<iRight && (i1==iEnd || a[i0]<=a[i1]))
                    b[j]=a[i0++];
                else
                    b[j]=a[i1++];
            for(j=i;j<iEnd;j++)
                a[j]=b[j];
        }
}
bool flag[1000003];
void cherpak(long long *a,int n)
{
    int cou=0;
    int i;
    int maxi=-1;
    for(i=0;i<n;i++)
        maxi=max(maxi,a[i]);
    for(i=0;i<=maxi;i++)
        flag[i]=false;
    for(i=0;i<n;i++)
        flag[a[i]]=true;
    for(i=0;i<=maxi;i++)
        if(flag[i])
            a[cou++]=i;
}
int main()
{
    long long mnog=37;
    scanf("%d %d",&n,&m);
    g.resize(n);
    int i,j;
    long long x,y;
    for(i=0;i<m;i++)
    {
        scanf("%I64d %I64d",&x,&y);
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=0;i<n;i++)
    {
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        cherpak(a,(int)coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    for(i=0;i<n;i++)
    {
        g[i].push_back(i);
        coun=0;
        for(j=0;j<g[i].size();j++)
            a[coun++]=g[i][j];
        cherpak(a,(int)coun);
        hash[i]=0;
        for(j=0;j<coun;j++)
        {
            a[j]++;
            while(a[j]>0)
            {
                hash[i]=(hash[i]*mnog+a[j]%10+'0')%717472347921347957;
                a[j]/=10;
            }
        }
    }
    mergesort(hash,b,n);
    i=0;
    while(i<n)
    {
        coun=0;
        j=i;
        while(j<n && hash[i]==hash[j])
        {
            j++;
            coun++;
        }
        i=j;
        ans+=((coun*coun-coun)/2);
    }
    printf("%I64d\n",ans);
    return 0;
}


// asdasdasda as dasd
#include <bits/stdc++.h>
using namespace std;
#define FREP(b) for(int i=0;i<b;i++)
#define REP(a,b,c) for(int a=b;a<c;a++)
#define asd(x)              cout<<__LINE__<<" :: "<<#x<< ": "<<x<<endl;
#define asdf(x, y)          cout<<__LINE__<<" :: "<<#x<< ": "<<x<<" | "<<#y<< ": "<<y<<endl;
typedef long long LL;
typedef pair<int,int> ii;

const int MAX = 1e6 + 3;
const LL L = 1e9 + 9;
map<LL, int> store;
vector<int> G[MAX];
int A[MAX][2], MOD[2];

void init(int n){
    A[0][0] = 1;
    REP(i, 1, n+1){
        A[i][0] = ((LL)A[i-1][0]*n);
    }
}

LL yolo(int a){
    LL hash = 0;
    REP(i, 0, G[a].size()){
        int u = G[a][i];
        hash = (hash + A[u][0]);
    }
    return hash;
}

int main(){
    int n, m,a,b;
    cin >> n >> m;
    init(n);
    REP(i, 0, m){
        scanf("%d %d", &a, &b);
        G[a].push_back(b);
        G[b].push_back(a);
    }
    LL ans = 0;
    REP(i,1,n+1){
        LL hash1 = yolo(i);
        ans += store[hash1];
        store[hash1]++;

        hash1 = (hash1 + A[i][0]);

        ans += store[hash1];
        store[hash1]++;
    }
    cout << ans << endl;
    return 0;
}


// asdasdasda as dasd
#include <bits/stdc++.h>
using namespace std;
#define FREP(b) for(int i=0;i<b;i++)
#define REP(a,b,c) for(int a=b;a<c;a++)
#define asd(x)              cout<<__LINE__<<" :: "<<#x<< ": "<<x<<endl;
#define asdf(x, y)          cout<<__LINE__<<" :: "<<#x<< ": "<<x<<" | "<<#y<< ": "<<y<<endl;
typedef long long LL;
typedef pair<int,int> ii;

const int MAX = 1e6 + 3;
const LL L = 1e9 + 9;
map<LL, int> store;
vector<int> G[MAX];
int A[MAX][2], MOD[2];

LL get(int hash1, int hash2){
   return (LL)hash1*L + hash2;
}

void init(int n){
    MOD[0] = 1e9 + 7, MOD[1] = 1e9 + 9;
    A[0][0] = A[0][1] = 1;
    REP(i, 1, n+1){
        A[i][0] = ((LL)A[i-1][0]*n)%MOD[0];
        A[i][1] = ((LL)A[i-1][1]*n)%MOD[1];
    }
}

int yolo(int a, int idx){
    int hash = 0;
    REP(i, 0, G[a].size()){
        int u = G[a][i];
        hash = (hash + A[u][idx]);
        if(hash >= MOD[idx]) hash -= MOD[idx];
    }
    return hash;
}

int main(){
    int n, m,a,b;
    cin >> n >> m;
    init(n);
    REP(i, 0, m){
        scanf("%d %d", &a, &b);
        G[a].push_back(b);
        G[b].push_back(a);
    }
    LL ans = 0;
    REP(i,1,n+1){
        int hash1 = yolo(i, 0), hash2 = yolo(i, 1);
        ans += store[get(hash1, hash2)];
        store[get(hash1, hash2)]++;

        hash1 = (hash1 + A[i][0]), hash2 = (hash2 + A[i][1]);
        if(hash1 >= MOD[0]) hash1 -= MOD[0];
        if(hash2 >= MOD[1])  hash2 -= MOD[1];
        ans += store[get(hash1, hash2)];
        store[get(hash1, hash2)]++;
    }
    cout << ans << endl;
    return 0;
}


// asdasdasda as dasd
#include <bits/stdc++.h>
using namespace std;
#define FREP(b) for(int i=0;i<b;i++)
#define REP(a,b,c) for(int a=b;a<c;a++)
#define asd(x)              cout<<__LINE__<<" :: "<<#x<< ": "<<x<<endl;
#define asdf(x, y)          cout<<__LINE__<<" :: "<<#x<< ": "<<x<<" | "<<#y<< ": "<<y<<endl;
typedef long long LL;
typedef pair<int,int> ii;

const int MAX = 1e6 + 3;
const LL L = 1e9 + 9;
map<LL, int> store;
vector<int> G[MAX];
int A[MAX][2], MOD[2];

LL get(int hash1, int hash2){
   return (LL)hash1*L + hash2;
}

void init(int n){
    MOD[0] = 1e9 + 7, MOD[1] = 1e9 + 9;
    A[0][0] = A[0][1] = 1;
    REP(i, 1, n+1){
        A[i][0] = ((LL)A[i-1][0]*n)%MOD[0];
        A[i][1] = ((LL)A[i-1][1]*n)%MOD[1];
    }
}

int yolo(int a, int idx){
    int hash = 0;
    REP(i, 0, G[a].size()){
        int u = G[a][i];
        hash = (hash + A[u][idx])%MOD[idx];
    }
    return hash;
}

int main(){
    int n, m,a,b;
    cin >> n >> m;
    init(n);
    REP(i, 0, m){
        scanf("%d %d", &a, &b);
        G[a].push_back(b);
        G[b].push_back(a);
    }
    LL ans = 0;
    REP(i,1,n+1){
        int hash1 = yolo(i, 0), hash2 = yolo(i, 1);
        ans += store[get(hash1, hash2)];
        store[get(hash1, hash2)]++;

        hash1 = (hash1 + A[i][0])%MOD[0], hash2 = (hash2 + A[i][1])%MOD[1];
        ans += store[get(hash1, hash2)];
        store[get(hash1, hash2)]++;
    }
    cout << ans << endl;
    return 0;
}


// asdasdasda as dasd
#include <bits/stdc++.h>
using namespace std;
#define FREP(b) for(int i=0;i<b;i++)
#define REP(a,b,c) for(int a=b;a<c;a++)
#define asd(x)              cout<<__LINE__<<" :: "<<#x<< ": "<<x<<endl;
#define asdf(x, y)          cout<<__LINE__<<" :: "<<#x<< ": "<<x<<" | "<<#y<< ": "<<y<<endl;
typedef long long LL;
typedef pair<int,int> ii;

const int MAX = 1e6 + 3;
const LL L = 1e9 + 9;
//map<LL, int> store;
vector<int> G[MAX];
int A[MAX][2], MOD[2];

LL get(int hash1, int hash2){
   return (LL)hash1*L + hash2;
}

void init(int n){
    MOD[0] = 1e9 + 7, MOD[1] = 1e9 + 9;
    A[0][0] = A[0][1] = 1;
    REP(i, 1, n+1){
        A[i][0] = ((LL)A[i-1][0]*n)%MOD[0];
        A[i][1] = ((LL)A[i-1][1]*n)%MOD[1];
    }
}

int yolo(int a, int idx){
    int hash = 0;
    REP(i, 0, G[a].size()){
        int u = G[a][i];
        hash = (hash + A[u][idx])%MOD[idx];
    }
    return hash;
}

int main(){
    int n, m,a,b;
    cin >> n >> m;
    init(n);
    REP(i, 0, m){
        scanf("%d %d", &a, &b);
        G[a].push_back(b);
        G[b].push_back(a);
    }

    vector<LL> store;

    REP(i,1,n+1){
        int hash1 = yolo(i, 0), hash2 = yolo(i, 1);
        store.push_back(get(hash1, hash2));

        hash1 = (hash1 + A[i][0])%MOD[0], hash2 = (hash2 + A[i][1])%MOD[1];
        store.push_back(get(hash1, hash2));
    }

    sort(store.begin(), store.end());
    int i = 0, sz = store.size(), j = 0, cnt = 0;
    LL ans = 0;
    while(i < sz){
        if(store[i] == store[j]) cnt++;
        else{
            ans += (LL)(cnt)*(cnt - 1)/2;
            j = i, cnt = 1;
        }
        i++;
    }
    ans += (LL)(cnt)*(cnt - 1)/2;
    cout << ans << endl;
    return 0;
}


// asdasdasda as dasd
#include <bits/stdc++.h>
using namespace std;
#define FREP(b) for(int i=0;i<b;i++)
#define REP(a,b,c) for(int a=b;a<c;a++)
#define asd(x)              cout<<__LINE__<<" :: "<<#x<< ": "<<x<<endl;
#define asdf(x, y)          cout<<__LINE__<<" :: "<<#x<< ": "<<x<<" | "<<#y<< ": "<<y<<endl;
typedef long long LL;
typedef pair<int,int> ii;

const int MAX = 1e6 + 3;
map<ii, int> store;
vector<int> G[MAX];
int A[MAX][2], MOD[2];

void init(int n){
    MOD[0] = 1e9 + 7, MOD[1] = 1e9 + 9;
    A[0][0] = A[0][1] = 1;
    REP(i, 1, n+1){
        A[i][0] = ((LL)A[i-1][0]*n)%MOD[0];
        A[i][1] = ((LL)A[i-1][1]*n)%MOD[1];
    }
}

int yolo(int a, int idx){
    int hash = 0;
    REP(i, 0, G[a].size()){
        int u = G[a][i];
        hash = (hash + A[u][idx])%MOD[idx];
    }
    return hash;
}

int main(){
    int n, m,a,b;
    cin >> n >> m;
    init(n);
    REP(i, 0, m){
        scanf("%d %d", &a, &b);
        G[a].push_back(b);
        G[b].push_back(a);
    }
    LL ans = 0;
    REP(i,1,n+1){
        int hash1 = yolo(i, 0), hash2 = yolo(i, 1);
        ans += store[ii(hash1, hash2)];
        store[ii(hash1, hash2)]++;

        hash1 = (hash1 + A[i][0])%MOD[0], hash2 = (hash2 + A[i][1])%MOD[1];
        ans += store[ii(hash1, hash2)];
        store[ii(hash1, hash2)]++;
    }
    cout << ans << endl;
    return 0;
}


// asdasdasda as dasd
#include <bits/stdc++.h>
using namespace std;
#define FREP(b) for(int i=0;i<b;i++)
#define REP(a,b,c) for(int a=b;a<c;a++)
#define asd(x)              cout<<__LINE__<<" :: "<<#x<< ": "<<x<<endl;
#define asdf(x, y)          cout<<__LINE__<<" :: "<<#x<< ": "<<x<<" | "<<#y<< ": "<<y<<endl;
typedef long long LL;
typedef pair<int,int> ii;

const int MAX = 1e6 + 3;
map<ii, int> store;
vector<int> G[MAX];
int A[MAX][2], MOD[2];

void init(int n){
    MOD[0] = 1e9 + 7, MOD[1] = 1e9 + 9;
    A[0][0] = A[0][1] = 1;
    REP(i, 1, n+1){
        A[i][0] = ((LL)A[i-1][0]*n)%MOD[0];
        A[i][1] = ((LL)A[i-1][1]*n)%MOD[1];
    }
}

int yolo(int a, int idx){
    LL hash = 0;
    REP(i, 0, G[a].size()){
        int u = G[a][i];
        hash = (hash + A[u][idx])%MOD[idx];
    }
    return hash;
}

int main(){
    int n, m,a,b;
    cin >> n >> m;
    init(n);
    REP(i, 0, m){
        scanf("%d %d", &a, &b);
        G[a].push_back(b);
        G[b].push_back(a);
    }
    LL ans = 0;
    REP(i,1,n+1){
        LL hash1 = yolo(i, 0), hash2 = yolo(i, 1);
        ans += (LL) store[ii(hash1, hash2)];
//        asd(i);
  //      asdf(hash1, hash2);
        store[ii(hash1, hash2)]++;
        hash1 = (hash1 + A[i][0])%MOD[0], hash2 = (hash2 + A[i][1])%MOD[1];
        ans += (LL) store[ii(hash1, hash2)];
    //    asdf(hash1, hash2);
        store[ii(hash1, hash2)]++;
    }
    cout << ans << endl;
    return 0;
}


// asdasdasda as dasd
#include <bits/stdc++.h>
using namespace std;
#define FREP(b) for(int i=0;i<b;i++)
#define REP(a,b,c) for(int a=b;a<c;a++)
#define asd(x)              cout<<__LINE__<<" :: "<<#x<< ": "<<x<<endl;
#define asdf(x, y)          cout<<__LINE__<<" :: "<<#x<< ": "<<x<<" | "<<#y<< ": "<<y<<endl;
typedef long long LL;
typedef pair<int,int> ii;

const int MAX = 1e6 + 3;
const LL L = 1e9 + 9;
map<LL, int> store;
vector<int> G[MAX];
int A[MAX][2], MOD[2];

LL get(int hash1, int hash2){
   return (LL)hash1*L + hash2;
}

void init(int n){
    MOD[0] = 1e9 + 7, MOD[1] = 1e9 + 9;
    A[0][0] = A[0][1] = 1;
    REP(i, 1, n+1){
        A[i][0] = ((LL)A[i-1][0]*n)%MOD[0];
        A[i][1] = ((LL)A[i-1][1]*n)%MOD[1];
    }
}

int yolo(int a, int idx){
    int hash = 0;
    REP(i, 0, G[a].size()){
        int u = G[a][i];
        hash = (hash + A[u][idx]);
//        if(hash >= MOD[idx]) hash -= MOD[idx];
    }
    return hash;
}

int main(){
    int n, m,a,b;
    cin >> n >> m;
    init(n);
    REP(i, 0, m){
        scanf("%d %d", &a, &b);
        G[a].push_back(b);
        G[b].push_back(a);
    }
    LL ans = 0;
    REP(i,1,n+1){
        int hash1 = yolo(i, 0), hash2 = yolo(i, 1);
        ans += store[get(hash1, hash2)];
        store[get(hash1, hash2)]++;

        hash1 = (hash1 + A[i][0]), hash2 = (hash2 + A[i][1]);
       // if(hash1 >= MOD[0]) hash1 -= MOD[0];
       // if(hash2 >= MOD[1])  hash2 -= MOD[1];
        ans += store[get(hash1, hash2)];
        store[get(hash1, hash2)]++;
    }
    cout << ans << endl;
    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[101000];
long long hash[101000];
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    for(int i=1;i<=n;i++){
        //e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h*101+e[i][j];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    long long ans=0;
    int l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<<endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r+1;
    }
    for(int i=1;i<=n;i++){
        e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h*101+e[i][j];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<<endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r+1;
    }
    cout <<ans<<endl;

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[1010000];
long long hash[1010000];
long long p[1010000];
vector<pair<int,int> > ve;
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        e[a].push_back(b);
        e[b].push_back(a);
        ve.push_back(make_pair(a,b));
    }
    p[1]=1;
    for(int i=2;i<=n;i++)p[i]=p[i-1]*31;
    for(int i=1;i<=n;i++){
        //e[i].push_back(i);
        //sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h+p[e[i][j]];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    long long ans=0;
    int l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<<" ";
    cout << endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    for(int i=0;i<ve.size();i++){
        int a=ve[i].first,b=ve[i].second;
        if(hash[a]+p[a]==hash[b]+p[b])ans++;
    }
    /*for(int i=1;i<=n;i++){
        e[i].push_back(i);
        //sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h+p[e[i][j]];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<< " ";
    cout<<endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }*/
    cout <<ans<<endl;

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[101000];
long long hash[101000];
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    for(int i=1;i<=n;i++){
        //e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h*31+e[i][j];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    long long ans=0;
    int l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<<" ";
    cout << endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    for(int i=1;i<=n;i++){
        e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h*31+e[i][j];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<< " ";
    cout<<endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    cout <<ans<<endl;

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[1010000];
long long hash[1010000];
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    for(int i=1;i<=n;i++){
        //e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h*n+e[i][j];
            h%=(1LL<<48) -1;

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    long long ans=0;
    int l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<<endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    for(int i=1;i<=n;i++){
        e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h*n+e[i][j];
            h%=(1LL<<48) -1;

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<<endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    cout <<ans<<endl;

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[1010000];
long long hash[1010000];
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    for(int i=1;i<=n;i++){
        //e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h*31+e[i][j];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    long long ans=0;
    int l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<<" ";
    cout << endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    for(int i=1;i<=n;i++){
        e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h*31+e[i][j];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<< " ";
    cout<<endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    cout <<ans<<endl;

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[1010000];
long long hash[1010000];
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    vector<vector<int> > v,v2;
    for(int i=1;i<=n;i++){
        //e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        v.push_back(e[i]);
        e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        v2.push_back(e[i]);
    }
    sort(v.begin(),v.end());
    sort(v2.begin(),v2.end());
    int id=0;
    long long ans=0;
    while(id<v.size()){
        int r=id+1;
        while(r<v.size()&&v[id]==v[r])r++;
        long long z=r-id;
        ans+=z*(z-1)/2;
        id=r;
    }
    id=0;
    while(id<v2.size()){
        int r=id+1;
        while(r<v2.size()&&v2[id]==v2[r])r++;
        long long z=r-id;
        ans+=z*(z-1)/2;
        id=r;
    }

    cout <<ans<<endl;

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[1010000];
long long hash[1010000];
long long p[1010000];
vector<pair<int,int> > ve;
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    p[1]=1;
    for(int i=2;i<=n;i++)p[i]=p[i-1]*31;
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        hash[a]+=p[b];
        hash[b]+=p[a];
        ve.push_back(make_pair(a,b));
    }

    long long ans=0;
    for(int i=0;i<ve.size();i++){
        int a=ve[i].first,b=ve[i].second;
        if(hash[a]+p[a]==hash[b]+p[b])ans++;
    }

        sort(hash+1,hash+n+1);
    int l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<<" ";
    cout << endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    /*for(int i=1;i<=n;i++){
        e[i].push_back(i);
        //sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h+p[e[i][j]];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<< " ";
    cout<<endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }*/
    cout <<ans<<endl;

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[101000];
long long hash[101000];
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    vector<vector<int> > v,v2;
    for(int i=1;i<=n;i++){
        //e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        v.push_back(e[i]);
        e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        v2.push_back(e[i]);
    }
    sort(v.begin(),v.end());
    sort(v2.begin(),v2.end());
    int id=0;
    long long ans=0;
    while(id<v.size()){
        int r=id+1;
        while(r<v.size()&&v[id]==v[r])r++;
        long long z=r-id;
        ans+=z*(z-1)/2;
        id=r;
    }
    id=0;
    while(id<v2.size()){
        int r=id+1;
        while(r<v2.size()&&v2[id]==v2[r])r++;
        long long z=r-id;
        ans+=z*(z-1)/2;
        id=r;
    }

    cout <<ans<<endl;

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[101000];
long long hash[101000];
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    vector<vector<int> > v,v2;
    for(int i=1;i<=n;i++){
        //e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        v.push_back(e[i]);
        e[i].push_back(i);
        v2.push_back(e[i]);
    }
    int id=0;
    while(id<v.size()){
        int r=id+1;
        while(r<v.size()&&v[id]==v[r])r++;
        long long z=r-id;
        ans+=z*(z-1)/2;
    }
    int id=0;
    while(id<v2.size()){
        int r=id+1;
        while(r<v2.size()&&v2[id]==v2[r])r++;
        long long z=r-id;
        ans+=z*(z-1)/2;
    }

    cout <<ans<<endl;

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[101000];
long long hash[101000];
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    for(int i=1;i<=n;i++){
        //e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h*n+e[i][j];
            h%=(1LL<<48) -1;

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    long long ans=0;
    int l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<<endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    for(int i=1;i<=n;i++){
        e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h*n+e[i][j];
            h%=(1LL<<48) -1;

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<<endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    cout <<ans<<endl;

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[101000];
long long hash[101000];
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    vector<vector<int> > v,v2;
    for(int i=1;i<=n;i++){
        //e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        v.push_back(e[i]);
        e[i].push_back(i);
        v2.push_back(e[i]);
    }
    int id=0;
    long long ans=0;
    while(id<v.size()){
        int r=id+1;
        while(r<v.size()&&v[id]==v[r])r++;
        long long z=r-id;
        ans+=z*(z-1)/2;
    }
    id=0;
    while(id<v2.size()){
        int r=id+1;
        while(r<v2.size()&&v2[id]==v2[r])r++;
        long long z=r-id;
        ans+=z*(z-1)/2;
    }

    cout <<ans<<endl;

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[101000];
long long hash[101000];
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    for(int i=1;i<=n;i++){
        //e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h*101+e[i][j];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    long long ans=0;
    int l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<<" ";
    cout << endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    for(int i=1;i<=n;i++){
        e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h*101+e[i][j];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<< " ";
    cout<<endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    cout <<ans<<endl;

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[1010000];
long long hash[1010000];
long long p[1010000];
vector<pair<int,int> > ve;
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        e[a].push_back(b);
        e[b].push_back(a);
        ve.push_back(make_pair(a,b));
    }
    p[1]=1;
    for(int i=2;i<=n;i++)p[i]=p[i-1]*31;
    for(int i=1;i<=n;i++){
        //e[i].push_back(i);
        //sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h+p[e[i][j]];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    long long ans=0;
    int l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<<" ";
    cout << endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    for(int i=0;i<ve.size();i++){
        int a=ve[i].first,b=ve[i].second;
        if(hash[a]+p[b]==hash[b]+p[a])ans++;
    }
    /*for(int i=1;i<=n;i++){
        e[i].push_back(i);
        //sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h+p[e[i][j]];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<< " ";
    cout<<endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }*/
    cout <<ans<<endl;

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[1010000];
long long hash[1010000];
long long p[1010000];
vector<pair<int,int> > ve;
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        e[a].push_back(b);
        e[b].push_back(a);
        ve.push_back(make_pair(a,b));
    }
    p[1]=1;
    for(int i=2;i<=n;i++)p[i]=p[i-1]*31;
    for(int i=1;i<=n;i++){
        //e[i].push_back(i);
        //sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h+p[e[i][j]];

        }
        hash[i]=h;
    }
    for(int i=0;i<ve.size();i++){
        int a=ve[i].first,b=ve[i].second;
        if(hash[a]+p[a]==hash[b]+p[b])ans++;
    }

        sort(hash+1,hash+n+1);
    long long ans=0;
    int l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<<" ";
    cout << endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    /*for(int i=1;i<=n;i++){
        e[i].push_back(i);
        //sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h+p[e[i][j]];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<< " ";
    cout<<endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }*/
    cout <<ans<<endl;

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[101000];
long long hash[101000];
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    for(int i=1;i<=n;i++){
        //e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h*n+e[i][j];
            h%=(1LL<<48) -1;

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    long long ans=0;
    int l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<<endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r+1;
    }
    for(int i=1;i<=n;i++){
        e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h*n+e[i][j];
            h%=(1LL<<48) -1;

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<<endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r+1;
    }
    cout <<ans<<endl;

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[1010000];
long long hash[1010000];
long long p[1010000];
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    p[1]=1;
    for(int i=2;i<=n;i++)p[i]=p[i-1]*31;
    for(int i=1;i<=n;i++){
        //e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h+p[e[i][j]];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    long long ans=0;
    int l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<<" ";
    cout << endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    for(int i=1;i<=n;i++){
        e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h+p[e[i][j]];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<< " ";
    cout<<endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    cout <<ans<<endl;

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[1010000];
long long hash[1010000];
long long p[1010000];
vector<pair<int,int> > ve;
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        e[a].push_back(b);
        e[b].push_back(a);
        ve.push_back(make_pair(a,b));
    }
    p[1]=1;
    for(int i=2;i<=n;i++)p[i]=p[i-1]*31;
    for(int i=1;i<=n;i++){
        //e[i].push_back(i);
        //sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h+p[e[i][j]];

        }
        hash[i]=h;
    }
    long long ans=0;
    for(int i=0;i<ve.size();i++){
        int a=ve[i].first,b=ve[i].second;
        if(hash[a]+p[a]==hash[b]+p[b])ans++;
    }

        sort(hash+1,hash+n+1);
    int l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<<" ";
    cout << endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    /*for(int i=1;i<=n;i++){
        e[i].push_back(i);
        //sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h+p[e[i][j]];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<< " ";
    cout<<endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }*/
    cout <<ans<<endl;

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[1010000];
long long hash[1010000];
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    for(int i=1;i<=n;i++){
        //e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h*109+e[i][j];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    long long ans=0;
    int l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<<" ";
    cout << endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    for(int i=1;i<=n;i++){
        e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h*109+e[i][j];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<< " ";
    cout<<endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    cout <<ans<<endl;

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[101000];
long long hash[101000];
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    vector<vector<int> > v,v2;
    for(int i=1;i<=n;i++){
        //e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        v.push_back(e[i]);
        e[i].push_back(i);
        sort(e[i].begin(),e[i].end());
        v2.push_back(e[i]);
    }
    int id=0;
    long long ans=0;
    while(id<v.size()){
        int r=id+1;
        while(r<v.size()&&v[id]==v[r])r++;
        long long z=r-id;
        ans+=z*(z-1)/2;
        id=r;
    }
    id=0;
    while(id<v2.size()){
        int r=id+1;
        while(r<v2.size()&&v2[id]==v2[r])r++;
        long long z=r-id;
        ans+=z*(z-1)/2;
        id=r;
    }

    cout <<ans<<endl;

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<queue>
using namespace std;
vector<int> e[1010000];
long long hash[1010000];
long long p[1010000];
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++){
        int a,b;
        cin >>a >>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    p[1]=1;
    for(int i=2;i<=n;i++)p[i]=p[i-1]*31;
    for(int i=1;i<=n;i++){
        //e[i].push_back(i);
        //sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h+p[e[i][j]];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    long long ans=0;
    int l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<<" ";
    cout << endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    for(int i=1;i<=n;i++){
        e[i].push_back(i);
        //sort(e[i].begin(),e[i].end());
        long long h=0;
        for(int j=0;j<e[i].size();j++){
            h=h+p[e[i][j]];

        }
        hash[i]=h;
    }

        sort(hash+1,hash+n+1);
    l=1;
    //for(int i=1;i<=n;i++)cout << hash[i]<< " ";
    cout<<endl;
    while(l<n){
        int r=l+1;
        while(r<=n&&hash[r]==hash[l])r++;
        long long z=r-l;
        ans+=(z)*(z-1)/2;
        l=r;
    }
    cout <<ans<<endl;

    return 0;
}


#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <map>
#include <cstdio>
#include <queue>
#include <tr1/unordered_map>

using namespace std;

typedef long long LL;

#define ff first
#define ss second
#define pb push_back
#define mp make_pair

#define FOREACH(it,c) for(typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define REP(i,n) for(int _n=n, i=0;i<_n;++i)
#define FOR(i,a,b) for(int i=(a),_b=(b);i<=_b;++i)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;--i)

const int Inf = 0x3f3f3f3f;

const int NMAX = 1000005;

vector<int> friends[NMAX];

LL pwr[NMAX];

LL get_hash(vector<int> &v)
{
	LL hash = 0;
	for (size_t i = 0; i < v.size(); ++i)
		hash += pwr[v[i]];

	return hash;
}

LL h[NMAX];

LL count_pairs(int N)
{
	sort(h+1, h+N+1);
	LL ret = 0, cnt = 1;
	FOR(i, 2, N)
		if (h[i] != h[i-1])
		{
			ret += cnt*(cnt - 1);
			cnt = 1;
		}
		else
			++cnt;
	ret += cnt*(cnt - 1);
	return ret;
}

int main()
{
	int n, m;
	cin>>n>>m;

	pwr[0] = 1;
	FOR(i, 1, n)
		pwr[i] = pwr[i-1]*1000007;

	while (m--)
	{
		int x, y;
		cin>>x>>y;
		friends[x].pb(y);
		friends[y].pb(x);
	}

	FOR(i, 1, n)
		h[i] = get_hash(friends[i]);

	LL ans = count_pairs(n);

	FOR(i, 1, n)
		friends[i].pb(i);

	FOR(i, 1, n)
		h[i] = get_hash(friends[i]);

	ans += count_pairs(n);

	cout<<ans/2<<"\n";

	return 0;
}


#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <map>
#include <cstdio>
#include <queue>
#include <tr1/unordered_map>

using namespace std;

typedef long long LL;

#define ff first
#define ss second
#define pb push_back
#define mp make_pair

#define FOREACH(it,c) for(typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define REP(i,n) for(int _n=n, i=0;i<_n;++i)
#define FOR(i,a,b) for(int i=(a),_b=(b);i<=_b;++i)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;--i)

const int Inf = 0x3f3f3f3f;

const int NMAX = 1000005;

vector<int> friends[NMAX];

LL get_hash(vector<int> v)
{
	sort(v.begin(), v.end());
	LL p = 1, hash = 0;
	for (size_t i = 0; i < v.size(); ++i)
		hash += v[i] * p, p *= 1000007;

	return hash;
}

tr1::unordered_map<LL, int> cnt;

LL h[NMAX];

int main()
{
	int n, m;
	cin>>n>>m;

	while (m--)
	{
		int x, y;
		cin>>x>>y;
		friends[x].pb(y);
		friends[y].pb(x);
	}

	FOR(i, 1, n)
		h[i] = get_hash(friends[i]);

	FOR(i, 1, n)
		cnt[h[i]]++;

	LL ans = 0;
	FOR(i, 1, n)
		ans += cnt[h[i]] - 1;

	FOR(i, 1, n)
		friends[i].pb(i);

	FOR(i, 1, n)
		h[i] = get_hash(friends[i]);

	cnt.clear();

	FOR(i, 1, n)
		cnt[h[i]]++;

	FOR(i, 1, n)
		ans += cnt[h[i]] - 1;

	cout<<ans/2<<"\n";

	return 0;
}


#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <map>
#include <cstdio>
#include <queue>
#include <tr1/unordered_map>

using namespace std;

typedef long long LL;

#define ff first
#define ss second
#define pb push_back
#define mp make_pair

#define FOREACH(it,c) for(typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define REP(i,n) for(int _n=n, i=0;i<_n;++i)
#define FOR(i,a,b) for(int i=(a),_b=(b);i<=_b;++i)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;--i)

const int Inf = 0x3f3f3f3f;

const int NMAX = 1000005;

vector<int> friends[NMAX];

LL get_hash(vector<int> &v)
{
	sort(v.begin(), v.end());
	//LL p = 1, hash = 0;
	//for (size_t i = 0; i < v.size(); ++i)
	//	hash += v[i] * p, p *= 1000007;
	LL hash = 1;
	for (size_t i = 0; i < v.size(); ++i)
		hash *= v[i] * (v[i] + 1000007);

	return hash;
}

LL h[NMAX];

LL count_pairs(int N)
{
	sort(h+1, h+N+1);
	LL ret = 0, cnt = 1;
	FOR(i, 2, N)
		if (h[i] != h[i-1])
		{
			ret += cnt*(cnt - 1);
			cnt = 1;
		}
		else
			++cnt;
	ret += cnt*(cnt - 1);
	return ret;
}

int main()
{
	int n, m;
	cin>>n>>m;

	while (m--)
	{
		int x, y;
		cin>>x>>y;
		friends[x].pb(y);
		friends[y].pb(x);
	}

	FOR(i, 1, n)
		h[i] = get_hash(friends[i]);

	LL ans = count_pairs(n);

	FOR(i, 1, n)
		friends[i].pb(i);

	FOR(i, 1, n)
		h[i] = get_hash(friends[i]);

	ans += count_pairs(n);

	cout<<ans/2<<"\n";

	return 0;
}


#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <map>
#include <cstdio>
#include <queue>

using namespace std;

typedef long long LL;

#define ff first
#define ss second
#define pb push_back
#define mp make_pair

#define FOREACH(it,c) for(typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define REP(i,n) for(int _n=n, i=0;i<_n;++i)
#define FOR(i,a,b) for(int i=(a),_b=(b);i<=_b;++i)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;--i)

const int Inf = 0x3f3f3f3f;

const int NMAX = 100005;

vector<int> friends[NMAX];

LL get_hash(vector<int> v)
{
	sort(v.begin(), v.end());
	LL p = 1, hash = 0;
	for (size_t i = 0; i < v.size(); ++i)
		hash += v[i] * p, p *= 1000007;

	return hash;
}

map<LL, int> cnt;

int main()
{
	int n, m;
	cin>>n>>m;

	while (m--)
	{
		int x, y;
		cin>>x>>y;
		friends[x].pb(y);
		friends[y].pb(x);
	}

	FOR(i, 1, n)
		cnt[get_hash(friends[i])]++;

	LL ans = 0;
	FOR(i, 1, n)
		ans += cnt[get_hash(friends[i])] - 1;

	FOR(i, 1, n)
		friends[i].pb(i);

	FOR(i, 1, n)
		cnt[get_hash(friends[i])] = 0;

	FOR(i, 1, n)
		cnt[get_hash(friends[i])]++;

	FOR(i, 1, n)
		ans += cnt[get_hash(friends[i])] - 1;

	cout<<ans/2<<"\n";

	return 0;
}


#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <map>
#include <cstdio>
#include <queue>
#include <tr1/unordered_map>

using namespace std;

typedef long long LL;

#define ff first
#define ss second
#define pb push_back
#define mp make_pair

#define FOREACH(it,c) for(typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define REP(i,n) for(int _n=n, i=0;i<_n;++i)
#define FOR(i,a,b) for(int i=(a),_b=(b);i<=_b;++i)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;--i)

const int Inf = 0x3f3f3f3f;

const int NMAX = 1000005;

vector<int> friends[NMAX];

LL get_hash(vector<int> v)
{
	sort(v.begin(), v.end());
	LL p = 1, hash = 0;
	for (size_t i = 0; i < v.size(); ++i)
		hash += v[i] * p, p *= 1000007;

	return hash;
}

LL h[NMAX];

LL count_pairs(int N)
{
	sort(h+1, h+N+1);
	LL ret = 0, cnt = 1;
	FOR(i, 2, N)
		if (h[i] != h[i-1])
		{
			ret += cnt*(cnt - 1);
			cnt = 1;
		}
		else
			++cnt;
	ret += cnt*(cnt - 1);
	return ret;
}

int main()
{
	int n, m;
	cin>>n>>m;

	while (m--)
	{
		int x, y;
		cin>>x>>y;
		friends[x].pb(y);
		friends[y].pb(x);
	}

	FOR(i, 1, n)
		h[i] = get_hash(friends[i]);

	LL ans = count_pairs(n);

	FOR(i, 1, n)
		friends[i].pb(i);

	FOR(i, 1, n)
		h[i] = get_hash(friends[i]);

	ans += count_pairs(n);

	cout<<ans/2<<"\n";

	return 0;
}


#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <map>
#include <cstdio>
#include <queue>

using namespace std;

typedef long long LL;

#define ff first
#define ss second
#define pb push_back
#define mp make_pair

#define FOREACH(it,c) for(typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define REP(i,n) for(int _n=n, i=0;i<_n;++i)
#define FOR(i,a,b) for(int i=(a),_b=(b);i<=_b;++i)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;--i)

const int Inf = 0x3f3f3f3f;

const int NMAX = 1000005;

vector<int> friends[NMAX];

LL get_hash(vector<int> v)
{
	sort(v.begin(), v.end());
	LL p = 1, hash = 0;
	for (size_t i = 0; i < v.size(); ++i)
		hash += v[i] * p, p *= 1000007;

	return hash;
}

map<LL, int> cnt;

int main()
{
	int n, m;
	cin>>n>>m;

	while (m--)
	{
		int x, y;
		cin>>x>>y;
		friends[x].pb(y);
		friends[y].pb(x);
	}

	FOR(i, 1, n)
		cnt[get_hash(friends[i])]++;

	LL ans = 0;
	FOR(i, 1, n)
		ans += cnt[get_hash(friends[i])] - 1;

	FOR(i, 1, n)
		friends[i].pb(i);

	FOR(i, 1, n)
		cnt[get_hash(friends[i])] = 0;

	FOR(i, 1, n)
		cnt[get_hash(friends[i])]++;

	FOR(i, 1, n)
		ans += cnt[get_hash(friends[i])] - 1;

	cout<<ans/2<<"\n";

	return 0;
}


#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <map>
#include <cstdio>
#include <queue>
#include <tr1/unordered_map>

using namespace std;

typedef long long LL;

#define ff first
#define ss second
#define pb push_back
#define mp make_pair

#define FOREACH(it,c) for(typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define REP(i,n) for(int _n=n, i=0;i<_n;++i)
#define FOR(i,a,b) for(int i=(a),_b=(b);i<=_b;++i)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;--i)

const int Inf = 0x3f3f3f3f;

const int NMAX = 1000005;

vector<int> friends[NMAX];

int get_hash(vector<int> v)
{
	sort(v.begin(), v.end());
	int p = 1, hash = 0;
	for (size_t i = 0; i < v.size(); ++i)
		hash += v[i] * p, p *= 1000007;

	return hash;
}

int h[NMAX];

LL count_pairs(int N)
{
	sort(h+1, h+N+1);
	LL ret = 0, cnt = 1;
	FOR(i, 2, N)
		if (h[i] != h[i-1])
		{
			ret += cnt*(cnt - 1);
			cnt = 1;
		}
		else
			++cnt;
	ret += cnt*(cnt - 1);
	return ret;
}

int main()
{
	int n, m;
	cin>>n>>m;

	while (m--)
	{
		int x, y;
		cin>>x>>y;
		friends[x].pb(y);
		friends[y].pb(x);
	}

	FOR(i, 1, n)
		h[i] = get_hash(friends[i]);

	LL ans = count_pairs(n);

	FOR(i, 1, n)
		friends[i].pb(i);

	FOR(i, 1, n)
		h[i] = get_hash(friends[i]);

	ans += count_pairs(n);

	cout<<ans/2<<"\n";

	return 0;
}


#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <map>
#include <cstdio>
#include <queue>
#include <tr1/unordered_map>

using namespace std;

typedef long long LL;

#define ff first
#define ss second
#define pb push_back
#define mp make_pair

#define FOREACH(it,c) for(typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define REP(i,n) for(int _n=n, i=0;i<_n;++i)
#define FOR(i,a,b) for(int i=(a),_b=(b);i<=_b;++i)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;--i)

const int Inf = 0x3f3f3f3f;

const int NMAX = 1000005;

vector<int> friends[NMAX];

LL get_hash(vector<int> &v)
{
	sort(v.begin(), v.end());
	LL p = 1, hash = 0;
	for (size_t i = 0; i < v.size(); ++i)
		hash += v[i] * p, p *= 1000007;

	return hash;
}

LL h[NMAX];

LL count_pairs(int N)
{
	sort(h+1, h+N+1);
	LL ret = 0, cnt = 1;
	FOR(i, 2, N)
		if (h[i] != h[i-1])
		{
			ret += cnt*(cnt - 1);
			cnt = 1;
		}
		else
			++cnt;
	ret += cnt*(cnt - 1);
	return ret;
}

int main()
{
	int n, m;
	cin>>n>>m;

	while (m--)
	{
		int x, y;
		cin>>x>>y;
		friends[x].pb(y);
		friends[y].pb(x);
	}

	FOR(i, 1, n)
		h[i] = get_hash(friends[i]);

	LL ans = count_pairs(n);

	FOR(i, 1, n)
		friends[i].pb(i);

	FOR(i, 1, n)
		h[i] = get_hash(friends[i]);

	ans += count_pairs(n);

	cout<<ans/2<<"\n";

	return 0;
}


#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <map>
#include <cstdio>
#include <queue>
#include <tr1/unordered_map>

using namespace std;

typedef long long LL;

#define ff first
#define ss second
#define pb push_back
#define mp make_pair

#define FOREACH(it,c) for(typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define REP(i,n) for(int _n=n, i=0;i<_n;++i)
#define FOR(i,a,b) for(int i=(a),_b=(b);i<=_b;++i)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;--i)

const int Inf = 0x3f3f3f3f;

const int NMAX = 1000005;

LL pwr[NMAX], h[NMAX];

LL count_pairs(int N)
{
	sort(h+1, h+N+1);
	LL ret = 0, cnt = 1;
	FOR(i, 2, N)
		if (h[i] != h[i-1])
		{
			ret += cnt*(cnt - 1);
			cnt = 1;
		}
		else
			++cnt;
	ret += cnt*(cnt - 1);
	return ret;
}

int main()
{
	int n, m;
	cin>>n>>m;

	pwr[0] = 1;
	FOR(i, 1, n)
		pwr[i] = pwr[i-1]*1000007;

	while (m--)
	{
		int x, y;
		cin>>x>>y;
		h[x] += pwr[y];
		h[y] += pwr[x];
	}

	LL ans = count_pairs(n);

	FOR(i, 1, n)
		h[i] += pwr[i];

	ans += count_pairs(n);

	cout<<ans/2<<"\n";

	return 0;
}


#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <map>
#include <cstdio>
#include <queue>
#include <tr1/unordered_map>

using namespace std;

typedef long long LL;

#define ff first
#define ss second
#define pb push_back
#define mp make_pair

#define FOREACH(it,c) for(typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define REP(i,n) for(int _n=n, i=0;i<_n;++i)
#define FOR(i,a,b) for(int i=(a),_b=(b);i<=_b;++i)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;--i)

const int Inf = 0x3f3f3f3f;

const int NMAX = 1000005;

vector<int> friends[NMAX];

LL get_hash(vector<int> v)
{
	//sort(v.begin(), v.end());
	LL p = 1, hash = 1;
	for (size_t i = 0; i < v.size(); ++i)
		hash *= v[i] + 1000007;
		//hash += v[i] * p, p *= 1000007;

	return hash;
}

tr1::unordered_map<LL, int> cnt;

LL h[NMAX];

int main()
{
	int n, m;
	cin>>n>>m;

	while (m--)
	{
		int x, y;
		cin>>x>>y;
		friends[x].pb(y);
		friends[y].pb(x);
	}

	FOR(i, 1, n)
		h[i] = get_hash(friends[i]);

	FOR(i, 1, n)
		cnt[h[i]]++;

	LL ans = 0;
	FOR(i, 1, n)
		ans += cnt[h[i]] - 1;

	FOR(i, 1, n)
		friends[i].pb(i);

	FOR(i, 1, n)
		h[i] = get_hash(friends[i]);

	cnt.clear();

	FOR(i, 1, n)
		cnt[h[i]]++;

	FOR(i, 1, n)
		ans += cnt[h[i]] - 1;

	cout<<ans/2<<"\n";

	return 0;
}