#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <cmath>
using namespace std;

#define INIT(x) memset(x,0,sizeof(x))
#define eps 1e-8
#define next next_
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x7fffffff;
const int inf = 0x3f3f3f3f;
const int maxn = 1000005;
const int N = 105;

inline void read(ll &x) {
    ll f=1;x=0;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    x*=f;
}

ll n,m,ans,cnt1,cnt2; //cnt1ά����ͨ�ߣ�cnt2ά���Ի���
ll in[maxn],fa[maxn];

ll get(ll x) {
	if(x==fa[x]) return x;
	return fa[x] = get(fa[x]);
}

void join(ll x,ll y) {
	ll a = get(x), b = get(y);
	if(a!=b) fa[b] = a;
}

int main() {
	read(n), read(m);
	for(int i=1;i<=n;i++) fa[i] = i;
	for(int i=0;i<m;i++) {
		ll x,y;
		read(x), read(y);
		join(x,y);
		if(x!=y) in[x]++, in[y]++;
		if(x!=y) cnt1++;
		else cnt2++;
	}
	for(int i=2;i<=n;i++) {
		if(fa[i]!=fa[1]) {
			cout<<0<<endl;
			return 0;
		}
	}
	for(int i=1;i<=n;i++) { //�����й��������ͨ��
		ans += in[i] * (in[i]-1) / 2;
	}
	ans += cnt1 * cnt2; //һ����ͨ�ߣ�һ���Ի�
	ans += cnt2 * (cnt2-1) / 2; //�����Ի�
	cout<<ans<<endl;
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <cmath>
using namespace std;

#define INIT(x) memset(x,0,sizeof(x))
#define eps 1e-8
#define next next_
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x7fffffff;
const int inf = 0x3f3f3f3f;
const int maxn = 200005;
const int N = 105;

inline void read(ll &x) {
    ll f=1;x=0;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    x*=f;
}

ll n,m,ans,cnt1,cnt2; //cnt1ά����ͨ�ߣ�cnt2ά���Ի���
ll in[maxn],fa[maxn];
vector<pair<ll,ll> >e;

ll get(ll x) {
	if(x==fa[x]) return x;
	return fa[x] = get(fa[x]);
}

void join(ll x,ll y) {
	ll a = get(x), b = get(y);
	if(a!=b) fa[b] = a;
}

int main() {
	read(n), read(m);
	for(int i=1;i<=n;i++) fa[i] = i;
	for(int i=0;i<m;i++) {
		ll x,y;
		read(x), read(y);
		join(x,y);
		if(x!=y) in[x]++, in[y]++;
		if(x!=y) cnt1++;
		else cnt2++;
	}
	for(int i=2;i<=n;i++) {
		if(fa[i]!=fa[1]) {
			cout<<0<<endl;
			return 0;
		}
	}
	for(int i=1;i<=m;i++) { //�����й��������ͨ��
		ans += in[i] * (in[i]-1) / 2;
	}
	ans += cnt1 * cnt2; //һ����ͨ�ߣ�һ���Ի�
	ans += cnt2*(cnt2-1) / 2; //�����Ի�
	cout<<ans<<endl;
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <cmath>
using namespace std;

#define INIT(x) memset(x,0,sizeof(x))
#define eps 1e-8
#define next next_
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x7fffffff;
const int inf = 0x3f3f3f3f;
const int maxn = 1000005;
const int N = 105;

inline void read(ll &x) {
    ll f=1;x=0;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    x*=f;
}

ll n,m,ans,cnt1,cnt2; //cnt1ά����ͨ�ߣ�cnt2ά���Ի���
ll in[maxn],fa[maxn];

ll get(ll x) {
	if(x==fa[x]) return x;
	return fa[x] = get(fa[x]);
}

void join(ll x,ll y) {
	ll a = get(x), b = get(y);
	if(a!=b) fa[b] = a;
}

int main() {
	read(n), read(m);
	for(int i=1;i<=n;i++) fa[i] = i;
	for(int i=0;i<m;i++) {
		ll x,y;
		read(x), read(y);
		if(x>y) swap(x,y);
		join(x,y);
		if(x!=y) in[x]++, in[y]++;
		if(x!=y) cnt1++;
		else cnt2++;
	}
	for(int i=2;i<=n;i++) {
		if(fa[i]!=fa[1]) {
			cout<<0<<endl;
			return 0;
		}
	}
	for(int i=1;i<=n;i++) { //�����й��������ͨ��
		ans += in[i] * (in[i]-1) / 2;
	}
	ans += cnt1 * cnt2; //һ����ͨ�ߣ�һ���Ի�
	ans += cnt2 * (cnt2-1) / 2; //�����Ի�
	cout<<ans<<endl;
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <cmath>
using namespace std;

#define INIT(x) memset(x,0,sizeof(x))
#define eps 1e-8
#define next next_
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x7fffffff;
const int inf = 0x3f3f3f3f;
const int maxn = 1000005;
const int N = 105;

inline void read(ll &x) {
    ll f=1;x=0;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    x*=f;
}

ll n,m,ans,cnt1,cnt2; //cnt1ά����ͨ�ߣ�cnt2ά���Ի���
ll in[maxn],fa[maxn];
bool vis[maxn]; //�жϹµ�

ll get(ll x) {
	if(x==fa[x]) return x;
	return fa[x] = get(fa[x]);
}

void join(ll x,ll y) {
	fa[get(x)] = get(y);
}

int main() {
	read(n), read(m);
	for(int i=1;i<=n;i++) fa[i] = i;
	for(int i=0;i<m;i++) {
		ll x,y;
		read(x), read(y);
		join(x,y);
		vis[x] = vis[y] = 1;
		if(x!=y) in[x]++, in[y]++;
		if(x!=y) cnt1++;
		else cnt2++;
	}
//	for(int i=1;i<=n;i++) cout<<i<<' '<<fa[i]<<endl;
	set<int> s;
	for(int i=1;i<=n;i++) {
		if(vis[i]) s.insert(get(i));
		if(s.size()>=2) {
			cout<<0<<endl;
			return 0;
		}
	}
	for(int i=1;i<=n;i++) { //�����й��������ͨ��
		ans += in[i] * (in[i]-1) / 2;
	}
	ans += cnt1 * cnt2; //һ����ͨ�ߣ�һ���Ի�
	ans += cnt2 * (cnt2-1) / 2; //�����Ի�
	cout<<ans<<endl;
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <cmath>
using namespace std;

#define INIT(x) memset(x,0,sizeof(x))
#define eps 1e-8
#define next next_
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x7fffffff;
const int inf = 0x3f3f3f3f;
const int maxn = 1000005;
const int N = 105;

inline void read(ll &x) {
    ll f=1;x=0;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    x*=f;
}

ll n,m,ans,cnt1,cnt2; //cnt1ά����ͨ�ߣ�cnt2ά���Ի���
ll in[maxn],fa[maxn];

ll get(ll x) {
	if(x==fa[x]) return x;
	return fa[x] = get(fa[x]);
}

void join(ll x,ll y) {
	fa[get(x)] = get(y);
}

int main() {
	read(n), read(m);
	for(int i=1;i<=n;i++) fa[i] = i;
	for(int i=0;i<m;i++) {
		ll x,y;
		read(x), read(y);
		join(x,y);
		if(x!=y) in[x]++, in[y]++;
		if(x!=y) cnt1++;
		else cnt2++;
	}
	for(int i=2;i<=n;i++) {
		if(get(i)!=get(1)) {
			cout<<0<<endl;
			return 0;
		}
	}
	for(int i=1;i<=n;i++) { //�����й��������ͨ��
		ans += in[i] * (in[i]-1) / 2;
	}
	ans += cnt1 * cnt2; //һ����ͨ�ߣ�һ���Ի�
	ans += cnt2 * (cnt2-1) / 2; //�����Ի�
	cout<<ans<<endl;
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <cmath>
using namespace std;

#define INIT(x) memset(x,0,sizeof(x))
#define eps 1e-8
#define next next_
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x7fffffff;
const int inf = 0x3f3f3f3f;
const int maxn = 200005;
const int N = 105;

inline void read(ll &x) {
    ll f=1;x=0;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    x*=f;
}

ll n,m,ans,cnt1,cnt2; //cnt1ά����ͨ�ߣ�cnt2ά���Ի���
ll in[maxn],fa[maxn];

ll get(ll x) {
	if(x==fa[x]) return x;
	return fa[x] = get(fa[x]);
}

void join(ll x,ll y) {
	ll a = get(x), b = get(y);
	if(a!=b) fa[b] = a;
}

int main() {
	read(n), read(m);
	for(int i=1;i<=n;i++) fa[i] = i;
	for(int i=0;i<m;i++) {
		ll x,y;
		read(x), read(y);
		join(x,y);
		if(x!=y) in[x]++, in[y]++;
		if(x!=y) cnt1++;
		else cnt2++;
	}
	for(int i=2;i<=n;i++) {
		if(fa[i]!=fa[1]) {
			cout<<0<<endl;
			return 0;
		}
	}
	for(int i=1;i<=n;i++) { //�����й��������ͨ��
		ans += in[i] * (in[i]-1) / 2;
	}
	ans += cnt1 * cnt2; //һ����ͨ�ߣ�һ���Ի�
	ans += cnt2 * (cnt2-1) / 2; //�����Ի�
	cout<<ans<<endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int OO = 1e9;
const double EPS = 1e-9;

#define ndl cout << '\n'
#define sz(v) int(v.size())
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define present(a, x) (a.find(x) != a.end())
#ifdef LOCAL
#define db(...) ({cout << "> Line " << __LINE__  \
		<< ": "; _db(#__VA_ARGS__, __VA_ARGS__);})
#define RNG() rng()
#else
#define db(...) true
#define RNG() true
#endif

template<class T>
void _db(const char *dbStr, T e) {
	cout << dbStr << " = " << e << endl;
}
template<class T, class... L>
void _db(const char *dbStr, T e, L... r) {
  while(*dbStr != ',') cout << *dbStr++;
  cout << " = " << e << ','; _db(dbStr + 1, r...);
}
template<class S, class T>
ostream& operator<<(ostream& o, const map<S, T>& v) {
	o << "["; int i = 0;
	for (const pair<S, T>& pr : v) o << (!i++ ? "" : ", ") << "{"
	<< pr.fs << " : " << pr.sc << "}"; return o << "]";
}
template<template <class, class...> class S, class T, class... L>
ostream& operator<<(ostream& o, const S<T, L...>& v) {
	o << "["; int i = 0;
	for (const auto& e : v) o << (!i++ ? "" : ", ") << e;
	return o << "]";
}
template<class S, class T>
ostream& operator<<(ostream& o, const pair<S, T>& pr) {
	return o << "(" << pr.fs << ", " << pr.sc << ")";
}
ostream& operator<<(ostream& o, const string& s) {
	for (const char& c : s) o << c;
	return o;
}

template<class T> using V = vector<T>;
template<class T> using VV = V<V<T>>;
template<class T> using VVV = VV<V<T>>;
using ll = long long;
using pii = pair<int, int>;
using vi = V<int>;
using vii = V<pii>;
using vvi = VV<int>;
using mii = map<int, int>;
using umii = unordered_map<int, int>;
using si = set<int>;
using usi = unordered_set<int>;

int n, m, l, cnt;
vvi adj;
V<bool> vis;

void dfs(int u) {
	vis[u] = 1;
	++cnt;
	for (auto& v : adj[u]) {
		if (!vis[v])
			dfs(v);
	}
}

int main() {
	#ifdef LOCAL
	auto stTime = clock();
//	freopen("in.txt", "r", stdin);
	mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
	#endif
	ios::sync_with_stdio(false);
	cout.precision(10);
	cin.tie(0);

	cin >> n >> m;

	adj.assign(n + 1, vi());
	vis.assign(n + 1, 0);

	for (int i = 1; i <= m; ++i) {
		int u, v;
		cin >> u >> v;
		if (u == v)
			++l;
		else {
			adj[u].pb(v);
			adj[v].pb(u);
		}
	}

	dfs(1);

	if (cnt != n)
		cout << "0\n";
	else {
		ll ans = l * 1LL * (m - l) + (l * 1LL * (l - 1)) / 2;
		for (int i = 1; i <= n; ++i)
			ans += (sz(adj[i]) * 1LL * (sz(adj[i]) - 1)) / 2;
		cout << ans << '\n';
	}

	#ifdef LOCAL
	cout << "\n\n\nExecution time: " <<
		(clock() - stTime) * 1e3 / CLOCKS_PER_SEC << " ms" << endl;
	#endif
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int OO = 1e9;
const double EPS = 1e-9;

#define ndl cout << '\n'
#define sz(v) int(v.size())
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define present(a, x) (a.find(x) != a.end())
#ifdef LOCAL
#define db(...) ({cout << "> Line " << __LINE__  \
		<< ": "; _db(#__VA_ARGS__, __VA_ARGS__);})
#define RNG() rng()
#else
#define db(...) true
#define RNG() true
#endif

template<class T>
void _db(const char *dbStr, T e) {
	cout << dbStr << " = " << e << endl;
}
template<class T, class... L>
void _db(const char *dbStr, T e, L... r) {
  while(*dbStr != ',') cout << *dbStr++;
  cout << " = " << e << ','; _db(dbStr + 1, r...);
}
template<class S, class T>
ostream& operator<<(ostream& o, const map<S, T>& v) {
	o << "["; int i = 0;
	for (const pair<S, T>& pr : v) o << (!i++ ? "" : ", ") << "{"
	<< pr.fs << " : " << pr.sc << "}"; return o << "]";
}
template<template <class, class...> class S, class T, class... L>
ostream& operator<<(ostream& o, const S<T, L...>& v) {
	o << "["; int i = 0;
	for (const auto& e : v) o << (!i++ ? "" : ", ") << e;
	return o << "]";
}
template<class S, class T>
ostream& operator<<(ostream& o, const pair<S, T>& pr) {
	return o << "(" << pr.fs << ", " << pr.sc << ")";
}
ostream& operator<<(ostream& o, const string& s) {
	for (const char& c : s) o << c;
	return o;
}

template<class T> using V = vector<T>;
template<class T> using VV = V<V<T>>;
template<class T> using VVV = VV<V<T>>;
using ll = long long;
using pii = pair<int, int>;
using vi = V<int>;
using vii = V<pii>;
using vvi = VV<int>;
using mii = map<int, int>;
using umii = unordered_map<int, int>;
using si = set<int>;
using usi = unordered_set<int>;

int n, m, l, cnt;
vvi adj;
V<bool> vis, isolated;

void dfs(int u) {
	vis[u] = 1;
	++cnt;
	for (auto& v : adj[u]) {
		if (!vis[v])
			dfs(v);
	}
}

int main() {
	#ifdef LOCAL
	auto stTime = clock();
//	freopen("in.txt", "r", stdin);
	mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
	#endif
	ios::sync_with_stdio(false);
	cout.precision(10);
	cin.tie(0);

	cin >> n >> m;

	adj.assign(n + 1, vi());
	vis.assign(n + 1, 0);
	isolated.assign(n + 1, 1);

	for (int i = 1; i <= m; ++i) {
		int u, v;
		cin >> u >> v;
		isolated[u] = isolated[v] = 0;
		if (u == v)
			++l;
		else {
			adj[u].pb(v);
			adj[v].pb(u);
		}
	}

	int cc = 0;
	for (int i = 1; i <= n; ++i) {
		if (isolated[i])
			continue;
		if (!vis[i]) {
			dfs(i);
			++cc;
		}
	}

	if (cc > 1) {
		cout << "0\n";
	} else {
		ll ans = l * 1LL * (m - l) + (l * 1LL * (l - 1)) / 2;
		for (int i = 1; i <= n; ++i)
			ans += (sz(adj[i]) * 1LL * (sz(adj[i]) - 1)) / 2;
		cout << ans << '\n';
	}

	#ifdef LOCAL
	cout << "\n\n\nExecution time: " <<
		(clock() - stTime) * 1e3 / CLOCKS_PER_SEC << " ms" << endl;
	#endif
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int OO = 1e9;
const double EPS = 1e-9;

#define ndl cout << '\n'
#define sz(v) int(v.size())
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define present(a, x) (a.find(x) != a.end())
#ifdef LOCAL
#define db(...) ({cout << "> Line " << __LINE__  \
		<< ": "; _db(#__VA_ARGS__, __VA_ARGS__);})
#define RNG() rng()
#else
#define db(...) true
#define RNG() true
#endif

template<class T>
void _db(const char *dbStr, T e) {
	cout << dbStr << " = " << e << endl;
}
template<class T, class... L>
void _db(const char *dbStr, T e, L... r) {
  while(*dbStr != ',') cout << *dbStr++;
  cout << " = " << e << ','; _db(dbStr + 1, r...);
}
template<class S, class T>
ostream& operator<<(ostream& o, const map<S, T>& v) {
	o << "["; int i = 0;
	for (const pair<S, T>& pr : v) o << (!i++ ? "" : ", ") << "{"
	<< pr.fs << " : " << pr.sc << "}"; return o << "]";
}
template<template <class, class...> class S, class T, class... L>
ostream& operator<<(ostream& o, const S<T, L...>& v) {
	o << "["; int i = 0;
	for (const auto& e : v) o << (!i++ ? "" : ", ") << e;
	return o << "]";
}
template<class S, class T>
ostream& operator<<(ostream& o, const pair<S, T>& pr) {
	return o << "(" << pr.fs << ", " << pr.sc << ")";
}
ostream& operator<<(ostream& o, const string& s) {
	for (const char& c : s) o << c;
	return o;
}

template<class T> using V = vector<T>;
template<class T> using VV = V<V<T>>;
template<class T> using VVV = VV<V<T>>;
using ll = long long;
using pii = pair<int, int>;
using vi = V<int>;
using vii = V<pii>;
using vvi = VV<int>;
using mii = map<int, int>;
using umii = unordered_map<int, int>;
using si = set<int>;
using usi = unordered_set<int>;

int n, m, l, cnt;
vvi adj;
V<bool> vis;

void dfs(int u) {
	vis[u] = 1;
	++cnt;
	for (auto& v : adj[u]) {
		if (!vis[v])
			dfs(v);
	}
}

int main() {
	#ifdef LOCAL
	auto stTime = clock();
//	freopen("in.txt", "r", stdin);
	mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
	#endif
	ios::sync_with_stdio(false);
	cout.precision(10);
	cin.tie(0);

	cin >> n >> m;

	adj.assign(n + 1, vi());
	vis.assign(n + 1, 0);

	for (int i = 1; i <= m; ++i) {
		int u, v;
		cin >> u >> v;
		if (u == v)
			++l;
		else {
			adj[u].pb(v);
			adj[v].pb(u);
		}
	}

	vi ccs;
	for (int i = 1; i <= n; ++i) {
		if (!vis[i]) {
			cnt = 0;
			dfs(i);
			db(cnt);
			if (cnt > 1)
				ccs.pb(cnt);
		}
	}

	if (sz(ccs) != 1) {
		cout << "0\n";
	} else {
		ll ans = l * 1LL * (m - l) + (l * 1LL * (l - 1)) / 2;
		for (int i = 1; i <= n; ++i)
			ans += (sz(adj[i]) * 1LL * (sz(adj[i]) - 1)) / 2;
		cout << ans << '\n';
	}

	#ifdef LOCAL
	cout << "\n\n\nExecution time: " <<
		(clock() - stTime) * 1e3 / CLOCKS_PER_SEC << " ms" << endl;
	#endif
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int OO = 1e9;
const double EPS = 1e-9;

#define ndl cout << '\n'
#define sz(v) int(v.size())
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define present(a, x) (a.find(x) != a.end())
#ifdef LOCAL
#define db(...) ({cout << "> Line " << __LINE__  \
		<< ": "; _db(#__VA_ARGS__, __VA_ARGS__);})
#define RNG() rng()
#else
#define db(...) true
#define RNG() true
#endif

template<class T>
void _db(const char *dbStr, T e) {
	cout << dbStr << " = " << e << endl;
}
template<class T, class... L>
void _db(const char *dbStr, T e, L... r) {
  while(*dbStr != ',') cout << *dbStr++;
  cout << " = " << e << ','; _db(dbStr + 1, r...);
}
template<class S, class T>
ostream& operator<<(ostream& o, const map<S, T>& v) {
	o << "["; int i = 0;
	for (const pair<S, T>& pr : v) o << (!i++ ? "" : ", ") << "{"
	<< pr.fs << " : " << pr.sc << "}"; return o << "]";
}
template<template <class, class...> class S, class T, class... L>
ostream& operator<<(ostream& o, const S<T, L...>& v) {
	o << "["; int i = 0;
	for (const auto& e : v) o << (!i++ ? "" : ", ") << e;
	return o << "]";
}
template<class S, class T>
ostream& operator<<(ostream& o, const pair<S, T>& pr) {
	return o << "(" << pr.fs << ", " << pr.sc << ")";
}
ostream& operator<<(ostream& o, const string& s) {
	for (const char& c : s) o << c;
	return o;
}

template<class T> using V = vector<T>;
template<class T> using VV = V<V<T>>;
template<class T> using VVV = VV<V<T>>;
using ll = long long;
using pii = pair<int, int>;
using vi = V<int>;
using vii = V<pii>;
using vvi = VV<int>;
using mii = map<int, int>;
using umii = unordered_map<int, int>;
using si = set<int>;
using usi = unordered_set<int>;

int n, m, l, cnt;
vvi adj;
V<bool> vis;

void dfs(int u) {
	vis[u] = 1;
	++cnt;
	for (auto& v : adj[u]) {
		if (!vis[v])
			dfs(v);
	}
}

int main() {
	#ifdef LOCAL
	auto stTime = clock();
//	freopen("in.txt", "r", stdin);
	mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
	#endif
	ios::sync_with_stdio(false);
	cout.precision(10);
	cin.tie(0);

	cin >> n >> m;

	adj.assign(n + 1, vi());
	vis.assign(n + 1, 0);

	for (int i = 1; i <= m; ++i) {
		int u, v;
		cin >> u >> v;
		if (u == v)
			++l;
		else {
			adj[u].pb(v);
			adj[v].pb(u);
		}
	}

	vi ccs;
	for (int i = 1; i <= n; ++i) {
		if (!vis[i]) {
			cnt = 0;
			dfs(i);
			db(cnt);
			if (cnt > 1)
				ccs.pb(cnt);
		}
	}

	if (sz(ccs) > 1) {
		cout << "0\n";
	} else {
		ll ans = l * 1LL * (m - l) + (l * 1LL * (l - 1)) / 2;
		for (int i = 1; i <= n; ++i)
			ans += (sz(adj[i]) * 1LL * (sz(adj[i]) - 1)) / 2;
		cout << ans << '\n';
	}

	#ifdef LOCAL
	cout << "\n\n\nExecution time: " <<
		(clock() - stTime) * 1e3 / CLOCKS_PER_SEC << " ms" << endl;
	#endif
	return 0;
}


//by Shriram Lokhande
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define testcases(t) int t,myzx;cin>>myzx;forsn(t,1,myzx+1)
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits
#define ln "\n"
#define kyahai(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); \
stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cout<<ln; }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
	cerr << *it << " = " << a << "\t\t";
	err(++it, args...);
}
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define all(n) n.begin() , n.end()
#define tfi first.first
#define tse first.second
#define tth second
typedef long long ll;
typedef long double ld;
typedef pair<int,int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
typedef pair< pair<int,int> , int> tri;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
//like set just find_by_order() and order_of_key() are extra

#pragma GCC optimize ("-O3")
template < typename tp > void in( tp & dig ){
    char ch=getchar();dig=0;ll flag=0;
    while(!isdigit(ch)){ if(ch=='-')flag=1;ch=getchar(); }
    while(isdigit(ch))dig=dig*10+ch-'0',ch=getchar();
    if(flag)dig=-dig;
}
const int LIM = 2e5+5 ,MOD = 1e9+7;
const ld EPS = 1e-9 , PI = 2*atan2((ld)1,(ld)0);

vv32 adj;
v32 vis;
ll num;
void dfs(int v){
	vis[v] = 1;
	num++;
	forstl(u,adj[v]) if(vis[u] != 1) {
		dfs(u);
	}
}

int main(){
	ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int n,m;
	cin>>n>>m;
	int u,v,x = 0;
	adj.assign(n,v32(0));
	vis.assign(n,0);
	ll loops = 0, vert[n];
	forn(i,n) vert[i] = 0;
	forn(i,m){
		cin>>u>>v;
		u--,v--;
		adj[u].pb(v);
		adj[v].pb(u);
		if(vis[u] == 0) x++;
		vis[u] = 1;
		if(vis[v] == 0) x++;
		vis[v] = 1;
		if(u == v) {
			loops++;
			continue;
		}
		vert[u]++;
		vert[v]++;
	}
	ll ans = 0;
	forn(i,n){
		ans += vert[i]*(vert[i]-1)/2;
	}
	ans += loops*(m - loops) + loops*(loops-1)/2;
	num = 0;
	vis.assign(n,0);
	dfs(u);
	//kyahai(loops,ans,num,x);
	cout<<((num == x) ? ans : 0)<<ln;
}


//by Shriram Lokhande
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define testcases(t) int t,myzx;cin>>myzx;forsn(t,1,myzx+1)
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits
#define ln "\n"
#define kyahai(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); \
stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cout<<ln; }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
	cerr << *it << " = " << a << "\t\t";
	err(++it, args...);
}
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define all(n) n.begin() , n.end()
#define tfi first.first
#define tse first.second
#define tth second
typedef long long ll;
typedef long double ld;
typedef pair<int,int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
typedef pair< pair<int,int> , int> tri;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
//like set just find_by_order() and order_of_key() are extra

#pragma GCC optimize ("-O3")
template < typename tp > void in( tp & dig ){
    char ch=getchar();dig=0;ll flag=0;
    while(!isdigit(ch)){ if(ch=='-')flag=1;ch=getchar(); }
    while(isdigit(ch))dig=dig*10+ch-'0',ch=getchar();
    if(flag)dig=-dig;
}
const int LIM = 2e5+5 ,MOD = 1e9+7;
const ld EPS = 1e-9 , PI = 2*atan2((ld)1,(ld)0);

vv32 adj;
v32 vis;
ll num;
void dfs(int v){
	vis[v] = 1;
	num++;
	forstl(u,adj[v]) if(vis[u] != 1) {
		dfs(u);
	}
}

int main(){
	ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int n,m;
	cin>>n>>m;
	int u,v,x;
	adj.assign(n,v32(0));
	vis.assign(n,0);
	ll loops = 0, vert[n];
	forn(i,n) vert[i] = 0;
	forn(i,m){
		cin>>u>>v;
		u--,v--;
		adj[u].pb(v);
		adj[v].pb(u);
		if(vis[u] == 0) x++;
		if(vis[v] == 0) x++;
		vis[u] = 1;
		vis[v] = 1;
		if(u == v) {
			loops++;
			continue;
		}
		vert[u]++;
		vert[v]++;
	}
	ll ans = 0;
	forn(i,n){
		ans += vert[i]*(vert[i]-1)/2;
	}
	ans += loops*(m - loops) + loops*(loops-1)/2;
	num = 0;
	vis.assign(n,0);
	dfs(u);
	//kyahai(loops,ans,num,x);
	cout<<((num == x) ? ans : 0)<<ln;
}


//by Shriram Lokhande
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define testcases(t) int t,myzx;cin>>myzx;forsn(t,1,myzx+1)
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits
#define ln "\n"
#define kyahai(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); \
stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cout<<ln; }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
	cerr << *it << " = " << a << "\t\t";
	err(++it, args...);
}
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define all(n) n.begin() , n.end()
#define tfi first.first
#define tse first.second
#define tth second
typedef long long ll;
typedef long double ld;
typedef pair<int,int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
typedef pair< pair<int,int> , int> tri;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
//like set just find_by_order() and order_of_key() are extra

#pragma GCC optimize ("-O3")
template < typename tp > void in( tp & dig ){
    char ch=getchar();dig=0;ll flag=0;
    while(!isdigit(ch)){ if(ch=='-')flag=1;ch=getchar(); }
    while(isdigit(ch))dig=dig*10+ch-'0',ch=getchar();
    if(flag)dig=-dig;
}
const int LIM = 2e5+5 ,MOD = 1e9+7;
const ld EPS = 1e-9 , PI = 2*atan2((ld)1,(ld)0);

vv32 adj;
v32 vis;
ll num;
void dfs(int v){
	vis[v] = 1;
	num++;
	forstl(u,adj[v]) if(vis[u] != 1) {
		dfs(u);
	}
}

int main(){
	ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int n,m;
	cin>>n>>m;
	int u,v,x = 0;
	adj.assign(n,v32(0));
	vis.assign(n,0);
	ll loops = 0, vert[n];
	forn(i,n) vert[i] = 0;
	forn(i,m){
		cin>>u>>v;
		u--,v--;
		adj[u].pb(v);
		adj[v].pb(u);
		if(vis[u] == 0) x++;
		if(vis[v] == 0) x++;
		vis[u] = 1;
		vis[v] = 1;
		if(u == v) {
			loops++;
			continue;
		}
		vert[u]++;
		vert[v]++;
	}
	ll ans = 0;
	forn(i,n){
		ans += vert[i]*(vert[i]-1)/2;
	}
	ans += loops*(m - loops) + loops*(loops-1)/2;
	num = 0;
	vis.assign(n,0);
	dfs(u);
	kyahai(loops,ans,num,x);
	cout<<((num == x) ? ans : 0)<<ln;
}


//by Shriram Lokhande
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define testcases(t) int t,myzx;cin>>myzx;forsn(t,1,myzx+1)
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits
#define ln "\n"
#define kyahai(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); \
stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cout<<ln; }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
	cerr << *it << " = " << a << "\t\t";
	err(++it, args...);
}
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define all(n) n.begin() , n.end()
#define tfi first.first
#define tse first.second
#define tth second
typedef long long ll;
typedef long double ld;
typedef pair<int,int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
typedef pair< pair<int,int> , int> tri;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
//like set just find_by_order() and order_of_key() are extra

#pragma GCC optimize ("-O3")
template < typename tp > void in( tp & dig ){
    char ch=getchar();dig=0;ll flag=0;
    while(!isdigit(ch)){ if(ch=='-')flag=1;ch=getchar(); }
    while(isdigit(ch))dig=dig*10+ch-'0',ch=getchar();
    if(flag)dig=-dig;
}
const int LIM = 2e5+5 ,MOD = 1e9+7;
const ld EPS = 1e-9 , PI = 2*atan2((ld)1,(ld)0);

vv32 adj;
v32 vis;
ll num;
void dfs(int v){
	vis[v] = 1;
	num++;
	forstl(u,adj[v]) if(vis[u] != 1) {
		dfs(u);
	}
}

int main(){
	ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int n,m;
	cin>>n>>m;
	int u,v;
	adj.assign(n,v32(0));
	vis.assign(n,0);
	ll loops = 0, vert[n];
	forn(i,n) vert[i] = 0;
	forn(i,m){
		cin>>u>>v;
		u--,v--;
		adj[u].pb(v);
		adj[v].pb(u);
		if(u == v) {
			loops++;
			continue;
		}
		vert[u]++;
		vert[v]++;
	}
	ll ans = 0;
	forn(i,n){
		ans += vert[i]*(vert[i]-1)/2;
	}
	//kyahai(loops,ans);
	ans += loops*(m - loops) + loops*(loops-1)/2;
	num = 0;
	dfs(0);
	cout<<((num == n) ? ans : 0)<<ln;
}


#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("unroll-loops")
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define int long long
#define fr(i,a,b) for(int i = a ; i <= b ; ++i)
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend()
#define sz(x) (int)(x).size()
#define pb push_back
#define fst first
#define snd second
using namespace __gnu_pbds;
using ordered_set =
 tree<int, null_type,less<int>,
 rb_tree_tag,tree_order_statistics_node_update>;
//find_by_order(k):returns iterator to kth element starting from 0
//order_of_key(k):returns count of elements strictly smaller than k
typedef long long ll;typedef pair<int, int> pii;
typedef vector<int> vi;typedef long double ld;
template<class T>
using min_heap = priority_queue<T,vector<T>,greater<T>>;
template<typename T> T gcd(T a, T b){return(b?__gcd(a,b):a);}
template<typename T> T lcm(T a, T b){return(a*(b/gcd(a,b)));}
template<class T> void re(T& x) { cin >> x; }
template<typename T>
void remdup(vector<T>& v) {
	sort(all(v)); v.erase(unique(all(v)), v.end());
}
template<typename T> void re(vector<T> &v) {trav(i,v) cin >> i;}
template<class H, class... T> void re(H& h, T&... t) { re(h); re(t...); }
void unsyncIO() { ios_base::sync_with_stdio(0); cin.tie(0); }
#ifdef np
#include "/home/wjex/cp/pr.h"
#else
#define trace(...)
#endif

constexpr int MOD = 1000000007;
constexpr int Nx = 1e6+5; // check

vi g[Nx+1];
int vis[Nx + 1];
void dfs(int v){
	vis[v] = 1 ;
	trav(i,g[v]) {
		if(!vis[i]) dfs(i);
	}
}
void solve(){
	int n , m;  re(n,m);
	int com = 0 ;
	vector<pii> e;
	rep(i,0,m){
		int a, b ; re(a,b);
		com+=(a==b);
		if(a!=b){
			g[a].pb(b);
			g[b].pb(a);
		}
		e.pb({a,b});
	}
	dfs(e.front().fst);
	int ans = 0 ;
	rep(i,0,m){
		if(!vis[e[i].fst]){
			cout << 0 << endl;
			return;
		}
	}
	fr(i,1,n){
		int deg = sz(g[i]);
		ans+=deg*(deg-1)/2;
	}
	ans+=com*(com-1)/2;
	cout << ans + com*(m-com) << endl;
}

signed main() {
	unsyncIO();
	int tt =1 ;
	//cin >> tt;
	rep(i,0,tt) solve();

#ifdef np
	cout <<endl<<endl<< "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
vector<int> g[N];
int u[N],v[N];
bool vis[N],z[N];
int dfs(int u)
{
    vis[u]=true;
    int ret=1;
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        if(vis[v]) continue;
        ret+=dfs(v);
    }
    return ret;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    memset(z,false,sizeof(z));
    memset(vis,false,sizeof(vis));
    int num=0,sum=0;
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&u[i],&v[i]);
        if(!vis[u[i]]) vis[u[i]]=true,sum++;
        if(!vis[v[i]]) vis[v[i]]=true,sum++;
        if(u[i]==v[i])
        {
            z[u[i]]=true,num++;
            continue;
        }
        g[u[i]].push_back(v[i]);
        g[v[i]].push_back(u[i]);
    }
    memset(vis,false,sizeof(vis));
    if(dfs(u[0])<sum)
    {
        printf("0\n");
        return 0;
    }
    ll ans=0;
    for(int i=0;i<m;i++)
    {
        int uu=u[i];
        int vv=v[i];
        if(uu==vv)
        {
            ans+=m-1;
            continue;
        }
        ans+=num;
        //if(uu==vv) ans--;
        ans+=g[uu].size()-1;
        //cout<<uu<<" "<<vv<<" "<<ans<<endl;

        ans+=g[vv].size()-1;
        //cout<<uu<<" "<<vv<<" "<<ans<<endl;
    }
    printf("%lld\n",ans/2);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
vector<int> g[N];
int u[N],v[N];
bool vis[N];
int dfs(int u)
{
    vis[u]=true;
    int ret=1;
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        if(vis[v]) continue;
        ret+=dfs(v);
    }
    return ret;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&u[i],&v[i]);
        g[u[i]].push_back(v[i]);
        if(u[i]!=v[i])
        g[v[i]].push_back(u[i]);
    }
    memset(vis,false,sizeof(vis));
    if(dfs(1)<n)
    {
        printf("0\n");
        return 0;
    }
    int ans=0;
    for(int i=0;i<m;i++)
    {
        int uu=u[i];
        int vv=v[i];
        ans+=g[uu].size()-1;
        //cout<<uu<<" "<<vv<<" "<<ans<<endl;
        if(uu==vv) continue;
        ans+=g[vv].size()-1;
    }
    printf("%d\n",ans/2);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
vector<int> g[N];
int u[N],v[N];
bool vis[N],z[N];
int dfs(int u)
{
    vis[u]=true;
    int ret=1;
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        if(vis[v]) continue;
        ret+=dfs(v);
    }
    return ret;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    memset(z,false,sizeof(z));
    int num=0;
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&u[i],&v[i]);
        if(u[i]==v[i])
        {
            z[u[i]]=true,num++;
            continue;
        }
        g[u[i]].push_back(v[i]);
        g[v[i]].push_back(u[i]);
    }
    memset(vis,false,sizeof(vis));
    if(dfs(1)<n)
    {
        printf("0\n");
        return 0;
    }
    ll ans=0;
    for(int i=0;i<m;i++)
    {
        int uu=u[i];
        int vv=v[i];
        if(uu==vv)
        {
            ans+=m-1;
            continue;
        }
        ans+=num;
        //if(uu==vv) ans--;
        ans+=g[uu].size()-1;
        //cout<<uu<<" "<<vv<<" "<<ans<<endl;

        ans+=g[vv].size()-1;
        //cout<<uu<<" "<<vv<<" "<<ans<<endl;
    }
    printf("%lld\n",ans/2);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
