Problem:
Score : 1700 points

Problem Statement

We have a grid with N rows and N columns.
The cell at the i-th row and j-th column is denoted (i, j).

Initially, M of the cells are painted black, and all other cells are white.
Specifically, the cells (a_1, b_1), (a_2, b_2), ..., (a_M, b_M) are painted black.

Snuke will try to paint as many white cells black as possible, according to the following rule:

If two cells (x, y) and (y, z) are both black and a cell (z, x) is white for integers 1≤x,y,z≤N, paint the cell (z, x) black.

Find the number of black cells when no more white cells can be painted black.

Constraints

1≤N≤10^5

1≤M≤10^5

1≤a_i,b_i≤N

All pairs (a_i, b_i) are distinct.

Input

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

N M
a_1 b_1
a_2 b_2
:
a_M b_M

Output

Print the number of black cells when no more white cells can be painted black.

Sample Input 1

3 2
1 2
2 3

Sample Output 1

3

It is possible to paint one white cell black, as follows:

Since cells (1, 2) and (2, 3) are both black and a cell (3, 1) is white, paint the cell (3, 1) black.

Sample Input 2

2 2
1 1
1 2

Sample Output 2

4

It is possible to paint two white cells black, as follows:

Since cells (1, 1) and (1, 2) are both black and a cell (2, 1) is white, paint the cell (2, 1) black.

Since cells (2, 1) and (1, 2) are both black and a cell (2, 2) is white, paint the cell (2, 2) black.

Sample Input 3

4 3
1 2
1 3
4 4

Sample Output 3

3

No white cells can be painted black.

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

#include <iostream>
#include <vector>
#define llint long long

using namespace std;

llint n, m;
vector<llint> G[100005], revG[100005];
llint color[100005];
llint cnt[3], ecnt;
bool used[100005];

bool dfs(llint v, llint c)
{
	color[v] = c;
	bool ret = true;
	for(int i = 0; i < G[v].size(); i++){
		if(color[G[v][i]] == (c+1)%3) continue;
		if(color[G[v][i]] != -1){
			ret = false;
			continue;
		}
		if(!dfs(G[v][i], (c+1)%3)) ret = false;
	}
	for(int i = 0; i < revG[v].size(); i++){
		if(color[revG[v][i]] == (c+2)%3) continue;
		if(color[revG[v][i]] != -1){
			ret = false;
			continue;
		}
		if(!dfs(revG[v][i], (c+2)%3)) ret = false;
	}
	return ret;
}

void dfs2(llint v)
{
	used[v] = true;
	cnt[color[v]]++;
	for(int i = 0; i < G[v].size(); i++){
		ecnt++;
		if(used[G[v][i]]) continue;
		dfs2(G[v][i]);
	}
	for(int i = 0; i < revG[v].size(); i++){
		if(used[revG[v][i]]) continue;
		dfs2(revG[v][i]);
	}
}

int main(void)
{
	cin >> n >> m;
	llint u, v;
	for(int i = 0; i < m; i++){
		cin >> u >> v;
		G[u].push_back(v);
		revG[v].push_back(u);
	}
	
	llint ans = 0; bool res;
	for(int i = 1; i <= n; i++) color[i] = -1;
	for(int i = 1; i <= n; i++){
		if(color[i] >= 0) continue;
		cnt[0] = cnt[1] = cnt[2] = ecnt = 0;
		res = dfs(i, 0), dfs2(i);
		if(res){
			if(cnt[0] && cnt[1] && cnt[2]){
				ans += cnt[0] * cnt[1] + cnt[1] * cnt[2] + cnt[2] * cnt[0];
			}else ans += ecnt;
		}
		else ans += (cnt[0]+cnt[1]+cnt[2])*(cnt[0]+cnt[1]+cnt[2]); 
	}
	cout << ans << endl;
	
	return 0;
}