#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
void * wmem;
char memarr[ 96000000 ] ;
template < class T> inline void walloc1d( T ** arr, int x, void ** mem = & wmem) {
static int skip[ 16 ] = { 0 , 15 , 14 , 13 , 12 , 11 , 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 } ;
( * mem) = ( void * ) ( ( ( char * ) ( * mem) ) + skip[ ( ( unsigned long long ) ( * mem) ) & 15 ] ) ;
( * arr) = ( T* ) ( * mem) ;
( * mem) = ( ( * arr) + x) ;
}
struct graph{
int N;
int * es;
int ** edge;
void setEdge( int N__, int M, int A[ ] , int B[ ] , void ** mem = & wmem) {
int i;
N = N__;
walloc1d( & es, N, mem) ;
walloc1d( & edge, N, mem) ;
for ( i= 0 ; i< ( N) ; i++ ) {
es[ i] = 0 ;
}
for ( i= 0 ; i< ( M) ; i++ ) {
es[ A[ i] ] ++ ;
es[ B[ i] ] ++ ;
}
for ( i= 0 ; i< ( N) ; i++ ) {
walloc1d( & edge[ i] , es[ i] , mem) ;
}
for ( i= 0 ; i< ( N) ; i++ ) {
es[ i] = 0 ;
}
for ( i= 0 ; i< ( M) ; i++ ) {
edge[ A[ i] ] [ es[ A[ i] ] ++ ] = B[ i] ;
edge[ B[ i] ] [ es[ B[ i] ] ++ ] = A[ i] ;
}
}
inline void bccDFS( int v, int u, int * res, int * rt, int & rts, int * S, int & Ss, int * inS, int * num, int & tm ) {
int i;
int k;
num[ v] = ++ tm ;
S[ Ss++ ] = v;
inS[ v] = 1 ;
rt[ rts++ ] = v;
for ( i= 0 ; i< ( es[ v] ) ; i++ ) {
int w = edge[ v] [ i] ;
if ( ! num[ w] ) {
bccDFS( w, v, res, rt, rts, S, Ss, inS, num, tm ) ;
}
else if ( u ! = w && inS[ w] ) {
while ( num[ rt[ rts- 1 ] ] > num[ w] ) {
rts-- ;
}
}
}
if ( v == rt[ rts- 1 ] ) {
k = S[ Ss- 1 ] ;
for ( ;; ) {
int w = S[ -- Ss] ;
inS[ w] = 0 ;
res[ w] = k;
if ( v== w) {
break ;
}
}
rts-- ;
}
}
int bcc( int res[ ] , void * mem= wmem) {
int i;
int k;
int * rt;
int * S;
int * num;
int * inS;
pair< int ,int > * arr;
int rts = 0 ;
int Ss = 0 ;
int tm = 0 ;
walloc1d( & num, N, & mem) ;
walloc1d( & rt, N, & mem) ;
walloc1d( & S, N, & mem) ;
walloc1d( & inS, N, & mem) ;
memset ( num, 0 , sizeof ( int ) * N) ;
memset ( inS, 0 , sizeof ( int ) * N) ;
for ( i= 0 ; i< ( N) ; i++ ) {
if ( ! num[ i] ) {
bccDFS( i, N, res, rt, rts, S, Ss, inS, num, tm ) ;
}
}
arr = ( pair< int ,int > * ) mem;
for ( i= 0 ; i< ( N) ; i++ ) {
arr[ i] .first = res[ i] ;
arr[ i] .second = i;
}
sort( arr, arr+ N) ;
k = 0 ;
for ( i= 0 ; i< ( N) ; i++ ) {
if ( i && arr[ i] .first ! = arr[ i- 1 ] .first ) {
k++ ;
}
res[ arr[ i] .second ] = k;
}
return k+ 1 ;
}
}
;
#define main dummy_main
int main( ) {
wmem = memarr;
return 0 ;
}
#undef main
int M;
int A[ 100000 ] ;
int B[ 100000 ] ;
int bc[ 100000 ] ;
class Solution{
public :
vector< vector< int >> criticalConnections( int N, vector< vector< int >> & connections) {
int i;
dummy_main( ) ;
graph g;
vector< vector< int > > res;
void * mem = wmem;
M = connections.size ( ) ;
for ( i= 0 ; i< ( M) ; i++ ) {
A[ i] = connections[ i] [ 0 ] ;
B[ i] = connections[ i] [ 1 ] ;
}
g.setEdge ( N,M,A,B) ;
g.bcc ( bc) ;
for ( i= 0 ; i< ( M) ; i++ ) {
if ( bc[ A[ i] ] ! = bc[ B[ i] ] ) {
res.push_back ( connections[ i] ) ;
}
}
wmem = mem;
return res;
}
}
;
// cLay varsion 20190914-1
// --- original code ---
// #define main dummy_main
// {}
// #undef main
//
// int M, A[1d5], B[1d5];
// int bc[1d5];
//
// class Solution {
// public:
// vector<vector<int>> criticalConnections(int N, vector<vector<int>>& connections) {
// dummy_main();
//
// graph g;
// vector<vector<int> > res;
// void *mem = wmem;
//
// M = connections.size();
// rep(i,M){
// A[i] = connections[i][0];
// B[i] = connections[i][1];
// }
// g.setEdge(N,M,A,B);
// g.bcc(bc);
//
// rep(i,M) if(bc[A[i]] != bc[B[i]]) res.push_back(connections[i]);
//
// wmem = mem;
// return res;
// }
// };
I3ByYWdtYSBHQ0Mgb3B0aW1pemUgKCJPZmFzdCIpCiNpbmNsdWRlPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CnZvaWQgKndtZW07CmNoYXIgbWVtYXJyWzk2MDAwMDAwXTsKdGVtcGxhdGU8Y2xhc3MgVD4gaW5saW5lIHZvaWQgd2FsbG9jMWQoVCAqKmFyciwgaW50IHgsIHZvaWQgKiptZW0gPSAmd21lbSl7CiAgc3RhdGljIGludCBza2lwWzE2XSA9IHswLCAxNSwgMTQsIDEzLCAxMiwgMTEsIDEwLCA5LCA4LCA3LCA2LCA1LCA0LCAzLCAyLCAxfTsKICAoKm1lbSkgPSAodm9pZCopKCAoKGNoYXIqKSgqbWVtKSkgKyBza2lwWygodW5zaWduZWQgbG9uZyBsb25nKSgqbWVtKSkgJiAxNV0gKTsKICAoKmFycik9KFQqKSgqbWVtKTsKICAoKm1lbSk9KCgqYXJyKSt4KTsKfQpzdHJ1Y3QgZ3JhcGh7CiAgaW50IE47CiAgaW50ICplczsKICBpbnQgKiplZGdlOwogIHZvaWQgc2V0RWRnZShpbnQgTl9fLCBpbnQgTSwgaW50IEFbXSwgaW50IEJbXSwgdm9pZCAqKm1lbSA9ICZ3bWVtKXsKICAgIGludCBpOwogICAgTiA9IE5fXzsKICAgIHdhbGxvYzFkKCZlcywgTiwgbWVtKTsKICAgIHdhbGxvYzFkKCZlZGdlLCBOLCBtZW0pOwogICAgZm9yKGk9MDtpPChOKTtpKyspewogICAgICBlc1tpXSA9IDA7CiAgICB9CiAgICBmb3IoaT0wO2k8KE0pO2krKyl7CiAgICAgIGVzW0FbaV1dKys7CiAgICAgIGVzW0JbaV1dKys7CiAgICB9CiAgICBmb3IoaT0wO2k8KE4pO2krKyl7CiAgICAgIHdhbGxvYzFkKCZlZGdlW2ldLCBlc1tpXSwgbWVtKTsKICAgIH0KICAgIGZvcihpPTA7aTwoTik7aSsrKXsKICAgICAgZXNbaV0gPSAwOwogICAgfQogICAgZm9yKGk9MDtpPChNKTtpKyspewogICAgICBlZGdlW0FbaV1dW2VzW0FbaV1dKytdID0gQltpXTsKICAgICAgZWRnZVtCW2ldXVtlc1tCW2ldXSsrXSA9IEFbaV07CiAgICB9CiAgfQogIGlubGluZSB2b2lkIGJjY0RGUyhpbnQgdiwgaW50IHUsIGludCAqcmVzLCBpbnQgKnJ0LCBpbnQgJnJ0cywgaW50ICpTLCBpbnQgJlNzLCBpbnQgKmluUywgaW50ICpudW0sIGludCAmdG0pewogICAgaW50IGk7CiAgICBpbnQgazsKICAgIG51bVt2XSA9ICsrdG07CiAgICBTW1NzKytdID0gdjsKICAgIGluU1t2XSA9IDE7CiAgICBydFtydHMrK10gPSB2OwogICAgZm9yKGk9MDtpPChlc1t2XSk7aSsrKXsKICAgICAgaW50IHcgPSBlZGdlW3ZdW2ldOwogICAgICBpZighbnVtW3ddKXsKICAgICAgICBiY2NERlModywgdiwgcmVzLCBydCwgcnRzLCBTLCBTcywgaW5TLCBudW0sIHRtKTsKICAgICAgfQogICAgICBlbHNlIGlmKHUgIT0gdyAmJiBpblNbd10pewogICAgICAgIHdoaWxlKG51bVtydFtydHMtMV1dID4gbnVtW3ddKXsKICAgICAgICAgIHJ0cy0tOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgaWYodiA9PSBydFtydHMtMV0pewogICAgICBrID0gU1tTcy0xXTsKICAgICAgZm9yKDs7KXsKICAgICAgICBpbnQgdyA9IFNbLS1Tc107CiAgICAgICAgaW5TW3ddID0gMDsKICAgICAgICByZXNbd10gPSBrOwogICAgICAgIGlmKHY9PXcpewogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJ0cy0tOwogICAgfQogIH0KICBpbnQgYmNjKGludCByZXNbXSwgdm9pZCAqbWVtPXdtZW0pewogICAgaW50IGk7CiAgICBpbnQgazsKICAgIGludCAqcnQ7CiAgICBpbnQgKlM7CiAgICBpbnQgKm51bTsKICAgIGludCAqaW5TOwogICAgcGFpcjxpbnQsaW50PiAqYXJyOwogICAgaW50IHJ0cyA9IDA7CiAgICBpbnQgU3MgPSAwOwogICAgaW50IHRtID0gMDsKICAgIHdhbGxvYzFkKCZudW0sIE4sICZtZW0pOwogICAgd2FsbG9jMWQoJnJ0LCBOLCAmbWVtKTsKICAgIHdhbGxvYzFkKCZTLCBOLCAmbWVtKTsKICAgIHdhbGxvYzFkKCZpblMsIE4sICZtZW0pOwogICAgbWVtc2V0KG51bSwgMCwgc2l6ZW9mKGludCkqTik7CiAgICBtZW1zZXQoaW5TLCAwLCBzaXplb2YoaW50KSpOKTsKICAgIGZvcihpPTA7aTwoTik7aSsrKXsKICAgICAgaWYoIW51bVtpXSl7CiAgICAgICAgYmNjREZTKGksIE4sIHJlcywgcnQsIHJ0cywgUywgU3MsIGluUywgbnVtLCB0bSk7CiAgICAgIH0KICAgIH0KICAgIGFyciA9IChwYWlyPGludCxpbnQ+KiltZW07CiAgICBmb3IoaT0wO2k8KE4pO2krKyl7CiAgICAgIGFycltpXS5maXJzdCA9IHJlc1tpXTsKICAgICAgYXJyW2ldLnNlY29uZCA9IGk7CiAgICB9CiAgICBzb3J0KGFyciwgYXJyK04pOwogICAgayA9IDA7CiAgICBmb3IoaT0wO2k8KE4pO2krKyl7CiAgICAgIGlmKGkgJiYgYXJyW2ldLmZpcnN0ICE9IGFycltpLTFdLmZpcnN0KXsKICAgICAgICBrKys7CiAgICAgIH0KICAgICAgcmVzW2FycltpXS5zZWNvbmRdID0gazsKICAgIH0KICAgIHJldHVybiBrKzE7CiAgfQp9CjsKI2RlZmluZSBtYWluIGR1bW15X21haW4KaW50IG1haW4oKXsKICB3bWVtID0gbWVtYXJyOwogIHJldHVybiAwOwp9CiN1bmRlZiBtYWluCmludCBNOwppbnQgQVsxMDAwMDBdOwppbnQgQlsxMDAwMDBdOwppbnQgYmNbMTAwMDAwXTsKY2xhc3MgU29sdXRpb257CiAgcHVibGljOgogIHZlY3Rvcjx2ZWN0b3I8aW50Pj4gY3JpdGljYWxDb25uZWN0aW9ucyhpbnQgTiwgdmVjdG9yPHZlY3RvcjxpbnQ+PiYgY29ubmVjdGlvbnMpewogICAgaW50IGk7CiAgICBkdW1teV9tYWluKCk7CiAgICBncmFwaCBnOwogICAgdmVjdG9yPHZlY3RvcjxpbnQ+ID4gcmVzOwogICAgdm9pZCAqbWVtID0gd21lbTsKICAgIE0gPSBjb25uZWN0aW9ucy5zaXplKCk7CiAgICBmb3IoaT0wO2k8KE0pO2krKyl7CiAgICAgIEFbaV0gPSBjb25uZWN0aW9uc1tpXVswXTsKICAgICAgQltpXSA9IGNvbm5lY3Rpb25zW2ldWzFdOwogICAgfQogICAgZy5zZXRFZGdlKE4sTSxBLEIpOwogICAgZy5iY2MoYmMpOwogICAgZm9yKGk9MDtpPChNKTtpKyspewogICAgICBpZihiY1tBW2ldXSAhPSBiY1tCW2ldXSl7CiAgICAgICAgcmVzLnB1c2hfYmFjayhjb25uZWN0aW9uc1tpXSk7CiAgICAgIH0KICAgIH0KICAgIHdtZW0gPSBtZW07CiAgICByZXR1cm4gcmVzOwogIH0KfQo7Ci8vIGNMYXkgdmFyc2lvbiAyMDE5MDkxNC0xCgovLyAtLS0gb3JpZ2luYWwgY29kZSAtLS0KLy8gI2RlZmluZSBtYWluIGR1bW15X21haW4KLy8ge30KLy8gI3VuZGVmIG1haW4KLy8gCi8vIGludCBNLCBBWzFkNV0sIEJbMWQ1XTsKLy8gaW50IGJjWzFkNV07Ci8vIAovLyBjbGFzcyBTb2x1dGlvbiB7Ci8vIHB1YmxpYzoKLy8gICB2ZWN0b3I8dmVjdG9yPGludD4+IGNyaXRpY2FsQ29ubmVjdGlvbnMoaW50IE4sIHZlY3Rvcjx2ZWN0b3I8aW50Pj4mIGNvbm5lY3Rpb25zKSB7Ci8vICAgICBkdW1teV9tYWluKCk7Ci8vIAovLyAgICAgZ3JhcGggZzsKLy8gICAgIHZlY3Rvcjx2ZWN0b3I8aW50PiA+IHJlczsKLy8gICAgIHZvaWQgKm1lbSA9IHdtZW07Ci8vIAovLyAgICAgTSA9IGNvbm5lY3Rpb25zLnNpemUoKTsKLy8gICAgIHJlcChpLE0pewovLyAgICAgICBBW2ldID0gY29ubmVjdGlvbnNbaV1bMF07Ci8vICAgICAgIEJbaV0gPSBjb25uZWN0aW9uc1tpXVsxXTsKLy8gICAgIH0KLy8gICAgIGcuc2V0RWRnZShOLE0sQSxCKTsKLy8gICAgIGcuYmNjKGJjKTsKLy8gCi8vICAgICByZXAoaSxNKSBpZihiY1tBW2ldXSAhPSBiY1tCW2ldXSkgcmVzLnB1c2hfYmFjayhjb25uZWN0aW9uc1tpXSk7Ci8vIAovLyAgICAgd21lbSA9IG1lbTsKLy8gICAgIHJldHVybiByZXM7Ci8vICAgfQovLyB9Owo=