vector<int> g[N];
int u[N],v[N];
bool vis[N],z[N];
int dfs(int u)
{
    vis[u]=true;
    int ret=1;
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        if(vis[v]) continue;
        ret+=dfs(v);
    }
    return ret;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    memset(z,false,sizeof(z));
    int num=0;
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&u[i],&v[i]);
        if(u[i]==v[i])
        {
            z[u[i]]=true,num++;
            continue;
        }
        g[u[i]].push_back(v[i]);
        g[v[i]].push_back(u[i]);
    }
    memset(vis,false,sizeof(vis));
    if(dfs(1)<n)
    {
        printf("0\n");
        return 0;
    }
    int ans=0;
    for(int i=0;i<m;i++)
    {
        int uu=u[i];
        int vv=v[i];
        if(uu==vv)
        {
            ans+=m-1;
            continue;
        }
        ans+=num;
        //if(uu==vv) ans--;
        ans+=g[uu].size()-1;
        //cout<<uu<<" "<<vv<<" "<<ans<<endl;

        ans+=g[vv].size()-1;
        //cout<<uu<<" "<<vv<<" "<<ans<<endl;
    }
    printf("%d\n",ans/2);
    return 0;
}


#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("O3")
#pragma GCC optimize("fast-math")
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>

#define ff first
#define ss second
#define pb emplace_back
#define all(x) x.begin(),x.end()
#define rall(x) (x).rbegin(),(x).rend()
#define re return
#define mp make_pair
#define sz(x) ((int)(x).size())
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define repx(i, x, n) for(int i = x; i < n; i++)
#define repd(i, x, n, d) for(int i = x; i < n; i += d)
#define rrepx(i, x, n) for(int i = n - 1; i >= x; i--)
#define rrepd(i, x, n, d) for(int i = n - 1; i >= x; i -= d)
#define unq(x); { sort(x.begin(), x.end()); x.resize(unique(x.begin(), x.end()) - x.begin()); }
#define sqr(x) ((x)*(x))

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pdd;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef vector<pll> vll;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vl> vvl;

