100 10
87 73
15 71
14 33
1 4
20 80
65 67
36 36
25 4
22 21
7 97
 4 2
3 3
3 4
 5 4
3 3
4 4
5 5
1 2
 4 4
1 2
2 3
3 1
4 4
 4 3
1 1
2 3
3 4
 1000000 1
255765 255765
 4 3
1 2
2 3
4 4
 4 2
1 1
1 2
 3 3
1 1
2 2
3 3
 5 4
1 1
2 3
2 4
2 5
 4 5
1 4
3 4
1 2
2 3
2 4
 4 4
2 3
2 4
3 4
4 4
 10 9
8 10
3 10
2 8
9 3
4 8
1 10
7 9
5 4
7 3
 10 10
1 2
2 3
3 4
4 5
5 1
6 6
7 7
8 8
9 9
10 10
 5 5
1 4
3 4
1 2
2 3
2 4
 3 3
1 2
2 2
3 3
 5 3
1 1
2 2
3 3
 6 12
1 2
1 3
2 3
1 1
2 2
3 3
4 5
5 6
4 6
4 4
5 5
6 6
 4 4
1 2
2 3
1 3
4 4
 5 4
1 2
3 3
4 4
5 5
 7 13
6 7
2 7
3 7
4 3
5 2
1 4
7 7
3 1
5 5
3 3
1 5
2 6
6 6
 2 2
1 1
2 2
 5 5
1 1
2 2
3 3
4 4
5 5
 1 1
1 1
 7 3
1 1
3 3
6 6
 3 3
1 1
2 3
3 3

0 1 0 0 0 0 0 1 0 0 8 6 12 0 8 0 0 0 0 0 57 0 0 0 0 0
import java.util.*;
import java.io.*;

public class d{
	static class DisjointSet{
		int[] p, rank;
		DisjointSet(int size){
			p = new int[size];
			rank = p.clone();
			for(int i = 0; i < size; i++) p[i] = i;
		}
		int findSet(int i){
			if(p[i] == i) return i;
			else{
				p[i] = findSet(p[i]);
				return p[i];
			}
		}
		boolean isSameSet(int a, int b){
			return findSet(a) == findSet(b);
		}
		void unionSet(int a, int b){
			if(!isSameSet(a, b)){
				int x = findSet(a), y = findSet(b);
				if(rank[x] > rank[y]) p[y] = x;
				else{
					p[x] = y;
					if(rank[x] == rank[y]) rank[y]++;
				}
			}
		}
	}
	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] line;
		
		line = br.readLine().split(" ");
		int N = Integer.parseInt(line[0]);
		int M = Integer.parseInt(line[1]);
		
		int[][] edges = new int[M][2];
		DisjointSet ds = new DisjointSet(N);
		long[] amtEdges = new long[N];
		boolean[] hasEdge = new boolean[N];
		
		long amtSelfLoops = 0, amtNormals = 0;
		for(int m = 0; m < M; m++){
			line = br.readLine().split(" ");
			edges[m][0] = Integer.parseInt(line[0])-1;
			edges[m][1] = Integer.parseInt(line[1])-1;
			hasEdge[edges[m][0]] = true;
			hasEdge[edges[m][1]] = true;
			if(edges[m][0] != edges[m][1]){
				amtEdges[edges[m][0]]++;
				amtEdges[edges[m][1]]++;
				amtNormals++;
				
			}
			else amtSelfLoops++;
			
			ds.unionSet(edges[m][0], edges[m][1]);
		}
		
		// is it possible to have any path connecting everything?
		for(int n=1;n<N;n++){
			if(!hasEdge[n]) continue;
			if(!ds.isSameSet(0, n)){
				System.out.println("0");
				return;
			}
		}
		
		// so it is. 
		// well, how many paths?
		// obviously any two normal take-once edges need to share a node so that an euler cycle
		// can still be formed.
		// a normal and a self loop can be take-ones no matter their placement
		long amtShares = (amtSelfLoops * (amtSelfLoops - 1)) / 2;
		amtShares += amtNormals * amtSelfLoops;
		for(int n=0;n<N;n++){
			amtShares += (amtEdges[n] * (amtEdges[n]-1)) / 2;
		}
		
		System.out.println(amtShares);
	}
}
