int pos[maxn]; // pos[u] 表示 u 在拓扑序中的位置,用于给出边排序 int ind[maxn];
boolcmp( int x, int y ){ return pos[x] < pos[y]; }
voidsolve( ){ int n = read( ), m = read( ); for( int i = 1; i <= m; ++ i ) { int u = read( ), v = read( ); adj[u].push_back( v ); ind[v] ++; }
queue<int> q; for( int i = 1; i <= n; ++ i ) { if( !ind[i] ) q.push( i ); }
vector<int> ord; // 拓扑序 ord.push_back( 0 ); while( !q.empty( ) ) { int u = q.front( ); q.pop( ); ord.push_back( u ); for( int v : adj[u] ) { if( --ind[v] == 0 ) q.push( v ); } }
for( int i = 1; i <= n; ++ i ) { pos[ord[i]] = i; }
for( int i = 1; i <= n; ++ i ) { sort( adj[i].begin( ), adj[i].end( ), cmp ); }
int ans = 0; for( int i = n; i >= 1; -- i ) { int u = ord[i]; for( int v : adj[u] ) { if( reach[u][v] ) { ans ++; continue; } reach[u] |= reach[v]; reach[u].set( v ); } } printf( "%d\n", ans ); }