#define DEBUG 1
//#define FILES 1

#ifdef DEBUG
#define debug(x)   cerr << #x << " " << x << endl;
#define debug_p(x) cerr << #x << " " << x.ff << " " << x.ss << endl;
#define debug_v(x) {cerr << #x << " "; for (auto i : x) cerr << i << " "; cerr << endl;}
#define debug_vp(x) {cerr << #x << " "; for (auto i : x) cerr << '[' << i.ff << " " << i.ss << ']'; cerr << endl;}
#define debug_v_v(x) {cerr << #x << "/*\n"; for (auto i : x) { for (auto i2 : i) cerr << i2 << " "; cerr << '\n';} cerr << "*/" << #x << endl;}
#else
#define debug(x) 0;
#define debug_p(x) 0;
#define debug_v(x) 0;
#define debug_vp(x) 0;
#define debug_v_v(x) 0;
#endif

#ifdef FILES
#define files(in, out); { freopen(in, "r", stdin); freopen(out, "w", stdout);}
#else
#define files(in, out) 0;
#endif

const int INF = 1e9 + 10;
const ll INFll = 2e18;
const int BASE1 = 179;
const int BASE2 = 653;
const ll MOD = 998244353;
const int MAXA = 2000001;
const int MAXN = 2e5 + 1;
const int MAXLOG = 22;
const ll COST = 1000 * 1000 * 1000;
const ld PI = 3.1415926535;
const ld EPS = 1e-15;

void dfs(ll v, vvi& g, vi& used, ll& res, ll& dop) {
    used[v] = true;
    for (auto u : g[v]) {
        if (!used[u])
            dfs(u, g, used, res, dop);
    }
    dop += (ll)sz(g[v]);
    res += (ll)sz(g[v]) * (sz(g[v]) - 1) / 2;
}

void solve() {
    ll n, m;
    cin >> n >> m;
    vvi g(n);
    ll cnt = 0;
    rep(i, m) {
        ll u, v;
        cin >> u >> v;
        u--; v--;
        if (u == v)
            cnt++;
        else {
            g[u].pb(v);
            g[v].pb(u);
        }
    }
    ll res = 0, comp = 0;
    vi used(n, 0);
    rep(v, n) {
        if (!used[v]) {
            ll dop = 0;
            dfs(v, g, used, res, dop);
            if (dop > 0)
                comp++;
        }
    }
    if (comp > 1) {
        cout << "0\n";
        return;
    }
    res += cnt * (m - cnt) + cnt * (cnt - 1) / 2;
    cout << res << "\n";
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int t = 1;
    //cin >> t;
    while (t--)
        solve();
    return 0;
}


#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("O3")
#pragma GCC optimize("fast-math")
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>

#define ff first
#define ss second
#define pb emplace_back
#define all(x) x.begin(),x.end()
#define rall(x) (x).rbegin(),(x).rend()
#define re return
#define mp make_pair
#define sz(x) ((int)(x).size())
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define repx(i, x, n) for(int i = x; i < n; i++)
#define repd(i, x, n, d) for(int i = x; i < n; i += d)
#define rrepx(i, x, n) for(int i = n - 1; i >= x; i--)
#define rrepd(i, x, n, d) for(int i = n - 1; i >= x; i -= d)
#define unq(x); { sort(x.begin(), x.end()); x.resize(unique(x.begin(), x.end()) - x.begin()); }
#define sqr(x) ((x)*(x))

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pdd;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef vector<pll> vll;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vl> vvl;

#define DEBUG 1
//#define FILES 1

#ifdef DEBUG
#define debug(x)   cerr << #x << " " << x << endl;
#define debug_p(x) cerr << #x << " " << x.ff << " " << x.ss << endl;
#define debug_v(x) {cerr << #x << " "; for (auto i : x) cerr << i << " "; cerr << endl;}
#define debug_vp(x) {cerr << #x << " "; for (auto i : x) cerr << '[' << i.ff << " " << i.ss << ']'; cerr << endl;}
#define debug_v_v(x) {cerr << #x << "/*\n"; for (auto i : x) { for (auto i2 : i) cerr << i2 << " "; cerr << '\n';} cerr << "*/" << #x << endl;}
#else
#define debug(x) 0;
#define debug_p(x) 0;
#define debug_v(x) 0;
#define debug_vp(x) 0;
#define debug_v_v(x) 0;
#endif

#ifdef FILES
#define files(in, out); { freopen(in, "r", stdin); freopen(out, "w", stdout);}
#else
#define files(in, out) 0;
#endif

const int INF = 1e9 + 10;
const ll INFll = 2e18;
const int BASE1 = 179;
const int BASE2 = 653;
const ll MOD = 998244353;
const int MAXA = 2000001;
const int MAXN = 2e5 + 1;
const int MAXLOG = 22;
const ll COST = 1000 * 1000 * 1000;
const ld PI = 3.1415926535;
const ld EPS = 1e-15;

void dfs(ll v, vvi& g, vi& used, ll& res, ll& dop) {
    used[v] = true;
    ll cnt = 0;
    for (auto u : g[v]) {
        if (!used[u])
            dfs(u, g, used, res, dop);
        if (u != v)
            cnt++;
    }
    dop += (ll)sz(g[v]);
    res += cnt * (cnt - 1) / 2;
}

void solve() {
    ll n, m;
    cin >> n >> m;
    vvi g(n);
    ll cnt = 0;
    rep(i, m) {
        ll u, v;
        cin >> u >> v;
        u--; v--;
        if (u == v)
            cnt++;
        g[u].pb(v);
        g[v].pb(u);
    }
    ll res = 0, comp = 0;
    vi used(n, 0);
    rep(v, n) {
        if (!used[v]) {
            ll dop = 0;
            dfs(v, g, used, res, dop);
            if (dop > 0)
                comp++;
        }
    }
    if (comp > 1) {
        cout << "0\n";
        return;
    }
    res += cnt * (m - cnt) + cnt * (cnt - 1) / 2;
    cout << res << "\n";
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int t = 1;
    //cin >> t;
    while (t--)
        solve();
    return 0;
}


#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("O3")
#pragma GCC optimize("fast-math")
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>

#define ff first
#define ss second
#define pb emplace_back
#define all(x) x.begin(),x.end()
#define rall(x) (x).rbegin(),(x).rend()
#define re return
#define mp make_pair
#define sz(x) ((int)(x).size())
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define repx(i, x, n) for(int i = x; i < n; i++)
#define repd(i, x, n, d) for(int i = x; i < n; i += d)
#define rrepx(i, x, n) for(int i = n - 1; i >= x; i--)
#define rrepd(i, x, n, d) for(int i = n - 1; i >= x; i -= d)
#define unq(x); { sort(x.begin(), x.end()); x.resize(unique(x.begin(), x.end()) - x.begin()); }
#define sqr(x) ((x)*(x))

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pdd;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef vector<pll> vll;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vl> vvl;

#define DEBUG 1
//#define FILES 1

#ifdef DEBUG
#define debug(x)   cerr << #x << " " << x << endl;
#define debug_p(x) cerr << #x << " " << x.ff << " " << x.ss << endl;
#define debug_v(x) {cerr << #x << " "; for (auto i : x) cerr << i << " "; cerr << endl;}
#define debug_vp(x) {cerr << #x << " "; for (auto i : x) cerr << '[' << i.ff << " " << i.ss << ']'; cerr << endl;}
#define debug_v_v(x) {cerr << #x << "/*\n"; for (auto i : x) { for (auto i2 : i) cerr << i2 << " "; cerr << '\n';} cerr << "*/" << #x << endl;}
#else
#define debug(x) 0;
#define debug_p(x) 0;
#define debug_v(x) 0;
#define debug_vp(x) 0;
#define debug_v_v(x) 0;
#endif

#ifdef FILES
#define files(in, out); { freopen(in, "r", stdin); freopen(out, "w", stdout);}
#else
#define files(in, out) 0;
#endif

const int INF = 1e9 + 10;
const ll INFll = 2e18;
const int BASE1 = 179;
const int BASE2 = 653;
const ll MOD = 998244353;
const int MAXA = 2000001;
const int MAXN = 2e5 + 1;
const int MAXLOG = 22;
const ll COST = 1000 * 1000 * 1000;
const ld PI = 3.1415926535;
const ld EPS = 1e-15;

void dfs(ll v, vvi& g, vi& used, ll& res) {
    used[v] = true;
    for (auto u : g[v]) {
        if (!used[u])
            dfs(u, g, used, res);
    }
    res += sz(g[v]) * (sz(g[v]) - 1) / 2;
}

void solve() {
    ll n, m;
    cin >> n >> m;
    vvi g(n);
    ll cnt = 0;
    rep(i, m) {
        ll u, v;
        cin >> u >> v;
        u--; v--;
        if (u == v)
            cnt++;
        else {
            g[u].pb(v);
            g[v].pb(u);
        }
    }
    ll res = 0;
    vi used(n, 0);
    dfs(0, g, used, res);
    rep(i, n) {
        if (!used[i]) {
            cout << "0\n";
            return;
        }
    }
    res += cnt * (m - cnt);
    cout << res << "\n";
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int t = 1;
    //cin >> t;
    while (t--)
        solve();
    return 0;
}


#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("O3")
#pragma GCC optimize("fast-math")
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>

#define ff first
#define ss second
#define pb emplace_back
#define all(x) x.begin(),x.end()
#define rall(x) (x).rbegin(),(x).rend()
#define re return
#define mp make_pair
#define sz(x) ((int)(x).size())
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define repx(i, x, n) for(int i = x; i < n; i++)
#define repd(i, x, n, d) for(int i = x; i < n; i += d)
#define rrepx(i, x, n) for(int i = n - 1; i >= x; i--)
#define rrepd(i, x, n, d) for(int i = n - 1; i >= x; i -= d)
#define unq(x); { sort(x.begin(), x.end()); x.resize(unique(x.begin(), x.end()) - x.begin()); }
#define sqr(x) ((x)*(x))

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pdd;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef vector<pll> vll;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vl> vvl;

#define DEBUG 1
//#define FILES 1

#ifdef DEBUG
#define debug(x)   cerr << #x << " " << x << endl;
#define debug_p(x) cerr << #x << " " << x.ff << " " << x.ss << endl;
#define debug_v(x) {cerr << #x << " "; for (auto i : x) cerr << i << " "; cerr << endl;}
#define debug_vp(x) {cerr << #x << " "; for (auto i : x) cerr << '[' << i.ff << " " << i.ss << ']'; cerr << endl;}
#define debug_v_v(x) {cerr << #x << "/*\n"; for (auto i : x) { for (auto i2 : i) cerr << i2 << " "; cerr << '\n';} cerr << "*/" << #x << endl;}
#else
#define debug(x) 0;
#define debug_p(x) 0;
#define debug_v(x) 0;
#define debug_vp(x) 0;
#define debug_v_v(x) 0;
#endif

#ifdef FILES
#define files(in, out); { freopen(in, "r", stdin); freopen(out, "w", stdout);}
#else
#define files(in, out) 0;
#endif

const int INF = 1e9 + 10;
const ll INFll = 2e18;
const int BASE1 = 179;
const int BASE2 = 653;
const ll MOD = 998244353;
const int MAXA = 2000001;
const int MAXN = 2e5 + 1;
const int MAXLOG = 22;
const ll COST = 1000 * 1000 * 1000;
const ld PI = 3.1415926535;
const ld EPS = 1e-15;

void dfs(ll v, vvi& g, vi& used, ll& res) {
    used[v] = true;
    for (auto u : g[v]) {
        if (!used[u])
            dfs(u, g, used, res);
    }
    res += (ll)sz(g[v]) * (sz(g[v]) - 1) / 2;
}

void solve() {
    ll n, m;
    cin >> n >> m;
    vvi g(n);
    ll cnt = 0;
    rep(i, m) {
        ll u, v;
        cin >> u >> v;
        u--; v--;
        if (u == v)
            cnt++;
        else {
            g[u].pb(v);
            g[v].pb(u);
        }
    }
    ll res = 0;
    vi used(n, 0);
    dfs(0, g, used, res);
    rep(i, n) {
        if (!used[i]) {
            cout << "0\n";
            return;
        }
    }
    res += cnt * (m - cnt) + cnt * (cnt - 1) / 2;
    cout << res << "\n";
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int t = 1;
    //cin >> t;
    while (t--)
        solve();
    return 0;
}


#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("O3")
#pragma GCC optimize("fast-math")
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>

#define ff first
#define ss second
#define pb emplace_back
#define all(x) x.begin(),x.end()
#define rall(x) (x).rbegin(),(x).rend()
#define re return
#define mp make_pair
#define sz(x) ((int)(x).size())
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define repx(i, x, n) for(int i = x; i < n; i++)
#define repd(i, x, n, d) for(int i = x; i < n; i += d)
#define rrepx(i, x, n) for(int i = n - 1; i >= x; i--)
#define rrepd(i, x, n, d) for(int i = n - 1; i >= x; i -= d)
#define unq(x); { sort(x.begin(), x.end()); x.resize(unique(x.begin(), x.end()) - x.begin()); }
#define sqr(x) ((x)*(x))

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pdd;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef vector<pll> vll;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vl> vvl;

#define DEBUG 1
//#define FILES 1

#ifdef DEBUG
#define debug(x)   cerr << #x << " " << x << endl;
#define debug_p(x) cerr << #x << " " << x.ff << " " << x.ss << endl;
#define debug_v(x) {cerr << #x << " "; for (auto i : x) cerr << i << " "; cerr << endl;}
#define debug_vp(x) {cerr << #x << " "; for (auto i : x) cerr << '[' << i.ff << " " << i.ss << ']'; cerr << endl;}
#define debug_v_v(x) {cerr << #x << "/*\n"; for (auto i : x) { for (auto i2 : i) cerr << i2 << " "; cerr << '\n';} cerr << "*/" << #x << endl;}
#else
#define debug(x) 0;
#define debug_p(x) 0;
#define debug_v(x) 0;
#define debug_vp(x) 0;
#define debug_v_v(x) 0;
#endif

#ifdef FILES
#define files(in, out); { freopen(in, "r", stdin); freopen(out, "w", stdout);}
#else
#define files(in, out) 0;
#endif

const int INF = 1e9 + 10;
const ll INFll = 2e18;
const int BASE1 = 179;
const int BASE2 = 653;
const ll MOD = 998244353;
const int MAXA = 2000001;
const int MAXN = 2e5 + 1;
const int MAXLOG = 22;
const ll COST = 1000 * 1000 * 1000;
const ld PI = 3.1415926535;
const ld EPS = 1e-15;

void dfs(ll v, vvi& g, vi& used, ll& res) {
    used[v] = true;
    for (auto u : g[v]) {
        if (!used[u])
            dfs(u, g, used, res);
    }
    res += sz(g[v]) * (sz(g[v]) - 1) / 2;
}

void solve() {
    ll n, m;
    cin >> n >> m;
    vvi g(n);
    ll cnt = 0;
    rep(i, m) {
        ll u, v;
        cin >> u >> v;
        u--; v--;
        if (u == v)
            cnt++;
        else {
            g[u].pb(v);
            g[v].pb(u);
        }
    }
    ll res = 0;
    vi used(n, 0);
    dfs(0, g, used, res);
    rep(i, n) {
        if (!used[i]) {
            cout << "0\n";
            return;
        }
    }
    res += cnt * (m - cnt) + cnt * (cnt - 1) / 2;
    cout << res << "\n";
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int t = 1;
    //cin >> t;
    while (t--)
        solve();
    return 0;
}


#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("O3")
#pragma GCC optimize("fast-math")
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>

#define ff first
#define ss second
#define pb emplace_back
#define all(x) x.begin(),x.end()
#define rall(x) (x).rbegin(),(x).rend()
#define re return
#define mp make_pair
#define sz(x) ((int)(x).size())
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define repx(i, x, n) for(int i = x; i < n; i++)
#define repd(i, x, n, d) for(int i = x; i < n; i += d)
#define rrepx(i, x, n) for(int i = n - 1; i >= x; i--)
#define rrepd(i, x, n, d) for(int i = n - 1; i >= x; i -= d)
#define unq(x); { sort(x.begin(), x.end()); x.resize(unique(x.begin(), x.end()) - x.begin()); }
#define sqr(x) ((x)*(x))

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pdd;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef vector<pll> vll;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vl> vvl;

#define DEBUG 1
//#define FILES 1

#ifdef DEBUG
#define debug(x)   cerr << #x << " " << x << endl;
#define debug_p(x) cerr << #x << " " << x.ff << " " << x.ss << endl;
#define debug_v(x) {cerr << #x << " "; for (auto i : x) cerr << i << " "; cerr << endl;}
#define debug_vp(x) {cerr << #x << " "; for (auto i : x) cerr << '[' << i.ff << " " << i.ss << ']'; cerr << endl;}
#define debug_v_v(x) {cerr << #x << "/*\n"; for (auto i : x) { for (auto i2 : i) cerr << i2 << " "; cerr << '\n';} cerr << "*/" << #x << endl;}
#else
#define debug(x) 0;
#define debug_p(x) 0;
#define debug_v(x) 0;
#define debug_vp(x) 0;
#define debug_v_v(x) 0;
#endif

#ifdef FILES
#define files(in, out); { freopen(in, "r", stdin); freopen(out, "w", stdout);}
#else
#define files(in, out) 0;
#endif

const int INF = 1e9 + 10;
const ll INFll = 2e18;
const int BASE1 = 179;
const int BASE2 = 653;
const ll MOD = 998244353;
const int MAXA = 2000001;
const int MAXN = 2e5 + 1;
const int MAXLOG = 22;
const ll COST = 1000 * 1000 * 1000;
const ld PI = 3.1415926535;
const ld EPS = 1e-15;

void dfs(ll v, vvi& g, vi& used, ll& res) {
    used[v] = true;
    for (auto u : g[v]) {
        if (!used[u])
            dfs(u, g, used, res);
    }
    res += (ll)sz(g[v]) * (sz(g[v]) - 1) / 2;
}

void solve() {
    ll n, m;
    cin >> n >> m;
    vvi g(n);
    ll cnt = 0;
    rep(i, m) {
        ll u, v;
        cin >> u >> v;
        u--; v--;
        if (u == v)
            cnt++;
        else {
            g[u].pb(v);
            g[v].pb(u);
        }
    }
    ll res = 0;
    vi used(n, 0);
    dfs(0, g, used, res);
    rep(i, n) {
        if (!used[i] && sz(g[i]) != 0) {
            cout << "0\n";
            return;
        }
    }
    res += cnt * (m - cnt) + cnt * (cnt - 1) / 2;
    cout << res << "\n";
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int t = 1;
    //cin >> t;
    while (t--)
        solve();
    return 0;
}


/*The woods are lovely, dark and deep,
But I have promises to keep,
And miles to go before I sleep,
And miles to go before I sleep.*/

//PRABHJOT SINGH A.K.A. PRABHI
//~~~~~conquizztador~~~~~

#include<bits/stdc++.h>
using namespace std;
#define lli long long int
#define pb push_back
#define fi first
#define se second
#define MOD 1000000007
const int maxn= 100010;
vector<int> v[10*maxn];
bool vis[10*maxn];
void dfs(int node)
{
	vis[node]=true;
	for(auto i: v[node])
		if(!vis[i])
			dfs(i);
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n=0,m=0,x=0,y=0;lli res=0ll;
    cin>>n>>m;
    for(int i=0;i<m;++i)
    {
    	cin>>x>>y;
    	--x;--y;
    	v[x].pb(y);
    	if(x!=y)
    		v[y].pb(x);
    }
    dfs(0);
    for(int i=0;i<n;++i)
    {
    	if(!vis[i]&&v[i].size()!=0)
    	{
    		cout<<"0";
    		return 0;
    	}
    }
    for(int i=0;i<n;++i)
    {
    	lli degree=v[i].size();
    	if(degree<2ll)
    		continue;
    	res+=(1ll*degree*(degree-1ll))/2ll;
    }
    cout<<res;
}


/*The woods are lovely, dark and deep,
But I have promises to keep,
And miles to go before I sleep,
And miles to go before I sleep.*/

//PRABHJOT SINGH A.K.A. PRABHI
//~~~~~conquizztador~~~~~

#include<bits/stdc++.h>
using namespace std;
#define lli long long int
#define pb push_back
#define fi first
#define se second
#define MOD 1000000007
const int maxn= 100010;
vector<int> v[10*maxn];
bool vis[10*maxn];
bool aux[10*maxn];
void dfs(int node)
{
	vis[node]=true;
	for(auto i: v[node])
		if(!vis[i])
			dfs(i);
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n=0,m=0,x=0,y=0,ct=0;lli res=0ll;
    cin>>n>>m;
    for(int i=0;i<m;++i)
    {
    	cin>>x>>y;
    	--x;--y;
    	if(x==y)
    	{
    		++ct;
    		aux[x]=true;
    	}
    	else
    	{
    		v[x].pb(y);
    		v[y].pb(x);
    	}
    }
    dfs(0);
    for(int i=0;i<n;++i)
    {
    	if(!vis[i]&&(v[i].size()!=0||aux[i]))
    	{
    		cout<<"0";
    		return 0;
    	}
    }
    for(int i=0;i<n;++i)
    {
    	lli degree=v[i].size();
    	if(degree<2ll)
    		continue;
    	res+=(1ll*degree*(degree-1ll))/2ll;
    }
    res+=1ll*ct*(m-ct)+(1ll*ct*(ct-1))/2;
    cout<<res;
}


/*The woods are lovely, dark and deep,
But I have promises to keep,
And miles to go before I sleep,
And miles to go before I sleep.*/

//PRABHJOT SINGH A.K.A. PRABHI
//~~~~~conquizztador~~~~~

#include<bits/stdc++.h>
using namespace std;
#define lli long long int
#define pb push_back
#define fi first
#define se second
#define MOD 1000000007
const int maxn= 100010;
vector<int> v[10*maxn];
bool vis[10*maxn];
bool aux[10*maxn];
void dfs(int node)
{
	vis[node]=true;
	for(auto i: v[node])
		if(!vis[i])
			dfs(i);
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n=0,m=0,x=0,y=0,ct=0,dfspt=0;lli res=0ll;
    cin>>n>>m;
    for(int i=0;i<m;++i)
    {
    	cin>>x>>y;
    	--x;--y;
    	if(x==y)
    	{
    		++ct;
    		aux[x]=true;
    	}
    	else
    	{
    		v[x].pb(y);
    		v[y].pb(x);
    		dfspt=x;
    	}
    }
    dfs(dfspt);
    for(int i=0;i<n;++i)
    {
    	if(!vis[i]&&(v[i].size()!=0||aux[i]))
    	{
    		cout<<"0";
    		return 0;
    	}
    }
    for(int i=0;i<n;++i)
    {
    	lli degree=v[i].size();
    	if(degree<2ll)
    		continue;
    	res+=(1ll*degree*(degree-1ll))/2ll;
    }
    res+=1ll*ct*(m-ct)+(1ll*ct*(ct-1))/2;
    cout<<res;
}


#include<bits/stdc++.h>
#define REP(i,j,k) for(int i=j;i<k;++i)
#define RREP(i,j,k) for(int i=(int)j-1;i>=k;--i)
#define int long long
#define pb emplace_back
#define P pair<int,int>
#define F first
#define S second
#define ALL(x) x.begin(),x.end()
#define sz(a) (int)(a).size()
#define MX 1000005
#define oo 1e18
#define L d*2
#define R d*2+1
#define mid (l+r>>1)
#define Ls l,mid,d*2
#define Rs mid+1,r,d*2+1
#define MIN(x,y) (x=min(x,(y)))
#define MAX(x,y) (x=max(x,(y)))
#define mo (int)(1e9+7)
#define IOS cin.tie(0) ,cout.tie(0), cout.sync_with_stdio(0)
using namespace std;
int n,m,ans,s[MX],a,b,ok[MX],cnt,f[MX],c[MX];
vector<int> G[MX];
void dfs(int v){
	ok[v] = 1;
	for(auto u:G[v]) if(!ok[u]) dfs(u);
}
main(){
	IOS;
	cin>>n>>m;
	REP(i,0,m){
		cin>>a>>b; c[a] = c[b] = 1;
		if(a!=b) G[a].pb(b),G[b].pb(a),s[a]++,s[b]++;
		else f[a] = 1,cnt++;
	}
	dfs(a);
	REP(i,1,n+1){
		if(!ok[i] && c[i]) return cout<<0,0;
		if(f[i]) ans += m-1;
		ans += s[i]*(s[i]-1)/2;
	}
	cout<<ans-cnt*(cnt-1)/2;
}


#include<bits/stdc++.h>
#define REP(i,j,k) for(int i=j;i<k;++i)
#define RREP(i,j,k) for(int i=(int)j-1;i>=k;--i)
#define int long long
#define pb emplace_back
#define P pair<int,int>
#define F first
#define S second
#define ALL(x) x.begin(),x.end()
#define sz(a) (int)(a).size()
#define MX 1000005
#define oo 1e18
#define L d*2
#define R d*2+1
#define mid (l+r>>1)
#define Ls l,mid,d*2
#define Rs mid+1,r,d*2+1
#define MIN(x,y) (x=min(x,(y)))
#define MAX(x,y) (x=max(x,(y)))
#define mo (int)(1e9+7)
#define IOS cin.tie(0) ,cout.tie(0), cout.sync_with_stdio(0)
using namespace std;
int n,m,ans,s[MX],a,b,ok[MX],cnt,f[MX];
vector<int> G[MX];
void dfs(int v){
	ok[v] = 1;
	for(auto u:G[v]) if(!ok[u]) dfs(u);
}
main(){
	IOS;
	cin>>n>>m;
	REP(i,0,m){
		cin>>a>>b;
		if(a!=b) G[a].pb(b),G[b].pb(a),s[a]++,s[b]++;
		else f[a] = 1,cnt++;
	}
	dfs(1);
	REP(i,1,n+1){
		if(!ok[i]) return cout<<0,0;
		if(f[i]) ans += m-1;
		ans += s[i]*(s[i]-1)/2;
	}
	cout<<ans-cnt*(cnt-1)/2;
}


#include<bits/stdc++.h>
#define REP(i,j,k) for(int i=j;i<k;++i)
#define RREP(i,j,k) for(int i=(int)j-1;i>=k;--i)
#define int long long
#define pb emplace_back
#define P pair<int,int>
#define F first
#define S second
#define ALL(x) x.begin(),x.end()
#define sz(a) (int)(a).size()
#define MX 1000005
#define oo 1e18
#define L d*2
#define R d*2+1
#define mid (l+r>>1)
#define Ls l,mid,d*2
#define Rs mid+1,r,d*2+1
#define MIN(x,y) (x=min(x,(y)))
#define MAX(x,y) (x=max(x,(y)))
#define mo (int)(1e9+7)
#define IOS cin.tie(0) ,cout.tie(0), cout.sync_with_stdio(0)
using namespace std;
int n,m,ans,s[MX],a,b,ok[MX];
vector<int> G[MX];
void dfs(int v){
	ok[v] = 1;
	for(auto u:G[v]) if(!ok[u]) dfs(u);
}
main(){
	IOS;
	cin>>n>>m;
	REP(i,0,m){
		cin>>a>>b,s[a]++;
		if(a!=b) G[a].pb(b),G[b].pb(a),s[b]++;
	}
	dfs(1);
	REP(i,1,n+1)
		if(!ok[i]) return cout<<0,0;
		else ans += s[i]*(s[i]-1)/2;
	cout<<ans;
}


