#include <bits/stdc++.h>
using namespace std;
using LL = long long;
constexpr int MAX_V = 1000100;
vector<int> G[MAX_V];
struct UnionFind {
  vector<int> par;
  vector<int> sizes;
  UnionFind(int n) : par(n), sizes(n, 1) {
    for (int i = 0; i < n; i++) {
      par[i] = i;
    }
  }
  int find(int x) { return x == par[x] ? x : par[x] = find(par[x]); }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (sizes[x] < sizes[y]) swap(x, y);
    par[y] = x;
    sizes[x] += sizes[y];
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int get_size(int x) { return sizes[find(x)]; }
  bool all_same() {
    bool good = true;
    for (int i = 0, n = par.size(); i < n; i++)
      if (find(0) != find(i)) good = false;
    return good;
  }
  int get_connectivity() {
    set<int> s;
    for (int i = 0, n = par.size(); i < n; i++) s.insert(find(i));
    return s.size();
  }
};
int main() {
  int n, m;
  cin >> n >> m;
  vector<int> a(m), b(m);
  for (int i = 0; i < m; i++) {
    scanf("%d %d", &a[i], &b[i]);
    a[i]--;
    b[i]--;
  }
  vector<int> loops;
  UnionFind UF(n);
  for (int i = 0; i < m; i++) {
    UF.unite(a[i], b[i]);
    if (a[i] == b[i]) {
      loops.push_back(a[i]);
    } else {
      G[a[i]].push_back(b[i]);
      G[b[i]].push_back(a[i]);
    }
  }
  set<int> S;
  for (int i = 0; i < m; i++) S.insert(UF.find(a[i]));
  if (S.size() > 1) {
    cout << 0;
    return 0;
  }
  LL ans = 0;
  for (int i = 0; i < n; i++) {
    LL d = G[i].size();
    ans += d * (d - 1) / 2;
  }
  LL sz = loops.size();
  ans += sz * (m - sz);
  ans += sz * (sz - 1) / 2;
  cout << ans;
  return 0;
}
