#include <bits/stdc++.h>
using namespace std;
struct node {
  int to;
  node(int to) : to(to){};
};
struct Euv {
  int u;
  int v;
  Euv(int u, int v) : u(u), v(v){};
};
const int MAXN = 1e6 + 100;
int inputedmin = MAXN;
long long int n, m;
long long int cnt_selfr;
long long int cnt = 0;
bool inputed[MAXN];
bool vis[MAXN];
vector<node> G[MAXN];
queue<Euv> Q;
inline void InitG(void) {
  for (int i = 0; i < MAXN; i++) {
    G[i].clear();
  }
};
inline void add(int u, int v) {
  G[u].push_back(node(v));
  G[v].push_back(node(u));
};
void dfs(int u);
bool connected(long long int n);
int main(int argc, const char* argv[]) {
  scanf("%lld %lld", &n, &m);
  InitG();
  memset(inputed, false, sizeof(inputed));
  for (long long int i = 1; i <= m; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    Q.push(Euv(u, v));
    inputedmin = min(inputedmin, min(u, v));
    inputed[u] = true;
    inputed[v] = true;
    if (u == v) {
      cnt_selfr++;
    } else {
      add(u, v);
    }
  }
  memset(vis, false, sizeof(vis));
  dfs(inputedmin);
  if (connected(n)) {
    while (!Q.empty()) {
      Euv E = Q.front();
      Q.pop();
      if (E.u == E.v) {
        cnt += m - 1;
      } else {
        long long int N = (long long int)G[E.u].size() +
                          (long long int)G[E.v].size() - 2 + cnt_selfr;
        cnt += N;
      }
    }
    printf("%lld\n", cnt / 2);
  } else {
    printf("0\n");
  }
  return 0;
}
void dfs(int u) {
  vis[u] = true;
  for (auto v : G[u]) {
    if (!vis[v.to]) {
      dfs(v.to);
    }
  }
}
bool connected(long long int n) {
  for (long long int i = 1; i <= n; i++) {
    if (inputed[i]) {
      if (!vis[i]) {
        return false;
      }
    }
  }
  return true;
}