#include<bits/stdc++.h>
using namespace std;
#define maxn 1000008
#define int long long
int de[maxn];
int first[maxn];
int nxt[maxn*2];
int last[maxn];
int to[maxn*2];
int cnt=0;
int zh=0;
bool vis[maxn];
int ttt=0;
void addedge(int a,int b){
    if(!first[a])first[a]=++cnt;
    else nxt[last[a]]=++cnt;
    last[a]=cnt;
    to[cnt]=b;
}
void dfs_lt(int u){
    vis[u]=1;
    ttt++;
    for(int q=first[u];q;q=nxt[q]){
        if(!vis[to[q]]){
            dfs_lt(to[q]);
        }
    }
}
main(){
    int n,m;
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=m;i++){
        int a,b;
        scanf("%lld%lld",&a,&b);
        if(a==b){zh++;continue;}
        addedge(a,b);
        addedge(b,a);
        de[a]++;
        de[b]++;
    }
    int num=0;
    int tar=0;
    for(int i=1;i<=n;i++){
        if(de[i]==0)num++;
        else tar=i;
    }
    dfs_lt(tar);
    if(ttt!=num){
        cout<<"0"<<endl;
    }else{
        for(int i=1;i<=n;i++)de[i]*=2;
        int ans=zh*(zh-1)/2;
        ans+=cnt/2*zh;
        int tot=0;
        for(int i=1;i<=n;i++){
            if(de[i]!=0)ans+=de[i]/2*(de[i]/2-1)/2;
        }
        cout<<ans<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define maxn 1000008
#define int long long
int de[maxn];
int first[maxn];
int nxt[maxn*2];
int last[maxn];
int to[maxn*2];
int cnt=0;
int zh=0;
bool vis[maxn];
bool has_edge[maxn];
int ttt=0;
void addedge(int a,int b){
    if(!first[a])first[a]=++cnt;
    else nxt[last[a]]=++cnt;
    last[a]=cnt;
    to[cnt]=b;
}
void dfs_lt(int u){
    vis[u]=1;
    ttt++;
    for(int q=first[u];q;q=nxt[q]){
        if(!vis[to[q]]){
            dfs_lt(to[q]);
        }
    }
}
main(){
    int n,m;
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=m;i++){
        int a,b;
        scanf("%lld%lld",&a,&b);
        has_edge[a]=has_edge[b]=1;
        if(a==b){zh++;continue;}
        addedge(a,b);
        addedge(b,a);
        de[a]++;
        de[b]++;
    }
    int num=0;
    int tar=0;
    for(int i=1;i<=n;i++){
        if(has_edge[i])num++,tar=i;
    }
    dfs_lt(tar);
    if(ttt!=num){
        cout<<"0"<<endl;
    }else{
        for(int i=1;i<=n;i++)de[i]*=2;
        int ans=zh*(zh-1)/2;
        ans+=cnt/2*zh;
        // cout<<zh<<' '<<cnt/2<<endl;
        int tot=0;
        for(int i=1;i<=n;i++){
            if(de[i]!=0)ans+=de[i]/2*(de[i]/2-1)/2;
        }
        cout<<ans<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define maxn 1000008
#define int long long
int de[maxn];
int first[maxn];
int nxt[maxn*2];
int last[maxn];
int to[maxn*2];
int cnt=0;
int zh=0;
bool vis[maxn];
bool has_edge[maxn];
int ttt=0;
void addedge(int a,int b){
    if(!first[a])first[a]=++cnt;
    else nxt[last[a]]=++cnt;
    last[a]=cnt;
    to[cnt]=b;
}
void dfs_lt(int u){
    vis[u]=1;
    ttt++;
    for(int q=first[u];q;q=nxt[q]){
        if(!vis[to[q]]){
            dfs_lt(to[q]);
        }
    }
}
main(){
    int n,m;
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=m;i++){
        int a,b;
        scanf("%lld%lld",&a,&b);
        has_edge[a]=has_edge[b]=1;
        if(a==b){zh++;continue;}
        addedge(a,b);
        addedge(b,a);
        de[a]++;
        de[b]++;
    }
    int num=0;
    int tar=0;
    for(int i=1;i<=n;i++){
        if(has_edge[i])num++,tar=i;
    }
    dfs_lt(tar);
    if(ttt!=num){
        cout<<"0"<<endl;
    }else{
        for(int i=1;i<=n;i++)de[i]*=2;
        int ans=zh*(zh-1)/2;
        ans+=cnt/2*zh;
        cout<<zh<<' '<<cnt/2<<endl;
        int tot=0;
        for(int i=1;i<=n;i++){
            if(de[i]!=0)ans+=de[i]/2*(de[i]/2-1)/2;
        }
        cout<<ans<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define maxn 1000008
#define int long long
int de[maxn];
int first[maxn];
int nxt[maxn*2];
int last[maxn];
int to[maxn*2];
int cnt=0;
int zh=0;
bool vis[maxn];
int ttt=0;
void addedge(int a,int b){
    if(!first[a])first[a]=++cnt;
    else nxt[last[a]]=++cnt;
    last[a]=cnt;
    to[cnt]=b;
}
void dfs_lt(int u){
    vis[u]=1;
    ttt++;
    for(int q=first[u];q;q=nxt[q]){
        if(!vis[to[q]]){
            dfs_lt(to[q]);
        }
    }
}
main(){
    int n,m;
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=m;i++){
        int a,b;
        scanf("%lld%lld",&a,&b);
        if(a==b){zh++;continue;}
        addedge(a,b);
        addedge(b,a);
        de[a]++;
        de[b]++;
    }
    int num=0;
    int tar=0;
    for(int i=1;i<=n;i++){
        if(de[i]!=0)num++,tar=i;
    }
    dfs_lt(tar);
    if(ttt!=num){
        cout<<"0"<<endl;
    }else{
        for(int i=1;i<=n;i++)de[i]*=2;
        int ans=zh*(zh-1)/2;
        ans+=cnt/2*zh;
        int tot=0;
        for(int i=1;i<=n;i++){
            if(de[i]!=0)ans+=de[i]/2*(de[i]/2-1)/2;
        }
        cout<<ans<<endl;
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e6+10;

vector<int> g[N];

bool was[N];

void dfs(int v) {
	was[v] = 1;
	for(auto i: g[v]) {
		if(!was[i]) dfs(i);
	}
}

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

	int z = m;
	while(m--) {
		int x, y; cin >> x >> y;
		g[x].push_back(y);
		g[y].push_back(x);
	}

	dfs(1);
	bool f = 0;
	for(int i = 1; i <= n; i++) {
		if(!was[i]) {
			f = 1;
			break;
		}
	}
	if(f) {
		cout << 0;
		return 0;
	}

	cout << (long long)z*(z-1)/2;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 1e6+10;

vector<int> g[N];

int was[N], sz[N];

int cnt;
void dfs(int v) {
	was[v] = cnt;
	sz[cnt]++;
	for(auto i: g[v]) {
		if(!was[i]) dfs(i);
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;

	int z = m;
	ll p = 0;
	while(m--) {
		int x, y; cin >> x >> y;
		if(x==y) p++;
		g[x].push_back(y);
		g[y].push_back(x);
	}

	int lol = 0;
	for(int i = 1; i <= n; i++) {
		if(!was[i]) {
			cnt++;
			dfs(i);
			if(sz[i] > 1) lol++;
		}
	}

	if(lol>1) {
		cout << 0;
		return 0;
	}

	ll ans = 0;
	for(int i = 1; i <= n; i++) {
		ll x = g[i].size();
		if(x > 1) {
			ans += x*(x-1)/2;
		}
	}
	ans += p*(p-1);
	ans += p*(z-p);
	cout << ans;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 1e6+10;

vector<int> g[N];

int was[N], sz[N];

int cnt;
void dfs(int v) {
	was[v] = cnt;
	sz[cnt]++;
	for(auto i: g[v]) {
		if(!was[i]) dfs(i);
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;

	int z = m;
	ll p = 0;
	while(m--) {
		int x, y; cin >> x >> y;
		if(x==y) p++;
		g[x].push_back(y);
		g[y].push_back(x);
	}

	int lol = 0;
	for(int i = 1; i <= n; i++) {
		if(!was[i]) {
			cnt++;
			dfs(i);
			if(sz[cnt] > 1) lol++;
		}
	}

	if(lol>1) {
		cout << 0;
		return 0;
	}

	ll ans = 0;
	for(int i = 1; i <= n; i++) {
		ll x = g[i].size();
		if(x > 1) {
			ans += x*(x-1)/2;
		}
	}
	ans += p*(p-1);
	ans += p*(z-p);
	cout << ans;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 1e6+10;

vector<int> g[N];

int was[N], sz[N];

int cnt;
void dfs(int v) {
	was[v] = cnt;
	sz[cnt]++;
	for(auto i: g[v]) {
		if(!was[i]) dfs(i);
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;

	int z = m;
	ll p = 0;
	while(m--) {
		int x, y; cin >> x >> y;
		if(x==y) {
			p++;
			continue;
		}
		g[x].push_back(y);
		g[y].push_back(x);
	}

	int lol = 0;
	for(int i = 1; i <= n; i++) {
		if(!was[i]) {
			cnt++;
			dfs(i);
			if(sz[cnt] > 1) lol++;
		}
	}

	if(lol>1) {
		cout << 0;
		return 0;
	}

	ll ans = 0;
	for(int i = 1; i <= n; i++) {
		ll x = g[i].size();
		if(x > 1) {
			ans += x*(x-1)/2;
		}
	}
	//cout << ans << endl;
	ans += p*(p-1)/2;
	//cout << ans << endl;
	ans += p*(z-p);
	cout << ans;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 1e6+10;

vector<int> g[N];

int was[N], sz[N];
int crcl[N];
int cnt;
void dfs(int v) {
	was[v] = cnt;
	sz[cnt] += ((int)g[v].size() + crcl[v]);
	for(auto i: g[v]) {
		if(!was[i]) dfs(i);
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;

	int z = m;
	ll p = 0;
	while(m--) {
		int x, y; cin >> x >> y;
		if(x==y) {
			p++;
			crcl[x]++;
			continue;
		}
		g[x].push_back(y);
		g[y].push_back(x);
	}

	int lol = 0;
	for(int i = 1; i <= n; i++) {
		if(!was[i]) {
			cnt++;
			dfs(i);
			if(sz[cnt] > 0) lol++;
		}
	}

	if(lol>1) {
		cout << 0;
		return 0;
	}

	ll ans = 0;
	for(int i = 1; i <= n; i++) {
		ll x = g[i].size();
		if(x > 1) {
			ans += x*(x-1)/2;
		}
	}
	//cout << ans << endl;
	ans += p*(p-1)/2;
	//cout << ans << endl;
	ans += p*(z-p);
	cout << ans;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 1e6+10;

vector<int> g[N];

int was[N], sz[N];

int cnt;
void dfs(int v) {
	was[v] = cnt;
	sz[cnt]++;
	for(auto i: g[v]) {
		if(!was[i]) dfs(i);
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;

	int z = m;
	ll p = 0;
	while(m--) {
		int x, y; cin >> x >> y;
		if(x==y) {
			p++;
			continue;
		}
		g[x].push_back(y);
		g[y].push_back(x);
	}

	int lol = 0;
	for(int i = 1; i <= n; i++) {
		if(!was[i]) {
			cnt++;
			dfs(i);
			if(sz[cnt] > 1) lol++;
		}
	}

	if(lol>1) {
		cout << 0;
		return 0;
	}

	ll ans = 0;
	for(int i = 1; i <= n; i++) {
		ll x = g[i].size();
		if(x > 1) {
			ans += x*(x-1)/2;
		}
	}
	//cout << ans << endl;
	ans += p*(p-1);
	//cout << ans << endl;
	ans += p*(z-p);
	cout << ans;
}


//Finite Disappointment and Infinite Hope
#include <bits/stdc++.h>
using namespace std;
#define help ios_base:: sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define dbg(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); \
stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); }
void err(istream_iterator<string> it) { cerr<<endl; }
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
	cerr << *it << " = " << a << "\t"; err(++it, args...);
}
template<typename T1,typename T2>
ostream& operator <<(ostream& c,pair<T1,T2> &v){
	c<<"("<<v.first<<","<<v.second<<")"; return c;
}
template <template <class...> class TT, class ...T>
ostream& operator<<(ostream& out,TT<T...>& c){
    out<<"{ ";
    for(auto &x:c) out<<x<<" ";
    out<<"}"; return out;
}
typedef long long ll;
const ll N=2e5+5,MOD=1e9+7;
vector<ll> adj[N];
bool vis[N];
void dfs(ll u){
    vis[u]=1;
    for(auto &v:adj[u])if(!vis[v])dfs(v);
}
inline ll nc2(ll n){
    return (n*(n-1))/2;
}
int main(){
help
    ll n,m,loops=0;cin>>n>>m;
    for(ll i=0;i<n;i++)vis[i]=1;
    for(ll i=0;i<m;i++){
        ll u,v;cin>>u>>v;
        u-=1;v-=1;
        if(u==v)loops++;
        else adj[u].push_back(v) , adj[v].push_back(u);
        vis[u]=vis[v]=0;
    }
    for(ll i=0;i<n;i++){
        if(!vis[i]){
            dfs(i);
            break;
        }
    }
    for(ll i=0;i<n;i++)if(!vis[i])return cout<<0 , 0;
    ll ans = 0;
    ans = ans + nc2(loops);
    ans = ans + loops*(m-loops);
    for(ll i=0;i<n;i++)ans+=nc2(adj[i].size());
    cout<<ans;
}


//Finite Disappointment and Infinite Hope
#include <bits/stdc++.h>
using namespace std;
#define help ios_base:: sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define dbg(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); \
stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); }
void err(istream_iterator<string> it) { cerr<<endl; }
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
	cerr << *it << " = " << a << "\t"; err(++it, args...);
}
template<typename T1,typename T2>
ostream& operator <<(ostream& c,pair<T1,T2> &v){
	c<<"("<<v.first<<","<<v.second<<")"; return c;
}
template <template <class...> class TT, class ...T>
ostream& operator<<(ostream& out,TT<T...>& c){
    out<<"{ ";
    for(auto &x:c) out<<x<<" ";
    out<<"}"; return out;
}
typedef long long ll;
const ll N=1e6+5,MOD=1e9+7;
vector<int> adj[N];
bool vis[N];
void dfs(int u){
    vis[u]=1;
    for(auto &v:adj[u])if(!vis[v])dfs(v);
}
inline ll nc2(int n){
    return (1ll*n*(n-1))/2;
}
int main(){
help
    int n,m,loops=0;cin>>n>>m;
    for(ll i=0;i<n;i++)vis[i]=1;
    for(ll i=0;i<m;i++){
        int u,v;cin>>u>>v;
        u-=1;v-=1;
        if(u==v)loops++;
        else adj[u].push_back(v) , adj[v].push_back(u);
        vis[u]=vis[v]=0;
    }
    for(int i=0;i<n;i++){
        if(!vis[i]){
            dfs(i);
            break;
        }
    }
    for(int i=0;i<n;i++)if(!vis[i])return cout<<0 , 0;
    ll ans = 0;
    ans = ans + nc2(loops);
    ans = ans + 1ll*loops*(m-loops);
    for(ll i=0;i<n;i++)ans+=nc2(adj[i].size());
    cout<<ans;
}


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

#define pb push_back

const int N = 1e6 +10;
int d[N], n, m, cntlp;
bool loop[N], mark[N];
long long ans;
vector <int> adj[N];

void input() {
	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		if (u == v) {
			loop[u] = true;
			cntlp++;
		}
		else {
			d[u]++, d[v]++;
			adj[u].pb(v);
			adj[v].pb(u);
		}
	}
}

void dfs(int u = 0) {
	mark[u] = true;
	for (auto v: adj[u]) {
		if (!mark[v]) {
			dfs(v);
		}
	}
}

int main() {
	ios:: sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);

	input();

	for (int i = 0; i < n; i++) {
		if (d[i] || loop[i]) {
			dfs(i);
			break;
		}
	}

	for (int i = 0; i < n; i++) {
		if (!mark[i] && (d[i] || loop[i])) {
			cout << 0;
			return 0;
		}
		if (d[i] > 1) {
			ans += 1LL * d[i] * (d[i] - 1) / 2;
		}
		if (loop[i]) {
			ans += m - cntlp;
		}
	}

	if (cntlp > 1) {
		ans += 1LL * cntlp * (cntlp - 1) / 2;
	}

	cout << ans;

	return 0;
}


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

#define pb push_back

const int N = 1e6 +10;
int d[N], n, m, cntlp;
bool loop[N], mark[N];
long long ans;
vector <int> adj[N];

void input() {
	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		if (u == v) {
			loop[u] = true;
			cntlp++;
		}
		else {
			d[u]++, d[v]++;
			adj[u].pb(v);
			adj[v].pb(u);
		}
	}
}

void dfs(int u = 0) {
	mark[u] = true;
	for (auto v: adj[u]) {
		if (!mark[v]) {
			dfs(v);
		}
	}
}

int main() {
	ios:: sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);

	input();

	for (int i = 0; i < n; i++) {
		if (d[i] || loop[i]) {
			dfs(i);
			break;
		}
	}

	for (int i = 0; i < n; i++) {
		if (!mark[i] && (d[i] || loop[i])) {
			cout << 0;
			return 0;
		}
		if (d[i] > 1) {
			ans += 1LL * d[i] * (d[i] - 1) / 2;
		}
		if (loop[i]) {
			ans += m - cntlp;
		}
	}

	if (cntlp > 1) {
		ans += cntlp * (cntlp - 1) / 2;
	}

	cout << ans;

	return 0;
}


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

#define pb push_back

const int N = 1e6 +10;
int d[N], n, m, cntlp;
bool loop[N], mark[N];
long long ans;
vector <int> adj[N];

void input() {
	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		if (u == v) {
			loop[u] = true;
			cntlp++;
		}
		else {
			d[u]++, d[v]++;
			adj[u].pb(v);
			adj[v].pb(u);
		}
	}
}

void dfs(int u = 0) {
	mark[u] = true;
	for (auto v: adj[u]) {
		if (!mark[v]) {
			dfs(v);
		}
	}
}

int main() {
	ios:: sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);

	input();
	dfs();
	for (int i = 0; i < n; i++) {
		if (!mark[i]) {
			cout << 0;
			return 0;
		}
		if (d[i] > 1) {
			ans += 1LL * d[i] * (d[i] - 1) / 2;
		}
		if (loop[i]) {
			ans += m - cntlp;
		}
	}

	if (cntlp > 1) {
		ans += cntlp * (cntlp - 1) / 2;
	}

	cout << ans;

	return 0;
}


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

#define pb push_back

const int N = 1e6 +10;
int d[N], n, m;
bool loop[N], mark[N];
long long ans;
vector <int> adj[N];

void input() {
	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		if (u == v) {
			loop[u] = true;
		}
		else {
			d[u]++, d[v]++;
			adj[u].pb(v);
			adj[v].pb(u);
		}
	}
}

void dfs(int u = 0) {
	mark[u] = true;
	for (auto v: adj[u]) {
		if (!mark[v]) {
			dfs(v);
		}
	}
}

int main() {
	ios:: sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);

	input();
	dfs();
	for (int i = 0; i < n; i++) {
		if (!mark[i]) {
			cout << 0;
			return 0;
		}
		if (d[i] > 1) {
			ans += 1LL * d[i] * (d[i] - 1) / 2;
		}
		if (loop[i]) {
			ans += d[i];
		}
	}

	cout << ans;

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define finish(x) return cout << x << endl, 0
#define ll long long

const int N = 1000001;

struct uni{
    int par[N], sz[N];
    void resize(int n){
        for(int i = 0 ; i < n ; i++)
            par[i] = i, sz[i] = 1;
    }
    void merge(int a, int b){
        a = find(a);
        b = find(b);
        if(a == b) return;
        if(sz[b] > sz[a]) swap(a, b);
        sz[a] += sz[b];
        par[b] = a;
    }
    int find(int a){
        while(par[a] != a) a = par[a];
        return a;
    }
};

int n, m, deg[N];
uni dsu;

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> m;
    dsu.resize(n + 1);
    for(int i = 0 ; i < m ; i++){
        int x, y;
        cin >> x >> y;
        dsu.merge(x, y);
        deg[x]++;
        if(x != y) deg[y]++;
    }
    if(dsu.sz[dsu.find(1)] != n) finish(0);
    ll ans = 0;
    for(int i = 1 ; i <= n ; i++)
        ans += 1LL * deg[i] * (deg[i] - 1);
    cout << ans / 2 << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define finish(x) return cout << x << endl, 0
#define ll long long

const int N = 1000001;

struct uni{
    int par[N], sz[N];
    void resize(int n){
        for(int i = 0 ; i < n ; i++)
            par[i] = i, sz[i] = 1;
    }
    void merge(int a, int b){
        a = find(a);
        b = find(b);
        if(a == b) return;
        if(sz[b] > sz[a]) swap(a, b);
        sz[a] += sz[b];
        par[b] = a;
    }
    int find(int a){
        while(par[a] != a) a = par[a];
        return a;
    }
};

int n, m, deg[N];
uni dsu;

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> m;
    dsu.resize(n + 1);
    int loops = 0;
    for(int i = 0 ; i < m ; i++){
        int x, y;
        cin >> x >> y;
        if(x == y){
            loops++;
            continue;
        }
        dsu.merge(x, y);
        deg[x]++;
        deg[y]++;
    }
    if(dsu.sz[dsu.find(1)] != n) finish(0);
    ll ans = 0;
    for(int i = 1 ; i <= n ; i++)
        ans += 1LL * deg[i] * (deg[i] - 1) / 2;
    ans += 1LL * loops * (loops - 1) / 2;
    ans += 1LL * loops * (m - loops);
    cout << ans << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define finish(x) return cout << x << endl, 0
#define ll long long

const int N = 1000001;

struct uni{
    int par[N], sz[N];
    void resize(int n){
        for(int i = 0 ; i < n ; i++)
            par[i] = i, sz[i] = 1;
    }
    void merge(int a, int b){
        a = find(a);
        b = find(b);
        if(a == b) return;
        if(sz[b] > sz[a]) swap(a, b);
        sz[a] += sz[b];
        par[b] = a;
    }
    int find(int a){
        while(par[a] != a) a = par[a];
        return a;
    }
};

int n, m, deg[N];
uni dsu;

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> m;
    dsu.resize(n + 1);
    int loops = 0;
    for(int i = 0 ; i < m ; i++){
        int x, y;
        cin >> x >> y;
        if(x == y){
            loops++;
            continue;
        }
        dsu.merge(x, y);
        deg[x]++;
        deg[y]++;
    }
    int nonodes = 0;
    for(int i = 1 ; i <= n ; i++)
        nonodes += deg[i] != 0;
    bool zero = 0;
    for(int i = 1 ; i <= n ; i++)
        zero |= dsu.sz[dsu.find(i)] == nonodes;
    if(zero == 0) finish(0);
    ll ans = 0;
    for(int i = 1 ; i <= n ; i++)
        ans += 1LL * deg[i] * (deg[i] - 1) / 2;
    ans += 1LL * loops * (loops - 1) / 2;
    ans += 1LL * loops * (m - loops);
    cout << ans << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define finish(x) return cout << x << endl, 0
#define ll long long

const int N = 1000001;

struct uni{
    int par[N], sz[N];
    void resize(int n){
        for(int i = 0 ; i < n ; i++)
            par[i] = i, sz[i] = 1;
    }
    void merge(int a, int b){
        a = find(a);
        b = find(b);
        if(a == b) return;
        if(sz[b] > sz[a]) swap(a, b);
        sz[a] += sz[b];
        par[b] = a;
    }
    int find(int a){
        while(par[a] != a) a = par[a];
        return a;
    }
};

int n, m;
vector <pair <int, int> > v[N];
uni dsu;

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> m;
    dsu.resize(n + 1);
    for(int i = 0 ; i < m ; i++){
        int x, y;
        cin >> x >> y;
        v[x].push_back(make_pair(y, i));
        if(x != y) v[y].push_back(make_pair(x, i));
    }
    ll ans = 0;
    for(int i = 1 ; i <= n ; i++){
        map <int, int> mp;
        int sum = 0;
        for(auto &j : v[i]){
            mp[dsu.find(j.second)]++;
            sum++;
        }
        for(auto &j : mp)
            ans += 1LL * j.second * (sum - j.second);
        for(int j = 1 ; j < (int)v[i].size() ; j++)
            dsu.merge(v[i][j].second, v[i][j - 1].second);
    }
    if(dsu.sz[dsu.find(0)] != m) ans = 0;
    cout << ans / 2 << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define finish(x) return cout << x << endl, 0
#define ll long long

const int N = 1000001;

struct uni{
    int par[N], sz[N];
    void resize(int n){
        for(int i = 0 ; i < n ; i++)
            par[i] = i, sz[i] = 1;
    }
    void merge(int a, int b){
        a = find(a);
        b = find(b);
        if(a == b) return;
        if(sz[b] > sz[a]) swap(a, b);
        sz[a] += sz[b];
        par[b] = a;
    }
    int find(int a){
        while(par[a] != a) a = par[a];
        return a;
    }
};

int n, m, deg[N];
bool loop[N];
uni dsu;

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> m;
    dsu.resize(n + 1);
    int loops = 0;
    for(int i = 0 ; i < m ; i++){
        int x, y;
        cin >> x >> y;
        if(x == y){
            loops++;
            loop[x] = 1;
            continue;
        }
        dsu.merge(x, y);
        deg[x]++;
        deg[y]++;
    }
    for(int i = 1 ; i <= n ; i++)
        if(n > 1 && deg[i] == 0 && loop[i])
            finish(0);
    int nonodes = 0;
    for(int i = 1 ; i <= n ; i++)
        nonodes += deg[i] != 0;
    bool zero = 0;
    for(int i = 1 ; i <= n ; i++)
        zero |= dsu.sz[dsu.find(i)] == nonodes;
    if(zero == 0) finish(0);
    ll ans = 0;
    for(int i = 1 ; i <= n ; i++)
        ans += 1LL * deg[i] * (deg[i] - 1) / 2;
    ans += 1LL * loops * (loops - 1) / 2;
    ans += 1LL * loops * (m - loops);
    cout << ans << endl;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>
#include <stdio.h>
#include <math.h>

