stablegradients/pie-gem5-bysrc huggingface dataset:
// Original C++ solution (slower):
#include<cstdio>

#include<iostream>

#include<algorithm>

#include<cstring>

using namespace std;

#define MAXN 200000

#define LL long long

#define INF 1000000000000000000

int n,top;

char s[MAXN+5],stk[MAXN+5];

int main()

{

	scanf("%s",s+1);

	n=strlen(s+1);

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

	{

		if(s[i]=='T')

		{

			if(stk[top]=='S')top--;

			else stk[++top]='T';

		}

		else stk[++top]='S';

	}

	printf("%d",top);

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<cstring>

#include<algorithm>

using namespace std;

#define MAXN 200005

#define LL long long

char s[MAXN];

int main()

{

	scanf("%s",s);

	int len=strlen(s);

	int ss=0,sum=0;

	for(int i=0;i<len;i++)

	{

		if(s[i]=='S') ss++;

		else if(s[i]=='T'&&ss) sum+=2,ss--;

	}

	printf("%d\n",len-sum);

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<cstdio>

#include<iostream>

#include<algorithm>

#include<cstring>

using namespace std;

#define MAXN 200000

#define LL long long

#define INF 1000000000000000000

int n,top;

char s[MAXN+5],stk[MAXN+5];

int main()

{

	scanf("%s",s+1);

	n=strlen(s+1);

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

	{

		if(s[i]=='T')

		{

			if(stk[top]=='S')top--;

			else stk[++top]='T';

		}

		else stk[++top]='S';//

	}

	printf("%d",top);

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<cstring>

#include<algorithm>

using namespace std;

#define MAXN 200005

#define LL long long

char s[MAXN];

int main()

{

	scanf("%s",s);

	int len=strlen(s);

	int ss=0,sum=0;

	for(int i=0;i<len;i++)

	{

		if(s[i]=='S') ss++;

		else if(s[i]=='T'&&ss) sum+=2,ss--;

	}

	printf("%d\n",len-sum);

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<stack>

#include<cstdio>

#include<cstring>

using namespace std;



#define MAXN 200000

int N;

char str[MAXN+5];



int main(){

    scanf("%s",str+1);

    N=strlen(str+1);

    stack<char> S;

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

        if(S.empty()){

            S.push(str[i]);

            continue;

        }

        char tmp=S.top();

        if(tmp=='S'&&str[i]=='T')

            S.pop();

        else

            S.push(str[i]);

    }

    printf("%d",S.size());

}


// Optimized solution to the same problem (faster):
#include<cstdio>

#include<cstring>

#include<algorithm>

using namespace std;

#define MAXN 200005

#define LL long long

char s[MAXN];

int main()

{

	scanf("%s",s);

	int len=strlen(s);

	int ss=0,sum=0;

	for(int i=0;i<len;i++)

	{

		if(s[i]=='S') ss++;

		else if(s[i]=='T'&&ss) sum+=2,ss--;

	}

	printf("%d\n",len-sum);

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <iostream>

using namespace std ;

int main(int argc, char** argv) {

	string str ;

	cin >> str ;

	int len = str.size() ;

	int cntt = 0 ;

	int cnts = 0 ;

	int cntall = 0 ;

	int bank ;

	for ( int i = 0 ; i < len ; i++ ) {

		if ( str[i] == 'S' ) {

			cnts += 1 ;

		}

		else if ( str[i] == 'T' ) {

			if ( cntt == cnts ) {

				cntall += 1 ;

			}

			if ( cnts > cntt ) {

				cntt += 1 ;

			}

		}

	}

	cout << cntall * 2 ;

	return 0;

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<algorithm>

#include<cstring>

using namespace std;

char x[200002];

int n,sums,sumt,ans;

int main()

{

	scanf("%s",x);

	ans=n=strlen(x);

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

	{

		if(x[i]=='S')sums++;

		else	if(sums)sumt++;

		if(sums>=sumt)

		{

			ans-=sumt*2;

			sums-=sumt;

			sumt=0;

		}

	}

	printf("%d",ans);

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

string s;

int ts,tt,ans;

int main(){

	cin>>s;

	if(s[0]=='S')

		ts++;

	else

		tt++;

	for(int i=1;i<(int)s.size();i++){

		if(s[i]!=s[i-1] && s[i]=='T'){

			tt=1;

		}

		else if(s[i]!=s[i-1] && s[i]=='S'){

			ans+=2*(min(ts,tt));

			if(ts>tt)

				ts=ts-tt+1;

			else

				ts=1;

			tt=0;

		}

		else if(s[i]=='S')

			ts++;

		else

			tt++;

	}

	ans+=2*(min(ts,tt));

	cout<<(int)s.size()-ans;

}


// Optimized solution to the same problem (faster):
#include<cstdio>

#include<algorithm>

#include<cstring>

using namespace std;

char x[200002];

int n,sums,sumt,ans;

int main()

{

	scanf("%s",x);

	ans=n=strlen(x);

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

	{

		if(x[i]=='S')sums++;

		else	if(sums)sumt++;

		if(sums>=sumt)

		{

			ans-=sumt*2;

			sums-=sumt;

			sumt=0;

		}

	}

	printf("%d",ans);

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<iostream>

#include<algorithm>

#include<cstdio>

#include<cstring>

#include<string>

using namespace std;

bool flag[200001];

int main()

{

	memset(flag,0,sizeof(flag));

	string c;

	cin>>c;

	int size=c.size();

	for(int i=0;i<size;i++)

	{

		if(!flag[i]&&c[i]=='S')

		{

			for(int j=i+1;j<size;j++)

			{

				if(!flag[j]&&c[j]!='T')

				{

					break;

				}

				else if(!flag[j]&&c[i]=='S'&&c[j]=='T')

				{

					flag[i]=1;flag[j]=1;

					for(int n=1,m=1;n<=i&&j+m<size;)

					{

						while(n<=i&&flag[i-n])

							if(flag[i-n])n++;

						while(j+m<size&&flag[j+m])

							if(flag[j+m])m++;

						if(!flag[i-n]&&!flag[j+m]&&c[i-n]=='S'&&c[j+m]=='T')

						{

							flag[i-n]=1;flag[j+m]=1;

						}

						else

						{

							break;

						}

					}

					break;

				}

			}

		}

	}

	int count=0;

	for(int i=0;i<size;i++)

	{

		

		if(!flag[i]){

			count++;

		}

	}

	cout<<count<<endl;

}


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

#include<string.h>

#include<vector>

using namespace std;

vector<char> Q;

int main()

{

	char s[200005];

	scanf("%s",s);//字符串

	int len=strlen(s);

	//printf("%d\n",len);

	for(int i=0;i<len;i++){

		if(!Q.empty()&&s[i]=='T'&&Q.back()=='S'){

			//把S拿出来

			Q.pop_back();

		}

		else

			Q.push_back(s[i]);//入数组

	}

	int cnt=0;

	while(!Q.empty()){

		Q.pop_back();

		cnt++;

	}

	printf("%d\n",cnt);

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<cstdio>

#include<algorithm>

#include<vector>

using namespace std;



typedef long long ll;

const int MAXN=1e5+5;



int n,m,flag;

int cnt[3],ncnt,ecnt,c[MAXN];

bool vis[MAXN],evis[MAXN];

struct node{

    int v,w,id;

    node(int _v,int _w,int _id):v(_v),w(_w),id(_id){}

};

vector<node> E[MAXN];



void dfs(int u){

    vis[u]=1;

    ncnt++;

    cnt[c[u]]++;

    for(int i=0;i<(int)E[u].size();i++){

        int v=E[u][i].v,w=E[u][i].w,id=E[u][i].id;

        if(evis[id]) continue; evis[id]=1; ecnt++;

        if(!vis[v]){

            c[v]=(c[u]+w+3)%3;

            dfs(v);

        }

        else if(c[v]!=(c[u]+w+3)%3) flag=1;

    }

}



int main(){



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

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

	    int u,v;

        scanf("%d%d",&u,&v);

        E[u].push_back(node(v,1,i));

        E[v].push_back(node(u,-1,i));

	}

	ll ans=0;

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

        if(vis[i]) continue;

        flag=ncnt=ecnt=cnt[0]=cnt[1]=cnt[2]=0;

        dfs(i);

        if(flag) ans+=1ll*ncnt*ncnt;

        else if(!cnt[0]||!cnt[1]||!cnt[2]) ans+=ecnt;

        else ans+=1ll*cnt[0]*cnt[1]+1ll*cnt[1]*cnt[2]+1ll*cnt[2]*cnt[0];

    }

    printf("%lld",ans);



	fclose(stdin);

	fclose(stdout);

}


// Optimized solution to the same problem (faster):
#include<cstdio>

#include<cstring>

#include<algorithm>

using namespace std;

const int N=200005;

typedef long long ll;

int n,m,V,E,cnt[3],col[N];

bool vis[N],vise[N*2],colored;

ll ans;

struct node{

    int u,v,w,nxt;

}edge[N*2];

int head[N],mcnt=1;

void add_edge(int u,int v,int w){

    mcnt++;

    edge[mcnt].u=u;

    edge[mcnt].v=v;

    edge[mcnt].w=w;

    edge[mcnt].nxt=head[u];

    head[u]=mcnt;

}

void dfs(int u)

{

	V++; vis[u]=true;

	cnt[col[u]]++;

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

        if(vise[i|1])

            continue ;

        vise[i|1]=1,E++;

        int v=edge[i].v,w=edge[i].w;

        if(!vis[v]){

            col[v]=(col[u]+w+3)%3;

            dfs(v);

        }

		else if((col[u]+w+3)%3!=col[v])

            colored=true;

	}

}

int main()

{

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

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

	{

		int x,y;

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

		add_edge(x,y,1);

		add_edge(y,x,-1);

	}

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

		if(!vis[i])

		{

			V=E=cnt[0]=cnt[1]=cnt[2]=colored=0;

			dfs(i);

			if(colored)

                ans+=1ll*V*V;

			else

                if(!cnt[0]||!cnt[1]||!cnt[2])

                    ans+=1ll*E;

			else

			ans+=1ll*cnt[0]*cnt[1]+1ll*cnt[1]*cnt[2]+1ll*cnt[0]*cnt[2];

		}

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

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <iostream>

#include <cstring>

#include <vector>

using namespace std;

typedef long long i64;

const int MAXN = 1e5 + 10;



i64 answer;

i64 totCnt;

i64 N, M;

i64 check[MAXN];

i64 cnt[3];



bool flag;



vector<pair<i64, i64> > Adj[MAXN];



inline void addEdge(i64 u, i64 v, i64 w)

{

	Adj[u].emplace_back(v, w);

}



void DFS(int cur)

{

	cnt[check[cur]] ++;



	for(auto x : Adj[cur])

	{

		totCnt += (x.second == 1);



		if(check[x.first] != -1)

		{

			if((check[cur] + x.second) % 3 != check[x.first])

				flag = true;

		}

		else

		{

			check[x.first] = (check[cur] + x.second) % 3;

			DFS(x.first);

		}

	}

}



int main()

{

	ios::sync_with_stdio(false), cin.tie(nullptr);



	cin >> N >> M;

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

	{

		i64 u, v;

		cin >> u >> v;

		addEdge(u, v, 1);

		addEdge(v, u, 2);

	}



	memset(check, -1, sizeof check);



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

	{

		if(check[i] != -1)

			continue;



		check[i] = 0, totCnt = 0;

		cnt[0] = cnt[1] = cnt[2] = 0;

		flag = false;



		DFS(i);

		if(flag)

			answer += (cnt[0] + cnt[1] + cnt[2]) * (cnt[0] + cnt[1] + cnt[2]);

		else if(!cnt[0] || !cnt[1] || !cnt[2])

			answer += totCnt;

		else

			answer += cnt[0] * cnt[1] + cnt[1] * cnt[2] + cnt[2] * cnt[0];



	}



	cout << answer << endl ;



	return 0;

}

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

using namespace std;

#define ll long long

#define REP(i,a,b) for(int i=(a),_end_=(b);i<=_end_;i++)

#define DREP(i,a,b) for(int i=(a),_end_=(b);i>=_end_;i--)

#define EREP(i,u) for(int i=start[u];i;i=e[i].next)

#define fi first

#define se second

#define mkr(a,b) make_pair(a,b)

#define SZ(A) ((int)A.size())

template<class T>inline void chkmin(T &a,T b){ if(a>b)a=b;}

template<class T>inline void chkmax(T &a,T b){ if(a<b)a=b;}

inline int read()

{

	int s=0,f=1;char ch=getchar();

	while(!isdigit(ch) && ch!='-')ch=getchar();

	if(ch=='-')ch=getchar(),f=-1;

	while(isdigit(ch))s=s*10+ch-'0',ch=getchar();

	return ~f?s:-s;

}



const int maxn=1e5+20;



struct node {

	int v,next,w;

};

node e[maxn<<1];

int cnt,start[maxn];

inline void addedge(int u,int v,int w){ e[++cnt]=(node){v,start[u],w};start[u]=cnt;}



int n,m;



int vis[maxn],dis[maxn];



inline void init()

{

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

	REP(i,1,m)

	{

		int u=read(),v=read();

		addedge(u,v,1);

		addedge(v,u,2);

	}

}



int num[3],EDGE;

int flg;



void dfs(int u)

{

	++num[dis[u]]; vis[u]=1;

	EREP(i,u)

	{

		EDGE++;

		int v=e[i].v;

		if(vis[v])

		{

			if(dis[v]==(dis[u]+e[i].w)%3)continue;

			else flg=1;

		}else dis[v]=(dis[u]+e[i].w)%3,dfs(v);

	}

}



ll ans;



inline void doing()

{

	REP(i,1,n)if(!vis[i])

	{

		memset(num,0,sizeof(num));EDGE=0;

		flg=0;

		dfs(i);

		int all=num[0]+num[1]+num[2];

		if(flg)ans+=(ll)all*all;

		else {

			if(num[0] && num[1] && num[2])REP(op,0,2)ans+=(ll)num[op]*num[(op+1)%3];

			else ans+=EDGE>>1;

		}

	}

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

}



int main()

{

	init();

	doing();

	return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<iostream>

#include<cstdio>

#include<cstdlib>

#include<cstring>

#include<algorithm>

using namespace std;



#define ll long long

#define mem(Arr,x) memset(Arr,x,sizeof(Arr))



const int maxN=100010;

const int maxM=maxN*2;

const int inf=2147483647;



int n,m;

int edgecnt=-1,Head[maxN],Next[maxM],V[maxM],W[maxM];

int Col[maxN];

bool getring;

ll edge,node;

bool vis[maxN];

ll Aper[3];



void Add_Edge(int u,int v,int w);

void dfs(int u,int col);



int main()

{

	ios::sync_with_stdio(false);mem(Head,-1);

	cin>>n>>m;

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

		int u,v;cin>>u>>v;Add_Edge(u,v,1);Add_Edge(v,u,2);

	}

	mem(Col,-1);

	ll Ans=0;

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

		if (Col[i]==-1)

		{

			getring=0;edge=0;node=0;Aper[0]=Aper[1]=Aper[2]=0;

			dfs(i,0);

			//cout<<getring<<" "<<edge<<" "<<node<<" "<<Aper[0]<<" "<<Aper[1]<<" "<<Aper[2]<<endl;

			if (getring) Ans+=(ll)node*node;

			else if ((Aper[0]==0)||(Aper[1]==0)||(Aper[2]==0)) Ans+=edge;

			else Ans+=(ll)Aper[0]*Aper[1]+(ll)Aper[1]*Aper[2]+(ll)Aper[2]*Aper[0];

		}

	cout<<Ans<<endl;

	return 0;

}



void Add_Edge(int u,int v,int w)

{

	edgecnt++;Next[edgecnt]=Head[u];Head[u]=edgecnt;V[edgecnt]=v;W[edgecnt]=w;

	return;

}



void dfs(int u,int col)

{

	if (Col[u]!=-1)

	{

		if (Col[u]!=col) getring=1;

		return;

	}

	

	Col[u]=col;Aper[col]++;node++;

	for (int i=Head[u];i!=-1;i=Next[i])

	{

		if (vis[i>>1]==0) vis[i>>1]=1,edge++;

		dfs(V[i],(col+W[i])%3);

	}

	return;

}


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

using namespace std;

const int N=2e5+10;

typedef long long ll;

int gi() {

    int x=0,o=1;char ch=getchar();

    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();

    if(ch=='-') o=-1,ch=getchar();

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

    return x*o;

}

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

int tot=1,h[N];

void adde(int u,int v) {

    e[++tot]=(edge){v,1,h[u]};h[u]=tot;

    e[++tot]=(edge){u,-1,h[v]};h[v]=tot;

}

int n,m,V,E,col[N],cnt[3];

bool vis[N],vise[N];

ll ans=0;

bool flag=0;

void dfs(int u) {

    V++;vis[u]=1;

    cnt[col[u]]++;

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

        if(vise[i>>1]) continue; vise[i>>1]=1,E++;

        int v=e[i].to;

        if(!vis[v]) col[v]=(col[u]+e[i].w+3)%3,dfs(v);

        else if(col[v]!=(col[u]+e[i].w+3)%3) flag=1;

    }

}

int main() {

    cin>>n>>m;

    for(int i=1,u,v;i<=m;i++) u=gi(),v=gi(),adde(u,v);

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

        if(!vis[i]) {

            V=E=cnt[0]=cnt[1]=cnt[2]=0;flag=0;dfs(i);

            if(flag) ans+=1ll*V*V;

            else if(!cnt[0]||!cnt[1]||!cnt[2]) ans+=E;

            else ans+=1ll*cnt[0]*cnt[1]+1ll*cnt[1]*cnt[2]+1ll*cnt[2]*cnt[0];

        }

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

    return 0;

}

//orzgzy

//鸡贼明年进队超稳


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

const int N=2e5+10;

typedef long long ll;

int gi() {

    int x=0,o=1;char ch=getchar();

    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();

    if(ch=='-') o=-1,ch=getchar();

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

    return x*o;

}

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

int tot=1,h[N];

void adde(int u,int v) {

    e[++tot]=(edge){v,1,h[u]};h[u]=tot;

    e[++tot]=(edge){u,-1,h[v]};h[v]=tot;

}

int n,m,V,E,col[N],cnt[3];

bool vis[N],vise[N];

ll ans=0;

bool flag=0;

void dfs(int u) {

    V++;vis[u]=1;

    cnt[col[u]]++;

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

        if(vise[i>>1]) continue; vise[i>>1]=1,E++;

        int v=e[i].to;

        if(!vis[v]) col[v]=(col[u]+e[i].w+3)%3,dfs(v);

        else if(col[v]!=(col[u]+e[i].w+3)%3) flag=1;

    }

}

int main() {

	//freopen("flower.in","r",stdin);

	//freopen("flower.out","w",stdout);

    cin>>n>>m;

    for(int i=1,u,v;i<=m;i++) u=gi(),v=gi(),adde(u,v);

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

        if(!vis[i]) {

            V=E=cnt[0]=cnt[1]=cnt[2]=0;flag=0;dfs(i);

            if(flag) ans+=1ll*V*V;

            else if(!cnt[0]||!cnt[1]||!cnt[2]) ans+=E;

            else ans+=1ll*cnt[0]*cnt[1]+1ll*cnt[1]*cnt[2]+1ll*cnt[2]*cnt[0];

        }

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

    return 0;

}


// Optimized solution to the same problem (faster):
#include<cstdio>

#include<cstring>

#include<algorithm>

#define MAXN 100000

using namespace std;

typedef long long LL;

struct node

{

	int to,w;

	node *nxt;

}edges[MAXN*4+5];

node *ncnt,*Adj[MAXN+5];

int N,M;

int col[MAXN+5],cnt[3],edcnt=0;

bool legal=true;

void Init()

{

	ncnt=&edges[0];

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

}

void AddEdge(int u,int v,int w)

{

	node *p=++ncnt;

	p->to=v;

	p->w=w;

	p->nxt=Adj[u];

	Adj[u]=p;

}

void DFS(int u)

{

	cnt[col[u]]++;

	for(node *p=Adj[u];p!=NULL;p=p->nxt)

	{

		int v=p->to;

		int w=p->w;

		if(w==1)

			edcnt++;

		if(col[v]==-1)

		{

			col[v]=(col[u]+w)%3;

			DFS(v);

		}

		else if(col[v]!=(col[u]+w)%3)

			legal=false;

	}

}

int main()

{

//	freopen("flower.in","r",stdin);

//	freopen("flower.out","w",stdout);

	Init();

	scanf("%d %d",&N,&M);

	int u,v;

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

	{

		scanf("%d %d",&u,&v);

		AddEdge(u,v,1);

		AddEdge(v,u,2);

	}

	LL ans=0;

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

		if(col[i]==-1)

		{

			edcnt=0;

			legal=true;

			memset(cnt,0,sizeof(cnt));

			col[i]=0;

			DFS(i);

			if(legal==false)

				ans+=(1LL*cnt[0]+1LL*cnt[1]+1LL*cnt[2])*(1LL*cnt[0]+1LL*cnt[1]+1LL*cnt[2]);

			else if(cnt[0]==0||cnt[1]==0||cnt[2]==0)

				ans+=1LL*edcnt;

			else if(legal==true)

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

		}

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

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>

 

using namespace std;

using namespace __gnu_pbds;

 

#define fi first

#define se second

#define mp make_pair

#define pb push_back

#define fbo find_by_order

#define ook order_of_key

 

typedef long long ll;

typedef pair<ll,ll> ii;

typedef vector<int> vi;

typedef long double ld; 

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;

typedef set<int>::iterator sit;

typedef map<int,int>::iterator mit;

typedef vector<int>::iterator vit;

 

vi adj[100001];

int out[100001];

int in[100001];

vi type[100001];

int color[100001];

bool used2 = false;

int cnt = 0;

int c[3];

ll mm = 0;

ll tote = 0;

bool dfs(int u, int col)

{

	used2|=(in[u]&&out[u]);

	cnt++; c[col]++;

	color[u] = col;

	bool res = 1;

	mm += out[u];

	tote++;

	for(int i = 0; i < adj[u].size(); i++)

	{

		int v = adj[u][i];

		int nw = (col+type[u][i])%3;

		if(color[v] == -1)

		{

			res&=dfs(v, nw);

		}

		else

		{

			if(color[v] != nw) res=false;

		}

	}

	return res;

}

 

int main()

{

	ios_base::sync_with_stdio(0); cin.tie(0);

	int n, m; cin>>n>>m;

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

	{

		int u, v; cin>>u>>v; u--; v--;

		adj[u].pb(v); adj[v].pb(u);

		type[u].pb(1); type[v].pb(2);

		out[u]++; in[v]++;

	}

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

	ll res = 0;

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

	{

		if(color[i] == -1)

		{

			used2 = false; cnt = 0;

			memset(c,0,sizeof(c));

			mm = 0; tote = 0;

			bool ans=dfs(i, 0);

			//cerr<<c[0]<<' '<<c[1]<<' '<<c[2]<<' '<<mm<<'\n';

			if(ans)

			{

				if(used2)

				{

					for(int j = 0; j < 3; j++)

					{

						res += ll(c[j])*ll(c[(j+1)%3]);

					}

				}

				else

				{

					res += mm;

				}

			}

			else

			{	

				res += ll(tote)*ll(tote);

			}

		}

	}

	cout<<res<<'\n';

}


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

#define ll long long

using namespace std;

const int N=1e5+10;

int n,m,cnt,num1,num2,chk;

int head[N],vis[N],col[N],to[N<<1],nxt[N<<1],val[N<<1],stk[3];

ll ans;

inline void add(int u,int v,int w){

	to[++cnt]=v,nxt[cnt]=head[u],val[cnt]=w,head[u]=cnt;

}

inline int tp(int x){ x=(x%3+3)%3; return x; }

void dfs(int u,int c){

	vis[u]=1,col[u]=c,stk[col[u]]++,num1++;

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

		int v=to[i];

		num2+=(val[i]==1);

		if(!vis[v]) dfs(v,tp(col[u]+val[i]));

		else if(col[v]!=tp(col[u]+val[i])) chk=1;

	}

}

int main(){

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

	for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); add(u,v,1),add(v,u,-1); }

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

		if(vis[i]) continue; 

		num1=0,num2=0,chk=0; stk[0]=stk[1]=stk[2]=0; 

		dfs(i,0);

		if(chk) ans+=1ll*num1*num1;

		else if(stk[0] && stk[1] && stk[2]) ans+=1ll*stk[0]*stk[1]+1ll*stk[1]*stk[2]+1ll*stk[2]*stk[0];

		else ans+=num2;

	}

	printf("%lld",ans);

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

#define ll long long

const int N=100005;

int n,m,cc,ff,sv,se,hd[N],vis[N],f[3];ll ans;

struct E{int v,nxt,w;}e[N*2];

inline void add(int u,int v,int w){e[++cc]=(E){v,hd[u],w};hd[u]=cc;}

void dfs(int x,int c)

{

	vis[x]=c;f[c]++;sv++;

	for(int i=hd[x];i;i=e[i].nxt)

	{

		int y=e[i].v;se+=(e[i].w==1);

		if(vis[y]==-1)dfs(y,(c+e[i].w)%3);

		else if(vis[y]!=(c+e[i].w)%3)ff=0;

	}

}

int main()

{

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

	for(int i=1,u,v;i<=m;i++)scanf("%d%d",&u,&v),add(u,v,1),add(v,u,2);

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

	for(int i=1;i<=n;i++)if(vis[i]==-1)

	{

		ff=1;f[0]=f[1]=f[2]=0;sv=se=0;dfs(i,0);

		ans+=!ff?1ll*sv*sv:(!min(f[0],min(f[1],f[2]))?se:(1ll*f[0]*f[1]+1ll*f[1]*f[2]+1ll*f[2]*f[0]));

	}

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

}


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

#define ll long long

using namespace std;

const int N=1e5+10;

int n,m,cnt,num1,num2,chk;

int head[N],vis[N],col[N],to[N<<1],nxt[N<<1],val[N<<1],stk[3];

ll ans;

inline void add(int u,int v,int w){

	to[++cnt]=v,nxt[cnt]=head[u],val[cnt]=w,head[u]=cnt;

}

inline int tp(int x){ x=(x%3+3)%3; return x; }

void dfs(int u,int c){

	vis[u]=1,col[u]=c,stk[col[u]]++,num1++;

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

		int v=to[i];

		num2+=(val[i]==1);

		if(!vis[v]) dfs(v,tp(col[u]+val[i]));

		else if(col[v]!=tp(col[u]+val[i])) chk=1;

	}

}

int main(){

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

	for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); add(u,v,1),add(v,u,-1); }

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

		if(vis[i]) continue; 

		num1=0,num2=0,chk=0; stk[0]=stk[1]=stk[2]=0; 

		dfs(i,0);

		if(chk) ans+=1ll*num1*num1;

		else if(stk[0] && stk[1] && stk[2]) ans+=1ll*stk[0]*stk[1]+1ll*stk[1]*stk[2]+1ll*stk[2]*stk[0];

		else ans+=num2;

	}

	printf("%lld",ans);

}

// Fastest known solution for this problem: