// Original C++ solution (slower):
#include<iostream>

#include<cstdio>

#include<cstring>

using namespace std;

 

int n,m,x,y;

int f[5],col[100005];

int tot=0,h[100005];

bool flag;

struct Edge{

	int x,dis,next;

}e[200005];

long long ans=0;

 

inline void add_edge(int x,int y,int z){

	e[++tot].x=y,e[tot].dis=z;

	e[tot].next=h[x],h[x]=tot;

}

 

void dfs(int x){

	f[col[x]]++;

	for(int i=h[x];i;i=e[i].next){

		f[3]+=e[i].dis==1;

		if(col[e[i].x]==-1){

			col[e[i].x]=(col[x]+e[i].dis)%3;

			dfs(e[i].x);

		}else{

			if(col[e[i].x]!=(col[x]+e[i].dis)%3)

				flag=true;

		}

	}

}

 

int main(){

	scanf("%d%d",&n,&m);

	for(int i=1;i<=m;i++){

		scanf("%d%d",&x,&y);

		add_edge(x,y,1);

		add_edge(y,x,2);

	}

	memset(col,-1,sizeof(col));

	for(int i=1;i<=n;i++)

	if(col[i]==-1){

		f[col[i]=0]=f[1]=f[2]=f[3]=flag=0;

		dfs(i);

		if(flag){

			int cnt=f[0]+f[1]+f[2];

			ans+=1LL*cnt*cnt;

		}else if(f[0]==0||f[1]==0||f[2]==0){

			ans+=f[3];

		}else{

			ans+=1LL*f[0]*f[1];

			ans+=1LL*f[1]*f[2];

			ans+=1LL*f[2]*f[0];

		}

	}

	printf("%lld",ans);

}


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>



typedef int INT;

#define int long long



namespace Stdin

{

    int read()

    {

        int sum = 0;

        char c = getchar(), f = c;

        while(c < '0' || c > '9') f = c, c = getchar();

        while(c >= '0' && c <= '9') sum = sum * 10 + c - '0', c = getchar();

        if(f == '-') sum *= -1;

        return sum;

    }

    char GetOnce(char s, char e)

    {

        char c = getchar();

        while(c < s || c > e) c = getchar();

        return c;

    }

}



namespace STD

{

    const int N = 100000 + 10;

    int n, m;

    int tot, sum, mrk;

    int C[N], S[4];

    int head[N], used[N], cnt;

    struct edge { int to, va, nxt; } e[N << 1];

    int ans;

    

    void Add(int x, int y)

    {

        e[++cnt] = (edge) { y,  1, head[x] }; head[x] = cnt;

        e[++cnt] = (edge) { x, -1, head[y] }; head[y] = cnt;

    }



    int Cal(int x) { x %= 3; if(x == 0) return 3; return x; }



    void DFS(int u)

    {

        tot++;

        S[C[u]]++;

        used[u] = 1;

        for(int i = head[u]; i; i = e[i].nxt)

        {

            sum++;

            int v = e[i].to;

            int w = e[i].va;

            if(used[v] == 0) C[v] = Cal(C[u] + w), DFS(v);

            if(C[v] == 0 || C[v] == Cal(C[u] + w)) continue;

            mrk = 1;

        }

    }

}



using namespace Stdin;

using namespace STD;



void MAIN()

{

    n = read(), m = read();

    for(int i = 1; i <= m; i++)

    {

        int x = read();

        int y = read();

        Add(x, y);

    }

    for(int i = 1; i <= n; i++)

    {

        if(used[i]) continue;

        memset(S, 0, sizeof(S));

        mrk = tot = sum = 0;

        C[i] = 1;

        DFS(i);

        if(mrk) ans += tot * tot;

        else if(S[1] == 0 || S[2] == 0 || S[3] == 0) ans += sum / 2;

        else ans += S[1] * S[2] + S[1] * S[3] + S[2] * S[3];

    }

    printf("%lld\n", ans);

}



INT main()

{

    #ifndef ONLINE_JUDGE

        // freopen("INPUT", "r", stdin);

        // freopen("OUTPUT", "w", stdout);

        // long _begin_time = clock();

    #endif

    

    MAIN();

    

    #ifndef ONLINE_JUDGE

        // long _end_time = clock();

        // printf("time = %ld ms", _end_time - _begin_time);

    #endif

    

    return 0;

}

// Fastest known solution for this problem: