import std.stdio, std.algorithm, std.conv, std.array, std.string, std.math, std.typecons, std.numeric;

void main()
{
    auto nm = readln.split.to!(int[]);
    auto N = nm[0];
    auto M = nm[1];
    int[][] G;
    G.length = N;
    foreach (_; 0..M) {
        auto ab = readln.split.to!(int[]);
        auto A = ab[0]-1;
        auto B = ab[1]-1;
        G[A] ~= B;
        G[B] ~= A;
    }

    auto es = new int[](N);
    long x, y, z;
    void walk(int i, int p, int c) {
        c = c == 1 ? 2 : 1;
        foreach (j; G[i]) if (j != p) {
            if (es[j] == 0) {
                if (c == 1) {
                    ++x;
                } else {
                    ++y;
                }
                es[j] = c;
                walk(j, i, c);
            } else if ((es[j] == 1 && c == 2) || es[j] == 2 && c == 1) {
                if (es[j] == 1) {
                    --x;
                } else {
                    --y;
                }
                ++z;
                es[j] = 3;
                walk(j, i, c);
            }
        }
    }
    es[0] = 1;
    ++x;
    walk(0, -1, 1);

    bool same(int i, int j) {
        return
            (es[i] == 1 && es[j] == 2) ||
            (es[i] == 2 && es[j] == 1) ||
            (es[i] == 3 && es[j] == 3);
    }

    auto memo = new bool[](N);
    memo[0] = true;
    long r;
    void solve(int i) {
        long n = (es[i] == 1 ? y : es[i] == 2 ? x : z);
        if (es[i] == 3) --n;
        foreach (j; G[i]) if (same(i, j)) --n;
        r += n;
        foreach (j; G[i]) if (!memo[j]) {
            memo[j] = true;
            solve(j);
        }
    }
    solve(0);
    writeln(r/2);
}