using namespace std;
long long coun[10000];
long long arr[10000];
int full = 0;
vector<long long> graph[10000];
bool binSearch(long long beg, long long end, long long num){
	if (beg == end){
		if (coun[beg] == num)return true;
		else return false;
	}
	if (binSearch(beg, (beg + end) / 2, num))return true;
	else if (binSearch((beg + end) / 2+1,end, num))return true;
	else return false;
}
void dps(int x){
	arr[x] = 1;
	full++;
	for each (long long y in graph[x])
	{
		if (arr[y] == 0)dps(y);
	}
	return;
}
int main(){
	long long n, m;
	long long ans=0;
	cin >> n>>m;
	for (int i = 0; i < n; i++){
		coun[i] = 0;
		arr[i] = 0;
	}
	for (int i = 0; i < m; i++){
		int a, b;
		cin >>a >> b;
		if (a == b){
			coun[a - 1]++;
			graph[a - 1].push_back(b - 1);
		}
		else{
			coun[a - 1]++;
			coun[b - 1]++;
			graph[a - 1].push_back(b - 1);
			graph[b - 1].push_back(a - 1);
		}
	}
	dps(0);
	if (full!=n){
		cout << 0;
		return 0;
	}
	for (int i = 0; i < n; i++){
		ans += coun[i]*(coun[i]-1) / 2;
	}

	cout << ans;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>
#include <stdio.h>
#include <math.h>

using namespace std;
int coun[1000090];
int pet[1000090];
int arr[1000090];
int full = 0;
vector<int> graph[1000090];
bool binSearch(int beg, int end, int num){
	if (beg == end){
		if (coun[beg] == num)return true;
		else return false;
	}
	if (binSearch(beg, (beg + end) / 2, num))return true;
	else if (binSearch((beg + end) / 2+1,end, num))return true;
	else return false;
}
void dps(int x){
	arr[x] = 1;
	full++;
	for (int i = 0; i < graph[x].size(); i++)
	//for each (int y in graph[x])
	{
		if (arr[graph[x][i]] == 0)dps(graph[x][i]);
	}
	return;
}
int main(){
	int n, m;
	int ans=0;
	cin >> n>>m;
	if (m == 1||n==1){
		cout << 0;
		return 0;
	}
	for (int i = 0; i < n; i++){
		coun[i] = 0;
		arr[i] = 0;
	}
	int a, b;
	for (int i = 0; i < m; i++){
		cin >>a >> b;
		if (a == b){
			pet[a - 1]++;
			graph[a - 1].push_back(b - 1);
		}
		else{
			coun[a - 1]++;
			coun[b - 1]++;
			graph[a - 1].push_back(b - 1);
			graph[b - 1].push_back(a - 1);
		}
	}
	int num = 0;
	int sumpet = 0;
	for (int i = 0; i < n; i++){
		if (graph[i].size()>0)num++;
	}
	dps(a-1);
	if (full!=num){
		cout << 0;
		return 0;
	}
	for (int i = 0; i < n; i++){
		sumpet += pet[i];
	}
	for (int i = 0; i < n; i++){
		if(coun[i]!=0)ans += coun[i]*(coun[i]-1) / 2;
	}
	ans += sumpet*(m - sumpet) + sumpet*(sumpet - 1) / 2;

	cout << ans;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>
#include <stdio.h>
#include <math.h>

using namespace std;
int coun[1000000];
int pet[1000000];
int arr[1000000];
int full = 0;
vector<int> graph[1000000];
bool binSearch(int beg, int end, int num){
	if (beg == end){
		if (coun[beg] == num)return true;
		else return false;
	}
	if (binSearch(beg, (beg + end) / 2, num))return true;
	else if (binSearch((beg + end) / 2+1,end, num))return true;
	else return false;
}
void dps(int x){
	arr[x] = 1;
	full++;
	for (int i = 0; i < graph[x].size(); i++)
	//for each (int y in graph[x])
	{
		if (arr[graph[x][i]] == 0)dps(graph[x][i]);
	}
	return;
}
int main(){
	int n, m;
	long long ans=0;
	cin >> n>>m;
	if (m == 1||n==1){
		cout << 0;
		return 0;
	}
	for (int i = 0; i < n; i++){
		coun[i] = 0;
		arr[i] = 0;
	}
	int a, b;
	for (int i = 0; i < m; i++){
		cin >>a >> b;
		if (a == b){
			pet[a - 1]++;
			graph[a - 1].push_back(b - 1);
		}
		else{
			coun[a - 1]++;
			coun[b - 1]++;
			graph[a - 1].push_back(b - 1);
			graph[b - 1].push_back(a - 1);
		}
	}
	int num = 0;
	int sumpet = 0;
	for (int i = 0; i < n; i++){
		if (graph[i].size()>0)num++;
	}
	dps(a-1);
	if (full!=num){
		cout << 0;
		return 0;
	}
	for (int i = 0; i < n; i++){
		sumpet += pet[i];
	}
	for (int i = 0; i < n; i++){
		if (coun[i] != 0)ans += (long long)coun[i] * ((long long)coun[i] - 1) / 2;
	}
	ans += (long long)sumpet*(long long)(m - sumpet) + (long long)sumpet*((long long)sumpet - 1) / 2;

	cout << ans;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>
#include <stdio.h>
#include <math.h>

using namespace std;
long long coun[100000];
long long arr[100000];
int full = 0;
vector<long long> graph[100000];
bool binSearch(long long beg, long long end, long long num){
	if (beg == end){
		if (coun[beg] == num)return true;
		else return false;
	}
	if (binSearch(beg, (beg + end) / 2, num))return true;
	else if (binSearch((beg + end) / 2+1,end, num))return true;
	else return false;
}
void dps(int x){
	arr[x] = 1;
	full++;
	for each (long long y in graph[x])
	{
		if (arr[y] == 0)dps(y);
	}
	return;
}
int main(){
	long long n, m;
	long long ans=0;
	cin >> n>>m;
	if (m == 1){
		cout << 1;
		return 0;
	}
	for (int i = 0; i < n; i++){
		coun[i] = 0;
		arr[i] = 0;
	}
		int a, b;
	for (int i = 0; i < m; i++){
		cin >>a >> b;
		if (a == b){
			coun[a - 1]++;
			graph[a - 1].push_back(b - 1);
		}
		else{
			coun[a - 1]++;
			coun[b - 1]++;
			graph[a - 1].push_back(b - 1);
			graph[b - 1].push_back(a - 1);
		}
	}
	int num = 0;
	for (int i = 0; i < n; i++){
		if (graph[i].size()>0)num++;
	}
	dps(a-1);
	if (full!=num){
		cout << 0;
		return 0;
	}
	for (int i = 0; i < n; i++){
		if(coun[i]!=0)ans += coun[i]*(coun[i]-1) / 2;
	}

	cout << ans;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>
#include <stdio.h>
#include <math.h>

using namespace std;
long long coun[1000009];
long long pet[1000009];
long long arr[1000009];
int full = 0;
vector<long long> graph[1000009];
bool binSearch(long long beg, long long end, long long num){
	if (beg == end){
		if (coun[beg] == num)return true;
		else return false;
	}
	if (binSearch(beg, (beg + end) / 2, num))return true;
	else if (binSearch((beg + end) / 2+1,end, num))return true;
	else return false;
}
void dps(int x){
	arr[x] = 1;
	full++;
	for (int i = 0; i < graph[x].size(); i++)
	//for each (long long y in graph[x])
	{
		if (arr[graph[x][i]] == 0)dps(graph[x][i]);
	}
	return;
}
int main(){
	long long n, m;
	long long ans=0;
	cin >> n>>m;
	if (m == 1||n==1){
		cout << 0;
		return 0;
	}
	for (int i = 0; i < n; i++){
		coun[i] = 0;
		arr[i] = 0;
	}
	long long a, b;
	for (int i = 0; i < m; i++){
		cin >>a >> b;
		if (a == b){
			pet[a - 1]++;
			graph[a - 1].push_back(b - 1);
		}
		else{
			coun[a - 1]++;
			coun[b - 1]++;
			graph[a - 1].push_back(b - 1);
			graph[b - 1].push_back(a - 1);
		}
	}
	long long num = 0;
	long long sumpet = 0;
	for (int i = 0; i < n; i++){
		if (graph[i].size()>0)num++;
	}
	dps(a-1);
	if (full!=num){
		cout << 0;
		return 0;
	}
	for (int i = 0; i < n; i++){
		sumpet += pet[i];
	}
	for (int i = 0; i < n; i++){
		if(coun[i]!=0)ans += coun[i]*(coun[i]-1) / 2;
	}
	ans += sumpet*(m - sumpet) + sumpet*(sumpet - 1) / 2;

	cout << ans;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>
#include <stdio.h>
#include <math.h>

using namespace std;
long long coun[1000005];
long long pet[1000050];
long long arr[1000005];
int full = 0;
vector<long long> graph[1000005];
bool binSearch(long long beg, long long end, long long num){
	if (beg == end){
		if (coun[beg] == num)return true;
		else return false;
	}
	if (binSearch(beg, (beg + end) / 2, num))return true;
	else if (binSearch((beg + end) / 2+1,end, num))return true;
	else return false;
}
void dps(int x){
	arr[x] = 1;
	full++;
	for each (long long y in graph[x])
	{
		if (arr[y] == 0)dps(y);
	}
	return;
}
int main(){
	long long n, m;
	long long ans=0;
	cin >> n>>m;
	if (m == 1||n==1){
		cout << 0;
		return 0;
	}
	for (int i = 0; i < n; i++){
		coun[i] = 0;
		arr[i] = 0;
	}
	long long a, b;
	for (int i = 0; i < m; i++){
		cin >>a >> b;
		if (a == b){
			pet[a - 1]++;
			graph[a - 1].push_back(b - 1);
		}
		else{
			coun[a - 1]++;
			coun[b - 1]++;
			graph[a - 1].push_back(b - 1);
			graph[b - 1].push_back(a - 1);
		}
	}
	long long num = 0;
	long long sumpet = 0;
	for (int i = 0; i < n; i++){
		if (graph[i].size()>0)num++;
	}
	dps(a-1);
	if (full!=num){
		cout << 0;
		return 0;
	}
	for (int i = 0; i < n; i++){
		sumpet += pet[i];
	}
	for (int i = 0; i < n; i++){
		if(coun[i]!=0)ans += coun[i]*(coun[i]-1) / 2;
	}
	ans += sumpet*(m - sumpet) + sumpet*(sumpet - 1) / 2;

	cout << ans;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>
#include <stdio.h>
#include <math.h>

using namespace std;
int coun[1000090];
int pet[1000090];
int arr[1000090];
int full = 0;
vector<int> graph[1000090];
bool binSearch(int beg, int end, int num){
	if (beg == end){
		if (coun[beg] == num)return true;
		else return false;
	}
	if (binSearch(beg, (beg + end) / 2, num))return true;
	else if (binSearch((beg + end) / 2+1,end, num))return true;
	else return false;
}
void dps(int x){
	arr[x] = 1;
	full++;
	for (int i = 0; i < graph[x].size(); i++)
	//for each (int y in graph[x])
	{
		if (arr[graph[x][i]] == 0)dps(graph[x][i]);
	}
	return;
}
int main(){
	int n, m;
	long long ans=0;
	cin >> n>>m;
	if (m == 1||n==1){
		cout << 0;
		return 0;
	}
	for (int i = 0; i < n; i++){
		coun[i] = 0;
		arr[i] = 0;
	}
	int a, b;
	for (int i = 0; i < m; i++){
		cin >>a >> b;
		if (a == b){
			pet[a - 1]++;
			graph[a - 1].push_back(b - 1);
		}
		else{
			coun[a - 1]++;
			coun[b - 1]++;
			graph[a - 1].push_back(b - 1);
			graph[b - 1].push_back(a - 1);
		}
	}
	int num = 0;
	long long sumpet = 0;
	for (int i = 0; i < n; i++){
		if (graph[i].size()>0)num++;
	}
	dps(a-1);
	if (full!=num){
		cout << 0;
		return 0;
	}
	for (int i = 0; i < n; i++){
		sumpet += pet[i];
	}
	for (int i = 0; i < n; i++){
		if(coun[i]!=0)ans += coun[i]*(coun[i]-1) / 2;
	}
	ans += sumpet*(m - sumpet) + sumpet*(sumpet - 1) / 2;

	cout << ans;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>
#include <stdio.h>
#include <math.h>

using namespace std;
int coun[1000000];
bool arr[1000000];
int full = 0;
vector<int> graph[1000000];
//bool binSearch(int beg, int end, int num){
//	if (beg == end){
//		if (coun[beg] == num)return true;
//		else return false;
//	}
//	if (binSearch(beg, (beg + end) / 2, num))return true;
//	else if (binSearch((beg + end) / 2+1,end, num))return true;
//	else return false;
//}
void dps(int x){
	arr[x] = false;
	full++;
	for (int i = 0; i < graph[x].size(); i++)
	//for each (int y in graph[x])
	{
		if (arr[graph[x][i]])dps(graph[x][i]);
	}
	return;
}
int main(){
	int n, m;
	long long ans=0;
	cin >> n>>m;
	if (m == 1||n==1){
		cout << 0;
		return 0;
	}
	for (int i = 0; i < n; i++){
		coun[i] = 0;
		arr[i] = true;
	}
	int a, b;
	int num = 0;
	int sumpet = 0;
	for (int i = 0; i < m; i++){
		cin >>a >> b;
		if (a == b){
			sumpet++;
			graph[a - 1].push_back(b - 1);
		}
		else{
			coun[a - 1]++;
			coun[b - 1]++;
			graph[a - 1].push_back(b - 1);
			graph[b - 1].push_back(a - 1);
		}
	}
	for (int i = 0; i < n; i++){
		if (graph[i].size()>0)num++;
	}
	dps(a-1);
	if (full!=num){
		cout << 0;
		return 0;
	}\
	for (int i = 0; i < n; i++){
		if (coun[i] >1)ans += (long long)coun[i] * ((long long)coun[i] - 1) / 2;
	}
	ans += (long long)sumpet*(long long)(m - sumpet) + (long long)sumpet*((long long)sumpet - 1) / 2;

	cout << ans;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>
#include <stdio.h>
#include <math.h>

using namespace std;
long long coun[100000];
long long pet[100000];
long long arr[100000];
int full = 0;
vector<long long> graph[100000];
bool binSearch(long long beg, long long end, long long num){
	if (beg == end){
		if (coun[beg] == num)return true;
		else return false;
	}
	if (binSearch(beg, (beg + end) / 2, num))return true;
	else if (binSearch((beg + end) / 2+1,end, num))return true;
	else return false;
}
void dps(int x){
	arr[x] = 1;
	full++;
	for each (long long y in graph[x])
	{
		if (arr[y] == 0)dps(y);
	}
	return;
}
int main(){
	long long n, m;
	long long ans=0;
	cin >> n>>m;
	if (m == 1||n==1){
		cout << 0;
		return 0;
	}
	for (int i = 0; i < n; i++){
		coun[i] = 0;
		arr[i] = 0;
	}
	long long a, b;
	for (int i = 0; i < m; i++){
		cin >>a >> b;
		if (a == b){
			pet[a - 1]++;
			graph[a - 1].push_back(b - 1);
		}
		else{
			coun[a - 1]++;
			coun[b - 1]++;
			graph[a - 1].push_back(b - 1);
			graph[b - 1].push_back(a - 1);
		}
	}
	long long num = 0;
	long long sumpet = 0;
	for (int i = 0; i < n; i++){
		if (graph[i].size()>0)num++;
	}
	dps(a-1);
	if (full!=num){
		cout << 0;
		return 0;
	}
	for (int i = 0; i < n; i++){
		sumpet += pet[i];
	}
	for (int i = 0; i < n; i++){
		if(coun[i]!=0)ans += coun[i]*(coun[i]-1) / 2;
	}
	ans += sumpet*(m - sumpet) + sumpet*(sumpet - 1) / 2;

	cout << ans;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>
#include <stdio.h>
#include <math.h>

using namespace std;
long long coun[1000000];
long long arr[1000000];
int full = 0;
vector<long long> graph[1000000];
bool binSearch(long long beg, long long end, long long num){
	if (beg == end){
		if (coun[beg] == num)return true;
		else return false;
	}
	if (binSearch(beg, (beg + end) / 2, num))return true;
	else if (binSearch((beg + end) / 2+1,end, num))return true;
	else return false;
}
void dps(int x){
	arr[x] = 1;
	full++;
	for each (long long y in graph[x])
	{
		if (arr[y] == 0)dps(y);
	}
	return;
}
int main(){
	long long n, m;
	long long ans=0;
	cin >> n>>m;
	for (int i = 0; i < n; i++){
		coun[i] = 0;
		arr[i] = 0;
	}
		int a, b;
	for (int i = 0; i < m; i++){
		cin >>a >> b;
		if (a == b){
			coun[a - 1]++;
			graph[a - 1].push_back(b - 1);
		}
		else{
			coun[a - 1]++;
			coun[b - 1]++;
			graph[a - 1].push_back(b - 1);
			graph[b - 1].push_back(a - 1);
		}
	}
	int num = 0;
	for (int i = 0; i < n; i++){
		if (graph[i].size()>0)num++;
	}
	dps(a-1);
	if (full!=num){
		cout << 0;
		return 0;
	}
	for (int i = 0; i < n; i++){
		ans += coun[i]*(coun[i]-1) / 2;
	}

	cout << ans;
	return 0;
}