#include<bits/stdc++.h>
using namespace std;

using Weight = long long;
using Vertex = int;
struct Edge {Vertex from, to; Weight weight;};
using Graph = std::vector<std::vector<Edge>>;

std::vector<std::vector<Vertex>> connected_component(const Graph& G) {
  std::vector<std::vector<Vertex>> cc;
  std::vector<bool> used(G.size());
  std::function<void(int)> dfs = [&](int v) {
    cc.back().push_back(v);
    used[v] = true;
    for(const auto& e: G[v]) if(!used[e.to]) dfs(e.to);
  };
  for(Vertex v = 0; v < G.size(); ++v) if(!used[v]) {
    cc.push_back(std::vector<Vertex>());
    dfs(v);
  }
  return cc;
}

using I = long long;

I com2(I n) {return n * (n - 1) / 2;}

bool check(const auto& G, auto s) {
  vector<int> color(G.size(), -1);
  function<bool(Vertex, int)> dfs = [&](auto v, auto c) {
    if(color[v] != -1) return color[v] == c;
    color[v] = c;
    c ^= 1;
    for(const auto& e: G[v]) if(!dfs(e.to, c)) return false;
    return true;
  };
  return dfs(s, 0);
}

int main() {
  I N, M;
  cin >> N >> M;
  Graph G(N);
  for(auto i=0; i<M; ++i) {
    int u, v;
    cin >> u >> v;
    --u; --v;
    G[u].push_back({u, v});
    G[v].push_back({v, u});
  }

  auto cc = connected_component(G);
  auto V = N - count_if(begin(cc), end(cc), [](const auto& v) {return v.size() == 1;});
  auto ans = N * N - V * V;
  I twocol = 0, obscure = 0;
  for(auto c: cc) if(c.size() != 1) {
    if(check(G, *begin(c))) ++twocol;
    else                    ++obscure;
  }
  ans += 2 * twocol + obscure;
  ans += 4 * com2(twocol) + 2 * com2(obscure);
  ans += 2 * twocol * obscure;
  cout << ans << endl;
}

#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
using namespace std;
using ll = long long ;
using P = pair<int,int> ;
using pll = pair<long long,long long>;
constexpr int INF = 1e9;
constexpr long long LINF = 1e17;
constexpr int MOD = 1000000007;
constexpr double PI = 3.14159265358979323846;
int v = 100005,e;
int c = 0;
vector<vector<int>> graph(v,vector<int>());
vector<bool> seen(v,false);
vector<int> ord(v);
vector<int> low(v);
vector<bool> isart(v,false);

void dfs(int i,int par=-1){
    seen[i] = true;
    ord[i] = low[i] = c++;
    int count = 0;

    for(int j:graph[i]){
        if(!seen[j]){
            dfs(j,i);
            ++ count;
            low[i] = min(low[i],low[j]);
            if(par != -1 && ord[i] <= low[j]) isart[i] = true;
        }else if(j!=par){
            low[i] = min(low[i],ord[j]);
        }
    }

    if(par==-1 && count>1) isart[i] = true;
    return;
}

int main(){
    cin >> v >> e;
    rep(i,e){
        int s,t;
        cin >> s >> t;
        graph[s].push_back(t);
        graph[t].push_back(s);
    }
    dfs(0);
    rep(i,v){
        if(isart[i]) cout << i << endl;
    }
    return 0;
}
