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

#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define RREP(i,a,b) for(int i=(int)(a);i<(int)(b);++i)
#define FOR(i,c) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();++i)
#define LET(x,a) __typeof(a) x(a)
//#define IFOR(i,it,c) for(__typeof((c).begin())it=(c).begin();it!=(c).end();++it,++i)
#define ALL(c) (c).begin(), (c).end()
#define MP make_pair

#define EXIST(e,s) ((s).find(e)!=(s).end())

#define RESET(a) memset((a),0,sizeof(a))
#define SET(a) memset((a),-1,sizeof(a))
#define PB push_back
#define DEC(it,command) __typeof(command) it=command

//debug
#define dump(x)  cerr << #x << " = " << (x) << endl;
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;
#define debug2(x) cerr << #x << " = [";REP(__ind,(x).size()){cerr << (x)[__ind] << ", ";}cerr << "] (L" << __LINE__ << ")" << endl;

const int INF=0x3f3f3f3f;

typedef long long Int;
typedef unsigned long long uInt;
typedef long double rn;

typedef pair<int,int> pii;

/*
#ifdef MYDEBUG
#include"debug.h"
#include"print.h"
#endif
*/
// }}}


//{{{ Graph
typedef int Weight;
struct Edge {
	int src, dst, rev;
	Weight weight;
	Edge(int src, int dst, Weight weight=1,int rev=-1) :
		src(src), dst(dst), weight(weight), rev(rev) { }
};
bool operator < (const Edge &e, const Edge &f) {
	return e.weight != f.weight ? e.weight > f.weight : // !!INVERSE!!
		e.src != f.src ? e.src < f.src : e.dst < f.dst;
}
typedef vector<Edge> Edges;
//typedef vector<Edges> Graph;

typedef vector<Weight> Array;
typedef vector<Array> Matrix;

struct Graph:vector<Edges>{
	Graph(){}
	Graph(const int &n){this->assign(n,Edges());}
	//add bi-directional edge
	void addBiEdge(int from ,int to, Weight w=1){
		while(this->size()<max(from,to)+1)this->push_back(Edges());
		this->at(from).push_back(Edge(from,to,w,this->at(to).size()));
		this->at(to).push_back(Edge(to,from,w,this->at(from).size()-1));
	}
	//add directional edge
	void addEdge(int from ,int to, Weight w=1){
		while(this->size()<from+1)this->push_back(Edges());
		this->at(from).push_back(Edge(from,to,w));
	}
};
#ifdef DEBUG
#include"graph/graphviz.h"
#endif
//}}}

int N,M;
Graph G;
vector<int> vis;

Int ct = 0;

bool dfs(int u, int t = 0){
	vis[u] = t;
	ct++;
	bool result = false;
	for(auto &e:G[u]){
		if(vis[e.dst]!=-1){
			if(vis[e.dst]==vis[u])result = true;
			continue;
		}
		result |= dfs(e.dst, 1-t);
	}
	return result;
}

int main(){
	cin>>N>>M;
	G.assign(N,Edges{});
	vis.assign(N,-1);
	REP(i,M){
		int u, v;
		cin>>u>>v;
		u--;v--;
		G.addBiEdge(u,v);
	}
	Int used = 0, unit = 0;
	Int bip = 0, non_bip = 0;
	REP(u,N){
		if(vis[u]!=-1)continue;
		ct = 0;
		bool result = dfs(u);
		if(ct>1){
			if(!result)bip++;
			else non_bip++;
			used += ct;
		}else{
			unit++;
		}
	}
	/*
	dump(bip);
	dump(non_bip);
	dump(used);
	dump(unit);
	*/
	Int ans = 0;
	ans+=bip*2;//OK
	ans+=non_bip;//OK
	ans+=bip*non_bip*2;//OK
	ans+=(bip*(bip-1)/2)*4;//OK...
	ans+=(non_bip*(non_bip-1)/2)*2;
	ans+=used*unit*2;//OK
	ans+=unit*unit;//OK
	cout<<ans<<endl;
//	cout<<bip*2+non_bip+bip*(bip-1)/2*4+bip*non_bip*2+non_bip*(non_bip-1)/2+used*unit*2+unit*unit<<endl;
	return 0;
}



Measured memory_bytes: 17152