Rng has a connected undirected graph with N vertices and M edges. Rng will add new edges to the graph by choosing two vertices u and v (u ≠ v) such that v can be reached by traversing exactly three edges from u, and then adding an edge connecting u and v. The task is to find the maximum possible number of edges that can be added. The constraints are 2 ≤ N ≤ 10^5, 1 ≤ M ≤ 10^5, 1 ≤ A_i, B_i ≤ N, and the graph has no self-loops or multiple edges, and is connected. The input is given in the format N M followed by pairs of A and B values. The output should be the maximum possible number of edges that can be added. Two sample inputs and their corresponding outputs are provided.

# Buggy version:
from collections import deque
n, m = map(int, input().split())
if n==2 or n==3:
    print(0)
    exit()

connect = [[] for _ in range(n)]
for _ in range(m):
    a, b = map(lambda x: int(x)-1, input().split())
    connect[a].append(b)
    connect[b].append(a)
#print(connect)
color= [-1]*n
color[0]=0
explored= {0}
next = deque(connect[0])
exploring =deque()
Yes = True
explored.add(0)
while next:
    now = next.popleft()
    exploring.extend(connect[now])
    while exploring:
        a=exploring.popleft()
        if color[a]==-1 or color[a]==(color[now]+1)%2:
            color[a]=(color[now]+1)%2
        else:
            Yes = False
        if a not in explored:
            next.append(a)
        explored.add(a)

Yes = False
if Yes:
    s=sum(color)
    print(s*(n-s)-m)
else:
    print(int(n*(n-1)/2-m))

# Fixed version:
from collections import deque
n, m = map(int, input().split())
connect = [[] for _ in range(n)]
for _ in range(m):
    a, b = map(lambda x: int(x)-1, input().split())
    connect[a].append(b)
    connect[b].append(a)
 
color = [-1]*n
color[0] = 0
explored = {0}
next = deque([0])
exploring =deque()
Yes = True
 
while next:
    now = next.popleft()
    exploring.extend(connect[now])
    while exploring:
        a = exploring.popleft()
        if color[a] == -1:
            color[a]=(color[now]+1)%2
        elif color[a] == (color[now]+1)%2:
            pass
        else:
            Yes = False
        if a not in explored:
            next.append(a)
        explored.add(a)
 
 
 
if Yes:
    s=sum(color)
    print(s*(n-s)-m)
