Problem:
Score : 800 points

Problem Statement

Takahashi has received an undirected graph with N vertices, numbered 1, 2, ..., N.
The edges in this graph are represented by (u_i, v_i).
There are no self-loops and multiple edges in this graph.

Based on this graph, Takahashi is now constructing a new graph with N^2 vertices, where each vertex is labeled with a pair of integers (a, b) (1 \leq a \leq N, 1 \leq b \leq N).
The edges in this new graph are generated by the following rule:

Span an edge between vertices (a, b) and (a', b') if and only if both of the following two edges exist in the original graph: an edge between vertices a and a', and an edge between vertices b and b'.

How many connected components are there in this new graph?

Constraints

2 \leq N \leq 100,000

0 \leq M \leq 200,000

1 \leq u_i < v_i \leq N

There exists no pair of distinct integers i and j such that u_i = u_j and v_i = v_j.

Input

The input is given from Standard Input in the following format:

N M
u_1 v_1
u_2 v_2
:
u_M v_M

Output

Print the number of the connected components in the graph constructed by Takahashi.

Sample Input 1

3 1
1 2

Sample Output 1

7

The graph constructed by Takahashi is as follows.

Sample Input 2

7 5
1 2
3 4
3 5
4 5
2 6

Sample Output 2

18

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

struct Union_Find {
    //各要素が属する集合の代表(根)を管理する
    //もし、要素xが根であればdata[x]は負の値を取り、-data[x]はxが属する集合の大きさに等しい
    vector<int> data;
    
    Union_Find(int size) : data(size, -1) {}
    bool Union(int x, int y) {
        x = Find(x);
        y = Find(y);
        bool is_union = (x != y);
        if (is_union) {
            if (data[x] > data[y]) swap(x, y);
            data[x] += data[y];
            data[y] = x;
        }
        return is_union;
    }
    int Find(int x) {
        if (data[x] < 0) { //要素xが根である
            return x;
        } else {
            data[x] = Find(data[x]); //data[x]がxの属する集合の根でない場合、根になるよう更新される
            return data[x];
        }
    }
    bool same(int x, int y) {
        return Find(x) == Find(y);
    }
    int size(int x) {
        return -data[Find(x)];
    }
};


int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int n, m;
	cin >> n >> m;
	vector<int> u(m), v(m);
	Union_Find uf(n);
	for (int i = 0; i < m; i++) {
		cin >> u[i] >> v[i];
		u[i]--;
		v[i]--;
		uf.Union(u[i], v[i]);
	}

	int cnt1 = 0, cnt2 = n;
	for (int i = 0; i < n; i++) {
		if (uf.Find(i) == i) {
			if (uf.size(i) > 1) cnt1++;
			else cnt2--;
		}
	}

	vector<int> memo(n, 0);
	Union_Find uf2(n);
	for (int i = 0; i < m; i++) {
		if (uf2.same(u[i], v[i])) {
			memo[uf.Find(u[i])] = 1;
		} else {
			uf2.Union(u[i], v[i]);
		}
	}
	int cnt3 = accumulate(memo.begin(), memo.end(), 0);
	cout << n << cnt1 << cnt2 << cnt3 << endl;
	cout << (ll)n * n - (ll)cnt2 * cnt2 + (ll)cnt1 * cnt1 - cnt3 << endl;
	return 0;
}