#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e9+7;
long long n,m,hhash[100010];
struct edge{
	long long u,v;
	edge(){}
	edge(long long _u,long long _v){
		u = _u;
		v = _v;
	}
}p[100010];
long long sum[100010];
int main(){
	memset(sum,0,sizeof(sum));
	scanf("%lld%lld",&n,&m);
	hhash[0] = 1;
	for(long long i = 1;i <= n;i++) hhash[i] = hhash[i-1]*19260817%mod;
	for(long long i = 1;i <= m;i++){
		scanf("%lld%lld",&p[i].u,&p[i].v);
		sum[p[i].u] += hhash[p[i].v];
		sum[p[i].v] += hhash[p[i].u];
	}
	long long fans = 0;
	for(long long i = 1;i <= m;i++){
		if(sum[p[i].u]+hhash[p[i].u] == sum[p[i].v]+hhash[p[i].v]){
			fans++;
		}
	}
	long long cnt = 0;
	sort(sum+1,sum+1+n);
	for(long long i = 2;i <= n;i++){
		if(sum[i] != sum[i-1]){
			fans += cnt*(cnt-1)/2;
			cnt = 1;
		}else{
			cnt++;
		}
	}
	fans += cnt*(cnt-1)/2;
	printf("%lld\n",fans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
unsigned long long wjc452 = 10007;
unsigned long long  n,m,hhash[100010];
struct edge{
	unsigned long long  u,v;
	edge(){}
	edge(unsigned long long  _u,unsigned long long  _v){
		u = _u;
		v = _v;
	}
}p[100010];
unsigned long long  sum[100010];
void get(){
    hhash[0]=1;
    for(unsigned long long  i = 1;i <= n;i++){
    	hhash[i] = hhash[i-1]*wjc452;
	}
}
int main(){
	memset(sum,0,sizeof(sum));
	scanf("%llu%llu",&n,&m);
	get();
	for(unsigned long long  i = 1;i <= m;i++){
		scanf("%llu%llu",&p[i].u,&p[i].v);
		sum[p[i].u] += hhash[p[i].v];
		sum[p[i].v] += hhash[p[i].u];
	}
	unsigned long long  fans = 0;
	for(unsigned long long  i = 1;i <= m;i++){
		if(sum[p[i].u]+hhash[p[i].u] == sum[p[i].v]+hhash[p[i].v]){
			fans++;
		}
	}
	unsigned long long  cnt = 1;
	sort(sum+1,sum+1+n);
	for(unsigned long long  i = 2;i <= n;i++){
		if(sum[i] != sum[i-1]){
			fans += cnt*(cnt-1)/2;
			cnt = 1;
		}else{
			cnt++;
		}
	}
	fans += cnt*(cnt-1)/2;
	printf("%llu\n",fans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int wjc452 = 1313;
int n,m,hhash[100010];
struct edge{
	int u,v;
	edge(){}
	edge(int _u,int _v){
		u = _u;
		v = _v;
	}
}p[100010];
long long sum[100010];

int main(){
	memset(sum,0,sizeof(sum));
	scanf("%d%d",&n,&m);
	hhash[0] = 1;
	for(long long i = 1;i <= n;i++) hhash[i] = hhash[i-1]*wjc452;
	for(long long i = 1;i <= m;i++){
		scanf("%d%d",&p[i].u,&p[i].v);
		sum[p[i].u] += hhash[p[i].v];
		sum[p[i].v] += hhash[p[i].u];
	}
	long long fans = 0;
	for(int i = 1;i <= m;i++){
		if(sum[p[i].u]+hhash[p[i].u] == sum[p[i].v]+hhash[p[i].v]){
			fans++;
		}
	}
	long long cnt = 1;
	sort(sum+1,sum+1+n);
	for(long long i = 2;i <= n;i++){
		if(sum[i] != sum[i-1]){
			fans += cnt*(cnt-1)/2;
			cnt = 1;
		}else{
			cnt++;
		}
	}
	fans += cnt*(cnt-1)/2;
	printf("%lld\n",fans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e9+7;
long long n,m,hhash[100010];
struct edge{
	long long u,v;
	edge(){}
	edge(long long _u,long long _v){
		u = _u;
		v = _v;
	}
}p[100010];
long long sum[100010];
int main(){
	memset(sum,0,sizeof(sum));
	scanf("%lld%lld",&n,&m);
	hhash[0] = 1;
	for(long long i = 1;i <= n;i++) hhash[i] = hhash[i-1]*19260817%mod;
	for(long long i = 1;i <= m;i++){
		scanf("%lld%lld",&p[i].u,&p[i].v);
		sum[p[i].u] += hhash[p[i].v];
		sum[p[i].v] += hhash[p[i].u];
	}
	long long fans = 0;
	for(long long i = 1;i <= m;i++){
		if(sum[p[i].u]+hhash[p[i].u] == sum[p[i].v]+hhash[p[i].v]){
			fans++;
		}
	}
	long long cnt = 0;
	sort(sum+1,sum+1+n);
	for(long long i = 1;i <= n;i++){
		if(sum[i] != sum[i-1]){
			cnt = 1;
		}else{
			if(sum[i] != sum[i+1]){
				cnt++;
				fans += cnt*(cnt-1)/2;
			}else{
				cnt++;
			}
		}
	}
	fans += cnt*(cnt-1)/2;
	printf("%lld\n",fans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e9+7;
const long long wjc452 = 1313;
long long n,m,hhash[100010];
struct edge{
	long long u,v;
	edge(){}
	edge(long long _u,long long _v){
		u = _u;
		v = _v;
	}
}p[100010];
long long sum[100010];
int main(){
	memset(sum,0,sizeof(sum));
	scanf("%lld%lld",&n,&m);
	hhash[0] = 1;
	for(long long i = 1;i <= n;i++) hhash[i] = hhash[i-1]*wjc452;
	for(long long i = 1;i <= m;i++){
		scanf("%lld%lld",&p[i].u,&p[i].v);
		sum[p[i].u] += hhash[p[i].v];
		sum[p[i].v] += hhash[p[i].u];
	}
	long long fans = 0;
	for(long long i = 1;i <= m;i++){
		if(sum[p[i].u]+hhash[p[i].u] == sum[p[i].v]+hhash[p[i].v]){
			fans++;
		}
	}
	long long cnt = 1;
	sort(sum+1,sum+1+n);
	for(long long i = 2;i <= n;i++){
		if(sum[i] != sum[i-1]){
			fans += cnt*(cnt-1)/2;
			cnt = 1;
		}else{
			cnt++;
		}
	}
	fans += cnt*(cnt-1)/2;
	printf("%lld\n",fans);
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <string>
#include <map>

#define FOR(i,b,e) for(int i=(b); i <= (e); ++i)
#define FORD(i,b,e) for(int i=(b); i >= (e); --i)
#define SIZE(c) (int) (c).size()
#define FORE(i,c) FOR(i,0,SIZE(c)-1)
#define FORDE(i,c) FORD(i,SIZE(c)-1,0)
#define MIN(x,y) ( ((x) < (y))? (x) : (y) )
#define MAX(x,y) ( ((x) > (y))? (x) : (y) )
#define PB push_back
#define MP make_pair
#define ST first
#define ND second
#define INF 1000000001

using namespace std;

typedef pair < int , int > PII;
typedef long long int LLI;

typedef vector < int > VI;
typedef vector < bool > VB;
typedef vector < PII > VP;
typedef vector < LLI > VL;

typedef vector < VI > VVI;
typedef vector < VL > VVL;
typedef vector < VB > VVB;

#define N 1000003
#define MOD 1000000007

LLI Pow[N];

void addUniEdge(int u, int v, VL &H)
{
    H[u] += Pow[v];
    H[u] %= MOD;
}

void addEdge(int u, int v, VL &H)
{
    addUniEdge(u, v, H);

    if (u != v)
        addUniEdge(v, u, H);
}

LLI cnt(VL H)
{
    sort(H.begin(), H.end());
    H.PB(-1);

    LLI ans = 0, cnt = 0;

    FORE(i,H)
    {
        if (i && H[i] != H[i-1])
        {
            ans += ( cnt * (cnt - 1) ) / 2;
            cnt = 0;
        }

        cnt++;
    }

    return ans;
}

/*************************************************************************/

int main()
{
    ios_base::sync_with_stdio(0);

    Pow[0] = 1;

    FOR(i,1,N-1)
        Pow[i] = (Pow[i-1] * 2)%MOD;

    int n, m;
    cin >> n >> m;

    VL H(n,0);

    FOR(i,1,m)
    {
        int u, v;

        cin >> u >> v;
        u--; v--;

        addEdge(u, v, H);
    }

    LLI ans = 0;

    ans += cnt(H);

    FOR(i,0,n-1)
        addEdge(i, i, H);

    ans += cnt(H);

    cout << ans;

    return 0;
}

/*************************************************************************/


#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <string>
#include <unordered_map>

#define FOR(i,b,e) for(int i=(b); i <= (e); ++i)
#define FORD(i,b,e) for(int i=(b); i >= (e); --i)
#define SIZE(c) (int) (c).size()
#define FORE(i,c) FOR(i,0,SIZE(c)-1)
#define FORDE(i,c) FORD(i,SIZE(c)-1,0)
#define MIN(x,y) ( ((x) < (y))? (x) : (y) )
#define MAX(x,y) ( ((x) > (y))? (x) : (y) )
#define PB push_back
#define MP make_pair
#define ST first
#define ND second
#define INF 1000000001

using namespace std;

typedef pair < int , int > PII;
typedef long long int LLI;

typedef vector < int > VI;
typedef vector < bool > VB;
typedef vector < PII > VP;
typedef vector < LLI > VL;

typedef vector < VI > VVI;
typedef vector < VL > VVL;
typedef vector < VB > VVB;

#define N 1000003
#define MOD 1000000000000000003

LLI Pow[N];

void addUniEdge(int u, int v, VL &H)
{
    H[u] += Pow[v];
    H[u] %= MOD;
}

void addEdge(int u, int v, VL &H)
{
    addUniEdge(u, v, H);

    if (u != v)
        addUniEdge(v, u, H);
}

LLI cnt(VL &H)
{
    unordered_map < LLI , LLI > M;

    FORE(i,H)
        M[ H[i] ]++;

    LLI ans = 0;

    for (unordered_map < LLI , LLI > :: iterator it = M.begin(); it != M.end(); it++)
        ans += (it->ND * (it->ND - 1)) / 2;

    return ans;
}

/*************************************************************************/

int main()
{
    ios_base::sync_with_stdio(0);

    Pow[0] = 1;

    FOR(i,1,N-1)
        Pow[i] = (Pow[i-1] * 2)%MOD;

    int n, m;
    cin >> n >> m;

    VL H(n,0);

    FOR(i,1,m)
    {
        int u, v;

        cin >> u >> v;
        u--; v--;

        addEdge(u, v, H);
    }

    LLI ans = 0;

    ans += cnt(H);

    FOR(i,0,n-1)
        addEdge(i, i, H);

    ans += cnt(H);

    cout << ans;

    return 0;
}

/*************************************************************************/


#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <string>
#include <map>

#define FOR(i,b,e) for(int i=(b); i <= (e); ++i)
#define FORD(i,b,e) for(int i=(b); i >= (e); --i)
#define SIZE(c) (int) (c).size()
#define FORE(i,c) FOR(i,0,SIZE(c)-1)
#define FORDE(i,c) FORD(i,SIZE(c)-1,0)
#define MIN(x,y) ( ((x) < (y))? (x) : (y) )
#define MAX(x,y) ( ((x) > (y))? (x) : (y) )
#define PB push_back
#define MP make_pair
#define ST first
#define ND second
#define INF 1000000001

using namespace std;

typedef pair < int , int > PII;
typedef long long int LLI;

typedef vector < int > VI;
typedef vector < bool > VB;
typedef vector < PII > VP;
typedef vector < LLI > VL;

typedef vector < VI > VVI;
typedef vector < VL > VVL;
typedef vector < VB > VVB;

#define N 1000003
#define MOD 1000000000000000003

LLI Pow[N];

void addUniEdge(int u, int v, VL &H)
{
    H[u] += Pow[v];
    H[u] %= MOD;
}

void addEdge(int u, int v, VL &H)
{
    addUniEdge(u, v, H);

    if (u != v)
        addUniEdge(v, u, H);
}

LLI cnt(VL H)
{
    sort(H.begin(), H.end());
    H.PB(-1);

    LLI ans = 0, cnt = 0;

    FORE(i,H)
    {
        if (i && H[i] != H[i-1])
        {
            ans += ( cnt * (cnt - 1) ) / 2;
            cnt = 0;
        }

        cnt++;
    }

    return ans;
}

/*************************************************************************/

int main()
{
    ios_base::sync_with_stdio(0);

    Pow[0] = 1;

    FOR(i,1,N-1)
        Pow[i] = (Pow[i-1] * 2)%MOD;

    int n, m;
    cin >> n >> m;

    VL H(n,0);

    FOR(i,1,m)
    {
        int u, v;

        cin >> u >> v;
        u--; v--;

        addEdge(u, v, H);
    }

    LLI ans = 0;

    ans += cnt(H);

    FOR(i,0,n-1)
        addEdge(i, i, H);

    ans += cnt(H);

    cout << ans;

    return 0;
}

/*************************************************************************/


#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <string>
#include <unordered_map>

#define FOR(i,b,e) for(int i=(b); i <= (e); ++i)
#define FORD(i,b,e) for(int i=(b); i >= (e); --i)
#define SIZE(c) (int) (c).size()
#define FORE(i,c) FOR(i,0,SIZE(c)-1)
#define FORDE(i,c) FORD(i,SIZE(c)-1,0)
#define MIN(x,y) ( ((x) < (y))? (x) : (y) )
#define MAX(x,y) ( ((x) > (y))? (x) : (y) )
#define PB push_back
#define MP make_pair
#define ST first
#define ND second
#define INF 1000000001

using namespace std;

typedef pair < int , int > PII;
typedef long long int LLI;

typedef vector < int > VI;
typedef vector < bool > VB;
typedef vector < PII > VP;
typedef vector < LLI > VL;

typedef vector < VI > VVI;
typedef vector < VL > VVL;
typedef vector < VB > VVB;

#define N 1000003
#define MOD 1000000000000000003

LLI Pow[N];

void addUniEdge(int u, int v, VL &H)
{
    H[u] += Pow[v];
    H[u] %= MOD;
}

void addEdge(int u, int v, VL &H)
{
    addUniEdge(u, v, H);

    if (u != v)
        addUniEdge(v, u, H);
}

LLI cnt(VL &H)
{
    unordered_map < LLI , LLI > M;

    FORE(i,H)
        M[ H[i] ]++;

    LLI ans = 0;

    for (unordered_map < LLI , LLI > :: iterator it = M.begin(); it != M.end(); it++)
        ans += (it->ND * (it->ND - 1)) / 2;

    return ans;
}

/*************************************************************************/

int main()
{
    Pow[0] = 1;

    FOR(i,1,N-1)
        Pow[i] = (Pow[i-1] * 2)%MOD;

    int n, m;
    scanf("%d%d", &n, &m);

    VL H(n,0);

    FOR(i,1,m)
    {
        int u, v;

        scanf("%d%d", &u, &v);
        u--; v--;

        addEdge(u, v, H);
    }

    LLI ans = 0;

    ans += cnt(H);

    FOR(i,0,n-1)
        addEdge(i, i, H);

    ans += cnt(H);

    printf("%I64d", ans);

    return 0;
}

/*************************************************************************/


#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <string>
#include <unordered_map>
#include <cstdio>

#define FOR(i,b,e) for(int i=(b); i <= (e); ++i)
#define FORD(i,b,e) for(int i=(b); i >= (e); --i)
#define SIZE(c) (int) (c).size()
#define FORE(i,c) FOR(i,0,SIZE(c)-1)
#define FORDE(i,c) FORD(i,SIZE(c)-1,0)
#define MIN(x,y) ( ((x) < (y))? (x) : (y) )
#define MAX(x,y) ( ((x) > (y))? (x) : (y) )
#define PB push_back
#define MP make_pair
#define ST first
#define ND second
#define INF 1000000001

using namespace std;

typedef pair < int , int > PII;
typedef long long int LLI;

typedef vector < int > VI;
typedef vector < bool > VB;
typedef vector < PII > VP;
typedef vector < LLI > VL;

typedef vector < VI > VVI;
typedef vector < VL > VVL;
typedef vector < VB > VVB;

#define N 1000003
#define MOD 1000000000000000003

LLI Pow[N];

void addUniEdge(int u, int v, VL &H)
{
    H[u] += Pow[v];
    H[u] %= MOD;
}

void addEdge(int u, int v, VL &H)
{
    addUniEdge(u, v, H);

    if (u != v)
        addUniEdge(v, u, H);
}

LLI cnt(VL &H)
{
    unordered_map < LLI , LLI > M;

    FORE(i,H)
        M[ H[i] ]++;

    LLI ans = 0;

    for (unordered_map < LLI , LLI > :: iterator it = M.begin(); it != M.end(); it++)
        ans += (it->ND * (it->ND - 1)) / 2;

    return ans;
}

/*************************************************************************/

int main()
{
    Pow[0] = 1;

    FOR(i,1,N-1)
        Pow[i] = (Pow[i-1] * 2)%MOD;

    int n, m;
    scanf("%d%d", &n, &m);

    VL H(n,0);

    FOR(i,1,m)
    {
        int u, v;

        scanf("%d%d", &u, &v);
        u--; v--;

        addEdge(u, v, H);
    }

    LLI ans = 0;

    ans += cnt(H);

    FOR(i,0,n-1)
        addEdge(i, i, H);

    ans += cnt(H);

    printf("%I64d", ans);

    return 0;
}

/*************************************************************************/


#include <bits/stdc++.h>
#define endl '\n'

#define int long long

using namespace std;
const int MAXN = (1 << 20);
const int base = (int)2;
const int mod = (int)1e17 + 9;

int n, m;
vector<int> G[MAXN];

void read()
{
	cin >> n >> m;
	for(int i = 0; i < m; i++)
	{
		int u, v;
		cin >> u >> v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
}

int base_pow[MAXN], h[MAXN];
map<int, int> fir, sec;

void solve()
{
	base_pow[0] = 1;
	for(int i = 1; i <= n; i++)
		base_pow[i] = (base_pow[i - 1] * base) % mod;

	for(int i = 1; i <= n; i++)
		for(int j = 0; j < G[i].size(); j++)
			h[i] = (h[i] + base_pow[G[i][j]]) % mod;

	fir.clear();
	sec.clear();

	int ans = 0, newh;
	for(int i = 1; i <= n; i++)
	{
		newh = (base_pow[i] + h[i]) % mod;
		ans += fir[newh];
		ans += sec[h[i]];
		fir[newh]++;
		sec[h[i]]++;
	}

	cout << ans << endl;
}

#undef int
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	read();
	solve();
	return 0;
}


#include <bits/stdc++.h>
#define endl '\n'

#define int unsigned long long

using namespace std;
const int MAXN = (1 << 20);
const int base = (int)3;

void Read(int &x);

int n, m;
vector<int> G[MAXN];

void read()
{
	//cin >> n >> m;
	Read(n);
	Read(m);
	for(int i = 0; i < m; i++)
	{
		int u, v;
		//cin >> u >> v;
		Read(u);
		Read(v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
}

int base_pow[MAXN], h[MAXN];
int fir[MAXN];

void solve()
{
	base_pow[0] = 1;
	for(int i = 1; i <= n; i++)
		base_pow[i] = base_pow[i - 1] * base;

	for(int i = 1; i <= n; i++)
		for(int j = 0; j < G[i].size(); j++)
			h[i] = h[i] + base_pow[G[i][j]];

	unsigned long long ans = 0;
	int newh;
	for(int i = 1; i <= n; i++)
	{
		newh = base_pow[i] + h[i];
		fir[i] = newh;
	}

	sort(h + 1, h + n + 1);
	sort(fir + 1, fir + n + 1);

	unsigned long long cnt = 1;
	for(int i = 2; i <= n; i++)
		if(h[i] == h[i - 1]) ans += (cnt++);
		else cnt = 1;

	cnt = 1;
	for(int i = 2; i <= n; i++)
		if(fir[i] == fir[i - 1]) ans += (cnt++);
		else cnt = 1;

	printf("%llu\n", ans);
	//cout << ans << endl;
}

#undef int
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	read();
	solve();
	return 0;
}

#define int unsigned long long
#define maxl 1000000
char sir[maxl];
int pos_ind = 0;

void Next() { if(++pos_ind == maxl) fread(sir, 1, maxl, stdin), pos_ind = 0;}
void Read(int &x)
{
	for(; sir[pos_ind] < '0' || sir[pos_ind] > '9'; Next());
	for(x = 0; sir[pos_ind] >= '0' && sir[pos_ind] <= '9'; Next())
		x = x * 10 + sir[pos_ind] - '0';
}


#include <bits/stdc++.h>
#define endl '\n'

#define int unsigned long long

using namespace std;
const int MAXN = (1 << 20);
const int base = (int)3;

int n, m;
vector<int> G[MAXN];

void read()
{
	cin >> n >> m;
	for(int i = 0; i < m; i++)
	{
		int u, v;
		cin >> u >> v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
}

int base_pow[MAXN], h[MAXN];
unordered_map<int, int> fir, sec;

void solve()
{
	base_pow[0] = 1;
	for(int i = 1; i <= n; i++)
		base_pow[i] = base_pow[i - 1] * base;

	for(int i = 1; i <= n; i++)
		for(int j = 0; j < G[i].size(); j++)
			h[i] = h[i] + base_pow[G[i][j]];

	fir.clear();
	sec.clear();

	int ans = 0, newh;
	for(int i = 1; i <= n; i++)
	{
		newh = base_pow[i] + h[i];
		ans += fir[newh];
		ans += sec[h[i]];
		fir[newh]++;
		sec[h[i]]++;
	}

	cout << ans << endl;
}

#undef int
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	read();
	solve();
	return 0;
}


#include <bits/stdc++.h>
#define endl '\n'

#define int unsigned

using namespace std;
const int MAXN = (1 << 20);
const int base = (int)3;

void Read(int &x);

int n, m;
vector<int> G[MAXN];

void read()
{
	//cin >> n >> m;
	Read(n);
	Read(m);
	for(int i = 0; i < m; i++)
	{
		int u, v;
		//cin >> u >> v;
		Read(u);
		Read(v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
}

int base_pow[MAXN], h[MAXN];
int fir[MAXN];

void solve()
{
	base_pow[0] = 1;
	for(int i = 1; i <= n; i++)
		base_pow[i] = base_pow[i - 1] * base;

	for(int i = 1; i <= n; i++)
		for(int j = 0; j < G[i].size(); j++)
			h[i] = h[i] + base_pow[G[i][j]];

	unsigned long long ans = 0;
	int newh;
	for(int i = 1; i <= n; i++)
	{
		newh = base_pow[i] + h[i];
		fir[i] = newh;
	}

	sort(h + 1, h + n + 1);
	sort(fir + 1, fir + n + 1);

	unsigned long long cnt = 1;
	for(int i = 2; i <= n; i++)
		if(h[i] == h[i - 1]) ans += (cnt++);
		else cnt = 1;

	cnt = 1;
	for(int i = 2; i <= n; i++)
		if(fir[i] == fir[i - 1]) ans += (cnt++);
		else cnt = 1;

	printf("%llu\n", ans);
	//cout << ans << endl;
}

#undef int
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	read();
	solve();
	return 0;
}

#define int unsigned
#define maxl 100000
char sir[maxl];
int pos_ind = 0;

void Next() { if(++pos_ind == maxl) fread(sir, 1, maxl, stdin), pos_ind = 0;}
void Read(int &x)
{
	for(; sir[pos_ind] < '0' || sir[pos_ind] > '9'; Next());
	for(x = 0; sir[pos_ind] >= '0' && sir[pos_ind] <= '9'; Next())
		x = x * 10 + sir[pos_ind] - '0';
}


#include <bits/stdc++.h>
#define endl '\n'

#define int unsigned long long

using namespace std;
const int MAXN = (1 << 20);
const int base = (int)2;

int n, m;
vector<int> G[MAXN];

void read()
{
	cin >> n >> m;
	for(int i = 0; i < m; i++)
	{
		int u, v;
		cin >> u >> v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
}

int base_pow[MAXN], h[MAXN];
unordered_map<int, int> fir, sec;

void solve()
{
	base_pow[0] = 1;
	for(int i = 1; i <= n; i++)
		base_pow[i] = base_pow[i - 1] * base;

	for(int i = 1; i <= n; i++)
		for(int j = 0; j < G[i].size(); j++)
			h[i] = h[i] + base_pow[G[i][j]];

	fir.clear();
	sec.clear();

	int ans = 0, newh;
	for(int i = 1; i <= n; i++)
	{
		newh = base_pow[i] + h[i];
		ans += fir[newh];
		ans += sec[h[i]];
		fir[newh]++;
		sec[h[i]]++;
	}

	cout << ans << endl;
}

#undef int
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	read();
	solve();
	return 0;
}


#include <bits/stdc++.h>
#define endl '\n'

#define int long long

using namespace std;
const int MAXN = (1 << 20);
const int base = (int)2;
const int mod = (int)1e9 + 9;

int n, m;
vector<int> G[MAXN];

void read()
{
	cin >> n >> m;
	for(int i = 0; i < m; i++)
	{
		int u, v;
		cin >> u >> v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
}

int base_pow[MAXN], h[MAXN];
map<int, int> fir, sec;

void solve()
{
	base_pow[0] = 1;
	for(int i = 1; i <= n; i++)
		base_pow[i] = (base_pow[i - 1] * base) % mod;

	for(int i = 1; i <= n; i++)
		for(int j = 0; j < G[i].size(); j++)
			h[i] = (h[i] + base_pow[G[i][j]]) % mod;

	fir.clear();
	sec.clear();

	int ans = 0, newh;
	for(int i = 1; i <= n; i++)
	{
		newh = (base_pow[i] + h[i]) % mod;
		ans += fir[newh];
		ans += sec[h[i]];
		fir[newh]++;
		sec[h[i]]++;
	}

	cout << ans << endl;
}

#undef int
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	read();
	solve();
	return 0;
}


#include <bits/stdc++.h>
#define endl '\n'

#define int unsigned long long

using namespace std;
const int MAXN = (1 << 20);
const int base = (int)3;

int n, m;
vector<int> G[MAXN];

void read()
{
	cin >> n >> m;
	for(int i = 0; i < m; i++)
	{
		int u, v;
		cin >> u >> v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
}

int base_pow[MAXN], h[MAXN];
int fir[MAXN];

void solve()
{
	base_pow[0] = 1;
	for(int i = 1; i <= n; i++)
		base_pow[i] = base_pow[i - 1] * base;

	for(int i = 1; i <= n; i++)
		for(int j = 0; j < G[i].size(); j++)
			h[i] = h[i] + base_pow[G[i][j]];

	int ans = 0, newh;
	for(int i = 1; i <= n; i++)
	{
		newh = base_pow[i] + h[i];
		fir[i] = newh;
	}

	sort(h + 1, h + n + 1);
	sort(fir + 1, fir + n + 1);

	int cnt = 1;
	for(int i = 2; i <= n; i++)
		if(h[i] == h[i - 1]) ans += (cnt++);
		else cnt = 1;

	cnt = 1;
	for(int i = 2; i <= n; i++)
		if(fir[i] == fir[i - 1]) ans += (cnt++);
		else cnt = 1;

	cout << ans << endl;
}

#undef int
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	read();
	solve();
	return 0;
}


#include <bits/stdc++.h>
#define endl '\n'

#define int unsigned long long

using namespace std;
const int MAXN = (1 << 20);
const int base = (int)3;

int n, m;
vector<int> G[MAXN];

void read()
{
	cin >> n >> m;
	for(int i = 0; i < m; i++)
	{
		int u, v;
		cin >> u >> v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
}

int base_pow[MAXN], h[MAXN];
multiset<int> fir, sec;

void solve()
{
	base_pow[0] = 1;
	for(int i = 1; i <= n; i++)
		base_pow[i] = base_pow[i - 1] * base;

	for(int i = 1; i <= n; i++)
		for(int j = 0; j < G[i].size(); j++)
			h[i] = h[i] + base_pow[G[i][j]];

	fir.clear();
	sec.clear();

	int ans = 0, newh;
	for(int i = 1; i <= n; i++)
	{
		newh = base_pow[i] + h[i];
		ans += fir.count(newh);
		ans += sec.count(h[i]);
		fir.insert(newh);
		sec.insert(h[i]);
	}

	cout << ans << endl;
}

#undef int
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	read();
	solve();
	return 0;
}


#include <bits/stdc++.h>
#define endl '\n'

#define int unsigned long long

using namespace std;
const int MAXN = (1 << 20);
const int base = (int)3;

int n, m;
vector<int> G[MAXN];

void read()
{
	cin >> n >> m;
	for(int i = 0; i < m; i++)
	{
		int u, v;
		cin >> u >> v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
}

int base_pow[MAXN], h[MAXN];
unordered_multiset<int> fir, sec;

void solve()
{
	base_pow[0] = 1;
	for(int i = 1; i <= n; i++)
		base_pow[i] = base_pow[i - 1] * base;

	for(int i = 1; i <= n; i++)
		for(int j = 0; j < G[i].size(); j++)
			h[i] = h[i] + base_pow[G[i][j]];

	fir.clear();
	sec.clear();

	int ans = 0, newh;
	for(int i = 1; i <= n; i++)
	{
		newh = base_pow[i] + h[i];
		ans += fir.count(newh);
		ans += sec.count(h[i]);
		fir.insert(newh);
		sec.insert(h[i]);
	}

	cout << ans << endl;
}

#undef int
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	read();
	solve();
	return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,sse3,sse4,popcnt,abm,mmx")

//#include<bits/stdc++.h>
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <string>
#include <bitset>
#include <cstdio>
#include <limits>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <numeric>
#include <sstream>
#include <cassert>
#include <iomanip>
#include <iostream>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>

#define _USE_MATH_DEFINES_
#define ll long long
#define ld long double
#define Accepted 0
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x.size())
#define every(x) x.begin(),x.end()
#define F first
#define S second
#define For(i,x,y)  for (ll i = x; i <= y; i ++)
#define FOr(i,x,y)  for (ll i = x; i >= y; i --)
#define SpeedForce ios_base::sync_with_stdio(0), cin.tie(0)
// ROAD to...                                                                                Red

using namespace std;

inline bool isvowel (char c) {
	c = tolower(c);
    if (c == 'a' || c == 'e' || c == 'i' || c == 'y' || c == 'o' || c == 'u') return 1;
    return 0;
}

const double eps = 0.000001;
const ld pi = acos(-1);
const int maxn = 1e7 + 9;
const ll MOD = 1e18 + 9;
const ll INF = 1e18 + 123;
const int inf = 2e9 + 11;
const int mxn = 1e6 + 9;
const int N = 3e5 + 123;
const int PRI = 555557;
const int pri = 997;
const int Magic = 2101;

//const int dx[] = {2, 2, 1, 1, -1, -1, -2, -2};
//const int dy[] = {1, -1, 2, -2, 2, -2, 1, -1};

/*
inline void NO () {
	puts("NO");
	exit(0);
}

inline void YES () {
	puts("YES");
	exit(0);
}
*/

int n, m, k;
vector < int > g[mxn];
long long ans;

pair < int, int > get_hash (vector < int > & v) {
	int mod = 1e9 + 7, mod2 = 1e9 + 123;
  	long long a = 0, b = 0;

  	for (int x : v) {
    	a = (a * PRI + x) % mod;
    	b = (b * pri + x) % mod2;
  	}
  	return mp(a, b);
}

map < pair < int, pair < int, int > > , int > cnt;
void calc () {
	cnt.clear();
	for (int i = 1; i <= n; i ++) {
    	sort(every(g[i]));
    	pair < int, int > cur = get_hash(g[i]);
    	ans += cnt[mp(g[i].size(), cur)];
    	cnt[mp(g[i].size(), cur)] ++;
    }
}

inline void Solve () {
	cin >> n >> m;
  	for (int i = 1, x, y; i <= m; i ++) {
    	cin >> x >> y;
    	g[x].pb(y);
    	g[y].pb(x);
  	}

  	calc();
  	for (int i = 1; i <= n; i ++)
    	g[i].pb(i);
  	calc();

	cout << ans;
}

int main () {
	int tests = 1;
	SpeedForce;
//	freopen(".in", "r", stdin);
//	freopen(".out", "w", stdout);
	//cin >> tests;
	while(tests --) {
		Solve ();
		// TooSimple ? True : False
	}
	// Accepted ? True : True
	return Accepted;
}

// Coded by Al... Bat...


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,sse3,sse4,popcnt,abm,mmx")

//#include<bits/stdc++.h>
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <string>
#include <bitset>
#include <cstdio>
#include <limits>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <numeric>
#include <sstream>
#include <cassert>
#include <iomanip>
#include <iostream>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>

#define _USE_MATH_DEFINES_
#define ll long long
#define ld long double
#define Accepted 0
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x.size())
#define every(x) x.begin(),x.end()
#define F first
#define S second
#define For(i,x,y)  for (ll i = x; i <= y; i ++)
#define FOr(i,x,y)  for (ll i = x; i >= y; i --)
#define SpeedForce ios_base::sync_with_stdio(0), cin.tie(0)
// ROAD to...                                                                                Red

using namespace std;

inline bool isvowel (char c) {
	c = tolower(c);
    if (c == 'a' || c == 'e' || c == 'i' || c == 'y' || c == 'o' || c == 'u') return 1;
    return 0;
}

const double eps = 0.000001;
const ld pi = acos(-1);
const int maxn = 1e7 + 9;
const ll MOD = 1e18 + 9;
const ll INF = 1e18 + 123;
const int inf = 2e9 + 11;
const int mxn = 1e6 + 9;
const int N = 3e5 + 123;
const int PRI = 555557;
const int pri = 997;
const int Magic = 2101;

//const int dx[] = {2, 2, 1, 1, -1, -1, -2, -2};
//const int dy[] = {1, -1, 2, -2, 2, -2, 1, -1};

/*
inline void NO () {
	puts("NO");
	exit(0);
}

inline void YES () {
	puts("YES");
	exit(0);
}
*/

int n, m, k;
vector < int > g[mxn];
long long ans;

pair < int, int > get_hash (vector < int > & v) {
	int mod = 1e9 + 7, mod2 = 1e9 + 11;
  	long long a = 0, b = 0;

  	for (int x : v) {
    	a = (a * PRI + x) % mod;
    	b = (b * PRI + x) % mod2;
  	}
  	return mp(a, b);
}

void calc () {
	vector < pair < int ,int > > st;
  	for (int i = 1; i <= n; i ++) {
    	sort(every(g[i]));
    	st.pb(get_hash(g[i]));
  	}

  	sort (every(st));
  	int len = 1;

  	for (int i = 1; i < n; i ++) {
    	if (st[i] != st[i - 1]) len = 1;
    	else {
      		ans += len;
      		len ++;
    	}
  	}
}

inline void Solve () {
	cin >> n >> m;
  	for (int i = 1, x, y; i <= m; i ++) {
    	cin >> x >> y;
    	g[x].pb(y);
    	g[y].pb(x);
  	}

  	calc();
  	for (int i = 1; i <= n; i ++)
    	g[i].pb(i);
  	calc();

	cout << ans;
}

int main () {
	int tests = 1;
	SpeedForce;
//	freopen(".in", "r", stdin);
//	freopen(".out", "w", stdout);
	//cin >> tests;
	while(tests --) {
		Solve ();
		// TooSimple ? True : False
	}
	// Accepted ? True : True
	return Accepted;
}

// Coded by Al... Bat...


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,sse3,sse4,popcnt,abm,mmx")

//#include<bits/stdc++.h>
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <string>
#include <bitset>
#include <cstdio>
#include <limits>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <numeric>
#include <sstream>
#include <cassert>
#include <iomanip>
#include <iostream>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>

#define _USE_MATH_DEFINES_
#define ll long long
#define ld long double
#define Accepted 0
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x.size())
#define every(x) x.begin(),x.end()
#define F first
#define S second
#define For(i,x,y)  for (ll i = x; i <= y; i ++)
#define FOr(i,x,y)  for (ll i = x; i >= y; i --)
#define SpeedForce ios_base::sync_with_stdio(0), cin.tie(0)
#define lld I64d
// ROAD to...                                                                                Red

using namespace std;

inline bool isvowel (char c) {
	c = tolower(c);
    if (c == 'a' || c == 'e' || c == 'i' || c == 'y' || c == 'o' || c == 'u') return 1;
    return 0;
}

const double eps = 0.000001;
const ld pi = acos(-1);
const int maxn = 1e7 + 9;
const ll MOD = 1e18 + 9;
const ll INF = 1e18 + 123;
const int inf = 2e9 + 11;
const int mxn = 1e6 + 9;
const int N = 3e5 + 123;
const int PRI = 555557;
const int pri = 997;
const int Magic = 2101;

//const int dx[] = {2, 2, 1, 1, -1, -1, -2, -2};
//const int dy[] = {1, -1, 2, -2, 2, -2, 1, -1};

/*
inline void NO () {
	puts("NO");
	exit(0);
}

inline void YES () {
	puts("YES");
	exit(0);
}
*/

int n, m, k;
vector < int > g[mxn];
long long ans;

inline pair < int, int > get_hash (vector < int > & v) {
	int mod = 1e9 + 7, mod2 = 1e9 + 123;
  	long long a = 0, b = 0;

  	for (int x : v) {
    	a = (a * PRI + x) % mod;
    	b = (b * pri + x) % mod2;
  	}
  	return mp(a, b);
}

map < pair < int, pair < int, int > > , int > cnt;
inline void calc () {
	cnt.clear();
	for (int i = 1; i <= n; i ++) {
    	sort(every(g[i]));
    	pair < int, int > cur = get_hash(g[i]);
    	ans += cnt[mp(g[i].size(), cur)];
    	cnt[mp(g[i].size(), cur)] ++;
    }
}

int main () {
	scanf("%d%d", &n, &m);
  	for (int i = 1, x, y; i <= m; i ++) {
    	scanf("%d%d", &x, &y);
    	g[x].pb(y);
    	g[y].pb(x);
  	}

  	calc();
  	for (int i = 1; i <= n; i ++)
    	g[i].pb(i);
  	calc();

	printf("%lld", ans);
}

// Coded by Al... Bat...


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,sse3,sse4,popcnt,abm,mmx")

//#include<bits/stdc++.h>
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <string>
#include <bitset>
#include <cstdio>
#include <limits>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <numeric>
#include <sstream>
#include <cassert>
#include <iomanip>
#include <iostream>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>

#define _USE_MATH_DEFINES_
#define ll long long
#define ld long double
#define Accepted 0
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x.size())
#define every(x) x.begin(),x.end()
#define F first
#define S second
#define For(i,x,y)  for (ll i = x; i <= y; i ++)
#define FOr(i,x,y)  for (ll i = x; i >= y; i --)
#define SpeedForce ios_base::sync_with_stdio(0), cin.tie(0)
// ROAD to...                                                                                Red

using namespace std;

inline bool isvowel (char c) {
	c = tolower(c);
    if (c == 'a' || c == 'e' || c == 'i' || c == 'y' || c == 'o' || c == 'u') return 1;
    return 0;
}

const double eps = 0.000001;
const ld pi = acos(-1);
const int maxn = 1e7 + 9;
const ll MOD = 1e18 + 9;
const ll INF = 1e18 + 123;
const int inf = 2e9 + 11;
const int mxn = 1e6 + 9;
const int N = 3e5 + 123;
const int PRI = 555557;
const int pri = 997;
const int Magic = 2101;

//const int dx[] = {2, 2, 1, 1, -1, -1, -2, -2};
//const int dy[] = {1, -1, 2, -2, 2, -2, 1, -1};

/*
inline void NO () {
	puts("NO");
	exit(0);
}

inline void YES () {
	puts("YES");
	exit(0);
}
*/

int n, m, k;
vector < int > g[mxn];
long long ans;

pair < int, int > get_hash (vector < int > & v) {
	int mod = 1e9 + 7, mod2 = 2e9 + 11;
  	long long a = 0, b = 0;

  	for (int x : v) {
    	a = (a * PRI + x) % mod;
    	b = (b * PRI + x) % mod2;
  	}
  	return mp(a, b);
}

void calc () {
	vector < pair < int ,int > > st;
  	for (int i = 1; i <= n; i ++) {
    	sort(every(g[i]));
    	st.pb(get_hash(g[i]));
  	}

  	sort (every(st));
  	int len = 1;

  	for (int i = 1; i < n; i ++) {
    	if (st[i] != st[i - 1]) len = 1;
    	else {
      		ans += len;
      		len ++;
    	}
  	}
}

inline void Solve () {
	cin >> n >> m;
  	for (int i = 1, x, y; i <= m; i ++) {
    	cin >> x >> y;
    	g[x].pb(y);
    	g[y].pb(x);
  	}

  	calc();
  	for (int i = 1; i <= n; i ++)
    	g[i].pb(i);
  	calc();

	cout << ans;
}

int main () {
	int tests = 1;
	SpeedForce;
//	freopen(".in", "r", stdin);
//	freopen(".out", "w", stdout);
	//cin >> tests;
	while(tests --) {
		Solve ();
		// TooSimple ? True : False
	}
	// Accepted ? True : True
	return Accepted;
}

// Coded by Al... Bat...


#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
#include <cstdlib>
#include <ctime>
using namespace std;

inline int read() {
	int x=0,f=1;
	char cr=getchar();
	while (cr>'9' || cr<'0') {
		if (cr=='-') f=-1;
		cr=getchar();
	}
	while (cr>='0' && cr<='9') {
		x=(x<<3)+(x<<1)+cr-'0';
		cr=getchar();
	}
	return x*f;
}
const int maxn=1000050;

map<unsigned long long,int> num;
vector<int> e[maxn];
unsigned long long has[maxn];
unsigned long long val[maxn];
double ans;

int main() {
	srand(time(0));
	memset(has,0x3f,sizeof(has));
	int n=read(),m=read();
	for (int i=1;i<=n;i++) {
		for (int j=1;j<=5;j++) {
			int temp=rand();
			while (!temp) temp=rand();
			has[i]*=temp;
		}
	}
	for (int i=1;i<=m;i++) {
		int x=read(),y=read();
		val[x]+=has[y],val[y]+=has[x];
		e[x].push_back(y);e[y].push_back(x);
	}
	for (int i=1;i<=n;i++)
		ans+=num[val[i]],num[val[i]]++;
	for (int i=1;i<=n;i++) {
		int now=i;
		for (int j=0;j<e[now].size();j++) {
			int to=e[now][j];
			if (val[now]+has[now]==val[to]+has[to]) ans+=0.5;
		}
	}
	printf("%.0lf",ans);
}


#include <bits/stdc++.h>
using namespace std;
const long long mod=19260817;
const int maxn=1010111;
int n,m;
long long a[maxn],sum[maxn];
long long C(long long x,long long y){
	long long res=x*(x-1)/y;
	return res;
}
pair<int,int> e[maxn];
int main(){
	cin>>n>>m;
	a[0]=1;
	for(long long i=1;i<=n;i++){
		a[i]=(a[i-1]*131);
	}
	for(int i=1;i<=m;i++){
		int x,y;
		cin>>x>>y;
		e[i].first=x;
		e[i].second=y;
		sum[x]+=a[y];
		sum[y]+=a[x];
		//sum[x]%=mod;
		//sum[y]%=mod;
	}
	long long ans=0;
	for(int i=1;i<=m;i++){
		int x=e[i].first,y=e[i].second;
		if(sum[x]-a[y]==sum[y]-a[x])ans++;
	}
	sort(sum+1,sum+1+n);
	//for(int i=1;i<=n;i++)cout<<i<<" : "<<sum[i]<<endl;
	long long cnt=1;
	sum[n+1]=-999999;
	for(int i=2;i<=n;i++){
		if(sum[i]==sum[i-1]){
			cnt++;
			ans+=(cnt-1);
		}else{
			cnt=1;
		}
	}
	cout<<ans<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int mod=10001587;
const int maxn=100111;
int n,m;
long long a[maxn],sum[maxn];
long long C(long long x,long long y){
	long long res=x*(x-1)/y;
	return res;
}
int main(){
	cin>>n>>m;
	a[0]=23333;
	for(int i=1;i<=n;i++){
		a[i]=(a[i-1]*(17*i)%mod*91238302)%mod;
		//sum[i]+=a[i];
	}
	for(int i=1;i<=m;i++){
		int aa,ab;
		cin>>aa>>ab;
		sum[aa]+=a[ab];
		sum[ab]+=a[aa];
		sum[aa]%=mod;
		sum[ab]%=mod;
	}
	for(int i=1;i<=n;i++){
		if(sum[i]!=0)sum[i]+=a[i];
	}
	sort(sum+1,sum+1+n);
	//for(int i=1;i<=n;i++)cout<<i<<" : "<<sum[i]<<endl;
	long long ans=0,cnt=0,ls=-1;
	sum[n+1]=-999999;
	for(int i=1;i<=n+1;i++){
		if(ls!=sum[i]){
			//cout<<ls<<" "<<sum[i]<<" "<<cnt<<" "<<C(cnt,2)<<endl;
			if(cnt>=2)ans+=C(cnt,2);
			ls=sum[i];
			cnt=1;
		}else{
			cnt++;
		}
	}
	cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define uint unsigned int
using namespace std;
const int maxn=2000010;
const int seed=1331;
const int seed2=131;
uint p[maxn],p2[maxn];long long ans;
pair<uint,uint>h[maxn];
int main()
{
    int N,M,u,v;
    scanf("%d%d",&N,&M); p[0]=1; p2[0]=1;
    rep(i,1,N) p[i]=p[i-1]*seed;
    rep(i,1,N) p2[i]=p2[i-1]*seed2;
    rep(i,1,N) h[i].first=p[i],h[i].second=p2[i];
    rep(i,1,M){
        scanf("%d%d",&u,&v);
        h[u].first+=p[v]; h[v].first+=p[u];
        h[u+N].first+=p[v]; h[v+N].first+=p[u];
        h[u].second+=p2[v]; h[v].second+=p2[u];
        h[u+N].second+=p2[v]; h[v+N].second+=p2[u];
    }
    sort(h+1,h+N+N+1);
    for(int i=1;i<=N+N;i++){
        int j=i;
        while(j+1<=N+N&&h[j+1]==h[i]) j++;
        ans+=(long long)(j-i+1)*(j-i)/2;
        i=j;
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define I inline
#define R register

I int read(){
	int x=0;bool f=0;char ch=getchar();
	while(!isdigit(ch))f|=ch=='-',ch=getchar();
	while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return f?-x:x;
}

I void write(int x){
	if(x<0)putchar('-'),x=-x;
	if(x>9)write(x/10);
	putchar(48+x%10);
}

I void writeln(int x){write(x);putchar('\n');}
I void writebl(int x){write(x);putchar(' ');}

const int maxn = 100000007;
const int p=2005;
int h[maxn],a[maxn];
int e[maxn][2];
void init(){
	h[0]=1;
	for(R int i=1;i<maxn;++i)h[i]=h[i-1]*p;
}

signed main(){
	int n=read(),m=read();
	init();
	for(R int i=1,u,v;i<=m;++i){
		e[i][0]=u=read();e[i][1]=v=read();
		a[u]+=h[v];a[v]+=h[u];
	}
	long long ans=0;
	for(R int i=1;i<=m;++i){
		int u=e[i][0],v=e[i][1];
		long long hu=a[u]+h[u],hv=a[v]+h[v];
		if(hu==hv)ans++;
	}sort(a+1,a+n+1);
	R int i=2,cnt=1;
	while(i<=n){
		if(a[i]==a[i-1])
			cnt++;
		else {
			ans+=cnt*(cnt-1)/2;
			cnt=1;
		}
		i++;
	}
	ans+=cnt*(cnt-1)/2;
	cout<<ans<<endl;
}


#include <iostream>
#include <algorithm>
using namespace std;

const int maxn=1000005;
typedef long long LL;

LL ha[maxn];
LL p=1313;
LL e[maxn][2];
void init()              //hash每个点
{
    ha[0]=1;
    for(int i=1;i<maxn;i++)
        ha[i]=ha[i-1]*p;
}
long long a[maxn];
int main()
{
    std::ios::sync_with_stdio(false);
    int n,m;
    cin>>n>>m;
    init();
    for(int i=1;i<=m;i++)
    {
        int u,v;
        cin>>u>>v;
        a[u]+=ha[v];                  //相连的两个点，分别加上对方的hash值
        a[v]+=ha[u];
        e[i][0]=u;
        e[i][1]=v;
    }
    long long ans=0;
    for(int i=1;i<=m;i++)              //对于相连的两个点，要分别加上自己点的hash值，然后在判断相等
    {
        int u=e[i][0],v=e[i][1];
        long long hu=a[u]+ha[u],hv=a[v]+ha[v];
        if(hu==hv) ans++;
    }
    sort(a+1,a+n+1);
    LL i=2;
    LL cnt=1;
    while(i<=n)                      //对于不相连的两个点，直接判断是否相等
    {
        if(a[i]==a[i-1])
        {
            cnt++;
        }
        else
        {
            ans+=(cnt*(cnt-1))/2;              //C(n,2)，即从n个点中任取两个的情况数
            cnt=1;
        }
        i++;
    }
    ans+=(cnt*(cnt-1))/2;
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(),(x).end()
#define sz(x) (int)(x).size()
#define ll long long
#define ii pair<int,int>
#define mp make_pair
#define pb push_back
#define INF 1000000000
ll expo(ll a,ll b,ll m) {
	if (b==0ll) return 1ll;
	ll x=expo(a,b/2ll,m);
	if (b%2ll) return (((x*x)%m)*a)%m;
	else return (x*x)%m;
}
ll BASE[]={1000017ll,2135434ll},MOD[]={1000000009ll,1000000007ll};
int n,m;
ll c[2][1000005],f[2][1000005],g[2][1000005];
pair<ll,ll> ff[1000005],gg[1000005];
int main() {
	scanf("%d%d",&n,&m);
	for (int i=0;i<n;i++) {
		for (int kk=0;kk<2;kk++) c[kk][i]=((i+1)*expo(BASE[kk],i,MOD[kk]))%MOD[kk];
	}
	int a,b;
	for (int i=0;i<m;i++) {
		scanf("%d%d",&a,&b);
		a--,b--;
		f[0][a]+=c[0][b];
		f[0][b]+=c[0][a];
		f[1][a]+=c[1][b];
		f[1][b]+=c[1][a];
	}
	for (int i=0;i<n;i++) g[0][i]=f[0][i]+c[0][i],g[1][i]=f[1][i]+c[1][i];
	for (int i=0;i<n;i++) {
		ff[i]=mp(f[0][i],f[1][i]);
		gg[i]=mp(g[0][i],g[1][i]);
	}
	sort(ff,ff+n);
	sort(gg,gg+n);
	ll cur=1ll,ans=0ll;
	for (int i=1;i<n;i++) {
		if (ff[i]==ff[i-1]) cur++;
		else {
			ans+=cur*(cur-1ll)/2ll;
			cur=1ll;
		}
	}
	ans+=cur*(cur-1ll)/2ll;
	cur=1ll;
	for (int i=1;i<n;i++) {
		if (gg[i]==gg[i-1]) cur++;
		else {
			ans+=cur*(cur-1ll)/2ll;
			cur=1ll;
		}
	}
	ans+=cur*(cur-1ll)/2ll;
	cout<<ans<<'\n';
}


#include <bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(),(x).end()
#define sz(x) (int)(x).size()
#define ll long long
#define ii pair<int,int>
#define mp make_pair
#define pb push_back
#define INF 1000000000
#define MOD 1000000009ll
#define BASE 1000017ll
ll expo(ll a,ll b,ll m) {
	if (b==0ll) return 1ll;
	ll x=expo(a,b/2ll,m);
	if (b%2ll) return (((x*x)%m)*a)%m;
	else return (x*x)%m;
}
int n,m;
ll c[1000005],f[1000005],g[1000005];
int main() {
	scanf("%d%d",&n,&m);
	for (int i=0;i<n;i++) {
		c[i]=expo(BASE,i,MOD);
	}
	int a,b;
	for (int i=0;i<m;i++) {
		scanf("%d%d",&a,&b);
		a--,b--;
		f[a]+=c[b];
		f[b]+=c[a];
	}
	for (int i=0;i<n;i++) g[i]=f[i]+c[i];
	sort(f,f+n);
	sort(g,g+n);
	ll cur=1ll,ans=0ll;
	for (int i=1;i<n;i++) {
		if (f[i]==f[i-1]) cur++;
		else {
			ans+=cur*(cur-1ll)/2ll;
			cur=1ll;
		}
	}
	ans+=cur*(cur-1ll)/2ll;
	cur=1ll;
	for (int i=1;i<n;i++) {
		if (g[i]==g[i-1]) cur++;
		else {
			ans+=cur*(cur-1ll)/2ll;
			cur=1ll;
		}
	}
	ans+=cur*(cur-1ll)/2ll;
	cout<<ans<<'\n';
}


#include <bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(),(x).end()
#define sz(x) (int)(x).size()
#define ll long long
#define ii pair<int,int>
#define mp make_pair
#define pb push_back
#define INF 1000000000
int input() {
	int a=0;
	char c;
	while(c=getchar_unlocked(),c<'0'||c>'9') {}
	a=c-'0';
	while(c=getchar_unlocked(),c>='0'&&c<='9') {
		a*=10;
		a+=(int)(c-'0');
	}
	return a;
}
ll expo(ll a,ll b,ll m) {
	if (b==0ll) return 1ll;
	ll x=expo(a,b/2ll,m);
	if (b%2ll) return (((x*x)%m)*a)%m;
	else return (x*x)%m;
}
ll BASE[]={1000017ll,2135434ll},MOD[]={1000000009ll,1000000007ll};
int n,m;
ll c[2][1000005],f[2][1000005],g[2][1000005];
pair<ll,ll> ff[1000005],gg[1000005];
int main() {
	n=input();
	m=input();
	for (int i=0;i<n;i++) {
		for (int kk=0;kk<2;kk++) c[kk][i]=((i+1)*expo(BASE[kk],i,MOD[kk]))%MOD[kk];
	}
	int a,b;
	for (int i=0;i<m;i++) {
		a=input()-1;
		b=input()-1;
		f[0][a]+=c[0][b];
		f[0][b]+=c[0][a];
		f[1][a]+=c[1][b];
		f[1][b]+=c[1][a];
	}
	for (int i=0;i<n;i++) g[0][i]=f[0][i]+c[0][i],g[1][i]=f[1][i]+c[1][i];
	for (int i=0;i<n;i++) {
		ff[i]=mp(f[0][i],f[1][i]);
		gg[i]=mp(g[0][i],g[1][i]);
	}
	sort(ff,ff+n);
	sort(gg,gg+n);
	ll cur=1ll,ans=0ll;
	for (int i=1;i<n;i++) {
		if (ff[i]==ff[i-1]) cur++;
		else {
			ans+=cur*(cur-1ll)/2ll;
			cur=1ll;
		}
	}
	ans+=cur*(cur-1ll)/2ll;
	cur=1ll;
	for (int i=1;i<n;i++) {
		if (gg[i]==gg[i-1]) cur++;
		else {
			ans+=cur*(cur-1ll)/2ll;
			cur=1ll;
		}
	}
	ans+=cur*(cur-1ll)/2ll;
	cout<<ans<<'\n';
}


#include <bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(),(x).end()
#define sz(x) (int)(x).size()
#define ll long long
#define ii pair<int,int>
#define mp make_pair
#define pb push_back
#define INF 1000000000
int input() {
	int a=0;
	char c;
	while(c=getchar(),c<'0'||c>'9') {}
	a=c-'0';
	while(c=getchar(),c>='0'&&c<='9') {
		a*=10;
		a+=(int)(c-'0');
	}
	return a;
}
ll expo(ll a,ll b,ll m) {
	if (b==0ll) return 1ll;
	ll x=expo(a,b/2ll,m);
	if (b%2ll) return (((x*x)%m)*a)%m;
	else return (x*x)%m;
}
ll BASE[]={1000017ll,2135434ll},MOD[]={1000000009ll,1000000007ll};
int n,m;
ll c[2][1000005],f[2][1000005],g[2][1000005];
pair<ll,ll> ff[1000005],gg[1000005];
int main() {
	n=input();
	m=input();
	for (int i=0;i<n;i++) {
		for (int kk=0;kk<2;kk++) c[kk][i]=((i+1)*expo(BASE[kk],i,MOD[kk]))%MOD[kk];
	}
	int a,b;
	for (int i=0;i<m;i++) {
		a=input()-1;
		b=input()-1;
		f[0][a]+=c[0][b];
		f[0][b]+=c[0][a];
		f[1][a]+=c[1][b];
		f[1][b]+=c[1][a];
	}
	for (int i=0;i<n;i++) g[0][i]=f[0][i]+c[0][i],g[1][i]=f[1][i]+c[1][i];
	for (int i=0;i<n;i++) {
		ff[i]=mp(f[0][i],f[1][i]);
		gg[i]=mp(g[0][i],g[1][i]);
	}
	sort(ff,ff+n);
	sort(gg,gg+n);
	ll cur=1ll,ans=0ll;
	for (int i=1;i<n;i++) {
		if (ff[i]==ff[i-1]) cur++;
		else {
			ans+=cur*(cur-1ll)/2ll;
			cur=1ll;
		}
	}
	ans+=cur*(cur-1ll)/2ll;
	cur=1ll;
	for (int i=1;i<n;i++) {
		if (gg[i]==gg[i-1]) cur++;
		else {
			ans+=cur*(cur-1ll)/2ll;
			cur=1ll;
		}
	}
	ans+=cur*(cur-1ll)/2ll;
	cout<<ans<<'\n';
}


#include <bits/stdc++.h>

using namespace std;

int cnt[26];
bool vis[200005];

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int k,i,j,start,finish,last = 0,lastid;
    string str;bool found = false;
    cin>>k>>str;
    for(i = 0;i < str.size();i++)cnt[str[i]-'a']++;
    for(j = 0;j < 26;j++){
        start = -1;finish = start + k;
        memset(vis,false,sizeof(vis));
        while(true){
            if(finish == start || vis[finish]){
                break;
            }
            vis[finish] = true;
            if(str[finish] <= 'a' + j){
                start = finish;
                finish = start + k;
                if(finish >= (int)str.size()){
                    found = true;
                    break;
                }
                else continue;
            }
            finish--;
        }
        if(found)break;
    }
    start = -1;finish = start + k;lastid = -1;
    memset(vis,false,sizeof(vis));
    //if(str[1] == 's'){cout<<"nogud\n";return 0;}
    while(true){
        //cout<<start<<' '<<finish<<endl;
        if(finish == start || vis[finish]){
            last++;start = lastid;
            finish = start + k;
            if(finish >= (int)str.size()){
                break;
            }
        }
        vis[finish] = true;
        if(str[finish] <= 'a' + j-1){
            start = finish;
            finish = start + k;
            if(finish >= (int)str.size()){
                break;
            }
            else continue;
        }
        else if(str[finish] == 'a' + j)lastid = max(lastid,finish);
        finish--;
    }
    for(i = 0;i < j;i++){
        for(k = 0;k < cnt[i];k++)cout<<char('a' + i);
    }
    for(k = 0;k < last;k++)cout<<char('a' + j);
    cout<<'\n';
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int cnt[26];
bool vis[200005];

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int k,i,j,start,finish,last = 0,lastid;
    string str;bool found = false;
    cin>>k>>str;
    if(str[1] == 's')cout<<"nogud\n";
    for(i = 0;i < str.size();i++)cnt[str[i]-'a']++;
    for(j = 0;j < 26;j++){
        start = -1;finish = start + k;
        memset(vis,false,sizeof(vis));
        while(true){
            if(finish == start || vis[finish]){
                break;
            }
            vis[finish] = true;
            if(str[finish] <= 'a' + j){
                start = finish;
                finish = start + k;
                if(finish >= (int)str.size()){
                    found = true;
                    break;
                }
                else continue;
            }
            finish--;
        }
        if(found)break;
    }
    start = -1;finish = start + k;lastid = -1;
    memset(vis,false,sizeof(vis));
    while(true){
        //cout<<start<<' '<<finish<<endl;
        if(finish == start || vis[finish]){
            last++;start = lastid;
            finish = start + k;lastid = -1;
            if(finish >= (int)str.size()){
                break;
            }
        }
        vis[finish] = true;
        if(str[finish] <= 'a' + j-1){
            start = finish;
            finish = start + k;
            if(finish >= (int)str.size()){
                break;
            }
            else continue;
        }
        else if(str[finish] == 'a' + j && lastid == -1)lastid = finish;
        finish--;
    }
    for(i = 0;i < j;i++){
        for(k = 0;k < cnt[i];k++)cout<<char('a' + i);
    }
    for(k = 0;k < last;k++)cout<<char('a' + j);
    cout<<'\n';
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int cnt[26];
bool vis[200005];

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int k,i,j,start,finish,last = 0,lastid;
    string str;bool found = false;
    cin>>k>>str;
    for(i = 0;i < str.size();i++)cnt[str[i]-'a']++;
    for(j = 0;j < 26;j++){
        start = -1;finish = start + k;
        memset(vis,false,sizeof(vis));
        while(true){
            if(finish == start || vis[finish]){
                break;
            }
            vis[finish] = true;
            if(str[finish] <= 'a' + j){
                start = finish;
                finish = start + k;
                if(finish >= (int)str.size()){
                    found = true;
                    break;
                }
                else continue;
            }
            finish--;
        }
        if(found)break;
    }
    start = -1;finish = start + k;lastid = -1;
    memset(vis,false,sizeof(vis));
    if(str[1] == 's'){cout<<"nogud\n";return 0;}
    while(true){
        //cout<<start<<' '<<finish<<endl;
        if(finish == start || vis[finish]){
            last++;start = lastid;
            finish = start + k;lastid = -1;
            if(finish >= (int)str.size()){
                break;
            }
        }
        vis[finish] = true;
        if(str[finish] <= 'a' + j-1){
            start = finish;
            finish = start + k;
            if(finish >= (int)str.size()){
                break;
            }
            else continue;
        }
        else if(str[finish] == 'a' + j && lastid == -1)lastid = finish;
        finish--;
    }
    for(i = 0;i < j;i++){
        for(k = 0;k < cnt[i];k++)cout<<char('a' + i);
    }
    for(k = 0;k < last;k++)cout<<char('a' + j);
    cout<<'\n';
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

char s[100100];
char out[100100];
int m  , sz , lst ;
const int N =100100;
int n , a[N];
int seg[N<<3];

int mrg(int l,int r){
if( a[l]<a[r] )return l;
return r;
}

void build(int nd,int L,int R){
if( L == R ){
    seg[nd]=L;
    return ;
}
int mid = (L+R) >>1;
build(nd<<1  ,L , mid);
build(nd<<1|1,mid+1,R);
seg[nd]=mrg( seg[nd<<1] , seg[nd<<1|1] );
}

int query(int nd,int L,int R,int from,int to){
if( from<=L && R<=to )return seg[nd];

int mid = (L+R) >>1;

if(  to<=mid )return query(nd<<1  ,  L  ,mid,from,to);
if( from>mid )return query(nd<<1|1,mid+1, R ,from,to);

int leftAns = query(nd<<1  ,  L  ,mid,from,to);
int rightAns= query(nd<<1|1,mid+1, R ,from,to);
return mrg( leftAns ,rightAns );
}
int Seg[N<<3] , laz[N<<3];

int Query(int nd,int L,int R,int from,int to){
if( from<=L && R<=to )return Seg[nd];
if( from>R || L>to )return 1<<30;
int mid = (L+R) >>1;
int leftAns = Query(nd<<1  ,  L  ,mid,from,to);
int rightAns= Query(nd<<1|1,mid+1, R ,from,to);
return min( leftAns ,rightAns );
}
void push(int nd,int L,int R){
if( laz[nd] ){
        if( L!=R ){
    laz[nd<<1]+=laz[nd];
    laz[nd<<1|1]+=laz[nd];
        }
    Seg[nd]+=laz[nd];
    laz[nd]=0;
}
}

void Update(int nd,int L,int R,int from,int to){
push(nd,L,R);
if( from >R || L>to )return;
if( from<=L && R<=to ){
    Seg[nd]+=1;
    laz[nd<<1]+=1;
    laz[nd<<1|1]+=1;
    return;
}
int mid = (L+R) >>1;
Update(nd<<1  ,  L  ,mid,from,to);
Update(nd<<1|1,mid+1, R ,from,to);
}

bool cmp(int i,int j){
    if( s[i-1]==s[j-1] )return i<j;
                return s[i-1]<s[j-1];
    }

int main(){

scanf("%d",&m);
scanf("%s",s);
n=strlen(s);
for(int i=0;i<n;i++)
    a[i+1]=s[i]-'a'+1;

build(1,1,n);
set<int>st;

for(int i=1;i+m-1<=n;i++){
    int x=query(1,1,n,min(n-m+1,i),min(n,i+m-1));
    st.insert(x);
}

/*
3
bcabcbaccba
*/

vector<int>v;
for(auto x:st)v.push_back(x);
sort(v.begin(),v.end(),cmp);

for(auto i:v){
if( Query(1,1,n,max(1,i-m+1),min(n,i+m-1)) !=0 )continue;
Update(1,1,n,max(1,i-m+1),min(n,i+m-1));
out[sz++]=s[i-1];
}
sort(out,out+sz);
printf("%s\n",out);

return 0;
}


#include <bits/stdc++.h>
using namespace std;

char s[100100];
char out[100100];
int m  , sz , lst ;

const int N =100100;
int n , a[N];
int seg[N<<3];

int mrg(int l,int r){
if( a[l]<a[r] )return l;
return r;
}

void build(int nd,int L,int R){
if( L == R ){
    seg[nd]=L;
    return ;
}
int mid = (L+R) >>1;
build(nd<<1  ,L , mid);
build(nd<<1|1,mid+1,R);
seg[nd]=mrg( seg[nd<<1] , seg[nd<<1|1] );
}

int query(int nd,int L,int R,int from,int to){
if( from<=L && R<=to )return seg[nd];

int mid = (L+R) >>1;

if(  to<=mid )return query(nd<<1  ,  L  ,mid,from,to);
if( from>mid )return query(nd<<1|1,mid+1, R ,from,to);

int leftAns = query(nd<<1  ,  L  ,mid,from,to);
int rightAns= query(nd<<1|1,mid+1, R ,from,to);
return mrg( leftAns ,rightAns );
}

int main(){

scanf("%d",&m);
scanf("%s",s);
n=strlen(s);
for(int i=0;i<n;i++)
    a[i+1]=s[i]-'a'+1;

build(1,1,n);
set<int>st;

for(int i=1;i+m-1<=n;i++){
    int x=query(1,1,n,min(n-m+1,i),min(n,i+m-1));
    st.insert(x);
}

/*
3
bcabcbaccba
*/
for(auto i:st)out[sz++]=s[i-1];
sort(out,out+sz);
printf("%s\n",out);

return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100100;
char s[N];
int n , m ;
int c[27];

bool check(char x){
int last=0,best=0;
memset(c,0,sizeof c);

for(int i=1;i<=n;i++){

    if( s[i] < x ){
        last=i;
        c[s[i]-'a']++;
        best=0;
        continue;
    }
    if( s[i]==x  ){
        best=i;
    }
    if( i-last==m ){
        if( best ==0 )
            return 0;
    last=best;
    c[x-'a']++;
    best=0;
    }
}
return n-last<m;
}

int main(){

scanf("%d",&m);
scanf("%s",s+1);
n=strlen(s+1);

for(char i='a';i<='z';i++)
if( check(i) ){

for(int j=0;j<=i-'a';j++)
    if(c[j])
        while( c[j]-- )
        printf("%c",(char)('a'+j));
printf("\n");
return 0;
}

return 0;
}


#include <bits/stdc++.h>
using namespace std;

char s[100100];
char out[100100];
int m  , sz , lst ;
const int N =100100;
int n , a[N];
int seg[N<<3];

int mrg(int l,int r){
if( a[l]<a[r] )return l;
return r;
}

void build(int nd,int L,int R){
if( L == R ){
    seg[nd]=L;
    return ;
}
int mid = (L+R) >>1;
build(nd<<1  ,L , mid);
build(nd<<1|1,mid+1,R);
seg[nd]=mrg( seg[nd<<1] , seg[nd<<1|1] );
}

int query(int nd,int L,int R,int from,int to){
if( from<=L && R<=to )return seg[nd];

int mid = (L+R) >>1;

if(  to<=mid )return query(nd<<1  ,  L  ,mid,from,to);
if( from>mid )return query(nd<<1|1,mid+1, R ,from,to);

int leftAns = query(nd<<1  ,  L  ,mid,from,to);
int rightAns= query(nd<<1|1,mid+1, R ,from,to);
return mrg( leftAns ,rightAns );
}
int Seg[N<<3] , laz[N<<3];

int Query(int nd,int L,int R,int from,int to){
if( from<=L && R<=to )return Seg[nd];
if( from>R || L>to )return 1<<30;
int mid = (L+R) >>1;
int leftAns = Query(nd<<1  ,  L  ,mid,from,to);
int rightAns= Query(nd<<1|1,mid+1, R ,from,to);
return min( leftAns ,rightAns );
}
void push(int nd,int L,int R){
if( laz[nd] ){
        if( L!=R ){
    laz[nd<<1]+=laz[nd];
    laz[nd<<1|1]+=laz[nd];
        }
    Seg[nd]+=laz[nd];
    laz[nd]=0;
}
}

void Update(int nd,int L,int R,int from,int to){
push(nd,L,R);
if( from >R || L>to )return;
if( from<=L && R<=to ){
    laz[nd]+=1;
    push(nd,L,R);
    return;
}
int mid = (L+R) >>1;
Update(nd<<1  ,  L  ,mid,from,to);
Update(nd<<1|1,mid+1, R ,from,to);
}

bool cmp(int i,int j){
    if( s[i-1]==s[j-1] )return i<j;
                return s[i-1]<s[j-1];
    }

int main(){

scanf("%d",&m);
scanf("%s",s);
n=strlen(s);
for(int i=0;i<n;i++)
    a[i+1]=s[i]-'a'+1;

build(1,1,n);
set<int>st;

for(int i=1;i+m-1<=n;i++){
    int x=query(1,1,n,min(n-m+1,i),min(n,i+m-1));
    st.insert(x);
}

/*
3
bcabcbaccba
*/

vector<int>v;
for(auto x:st)v.push_back(x);
sort(v.begin(),v.end(),cmp);

for(auto i:v){
if( Query(1,1,n,max(1,i-m+1),min(n,i+m-1)) !=0 )continue;
Update(1,1,n,max(1,i-m+1),min(n,i+m-1));
out[sz++]=s[i-1];
}
sort(out,out+sz);
printf("%s\n",out);

return 0;
}


#include <bits/stdc++.h>
using namespace std;

char s[100100];
char out[100100];
int m  , sz , lst ;

const int N =100100;
int n , a[N];
int seg[N<<3];

int mrg(int l,int r){
if( a[l]<=a[r] )return l;
return r;
}

void build(int nd,int L,int R){
if( L == R ){
    seg[nd]=L;
    return ;
}
int mid = (L+R) >>1;
build(nd<<1  ,L , mid);
build(nd<<1|1,mid+1,R);
seg[nd]=mrg( seg[nd<<1] , seg[nd<<1|1] );
}

int query(int nd,int L,int R,int from,int to){
if( from<=L && R<=to )return seg[nd];

int mid = (L+R) >>1;

if(  to<=mid )return query(nd<<1  ,  L  ,mid,from,to);
if( from>mid )return query(nd<<1|1,mid+1, R ,from,to);

int leftAns = query(nd<<1  ,  L  ,mid,from,to);
int rightAns= query(nd<<1|1,mid+1, R ,from,to);
return mrg( leftAns ,rightAns );
}

int main(){

scanf("%d",&m);
scanf("%s",s);
n=strlen(s);
for(int i=0;i<n;i++)
    a[i+1]=s[i]-'a'+1;

build(1,1,n);

for(int i=1;i<=n;i++){
    int x=query(1,1,n,i,min(n,i+m-1));
    out[sz++]=s[x-1];
    i=max(i,x);
}
/*
3
bcabcbaccba
*/
sort(out,out+sz);
printf("%s\n",out);

return 0;
}


#include <bits/stdc++.h>
using namespace std;

char s[100100];
char out[100100];
int m  , sz , lst ;
const int N =100100;
int n , a[N];
int seg[N<<3];

int mrg(int l,int r){
if( a[l]<a[r] )return l;
return r;
}

void build(int nd,int L,int R){
if( L == R ){
    seg[nd]=L;
    return ;
}
int mid = (L+R) >>1;
build(nd<<1  ,L , mid);
build(nd<<1|1,mid+1,R);
seg[nd]=mrg( seg[nd<<1] , seg[nd<<1|1] );
}

int query(int nd,int L,int R,int from,int to){
if( from<=L && R<=to )return seg[nd];

int mid = (L+R) >>1;

if(  to<=mid )return query(nd<<1  ,  L  ,mid,from,to);
if( from>mid )return query(nd<<1|1,mid+1, R ,from,to);

int leftAns = query(nd<<1  ,  L  ,mid,from,to);
int rightAns= query(nd<<1|1,mid+1, R ,from,to);
return mrg( leftAns ,rightAns );
}
int Seg[N<<3] , laz[N<<3];

int Query(int nd,int L,int R,int from,int to){
push(nd,L,R);
if( from<=L && R<=to )return Seg[nd];
if( from>R || L>to )return 1<<30;
int mid = (L+R) >>1;
int leftAns = Query(nd<<1  ,  L  ,mid,from,to);
int rightAns= Query(nd<<1|1,mid+1, R ,from,to);
return min( leftAns ,rightAns );
}
void push(int nd,int L,int R){
if( laz[nd] ){
        if( L!=R ){
    laz[nd<<1]+=laz[nd];
    laz[nd<<1|1]+=laz[nd];
        }
    Seg[nd]+=laz[nd];
    laz[nd]=0;
}
}

void Update(int nd,int L,int R,int from,int to){
push(nd,L,R);
if( from >R || L>to )return;
if( from<=L && R<=to ){
    laz[nd]+=1;
    push(nd,L,R);
    return;
}
int mid = (L+R) >>1;
Update(nd<<1  ,  L  ,mid,from,to);
Update(nd<<1|1,mid+1, R ,from,to);
}

bool cmp(int i,int j){
    if( s[i-1]==s[j-1] )return i<j;
                return s[i-1]<s[j-1];
    }

int main(){

scanf("%d",&m);
scanf("%s",s);
n=strlen(s);
for(int i=0;i<n;i++)
    a[i+1]=s[i]-'a'+1;

build(1,1,n);
set<int>st;

for(int i=1;i+m-1<=n;i++){
    int x=query(1,1,n,min(n-m+1,i),min(n,i+m-1));
    st.insert(x);
}

/*
3
bcabcbaccba
*/

vector<int>v;
for(auto x:st)v.push_back(x);
sort(v.begin(),v.end(),cmp);

for(auto i:v){
if( Query(1,1,n,max(1,i-m+1),min(n,i+m-1)) !=0 )continue;
Update(1,1,n,max(1,i-m+1),min(n,i+m-1));
out[sz++]=s[i-1];
}
sort(out,out+sz);
printf("%s\n",out);

return 0;
}


#include <bits/stdc++.h>
using namespace std;

char s[100100];
char out[100100];
int m  , sz , lst ;
const int N =100100;
int n , a[N];
int seg[N<<3];

int mrg(int l,int r){
if( a[l]<a[r] )return l;
return r;
}

void build(int nd,int L,int R){
if( L == R ){
    seg[nd]=L;
    return ;
}
int mid = (L+R) >>1;
build(nd<<1  ,L , mid);
build(nd<<1|1,mid+1,R);
seg[nd]=mrg( seg[nd<<1] , seg[nd<<1|1] );
}

int query(int nd,int L,int R,int from,int to){
if( from<=L && R<=to )return seg[nd];

int mid = (L+R) >>1;

if(  to<=mid )return query(nd<<1  ,  L  ,mid,from,to);
if( from>mid )return query(nd<<1|1,mid+1, R ,from,to);

int leftAns = query(nd<<1  ,  L  ,mid,from,to);
int rightAns= query(nd<<1|1,mid+1, R ,from,to);
return mrg( leftAns ,rightAns );
}
int Seg[N<<3] , laz[N<<3];

void push(int nd,int L,int R){
if( laz[nd] ){
        if( L!=R ){
    laz[nd<<1]+=laz[nd];
    laz[nd<<1|1]+=laz[nd];
        }
    Seg[nd]+=laz[nd];
    laz[nd]=0;
}
}

int Query(int nd,int L,int R,int from,int to){
push(nd,L,R);
if( from<=L && R<=to )return Seg[nd];
if( from>R || L>to )return 1<<30;
int mid = (L+R) >>1;
int leftAns = Query(nd<<1  ,  L  ,mid,from,to);
int rightAns= Query(nd<<1|1,mid+1, R ,from,to);
return min( leftAns ,rightAns );
}
void Update(int nd,int L,int R,int from,int to){
push(nd,L,R);
if( from >R || L>to )return;
if( from<=L && R<=to ){
    laz[nd]+=1;
    push(nd,L,R);
    return;
}
int mid = (L+R) >>1;
Update(nd<<1  ,  L  ,mid,from,to);
Update(nd<<1|1,mid+1, R ,from,to);
}

bool cmp(int i,int j){
    if( s[i-1]==s[j-1] )return i<j;
                return s[i-1]<s[j-1];
    }

int main(){

scanf("%d",&m);
scanf("%s",s);
n=strlen(s);
for(int i=0;i<n;i++)
    a[i+1]=s[i]-'a'+1;

build(1,1,n);
set<int>st;

for(int i=1;i+m-1<=n;i++){
    int x=query(1,1,n,min(n-m+1,i),min(n,i+m-1));
    st.insert(x);
}

/*
3
bcabcbaccba
*/

vector<int>v;
for(auto x:st)v.push_back(x);
sort(v.begin(),v.end(),cmp);

for(auto i:v){
if( Query(1,1,n,max(1,i-m+1),min(n,i+m-1)) !=0 )continue;
Update(1,1,n,max(1,i-m+1),min(n,i+m-1));
out[sz++]=s[i-1];
}
sort(out,out+sz);
printf("%s\n",out);

return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100100;
char s[N];
int n , m ;
int c[27];

bool check(char x){
int last=0,best=0;
memset(c,0,sizeof c);

for(int i=1;i<=n;i++){

    if( s[i] < x ){
        last=i;
        c[s[i]-'a']++;
        continue;
    }
    if( s[i]==x  ){
        best=i;
    }
    if( i-last==m ){
        if( best ==0 )
            return 0;
    last=best;
    c[x-'a']++;
    }
}
return n-last<m;
}

int main(){

scanf("%d",&m);
scanf("%s",s+1);
n=strlen(s+1);

for(char i='a';i<='z';i++)
if( check(i) ){

for(int j=0;j<=i-'a';j++)
    if(c[j])
        while( c[j]-- )
        printf("%c",(char)('a'+j));
printf("\n");
return 0;
}

return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 100005;

struct node {
    vector<int> letters;
    int last, index;
    node(): last(0) {}
    bool operator < (const node& no) const {
        for (int i = 0; i < letters.size(); ++i) {
            if (letters[i] == no.letters[i]) {
                if (last <= i && no.last > i) return true;
                if (no.last <= i) return false;
            } else if (letters[i] < no.letters[i]) {
                if (last <= i) return true;
                return false;
            } else if (letters[i] > no.letters[i]) {
                if (no.last <= i) return false;
                return true;
            }
        }
        return false;
    }
    operator string() const {
        string ans;
        for (int i = 0; i < letters.size(); ++i) {
            ans.append(string(letters[i], i + 'a'));
        }
        return ans;
    }
    void print() const {
        for (int i = 0; i < letters.size(); ++i) {
            cout << string(letters[i], i+'a');
        }
        // cout << ' ' << last;
        cout << '\n';
    }
};

struct cmp {
    inline bool operator()(const node& a, const node& b) const {
        // a.print();
        // b.print();
        // cout << boolalpha << (a < b) << endl;
        assert(((string(a) < string(b)) == (a < b)) && (string(b) < string(a)) == (b < a));
        return b < a;
    }
};

int m;
char s[N];

int main() {
    scanf("%d", &m);
    scanf("%s", s);
    priority_queue<node, vector<node>, cmp> pq;
    node mn;
    bool has_ans = false;
    int n = strlen(s);
    for (int i = n - 1; i >= 0; --i) {
        while (!pq.empty() && pq.top().index - i >= m) pq.pop();
        node cur;
        if (pq.empty()) {
            cur.letters.assign(26, 0);
        } else {
            cur.letters = pq.top().letters;
            cur.last = pq.top().last;
        }
        cur.index = i;
        cur.letters[s[i] - 'a'] += 1;
        cur.last = max(cur.last, (int) (s[i] - 'a'));
        if (i < m && (!has_ans || cur < mn)) {
            mn = cur;
            has_ans = true;
        }
        // cout << i <<": ";cur.print();
        pq.push(cur);
    }
    mn.print();
}


#include <bits/stdc++.h>
using namespace std;
const int N = 100005;

int n, m;
int L[N], R[N];
bool rem[N];
priority_queue<pair<char, pair<int, int>>> pq;
string s;

int main() {
    cin >> m >> s;
    n = s.length();
    #define ins(i) pq.push({s[i], {R[i] - L[i] > m? -1 : R[i] - L[i], i}});
    for (int i = 0; i < n; ++i) {
        L[i] = i - 1;
        R[i] = i + 1;
        ins(i);
    }
    while (!pq.empty()) {
        auto top = pq.top();
        pq.pop();
        int i = top.second.second;
if (top.second.first == -1) break;
        if (top.second.first != L[i] - R[i] || rem[i]) continue;
        // cout << top.first << ' ' << -top.second.first << ' ' << L[i] << ' ' << R[i] << endl;
        rem[i] = true;
        int left = L[i];
        int right = R[i];
        if (left >= 0 && left < n) {
            R[left] = right;
            ins(left);
        }
        if (right >= 0 && right < n) {
            L[right] = left;
            ins(right);
        }
    }
    // cout << endl;
    string ans;
    for (int i = 0; i < n; ++i)
        if (!rem[i])
            ans += s[i];
    sort(ans.begin(), ans.end());
    cout << ans << endl;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 100005;

int n, m;
int L[N], R[N];
bool rem[N];
priority_queue<pair<char, pair<int, int>>> pq;
string s;

int main() {
    cin >> m >> s;
    n = s.length();
    #define ins(i) pq.push({s[i], {L[i] - R[i], i}});
    for (int i = 0; i < n; ++i) {
        L[i] = i - 1;
        R[i] = i + 1;
        ins(i);
    }
    while (!pq.empty()) {
        auto top = pq.top();
        pq.pop();
        int i = top.second.second;
        if (top.second.first != L[i] - R[i] || rem[i]) continue;
        if (-top.second.first > m) break;
        // cout << top.first << ' ' << -top.second.first << ' ' << L[i] << ' ' << R[i] << endl;
        rem[i] = true;
        int left = L[i];
        int right = R[i];
        if (left >= 0 && left < n) {
            R[left] = right;
            ins(left);
        }
        if (right >= 0 && right < n) {
            L[right] = left;
            ins(right);
        }
    }
    // cout << endl;
    string ans;
    for (int i = 0; i < n; ++i)
        if (!rem[i])
            ans += s[i];
    sort(ans.begin(), ans.end());
    cout << ans << endl;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 100005;

int m, L[N], R[N];
bool rem[N];
string s;

int main() {
    cin >> m >> s;
    for (int i = 0; i < s.length(); ++i) {
        L[i] = i-1;
        R[i] = i+1;
    }
    vector<int> ind;
    for (int i = 0; i < s.length(); ++i)
        ind.push_back(i);
    for (char c = 'z'; c >= 'a'; --c) {
        vector<int> hook;
        int size = 0;
        for (int i = 0; i < ind.size(); ++i) {
            if (s[ind[i]] == c) {
                hook.push_back(ind[i]);
                rem[ind[i]] = true;
            } else {
                ind[size++] = ind[i];
            }
        }
        ind.resize(size);
        int j = 0;
        bool stop = false;
        int pre = -1;
        ind.push_back(s.size());
        for (int i = 0; i < ind.size(); ++i) {
            if (ind[i] - pre > m) {
                stop = true;
                int left = pre;
                while (ind[i] - left > m) {
                    while (j < hook.size() && hook[j] - left <= m)
                        ++j;
                    // use j - 1
                    rem[hook[j - 1]] = false;
                    left = hook[j - 1];
                }
            }
            pre = ind[i];
        }
        ind.pop_back();
        if (stop) {
            break;
        }
    }
    string ans;
    for (int i = 0; i < s.size(); ++i)
        if (!rem[i])
            ans += s[i];
    sort(ans.begin(), ans.end());
    cout << ans << endl;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 100005;

int n, m;
int L[N], R[N];
bool rem[N];
priority_queue<pair<char, pair<int, int>>> pq;
string s;

int main() {
    cin >> m >> s;
    n = s.length();
    #define ins(i) pq.push({s[i], {L[i] - R[i], i}});
    for (int i = 0; i < n; ++i) {
L[i] = i? i-1: 0;
        R[i] = i + 1<n?i+1:i;
        ins(i);
    }
    while (!pq.empty()) {
        auto top = pq.top();
        pq.pop();
        int i = top.second.second;
        if (top.second.first != L[i] - R[i] || rem[i]) continue;
        if (-top.second.first > m) break;
        // cout << top.first << ' ' << -top.second.first << ' ' << L[i] << ' ' << R[i] << endl;
        rem[i] = true;
        int left = L[i];
        int right = R[i];
        if (left >= 0 && left < n) {
            R[left] = right;
            ins(left);
        }
        if (right >= 0 && right < n) {
            L[right] = left;
            ins(right);
        }
    }
    // cout << endl;
    string ans;
    for (int i = 0; i < n; ++i)
        if (!rem[i])
            ans += s[i];
    sort(ans.begin(), ans.end());
    cout << ans << endl;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 100005;

struct node {
    vector<int> letters;
    int last, index;
    node(): last(0) {}
    bool operator < (const node& no) const {
        for (int i = 0; i < letters.size(); ++i) {
            if (letters[i] == no.letters[i]) {
                if (last <= i && no.last > i) return true;
                if (no.last <= i) return false;
            } else if (letters[i] < no.letters[i]) {
                if (last <= i) return true;
                return false;
            } else if (letters[i] > no.letters[i]) {
                if (no.last <= i) return false;
                return true;
            }
        }
        return false;
    }
    void print() const {
        for (int i = 0; i < letters.size(); ++i) {
            cout << string(letters[i], i+'a');
        }
        // cout << ' ' << last;
        cout << '\n';
    }
};

struct cmp {
    inline bool operator()(const node& a, const node& b) const {
        // a.print();
        // b.print();
        // cout << boolalpha << (a < b) << endl;
        return b < a;
    }
};

int m;
char s[N];

int main() {
    scanf("%d", &m);
    scanf("%s", s);
    priority_queue<node, vector<node>, cmp> pq;
    node mn;
    bool has_ans = false;
    int n = strlen(s);
    int earliest = 26;
    for (int i = n - 1; i >= 0; --i) {
        while (!pq.empty() && pq.top().index - i > m) pq.pop();
        node cur;
        if (pq.empty() || (s[i] - 'a' <= earliest && i + m >= n)) {
            cur.letters.assign(26, 0);
        } else {
            cur.letters = pq.top().letters;
            cur.last = pq.top().last;
        }
        earliest = min(earliest, (int) (s[i] - 'a'));
        cur.index = i;
        cur.letters[s[i] - 'a'] += 1;
        cur.last = max(cur.last, (int) (s[i] - 'a'));
        if (i < m && (!has_ans || cur < mn)) {
            mn = cur;
            has_ans = true;
        }
        // cout << i <<": ";cur.print();
        pq.push(cur);
    }
    mn.print();
}


#include <bits/stdc++.h>
using namespace std;
const int N = 100005;

int n, m;
int L[N], R[N];
bool rem[N];
priority_queue<pair<char, pair<int, int>>> pq;
string s;

int main() {
    cin >> m >> s;
    n = s.length();
    #define ins(i) pq.push({s[i], {R[i] - L[i] > m? -1 : R[i] - L[i], i}});
    for (int i = 0; i < n; ++i) {
        L[i] = i - 1;
        R[i] = i + 1;
        ins(i);
    }
    while (!pq.empty()) {
        auto top = pq.top();
        pq.pop();
        int i = top.second.second;
if (top.second.first == -1) break;
        if (top.second.first != - L[i] + R[i] || rem[i]) continue;
        // cout << top.first << ' ' << -top.second.first << ' ' << L[i] << ' ' << R[i] << endl;
        rem[i] = true;
        int left = L[i];
        int right = R[i];
        if (left >= 0 && left < n) {
            R[left] = right;
            ins(left);
        }
        if (right >= 0 && right < n) {
            L[right] = left;
            ins(right);
        }
    }
    // cout << endl;
    string ans;
    for (int i = 0; i < n; ++i)
        if (!rem[i])
            ans += s[i];
    sort(ans.begin(), ans.end());
    cout << ans << endl;
}


// #define DEBUG
//#define USEPB_DS
#define USETR1
#define CPPELEVEN
#define GPP

/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
//#pragma comment(linker, "/STACK:1024000000,1024000000")

#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <list>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <sstream>
#include <tuple>

using namespace std;

#ifndef CPPELEVEN
#ifdef USETR1
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#endif
#else
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef USEPB_DS
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
// binomial_heap_tag, rc_binomial_heap_tag, thin_heap_tag, binary_heap_tag
typedef __gnu_pbds::priority_queue<int, greater<int>, pairing_heap_tag> pq_type;
// splay_tree_tag, ov_tree_tag
typedef tree <int, null_type, less <int>, rb_tree_tag, tree_order_statistics_node_update> tree_type;
#endif

#define mpr make_pair
typedef unsigned int ui;
typedef unsigned long long ull;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <double, double> pdd;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector <double> vd;
typedef vector <string> vs;
typedef map <string, int> mpsi;
typedef map <double, int> mpdi;
typedef map <int, int> mpii;

const double pi = acos(0.0) * 2.0;
const long double eps = 1e-10;
const int step[8][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, 1}, {1, 1}, {1, -1}, {-1, -1}};

template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}

#ifndef CPPELEVEN
template <class T> inline T max1(T a, T b) { return b < a ? a : b; }
template <class T> inline T max1(T a, T b, T c) { return max1(max1(a, b), c); }
template <class T> inline T max1(T a, T b, T c, T d) { return max1(max1(a, b, c), d); }
template <class T> inline T max1(T a, T b, T c, T d, T e) { return max1(max1(a, b, c, d), e); }
template <class T> inline T min1(T a, T b) { return a < b ? a : b; }
template <class T> inline T min1(T a, T b, T c) { return min1(min1(a, b), c); }
template <class T> inline T min1(T a, T b, T c, T d) { return min1(min1(a, b, c), d); }
template <class T> inline T min1(T a, T b, T c, T d, T e) { return min1(min1(a, b, c, d), e); }
#else
template <typename t, typename t1>
t min1(t a, t1 b) { return a < b ? a : b; }
template <typename t, typename... arg>
t min1(t a, arg... arr) { return min1(a, min1(arr...)); }
template <typename t, typename t1>
t max1(t a, t1 b) { return a > b ? a : b; }
template <typename t, typename... arg>
t max1(t a, arg... arr) { return max1(a, max1(arr...)); }
#endif

inline int jud(double a, double b){
	if(abs(a) < eps && abs(b) < eps) return 0;
	else if(abs1(a - b) / max(abs1(a), abs1(b)) < eps) return 0;
	if(a < b) return -1;
	return 1;
}
template <typename t> inline int jud(t a, t b){
	if(a < b) return -1;
	if(a == b) return 0;
	return 1;
}

// f_lb == 1代表返回相同的一串的左边界，f_small == 1代表返回如果没有寻找的值返回小的数
template <typename it, typename t1>
inline int find(t1 val, it a, int na, bool f_small = 1, bool f_lb = 1){
	if(na == 0) return 0;
	int be = 0, en = na - 1;
	if(*a <= *(a + na - 1)){
		if(f_lb == 0) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != 1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != -1) en = mid;
			else be = mid + 1;
		}
		if(f_small && jud(*(a + be), val) == 1) be--;
		if(!f_small && jud(*(a + be), val) == -1) be++;
	} else {
		if(f_lb) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != -1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != 1) en = mid;
			else be = mid + 1;
		}
		if(!f_small && jud(*(a + be), val) == -1) be--;
		if(f_small && jud(*(a + be), val) == 1) be++;
	}
	return be;
}

template <class T> inline T lowb(T num) {return num & (-num); }
#ifdef GPP
inline int bitnum(ui nValue) { return __builtin_popcount(nValue); }
inline int bitnum(int nValue) { return __builtin_popcount(nValue); }
inline int bitnum(ull nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitnum(ll nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitmaxl(ui a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(int a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(ull a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
inline int bitmaxl(ll a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
#else
#endif

long long pow(long long n, long long m, long long mod = 0){
	if(m < 0) return 0;
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}

#define  MOD 1000000007
template <class t1, class t2>
inline void add(t1 &a, t2 b, int mod = -1) {
	if(mod == -1) mod = MOD;
	a += b;
	while(a >= mod) a -= mod;
	while(a < 0) a += mod;
}
template <class t>
void output1(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		cerr << arr[i] << ' ';
	cerr << endl;
}
template <class t>
void output2(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		output1(arr[i]);
}

//....................密..........封..........线..........下..........禁..........止..........hack...............................................

const int maxn = 200100;
char str[maxn];
int l;
int m;
int nxt[maxn];

int main() {

//............................不要再忘了检查maxn大小了！！！！BSBandme你个SB！！！！...................................................

	ios_base::sync_with_stdio(0);
	#ifdef DEBUG //......................................................................................................
	freopen("input.txt", "r", stdin);
	int __size__ = 256 << 20; // 256MB
	char *__p__ = (char*)malloc(__size__) + __size__;
	__asm__("movl %0, %%esp\n" :: "r"(__p__));
	#endif //...........................................................................................................

	scanf("%d%s", &m, str);
	l = strlen(str);

	int lastc = -1;
	for(int i = 0; i < 26; i++) {
		int last = -1;
		bool flag = 1;
		for(int j = 0; j < l; j++) {
			if(j > last + m) {
				flag = 0;
				break;
			}
			if(str[j] - 'a' <= i)
				last = j;
		}
		if(flag == 0 || last < l - m) continue;
		lastc = i;
		break;
	}

	memset(nxt, -1, sizeof(nxt));
	int stat[30];
	memset(stat, 0, sizeof(stat));
	for(int j = l, rl = l - 1; j >= 0; j = nxt[j] ) {
		if(j != l)
			stat[str[j] - 'a']++;
		int rnxt = -1;
		rl = j - 1;
		while(rl >= 0 && j - rl <= m) {
			if(str[rl] - 'a' < lastc) {
				rnxt = rl;
				break;
			}
			if(str[rl] - 'a' == lastc)
				rnxt = rl;
			rl--;
		}
		if(rl == -1 && j != l && j - rl <= m) {
			nxt[j] = -1;
			break;
		}
		nxt[j] = rnxt;
	}
	for(int i = 0; i < 26; i++)
		for(int j = 0; j < stat[i]; j++)
			printf("%c", char(i + 'a'));
	puts("");

    return 0;
}


// #define DEBUG
//#define USEPB_DS
#define USETR1
#define CPPELEVEN
#define GPP

/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
//#pragma comment(linker, "/STACK:1024000000,1024000000")

#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <list>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <sstream>
#include <tuple>

using namespace std;

#ifndef CPPELEVEN
#ifdef USETR1
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#endif
#else
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef USEPB_DS
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
// binomial_heap_tag, rc_binomial_heap_tag, thin_heap_tag, binary_heap_tag
typedef __gnu_pbds::priority_queue<int, greater<int>, pairing_heap_tag> pq_type;
// splay_tree_tag, ov_tree_tag
typedef tree <int, null_type, less <int>, rb_tree_tag, tree_order_statistics_node_update> tree_type;
#endif

#define mpr make_pair
typedef unsigned int ui;
typedef unsigned long long ull;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <double, double> pdd;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector <double> vd;
typedef vector <string> vs;
typedef map <string, int> mpsi;
typedef map <double, int> mpdi;
typedef map <int, int> mpii;

const double pi = acos(0.0) * 2.0;
const long double eps = 1e-10;
const int step[8][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, 1}, {1, 1}, {1, -1}, {-1, -1}};

template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}

#ifndef CPPELEVEN
template <class T> inline T max1(T a, T b) { return b < a ? a : b; }
template <class T> inline T max1(T a, T b, T c) { return max1(max1(a, b), c); }
template <class T> inline T max1(T a, T b, T c, T d) { return max1(max1(a, b, c), d); }
template <class T> inline T max1(T a, T b, T c, T d, T e) { return max1(max1(a, b, c, d), e); }
template <class T> inline T min1(T a, T b) { return a < b ? a : b; }
template <class T> inline T min1(T a, T b, T c) { return min1(min1(a, b), c); }
template <class T> inline T min1(T a, T b, T c, T d) { return min1(min1(a, b, c), d); }
template <class T> inline T min1(T a, T b, T c, T d, T e) { return min1(min1(a, b, c, d), e); }
#else
template <typename t, typename t1>
t min1(t a, t1 b) { return a < b ? a : b; }
template <typename t, typename... arg>
t min1(t a, arg... arr) { return min1(a, min1(arr...)); }
template <typename t, typename t1>
t max1(t a, t1 b) { return a > b ? a : b; }
template <typename t, typename... arg>
t max1(t a, arg... arr) { return max1(a, max1(arr...)); }
#endif

inline int jud(double a, double b){
	if(abs(a) < eps && abs(b) < eps) return 0;
	else if(abs1(a - b) / max(abs1(a), abs1(b)) < eps) return 0;
	if(a < b) return -1;
	return 1;
}
template <typename t> inline int jud(t a, t b){
	if(a < b) return -1;
	if(a == b) return 0;
	return 1;
}

// f_lb == 1代表返回相同的一串的左边界，f_small == 1代表返回如果没有寻找的值返回小的数
template <typename it, typename t1>
inline int find(t1 val, it a, int na, bool f_small = 1, bool f_lb = 1){
	if(na == 0) return 0;
	int be = 0, en = na - 1;
	if(*a <= *(a + na - 1)){
		if(f_lb == 0) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != 1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != -1) en = mid;
			else be = mid + 1;
		}
		if(f_small && jud(*(a + be), val) == 1) be--;
		if(!f_small && jud(*(a + be), val) == -1) be++;
	} else {
		if(f_lb) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != -1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != 1) en = mid;
			else be = mid + 1;
		}
		if(!f_small && jud(*(a + be), val) == -1) be--;
		if(f_small && jud(*(a + be), val) == 1) be++;
	}
	return be;
}

template <class T> inline T lowb(T num) {return num & (-num); }
#ifdef GPP
inline int bitnum(ui nValue) { return __builtin_popcount(nValue); }
inline int bitnum(int nValue) { return __builtin_popcount(nValue); }
inline int bitnum(ull nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitnum(ll nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitmaxl(ui a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(int a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(ull a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
inline int bitmaxl(ll a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
#else
#endif

long long pow(long long n, long long m, long long mod = 0){
	if(m < 0) return 0;
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}

#define  MOD 1000000007
template <class t1, class t2>
inline void add(t1 &a, t2 b, int mod = -1) {
	if(mod == -1) mod = MOD;
	a += b;
	while(a >= mod) a -= mod;
	while(a < 0) a += mod;
}
template <class t>
void output1(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		cerr << arr[i] << ' ';
	cerr << endl;
}
template <class t>
void output2(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		output1(arr[i]);
}

//....................密..........封..........线..........下..........禁..........止..........hack...............................................

const int maxn = 100100;
char str[maxn];
int l;
int m;
int nxt[maxn];

int main() {

//............................不要再忘了检查maxn大小了！！！！BSBandme你个SB！！！！...................................................

	ios_base::sync_with_stdio(0);
	#ifdef DEBUG //......................................................................................................
	freopen("input.txt", "r", stdin);
	int __size__ = 256 << 20; // 256MB
	char *__p__ = (char*)malloc(__size__) + __size__;
	__asm__("movl %0, %%esp\n" :: "r"(__p__));
	#endif //...........................................................................................................

	scanf("%d%s", &m, str);
	l = strlen(str);

	int lastc = -1;
	for(int i = 0; i < 26; i++) {
		int last = -1;
		bool flag = 1;
		for(int j = 0; j < l; j++) {
			if(j > last + m) {
				flag = 0;
				break;
			}
			if(str[j] - 'a' <= i)
				last = j;
		}
		if(flag == 0 || last < l - m) continue;
		lastc = i;
		break;
	}

	memset(nxt, -1, sizeof(nxt));
	int stat[30];
	memset(stat, 0, sizeof(stat));
	for(int j = l, rl = l - 1; j >= 0; j = nxt[j] ) {
		if(j != l)
			stat[str[j] - 'a']++;
		int rnxt = -1;
		rl = j - 1;
		while(rl >= 0 && j - rl <= m) {
			if(str[rl] - 'a' < lastc) {
				rnxt = rl;
				break;
			}
			if(str[rl] - 'a' == lastc)
				rnxt = rl;
			rl--;
		}
		if(rl == -1) {
			nxt[j] = -1;
			break;
		}
		nxt[j] = rnxt;
	}
	for(int i = 0; i < 26; i++)
		for(int j = 0 ;j < stat[i]; j++)
			printf("%c", char(i + 'a'));
	puts("");

    return 0;
}


// #define DEBUG
//#define USEPB_DS
#define USETR1
#define CPPELEVEN
#define GPP

/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
//#pragma comment(linker, "/STACK:1024000000,1024000000")

#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <list>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <sstream>
#include <tuple>

using namespace std;

#ifndef CPPELEVEN
#ifdef USETR1
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#endif
#else
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef USEPB_DS
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
// binomial_heap_tag, rc_binomial_heap_tag, thin_heap_tag, binary_heap_tag
typedef __gnu_pbds::priority_queue<int, greater<int>, pairing_heap_tag> pq_type;
// splay_tree_tag, ov_tree_tag
typedef tree <int, null_type, less <int>, rb_tree_tag, tree_order_statistics_node_update> tree_type;
#endif

#define mpr make_pair
typedef unsigned int ui;
typedef unsigned long long ull;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <double, double> pdd;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector <double> vd;
typedef vector <string> vs;
typedef map <string, int> mpsi;
typedef map <double, int> mpdi;
typedef map <int, int> mpii;

const double pi = acos(0.0) * 2.0;
const long double eps = 1e-10;
const int step[8][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, 1}, {1, 1}, {1, -1}, {-1, -1}};

template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}

#ifndef CPPELEVEN
template <class T> inline T max1(T a, T b) { return b < a ? a : b; }
template <class T> inline T max1(T a, T b, T c) { return max1(max1(a, b), c); }
template <class T> inline T max1(T a, T b, T c, T d) { return max1(max1(a, b, c), d); }
template <class T> inline T max1(T a, T b, T c, T d, T e) { return max1(max1(a, b, c, d), e); }
template <class T> inline T min1(T a, T b) { return a < b ? a : b; }
template <class T> inline T min1(T a, T b, T c) { return min1(min1(a, b), c); }
template <class T> inline T min1(T a, T b, T c, T d) { return min1(min1(a, b, c), d); }
template <class T> inline T min1(T a, T b, T c, T d, T e) { return min1(min1(a, b, c, d), e); }
#else
template <typename t, typename t1>
t min1(t a, t1 b) { return a < b ? a : b; }
template <typename t, typename... arg>
t min1(t a, arg... arr) { return min1(a, min1(arr...)); }
template <typename t, typename t1>
t max1(t a, t1 b) { return a > b ? a : b; }
template <typename t, typename... arg>
t max1(t a, arg... arr) { return max1(a, max1(arr...)); }
#endif

inline int jud(double a, double b){
	if(abs(a) < eps && abs(b) < eps) return 0;
	else if(abs1(a - b) / max(abs1(a), abs1(b)) < eps) return 0;
	if(a < b) return -1;
	return 1;
}
template <typename t> inline int jud(t a, t b){
	if(a < b) return -1;
	if(a == b) return 0;
	return 1;
}

// f_lb == 1代表返回相同的一串的左边界，f_small == 1代表返回如果没有寻找的值返回小的数
template <typename it, typename t1>
inline int find(t1 val, it a, int na, bool f_small = 1, bool f_lb = 1){
	if(na == 0) return 0;
	int be = 0, en = na - 1;
	if(*a <= *(a + na - 1)){
		if(f_lb == 0) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != 1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != -1) en = mid;
			else be = mid + 1;
		}
		if(f_small && jud(*(a + be), val) == 1) be--;
		if(!f_small && jud(*(a + be), val) == -1) be++;
	} else {
		if(f_lb) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != -1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != 1) en = mid;
			else be = mid + 1;
		}
		if(!f_small && jud(*(a + be), val) == -1) be--;
		if(f_small && jud(*(a + be), val) == 1) be++;
	}
	return be;
}

template <class T> inline T lowb(T num) {return num & (-num); }
#ifdef GPP
inline int bitnum(ui nValue) { return __builtin_popcount(nValue); }
inline int bitnum(int nValue) { return __builtin_popcount(nValue); }
inline int bitnum(ull nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitnum(ll nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitmaxl(ui a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(int a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(ull a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
inline int bitmaxl(ll a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
#else
#endif

long long pow(long long n, long long m, long long mod = 0){
	if(m < 0) return 0;
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}

#define  MOD 1000000007
template <class t1, class t2>
inline void add(t1 &a, t2 b, int mod = -1) {
	if(mod == -1) mod = MOD;
	a += b;
	while(a >= mod) a -= mod;
	while(a < 0) a += mod;
}
template <class t>
void output1(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		cerr << arr[i] << ' ';
	cerr << endl;
}
template <class t>
void output2(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		output1(arr[i]);
}

//....................密..........封..........线..........下..........禁..........止..........hack...............................................

const int maxn = 100100;
char str[maxn];
int l;
int m;
int nxt[maxn];

int main() {

//............................不要再忘了检查maxn大小了！！！！BSBandme你个SB！！！！...................................................

	ios_base::sync_with_stdio(0);
	#ifdef DEBUG //......................................................................................................
	freopen("input.txt", "r", stdin);
	int __size__ = 256 << 20; // 256MB
	char *__p__ = (char*)malloc(__size__) + __size__;
	__asm__("movl %0, %%esp\n" :: "r"(__p__));
	#endif //...........................................................................................................

	scanf("%d%s", &m, str);
	l = strlen(str);

	int lastc = -1;
	for(int i = 0; i < 26; i++) {
		int last = -1;
		bool flag = 1;
		for(int j = 0; j < l; j++) {
			if(j > last + m) {
				flag = 0;
				break;
			}
			if(str[j] - 'a' <= i)
				last = j;
		}
		if(flag == 0 || last < l - 3) continue;
		lastc = i;
		break;
	}

	memset(nxt, -1, sizeof(nxt));
	int stat[30];
	memset(stat, 0, sizeof(stat));
	for(int j = l, rl = l - 1; j >= 0; j = nxt[j] ) {
		if(j != l)
			stat[str[j] - 'a']++;
		int rnxt = -1;
		rl = j - 1;
		while(rl >= 0 && j - rl <= m) {
			if(str[rl] - 'a' < lastc) {
				rnxt = rl;
				break;
			}
			if(str[rl] - 'a' == lastc)
				rnxt = rl;
			rl--;
		}
		if(rl == -1) {
			nxt[j] = -1;
			break;
		}
		nxt[j] = rnxt;
	}
	for(int i = 0; i < 26; i++)
		for(int j = 0 ;j < stat[i]; j++)
			printf("%c", char(i + 'a'));
	puts("");

    return 0;
}