else:
    print(n*(n-1)//2-m)

# Buggy version:
from collections import deque
n, m = map(int, input().split())
connect = [[] for _ in range(n)]
for _ in range(m):
    a, b = map(lambda x: int(x)-1, input().split())
    connect[a].append(b)
    connect[b].append(a)

color = [-1]*n
color[0] = 0
explored = {0}
next = deque(connect[0])
exploring =deque()
Yes = True
explored.add(0)
while next:
    now = next.popleft()
    exploring.extend(connect[now])
    while exploring:
        a = exploring.popleft()
        if color[a] == -1:
            color[a]=(color[now]+1)%2
        elif color[a] == (color[now]+1)%2:
            pass
        else:
            Yes = False
        if a not in explored:
            next.append(a)
        explored.add(a)

if Yes:
    s=sum(color)
    print(0)
else:
    print(int(n*(n-1)/2-m))

# Fixed version:
from collections import deque
n, m = map(int, input().split())
connect = [[] for _ in range(n)]
for _ in range(m):
    a, b = map(lambda x: int(x)-1, input().split())
    connect[a].append(b)
    connect[b].append(a)

color = [-1]*n
color[0] = 0
explored = {0}
next = deque([0])
exploring =deque()
Yes = True
explored.add(0)
while next:
    now = next.popleft()
    for a in connect[now]:
        if color[a] != -1:
            if color[a] != (color[now]+1)%2:
                Yes = False
            continue
        color[a] = (color[now]+1)%2
        next.append(a)
        
        
    '''
    exploring.extend(connect[now])
    while exploring:
        a = exploring.popleft()
        if color[a] == -1:
            color[a]=(color[now]+1)%2
        elif color[a] == (color[now]+1)%2:
            pass
        else:
            Yes = False
        if a not in explored:
            next.append(a)
        explored.add(a)
        '''
if Yes:
    s=sum(color)
    print(s*(n-s)-m)
else:
    print(n*(n-1)//2-m)

# Buggy version:
from collections import deque, defaultdict
N, M = map(int, input().split())
graph = [[] for _ in range(N)]

for i in range(M):
    a, b = map(int, input().split())
    a -= 1; b -= 1;
    graph[a].append(b)
    graph[b].append(a)


visited = [False for _ in range(N)]
color = [0 for _ in range(N)]

def dfs(now, c):

    color[now] = c

    for adj in graph[now]:
        if color[adj] == c:
            return False

        if color[adj] == 0 and not dfs(adj, -c):
            return False

    return True

ans = dfs(0, 1)
white = color.count(-1)
black = N - white
if ans:
    print(black * white - M)
else:
    print(N * (N+1)//2 - M)


# Fixed version:
from collections import deque, defaultdict
import sys

sys.setrecursionlimit(10**8)
N, M = map(int, input().split())
graph = [[] for _ in range(N)]

for i in range(M):
    a, b = map(int, input().split())
    a -= 1; b -= 1;
    graph[a].append(b)
    graph[b].append(a)


visited = [False for _ in range(N)]
color = [0 for _ in range(N)]

def dfs(now, c):

    color[now] = c

    for adj in graph[now]:
        if color[adj] == c:
            return False

        if color[adj] == 0 and not dfs(adj, -c):
            return False

    return True

ans = dfs(0, 1)
white = color.count(-1)
black = N - white
if ans:
    print(black * white - M)
else:
    print(N * (N-1)//2 - M)

# Buggy version:
# CODE FESTIVAL 2017 qualB C 3 Steps　
from collections import deque

f=lambda:map(int,input().split())
N,M=f()
G=[[] for _ in [0]*(N+1)]
for i in range(M):
    a,b=f()
    if not i:
        fa,fb=a,b
    G[a].append(b)
    G[b].append(a)
    
res=0
INF=10**9

def bfs(a):
    q=deque()
    q.append(a)
    d=[INF]*(N+1)
    d[a]=0
    res=0
    while q:
        r=q.popleft()
        for nr in G[r]:
            if d[nr]==INF:
                q.append(nr)
                d[nr]=(d[r]+1)%2
                res+=1
    return d

d=bfs(1)
isPer=False
for i in G[1]:
    if d[i]==0:
        isPer=True
        break
if isPer:
    print(N*N-M)
else:
    print(((N//2)**2)//1-M)

# Fixed version:
# CODE FESTIVAL 2017 qualB C 3 Steps　
from collections import deque

f=lambda:map(int,input().split())
N,M=f()
G=[[] for _ in [0]*(N+1)]
for i in range(M):
    a,b=f()
    if not i:
        fa,fb=a,b
    G[a].append(b)
    G[b].append(a)
    
res=0
INF=10**9

def bfs(a):
    q=deque()
    q.append(a)
    d=[0]*(N+1)
    d[a]=1
    res=0
    while q:
        r=q.popleft()
        for nr in G[r]:
            if d[nr]==0:
                q.append(nr)
                d[nr]=-d[r]
            else:
                if d[nr]==d[r]:
                    return (False,[])
    return (True,d)
check=bfs(1)
if not check[0]:
    print((N*(N-1))//2-M)
else:
    print(check[1].count(1)*check[1].count(-1)-M)

# Buggy version:
from sys import setrecursionlimit

setrecursionlimit(10**10)

def dfs(v):
    flag = True

    for nxt in edge[v]:
        if l[v] == l[nxt]:
            return False
        elif l[v] + l[nxt] == 1:
            continue
        else:
            l[nxt] = 1 - l[v]
            cnt[1-l[v]] += 1
            flag &= dfs(nxt)
    
    return flag
        

n, m = map(int, input().split())
edge = [[] for _ in range(n)]
for _ in range(m):
    a, b = map(int, input().split())
    edge[a-1].append(b-1)
    edge[b-1].append(a-1)

l = [-1] * n
l[0] = 0
cnt = [1, 0]

if dfs(0):
    print(cnt[0] * cnt[1] - m)
else:
    print(n * (n - 1) // 2 - m)

# Fixed version:
from sys import setrecursionlimit

setrecursionlimit(10**6)

def dfs(v):
    flag = True

    for nxt in edge[v]:
        if l[v] == l[nxt]:
            return False
        elif l[v] + l[nxt] == 1:
            continue
        else:
            l[nxt] = 1 - l[v]
            cnt[1-l[v]] += 1
            flag &= dfs(nxt)
    
    return flag
        

n, m = map(int, input().split())
edge = [[] for _ in range(n)]
for _ in range(m):
    a, b = map(int, input().split())
    edge[a-1].append(b-1)
    edge[b-1].append(a-1)

l = [-1] * n
l[0] = 0
cnt = [1, 0]

if dfs(0):
    print(cnt[0] * cnt[1] - m)
else:
    print(n * (n - 1) // 2 - m)

# Buggy version:
import sys
input = sys.stdin.buffer.readline

#sys.setrecursionlimit(10**9)
#from functools import lru_cache

def RD(): return sys.stdin.read()
def II(): return int(input())
def MI(): return map(int,input().split())
def MF(): return map(float,input().split())
def LI(): return list(map(int,input().split()))
def LF(): return list(map(float,input().split()))
def TI(): return tuple(map(int,input().split()))
# rstrip().decode()

from collections import deque

def main():
	n,m=MI()

	G=[[] for _ in range(n+1)]

	for _ in range(m):
		a,b=MI()
		G[a].append(b)
		G[b].append(a)
	#print(G)

	D=[-1]*(n+1)


	Q=deque()
	Q.append([1,0])

	#print(Q)

	f=0

	while Q:
		#print(Q)
		now,d=Q.popleft()
		D[now]=d
		for nx in G[now]:
			if D[nx]==-1:
				Q.append([nx,d+1])
			elif D[nx]%2!=d%2:
				continue
			else:
				f=1
				break


	if f==1:
		ans=(n*(n-1))//2+5
	else:
		ans=(n//2+n%2)*(n//2)

	ans-=m

	print(ans)

















if __name__ == "__main__":
	main()


# Fixed version:
import sys
input = sys.stdin.buffer.readline

#sys.setrecursionlimit(10**9)
#from functools import lru_cache

def RD(): return sys.stdin.read()
def II(): return int(input())
def MI(): return map(int,input().split())
def MF(): return map(float,input().split())
def LI(): return list(map(int,input().split()))
def LF(): return list(map(float,input().split()))
def TI(): return tuple(map(int,input().split()))
# rstrip().decode()

from collections import deque

def main():
	n,m=MI()

	G=[[] for _ in range(n+1)]

	for _ in range(m):
		a,b=MI()
		G[a].append(b)
		G[b].append(a)
	#print(G)

	D=[-1]*(n+1)


	Q=deque()
	Q.append([1,0])

	#print(Q)

	f=0

	while Q:
		#print(Q)
		now,d=Q.pop()
		D[now]=d
		for nx in G[now]:
			if D[nx]==-1:
				Q.append([nx,1-d])
			elif D[nx]!=d:
				continue
			else:
				f=1
				break


	if f==1:
		ans=(n*(n-1))//2
	else:
		ans=D.count(0)*D.count(1)


	ans-=m

	print(ans)

















if __name__ == "__main__":
	main()

# Buggy version:
# coding:utf-8
class Tree(object):
    def __init__(self, N):
        self.tree   = [[] for _ in range(N)]
        self.colors = [0  for _ in range(N)]

    def add_node(self, a, b):
        self.tree[a].append(b)
    # 二部グラフか判定する関数
    def is_bipartite_graph(self, v, color):
        self.colors[v] = color
        for to in self.tree[v]:
            if self.colors[to] == color:
                return False
            if self.colors[to] == 0 and not self.is_bipartite_graph(to, -color):
                return False
        return True
    
    def count_node(self, color):
        return self.colors.count(color)
    
if __name__ == "__main__":

    # input data
    N, M = map(int, input().split())
    tree = Tree(N)
    for _ in range(M):
        a, b = map(int, input().split())
        tree.add_node(a-1, b-1)
        tree.add_node(b-1, a-1)
    
    # tree dp
    is_bpr = tree.is_bipartite_graph(0, 1)
    if is_bpr:
        bla = tree.count_node(1)
        whi = N - bla
        print(bla*whi-M)
    else:
        print(N*(N-1)/2-M)



# Fixed version:
# coding:utf-8
class Tree(object):
    def __init__(self, N):
        self.tree   = [[] for _ in range(N)]
        self.colors = [0  for _ in range(N)]

    def add_node(self, a, b):
        self.tree[a].append(b)
    # 二部グラフか判定する関数
    def is_bipartite_graph(self, v, color):
        self.colors[v] = color
        for to in self.tree[v]:
            if self.colors[to] == color:
                return False
            if self.colors[to] == 0 and not self.is_bipartite_graph(to, -color):
                return False
        return True
    
    def count_node(self, color):
        return self.colors.count(color)
    
if __name__ == "__main__":

    import sys
    sys.setrecursionlimit(200000)
    # input data
    N, M = map(int, input().split())
    tree = Tree(N)
    for _ in range(M):
        a, b = map(int, input().split())
        tree.add_node(a-1, b-1)
        tree.add_node(b-1, a-1)
    
    # tree dp
    is_bpr = tree.is_bipartite_graph(0, 1)
    if is_bpr:
        bla = tree.count_node(1)
        whi = N - bla
        print(bla*whi-M)
    else:
        print(int(N*(N-1)/2-M))

# Buggy version:
import sys
sys.setrecursionlimit(10**7)

N, M = map(int,input().split())

michi = [[] for i in range(N)]
for i in range(M):
  tempa, tempb = map(int,input().split())
  michi[tempa-1].append(tempb-1)
  michi[tempb-1].append(tempa-1)
print(michi)
  
colors = [0 for i in range(N)]

def dfs(v,color):
  colors[v] = color
  for to in michi[v]:
    if colors[to] == color:
      return False
    if colors[to] == 0 and not dfs(to,-color):
      return False
  return True

if dfs(0,1):
  a = colors.count(1)
  b = colors.count(-1)
  #print(colors)
  print(a*b-M)
else:
  print(N*(N-1)//2 - M)

# Fixed version:
import sys
sys.setrecursionlimit(10**7)

N, M = map(int,input().split())

michi = [[] for i in range(N)]
for i in range(M):
  tempa, tempb = map(int,input().split())
  michi[tempa-1].append(tempb-1)
  michi[tempb-1].append(tempa-1)
#print(michi)
  
colors = [0 for i in range(N)]

def dfs(v,color):
  colors[v] = color
  for to in michi[v]:
    if colors[to] == color:
      return False
    if colors[to] == 0 and not dfs(to,-color):
      return False
  return True

if dfs(0,1):
  a = colors.count(1)
  b = colors.count(-1)
  #print(colors)
  print(a*b-M)
else:
  print(N*(N-1)//2 - M)

# Buggy version:
import sys
sys.setrecursionlimit(10**6)
n,m=map(int,input().split())
s=[[]for i in range(n+1)]
c=[0]*(n+1)
for i in range(m):
    a,b=map(int,input().split())
    s[a].append(b)
    s[b].append(a)
def dfs(v,t):
    c[v]=t
    print('start :'+str(c))
    for i in s[v]:
        if c[i]==t:
            return False
        if c[i]==0:
            dfs(i,-t)
            # return False
    else:
        return True
if dfs(1,1):
    q=c.count(1)
    print((n-q)*q-m)
else:
    print((n*(n-1)//2)-m)

# Fixed version:
import sys
sys.setrecursionlimit(10**6)
n,m=map(int,input().split())
s=[[]for i in range(n+1)]
c=[0]*(n+1)
for i in range(m):
    a,b=map(int,input().split())
    s[a].append(b)
    s[b].append(a)
def dfs(v,t):
    c[v]=t
    # print('start :'+str(c))
    for i in s[v]:
        if c[i]==t:
            return False
        if c[i]==0 and not dfs(i,-t):
            return False
    else:
        return True
if dfs(1,1):
    q=c.count(1)
    print((n-q)*q-m)
else:
    print((n*(n-1)//2)-m)

# Buggy version:
import sys
sys.setrecursionlimit(10**7)

def dfs(v, color):
    colors[v] = color
    for to in g[v]:
        if colors[to] == color: return False
        if colors[to] == 0 and not dfs(to, -color):
            return False
    return True

n, m = map(int, input().split())

g = [[] for _ in range(n)]
for _ in range(m):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    g[a].append(b)
    g[b].append(a)

colors = [0]*n

ans = -m
if dfs(0,1):
  b = sum(colors)//2
  w = n-b
  ans += b*w
else:
  ans += n*(n-1)//2
print(ans)

# Fixed version:
import sys
sys.setrecursionlimit(10**7)

def dfs(v, color):
    colors[v] = color
    for to in g[v]:
        if colors[to] == color: return False
        if colors[to] == 0 and not dfs(to, -color):
            return False
    return True

n, m = map(int, input().split())

g = [[] for _ in range(n)]
for _ in range(m):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    g[a].append(b)
    g[b].append(a)

colors = [0]*n

ans = -m
if dfs(0,1):
  b = (sum(colors)+n)//2
  w = n-b
  ans += b*w
else:
  ans += n*(n-1)//2
print(ans)

# Buggy version:
from collections import deque

def dfs():
    global color
    global edge
    color = [-1] * n
    edge = [[] for _ in range(n)]

    q = deque([])
    q.append(0)
    color[0] = 1
    
    while q:
        p = q.pop()
        for u in edge[p]:
            if color[u] == -1:
                color[u] = (color[p] + 1) % 2
                q.append(u)
            else:
                if color[u] == color[p]:
                    return False
    return True

n, m = map(int, input().split())

for i in range(m):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    edge[a].append(b)
    edge[b].append(a)


if dfs():
    B = 0
    W = 0
    for i in range(n):
        if color[i] == 1:
            B += 1
        else:
            W += 1
    print(B*W - m)
else:
    print(n * (n-1) // 2 - m)

# Fixed version:
from collections import deque

def dfs():
    global color
    color = [-1] * n
    q = deque([])
    q.append(0)
    color[0] = 1
    
    while q:
        p = q.pop()
        for u in edge[p]:
            if color[u] == -1:
                color[u] = (color[p] + 1) % 2
                q.append(u)
            else:
                if color[u] == color[p]:
                    return False
    return True

n, m = map(int, input().split())
edge = [[] for _ in range(n)]

for i in range(m):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    edge[a].append(b)
    edge[b].append(a)


if dfs():
    B = 0
    W = 0
    for i in range(n):
        if color[i] == 1:
            B += 1
        else:
            W += 1
    print(B*W - m)
else:
    print(n * (n-1) // 2 - m)

# Buggy version:
def main():
    n,m=map(int,input().split())
    ab=[list(map(int,input().split())) for _ in [0]*m]
    g=[[] for _ in [0]*n]
    [g[a-1].append(b-1) for a,b in ab]
    [g[b-1].append(a-1) for a,b in ab]
    ans=[None]*n
    ans[0]=0
    temp=[0]
    while temp:
        i=temp.pop()
        for j in g[i]:
            if ans[j]==None:
                ans[j]=ans[i]^True
                temp.append(j)
            else:
                if ans[i]^ans[j]==0:
                    #print(n*(n-1)//2-m)
                    print(1/0)
                    return 0
    print((ans.count(0)*(ans.count(0)-1)//2)*(ans.count(1)*(ans.count(1)-1)//2)-m)
main()

# Fixed version:
def main():
    n,m=map(int,input().split())
    ab=[list(map(int,input().split())) for _ in [0]*m]
    g=[[] for _ in [0]*n]
    [g[a-1].append(b-1) for a,b in ab]
    [g[b-1].append(a-1) for a,b in ab]
    ans=[None]*n
    ans[0]=0
    temp=[0]
    while temp:
        i=temp.pop()
        for j in g[i]:
            if ans[j]==None:
                ans[j]=ans[i]^True
                temp.append(j)
            else:
                if ans[i]^ans[j]==0:
                    print(n*(n-1)//2-m)
                    return 0
    print(ans.count(0)*ans.count(1)-m)
main()

# Buggy version:
N,M = map(int,input().split())
e_list = [[] for i in range(N)]
for i in range(M):
    a,b = map(lambda x:int(x)-1, input().split())
    e_list[a].append(b)
    e_list[b].append(a)
bin_or_not = True
ans = (N-1)*N//2 - M
w_or_b = [-1]*N
stack = [0]
w_or_b[0] = 0
while stack:
    x = stack.pop()
    for i in e_list[x]:
        if w_or_b[i] >= 0:
            bin_or_not = not(w_or_b[x]^w_or_b[i])
        else:
            w_or_b[i] = (w_or_b[x] + 1)%2
            stack.append(i)
    if not bin_or_not:
        break
if bin_or_not:
    w =  w_or_b.count(0)
    b = w_or_b.count(1)
    ans = w*b - M
print(ans)

# Fixed version:
N,M = map(int,input().split())
e_list = [[] for i in range(N)]
for i in range(M):
    a,b = map(lambda x:int(x)-1, input().split())
    e_list[a].append(b)
    e_list[b].append(a)
bin_or_not = True
ans = (N-1)*N//2 - M
w_or_b = [-1]*N
stack = [0]
w_or_b[0] = 0
while stack:
    x = stack.pop()
    for i in e_list[x]:
        if w_or_b[i] >= 0:
            bin_or_not = w_or_b[x]^w_or_b[i]
        else:
            w_or_b[i] = (w_or_b[x] + 1)%2
            stack.append(i)
        if not bin_or_not:
            break
    if not bin_or_not:
        break
if bin_or_not:
    w =  w_or_b.count(0)
    b = w_or_b.count(1)
    ans = w*b - M
print(ans)

# Buggy version:
N, M = map(int, input().split())
G = [[] for _ in range(N)]
for _ in range(M):
    a, b = map(int, input().split())
    G[a-1].append(b-1)
    G[b-1].append(a-1)
def is_bipartite(G):
    n = len(G)
    color = [-1]*n
    que = deque([0])
    color[0] = 0
    while que:
        v = que.pop()
        c = color[v]
        for nv in G[v]:
            if color[nv]<0:
                color[nv] = 1-c
                que.append(nv)
            elif color[nv] == c:
                return False
    return color
color = is_bipartite(G)
if color:
    a = color.count(0)
    b = N-a
    print(a*b-M)
else:
    print(N*(N-1)//2-M)
            
            

# Fixed version:
from collections import deque
N, M = map(int, input().split())
G = [[] for _ in range(N)]
for _ in range(M):
    a, b = map(int, input().split())
    G[a-1].append(b-1)
    G[b-1].append(a-1)
def is_bipartite(G):
    n = len(G)
    color = [-1]*n
    que = deque([0])
    color[0] = 0
    while que:
        v = que.pop()
        c = color[v]
        for nv in G[v]:
            if color[nv]<0:
                color[nv] = 1-c
                que.append(nv)
            elif color[nv] == c:
                return False
    return color
color = is_bipartite(G)
if color:
    a = color.count(0)
    b = N-a
    print(a*b-M)
else:
    print(N*(N-1)//2-M)

# Buggy version:
import sys
sys.setrecursionlimit(10 ** 7)

N, M = map(int,input().split())

AB = [list(map(int, input().split())) for _ in range(M)]

graph = [[] for _ in range(N)]
for a,b in AB:
    graph[a−1].append(b-1)
    graph[b-1].append(a-1)

# 二部グラフかどうかの判定
color = [None] * N
color[0] = 0
q = [0]
while q:
    x = q.pop()
    for y in graph[x]:
        if color[y] is None:
            color[y] = 1 - color[x]
            q.append(y)

# 二部グラフかどうか
bg = all(color[a] != color[b] for a, b in AB)

if bg:
    # 完全二部グラフにする
    x = sum(color)
    y = N - x
    answer = x*y - M
else:
    # 完全グラフにする(奇数長のパスがある場合は必ず2ずつ減らしていけば長さが3になる)
    answer = N*(N-1)//2 - M

print(answer)


# Fixed version:
import sys
sys.setrecursionlimit(10 ** 7)

N, M = map(int, input().split())
AB = [list(map(int, input().split())) for _ in range(M)]
graph = [[] for _ in range(N)]

for a, b in AB:
    graph[a-1].append(b-1)
    graph[b-1].append(a-1)

# 二部グラフかどうかの判定
color = [None] * N
color[0] = 0
q = [0]
while q:
    x = q.pop()
    for y in graph[x]:
        if color[y] is None:
            color[y] = 1 - color[x]
            q.append(y)

# 二部グラフかどうか
is_bg = all(color[a-1] != color[b-1] for a, b in AB)

if is_bg:
    # 完全二部グラフにする
    x = sum(color)
    y = N - x
    answer = x*y - M
else:
    # 完全グラフにする(奇数長のパスがある場合は必ず2ずつ減らしていけば長さが3になる)
    answer = N*(N-1)//2 - M

print(answer)

# Buggy version:
import sys
sys.setrecursionlimit(500000)

def dfs(v,c):
    color[v] = c

    for i in a[v]:
        if color[i] != -1:
            if color[i] == c:return False
            continue
        if dfs(i,1-c) == False:return False

n,m = map(int,input().split())
a = [[]for i in range(n)]
color = [-1 for _ in range(n)]

for i in range(m):
    x,y= map(int,input().split())
    a[x-1].append(y-1)
    a[y-1].append(x-1)
print(a)
if dfs(0,0) == False:
    print(n*(n-1)//2-m)
else:print((n-n//2)*(n//2) - m)

# Fixed version:
import sys
sys.setrecursionlimit(500000)

def dfs(v,c):
    color[v] = c

    for i in a[v]:
        if color[i] != -1:
            if color[i] == c:return False
            continue
        if dfs(i,1-c) == False:return False

n,m = map(int,input().split())
a = [[]for i in range(n)]
color = [-1 for _ in range(n)]

for i in range(m):
    x,y= map(int,input().split())
    a[x-1].append(y-1)
    a[y-1].append(x-1)
if dfs(0,0) == False:
    print(n*(n-1)//2-m)
else:print(color.count(0) * color.count(1) -m)

# Buggy version:

import sys
from collections import deque, defaultdict
import copy
import bisect
#sys.setrecursionlimit(10 ** 9)
import math
import heapq
from itertools import combinations, permutations

import sys
def input():
	return sys.stdin.readline().strip()

N, M = list(map(int, input().split()))

graph = [[] for _ in range(N)]
graph2 = [-1 for _ in range(N)]
for i in range(M):
	a, b = list(map(int, input().split()))
	a -= 1
	b -= 1
	graph[a].append(b)
	graph[b].append(a)

que = deque([])
que.append(0)
graph2[0] = 0
nibu = 1

num01 = dict()
num01[0] = 1
num01[1] = 0

while len(que) > 0:
	node = que.popleft()
	for edge in graph[node]:
		if graph2[edge] == -1:
			graph2[edge] = (graph2[node] + 1) % 2
			que.append(edge)
			num01[graph2[edge]] += 1
		elif graph2[node] == graph2[edge]:
			nibu = 0

if nibu == 0:
	print(N*(N-1)//2 - M)
else:
	print(num01[0]*num01[1] - 1)

# Fixed version:

import sys
from collections import deque, defaultdict
import copy
import bisect
#sys.setrecursionlimit(10 ** 9)
import math
import heapq
from itertools import combinations, permutations

import sys
def input():
	return sys.stdin.readline().strip()

N, M = list(map(int, input().split()))

graph = [[] for _ in range(N)]
graph2 = [-1 for _ in range(N)]
for i in range(M):
	a, b = list(map(int, input().split()))
	a -= 1
	b -= 1
	graph[a].append(b)
	graph[b].append(a)

que = deque([])
que.append(0)
graph2[0] = 0
nibu = 1

num01 = dict()
num01[0] = 1
num01[1] = 0

while len(que) > 0:
	node = que.popleft()
	for edge in graph[node]:
		if graph2[edge] == -1:
			graph2[edge] = (graph2[node] + 1) % 2
			que.append(edge)
			num01[graph2[edge]] += 1
		elif graph2[node] == graph2[edge]:
			nibu = 0

if nibu == 0:
	print(N*(N-1)//2 - M)
else:
	print(num01[0]*num01[1] - M)

# Buggy version:
from collections import defaultdict
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**7)

n, m = map(int, (input().split()))
dic = defaultdict(list)
seen = [-1] * (n+1)

for _ in range(m):
    a, b = map(int, input().split())
    dic[a].append(b)
    dic[b].append(a)


def dfs(v, todo, color):
    if seen[v] == color:  # 同じ色で戻ってくる = 偶サイクル
        return
    elif seen[v] == 1-color:  # 異なる色で戻ってくる = 奇サイクル
        return False

    seen[v] = color
    for new_v in todo:
        new_todo = dic[new_v]
        dfs(new_v, new_todo, 1-color)


if dfs(1, dic[1], 0) is False:
    ans = 0.5 * n * (n-1) - m

else:
    black = seen.count(0)
    white = seen.count(1)
    ans = black * white - m

print(int(ans))

# Fixed version:
from collections import defaultdict
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**7)

n, m = map(int, (input().split()))
dic = defaultdict(list)
seen = [-1] * (n+1)

for _ in range(m):
    a, b = map(int, input().split())
    dic[a].append(b)
    dic[b].append(a)


def dfs(v, todo, color):
    if seen[v] == color:  # 同じ色で戻ってくる = 偶サイクル
        return
    elif seen[v] == 1-color:  # 異なる色で戻ってくる = 奇サイクル
        global odd_cycle
        odd_cycle = True
        return

    seen[v] = color
    for new_v in todo:
        new_todo = dic[new_v]
        dfs(new_v, new_todo, 1-color)


odd_cycle = False
dfs(1, dic[1], 0)
if odd_cycle:
    ans = 0.5 * n * (n-1) - m
else:
    black = seen.count(0)
    white = seen.count(1)
    ans = black * white - m

print(int(ans))

# Buggy version:
import sys
sys.setrecursionlimit(10**6)
from operator import mul
from functools import reduce

def comb(n,r):
    r = min(n-r,r)
    if r == 0: return 1
    over = reduce(mul, range(n, n - r, -1))
    under = reduce(mul, range(1,r + 1))
    return over // under


def dfs(v, cur):
    color[v] = cur
    
    for next_v in Graph[v]:
        if color[next_v] != -1:
            if color[next_v] != cur:
                continue
            else:
                return False
        elif not dfs(next_v, 1-cur):
            return False
    return True
        


N, M = map(int, input().split())
AB = [[int(_) for _ in input().split()] for _ in range(M)]
Graph = [[] for _ in range(N)]
color = [-1]*N

for i in AB:
    Graph[i[0]-1].append(i[1]-1)
    Graph[i[1]-1].append(i[0]-1)

if dfs(0, 0):
  	black = color.count(0)
    white = N - black
    print(black*white-M)
else:
    print(comb(N, 2)-M)

# Fixed version:
import sys
sys.setrecursionlimit(10**6)
from operator import mul
from functools import reduce

def comb(n,r):
    r = min(n-r,r)
    if r == 0: return 1
    over = reduce(mul, range(n, n - r, -1))
    under = reduce(mul, range(1,r + 1))
    return over // under


def dfs(v, cur):
    color[v] = cur
    
    for next_v in Graph[v]:
        if color[next_v] != -1:
            if color[next_v] != cur:
                continue
            else:
                return False
        elif not dfs(next_v, 1-cur):
            return False
    return True
        


N, M = map(int, input().split())
AB = [[int(_) for _ in input().split()] for _ in range(M)]
Graph = [[] for _ in range(N)]
color = [-1]*N

for i in AB:
    Graph[i[0]-1].append(i[1]-1)
    Graph[i[1]-1].append(i[0]-1)

if dfs(0, 0):
    black = color.count(0)
    white = N - black
    print(black*white-M)
else:
    print(comb(N, 2)-M)

# Buggy version:
import sys
sys.setrecursionlimit(10**6)
n,m=map(int,input().split())
s=[[]for i in range(n+1)]
c=[0]*(n+1)
for i in range(m):
    a,b=map(int,input().split())
    s[a].append(b)
    s[b].append(a)
def dfs(v,t):
    c[v]=t
    for i in s[v]:
        if c[i]==t:
            return false
        if c[i]==0 and not dfs(i,-t):
            return false
    else:
        return True
if dfs(1,1):
    q=c.count(1)
    print((n-q)*q-m)
else:
    print((n*(n-1)//2)-m)

# Fixed version:
import sys
sys.setrecursionlimit(10**6)
n,m=map(int,input().split())
s=[[]for i in range(n+1)]
c=[0]*(n+1)
for i in range(m):
    a,b=map(int,input().split())
    s[a].append(b)
    s[b].append(a)
def dfs(v,t):
    c[v]=t
    for i in s[v]:
        if c[i]==t:
            return False
        if c[i]==0 and not dfs(i,-t):
            return False
    else:
        return True
if dfs(1,1):
    q=c.count(1)
    print((n-q)*q-m)
else:
    print((n*(n-1)//2)-m)

# Buggy version:
from collections import deque
N, M = map(int, input().split())
G = [[] for i in range(N)]
for m in range(M):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    G[a].append(b)
    G[b].append(a)

color = [-1 for i in range(N)]
visits = [False for i in range(N)]
paths = deque()


def Bipartial():
    paths.append(0)
    color[0] = 0
    while paths:
        x = paths.pop()
        visits[x] = True
        for g in G[x]:
            if visits[g] and color[g] == color[x]:
                return False
            elif not visits[g]:
                paths.append(g)
                color[g] = (color[x]+1) % 2
        return True


if Bipartial():
    B = color.count(0)
    W = color.count(1)
    ans = B * W - M
else:
    ans = (N * (N - 1)) // 2 - M
print(ans)


# Fixed version:
from collections import deque
N, M = map(int, input().split())
G = [[] for i in range(N)]
for m in range(M):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    G[a].append(b)
    G[b].append(a)

color = [-1 for i in range(N)]
visits = [False for i in range(N)]
paths = deque()


def Bipartial():
    paths.append(0)
    color[0] = 0
    while paths:
        x = paths.pop()
        visits[x] = True
        for g in G[x]:
            if visits[g] and color[g] == color[x]:
                return False
            elif not visits[g]:
                paths.append(g)
                color[g] = (color[x]+1) % 2
    return True


if Bipartial():
    B = color.count(0)
    W = color.count(1)
    ans = B * W - M
else:
    ans = (N * (N - 1)) // 2 - M
print(ans)

# Buggy version:
import sys
sys.setrecursionlimit(100000)
fin = sys.stdin.readline

N, M = [int(elem) for elem in fin().split()]
adj = [[] for _ in range(N)]
for _ in range(M):
    a, b = [int(elem) - 1 for elem in fin().split()]
    adj[a].append(b)
    adj[b].append(a)


def judge_bipartite(adj, v, color, colors):
    colors[v] = color
    for neighbor in adj[v]:
        if colors[neighbor] is None:
            if not judge_bipartite(adj, neighbor, 1 - color, colors):
                return False
        else:
            if colors[neighbor] == color:
                return False
    else:
        return True

colors = [None] * N
bipartite = judge_bipartite(adj, 0, 0, colors)
print(bipartite, colors)
if not bipartite:
    print(N * (N - 1) // 2 - M)
else:
    num_b = sum([v == 0 for v in colors])
    num_w = N - num_b
    print(num_b * num_w - M)


# Fixed version:
import sys
sys.setrecursionlimit(100000)
fin = sys.stdin.readline

N, M = [int(elem) for elem in fin().split()]
adj = [[] for _ in range(N)]
for _ in range(M):
    a, b = [int(elem) - 1 for elem in fin().split()]
    adj[a].append(b)
    adj[b].append(a)


def judge_bipartite(adj, v, color, colors):
    colors[v] = color
    for neighbor in adj[v]:
        if colors[neighbor] is None:
            if not judge_bipartite(adj, neighbor, 1 - color, colors):
                return False
        else:
            if colors[neighbor] == color:
                return False
    else:
        return True

colors = [None] * N
bipartite = judge_bipartite(adj, 0, 0, colors)

if not bipartite:
    print(N * (N - 1) // 2 - M)
else:
    num_b = sum([v == 0 for v in colors])
    num_w = N - num_b
    print(num_b * num_w - M)

# Buggy version:
import sys
sys.getrecursionlimit(1000000)

N, M = map(int, input().split())

G = [[] for i in range(N)]
for _ in range(M):
    Ai, Bi = map(int, input().split())
    G[Ai - 1].append(Bi - 1)
    G[Bi - 1].append(Ai - 1)

color = [0] * N
def dfs(v, c):
    '''
    頂点vをcで塗る　そこから深さ優先探索で交互に塗っていく
    '''
    color[v] = c
    for i in G[v]:
        if color[i] == c:
            return False
        if color[i] == 0 and not(dfs(i, -c)):
            return False
    return True

if dfs(0, 1):
    print(color.count(1) * color.count(-1) - M)
else:
    print(N * (N - 1) // 2 - M)


# Fixed version:
import sys
sys.setrecursionlimit(1000000)

N, M = map(int, input().split())

G = [[] for i in range(N)]
for _ in range(M):
    Ai, Bi = map(int, input().split())
    G[Ai - 1].append(Bi - 1)
    G[Bi - 1].append(Ai - 1)

color = [0] * N
def dfs(v, c):
    '''
    頂点vをcで塗る　そこから深さ優先探索で交互に塗っていく
    '''
    color[v] = c
    for i in G[v]:
        if color[i] == c:
            return False
        if color[i] == 0 and not(dfs(i, -c)):
            return False
    return True

if dfs(0, 1):
    print(color.count(1) * color.count(-1) - M)
else:
    print(N * (N - 1) // 2 - M)

# Buggy version:
n, m = map(int, input().split())
edge = [[] for i in range(n)]
for i in range(m):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    edge[a].append(b)
    edge[b].append(a)
# -1 → 0,1に塗っていきます
color=[-1 for i in range(n)]
def dfs(pos):
    ret = True
    for i in range(len(edge[pos])):
        to = edge[pos][i]
        if color[to] == -1:
            color[to] = 1 ^ color[pos]
            ret &= dfs(to)
        else:
            ret &= color[to]==color[pos]
    return ret

color[0]=0
if dfs(0):
    print(color)
    black, white = 0, 0
    for i in range(n):
        if color[i]==0:
            black += 1
        else:
            white += 1
    print(black*white-m)
else:
    print(n*(n-1)//2-m)

# Fixed version:
import sys
sys.setrecursionlimit(10**8)
n, m = map(int, input().split())
edge = [[] for i in range(n)]
for i in range(m):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    edge[a].append(b)
    edge[b].append(a)
# -1 → 0,1に塗っていきます
color=[-1 for i in range(n)]
def dfs(pos):
    ret = True
    for i in range(len(edge[pos])):
        to = edge[pos][i]
        if color[to] == -1:
            color[to] = 1 ^ color[pos]
            ret &= dfs(to)
        else:
            ret &= not (color[to]==color[pos])
    return ret

color[0]=0
if dfs(0):
    black, white = 0, 0
    for i in range(n):
        if color[i]==0:
            black += 1
        else:
            white += 1
    print(black*white-m)
else:
    print(n*(n-1)//2-m)