#include<bits/stdc++.h>
using namespace std;

#pragma GCC target("avx,avx2,fma")
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")

#define s second
#define f first

const int maxn = 1e5 + 10;
const int inf = 1e9 + 7;

int t;
int n, m;
int h[maxn];
int up[maxn];
int st[maxn];
int ft[maxn];
int top[maxn];
bool mk[maxn];
int mark[maxn];
int getup[maxn];
vector<int> ans;
vector<int> adj[maxn];
int partialmarshal[maxn];
vector<pair<pair<int, int>, int>> edge;
pair<int, pair<int, int>> tmp[4];
pair<int, pair<int, int>> down[maxn][2];

void in();
void solve();
void check(int);
void dfs(int);
void dfs2(int, int par = -1);
bool cmp(pair<pair<int, int>, int>, pair<pair<int, int>, int>);
void upd(int, pair<int, pair<int, int>>, pair<int, pair<int, int>>);
void out();

int main(){
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);
    in();
    solve();
    out();
}

void in(){
    cin >> n >> m;
    for(int i = 0; i < m; i++){
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        edge.push_back({{u, v}, i});
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
}

void solve(){
    for(int i = 0; i < n; i++){
        if(!mark[i]){
            getup[i] = -1;
            dfs(i);
            dfs2(i);
        }
    }
    sort(edge.begin(), edge.end(), cmp);
    for(int i = 0; i < m; i++){
        if(h[edge[i].f.f] < h[edge[i].f.s])
            swap(edge[i].f.f, edge[i].f.s);
        if(h[edge[i].f.f] - h[edge[i].f.s] == 1)
            top[edge[i].f.f] = i;
    }
    for(int i = 0; i < m; i++)
        check(i);
}

bool cmp(pair<pair<int, int>, int> A, pair<pair<int, int>, int> B){
    pair<int, int> a = A.f;
    pair<int, int> b = B.f;
    if(h[a.f] < h[a.s])
        swap(a.f, a.s);
    if(h[b.f] < h[b.s])
        swap(b.f, b.s);
    int modea = h[a.f] - h[a.s];
    int modeb = h[b.f] - h[b.s];
    if(modea == modeb)
        return h[a.s] < h[b.s];
    return modea < modeb;
}

void check(int e){
    int u = edge[e].f.s;
    int v = edge[e].f.f;
    bool fc = 0;
    if(h[v] - h[u] == 1){
        bool ec = 0;
        if(down[v][0].f <= h[u] && down[v][1].f > h[u]){
            if(down[v][0].f < h[u])
                ec = 1;
            int U = down[v][0].s.f;
            int V = down[v][0].s.s;
            if(getup[U] == h[V] && down[U][1].f >= h[U] && partialmarshal[U] - partialmarshal[V] == 1)
                fc = 1;
        }
        if(ec && !mk[top[u]])
            fc = 0;
    }
    else
        fc = mk[top[v]];
    if(fc){
        mk[e] = 1;
        ans.push_back(edge[e].s + 1);
    }
}

void dfs(int u){
    up[u] = -1;
    st[u] = t++;
    down[u][0] = {inf, {0, 0}};
    down[u][1] = {inf, {0, 0}};
    mark[u] = 1;
    for(auto v: adj[u]){
        if(!mark[v]){
            h[v] = h[u] + 1;
            dfs(v);
            upd(u, down[v][0], down[v][1]);
        }
        else if(h[u] - 1 > h[v]){
            up[u] = max(up[u], h[v]);
            upd(u, {h[v], {u, v}}, {inf, {0, 0}});
        }
    }
    ft[u] = t;
}

void dfs2(int u, int par){
    getup[u] = max(getup[u], up[u]);
    mark[u] = 2;
    if(par != -1){
        for(auto v: adj[par])
            if(h[v] > h[par] + 1 && st[u] < st[v] && ft[v] <= ft[u])
                partialmarshal[u]++;
    }
    for(auto v: adj[u]){
        if(mark[v] == 1){
            partialmarshal[v] = partialmarshal[u];
            getup[v] = getup[u];
            dfs2(v, u);
        }
    }
}

void upd(int i, pair<int, pair<int, int>> a, pair<int, pair<int, int>> b){
    tmp[0] = a;
    tmp[1] = b;
    tmp[2] = down[i][0];
    tmp[3] = down[i][1];
    sort(tmp, tmp + 4);
    down[i][0] = tmp[0];
    down[i][1] = tmp[1];
}

void out(){
    sort(ans.begin(), ans.end());
    cout << ans.size() << '\n';
    for(auto x: ans)
        cout << x << ' ';
}


#include<bits/stdc++.h>
using namespace std;

#define s second
#define f first

const int maxn = 1e5 + 10;
const int inf = 1e9 + 7;

int n, m;
int h[maxn];
int up[maxn];
int top[maxn];
bool mk[maxn];
int mark[maxn];
int getup[maxn];
vector<int> ans;
vector<int> adj[maxn];
vector<pair<pair<int, int>, int>> edge;
pair<int, pair<int, int>> tmp[4];
pair<int, pair<int, int>> down[maxn][2];

void in();
void solve();
void check(int);
void dfs(int);
void dfs2(int);
bool cmp(pair<pair<int, int>, int>, pair<pair<int, int>, int>);
void upd(int, pair<int, pair<int, int>>, pair<int, pair<int, int>>);
void out();

int main(){
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);
    in();
    solve();
    out();
}

void in(){
    cin >> n >> m;
    for(int i = 0; i < m; i++){
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        edge.push_back({{u, v}, i});
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
}

void solve(){
    for(int i = 0; i < n; i++){
        if(!mark[i]){
            dfs(i);
            dfs2(i);
        }
    }
    sort(edge.begin(), edge.end(), cmp);
    for(int i = 0; i < m; i++){
        if(h[edge[i].f.f] < h[edge[i].f.s])
            swap(edge[i].f.f, edge[i].f.s);
        if(h[edge[i].f.f] - h[edge[i].f.s] == 1)
            top[edge[i].f.f] = i;
    }
    for(int i = 0; i < m; i++)
        check(i);
}

bool cmp(pair<pair<int, int>, int> A, pair<pair<int, int>, int> B){
    pair<int, int> a = A.f;
    pair<int, int> b = B.f;
    if(h[a.f] < h[a.s])
        swap(a.f, a.s);
    if(h[b.f] < h[b.s])
        swap(b.f, b.s);
    int modea = h[a.f] - h[a.s];
    int modeb = h[b.f] - h[b.s];
    if(modea == modeb)
        return h[a.s] < h[b.s];
    return modea < modeb;
}

void check(int e){
    int u = edge[e].f.s;
    int v = edge[e].f.f;
    bool fc = 0;
    if(h[v] - h[u] == 1){
        bool ec = 0;
        if(down[v][0].f <= h[u] && down[v][1].f > h[u]){
            if(down[v][0].f < h[u])
                ec = 1;
            int U = down[v][0].s.f;
            int V = down[v][0].s.s;
            if(getup[U] - getup[V] == 1)
                fc = 1;
        }
        if(ec && !mk[top[u]])
            fc = 0;
    }
    else
        fc = mk[top[v]];
    if(fc){
        mk[e] = 1;
        ans.push_back(edge[e].s + 1);
    }
}

void dfs(int u){
    down[u][0] = {inf, {0, 0}};
    down[u][1] = {inf, {0, 0}};
    mark[u] = 1;
    for(auto v: adj[u]){
        if(!mark[v]){
            h[v] = h[u] + 1;
            dfs(v);
            upd(u, down[v][0], down[v][1]);
        }
        else if(h[u] - 1 > h[v]){
            up[v]++;
            upd(u, {h[v], {u, v}}, {inf, {0, 0}});
        }
    }
}

void dfs2(int u){
    mark[u] = 2;
    for(auto v: adj[u]){
        if(mark[v] == 1){
            getup[v] = getup[u] + up[u];
            dfs2(v);
        }
    }
}

void upd(int i, pair<int, pair<int, int>> a, pair<int, pair<int, int>> b){
    tmp[0] = a;
    tmp[1] = b;
    tmp[2] = down[i][0];
    tmp[3] = down[i][1];
    sort(tmp, tmp + 4);
    down[i][0] = tmp[0];
    down[i][1] = tmp[1];
}

void out(){
    sort(ans.begin(), ans.end());
    cout << ans.size() << '\n';
    for(auto x: ans)
        cout << x << ' ';
}


#include<bits/stdc++.h>
using namespace std;

#define s second
#define f first

const int maxn = 1e5 + 10;
const int inf = 1e9 + 7;

int n, m;
int h[maxn];
int up[maxn];
int top[maxn];
bool mk[maxn];
int mark[maxn];
int getup[maxn];
vector<int> ans;
vector<int> adj[maxn];
vector<pair<pair<int, int>, int>> edge;
pair<int, pair<int, int>> tmp[4];
pair<int, pair<int, int>> down[maxn][2];

void in();
void solve();
void check(int);
void dfs(int);
void dfs2(int);
bool cmp(pair<pair<int, int>, int>, pair<pair<int, int>, int>);
void upd(int, pair<int, pair<int, int>>, pair<int, pair<int, int>>);
void out();

int main(){
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);
    in();
    solve();
    out();
}

void in(){
    cin >> n >> m;
    for(int i = 0; i < m; i++){
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        edge.push_back({{u, v}, i});
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
}

void solve(){
    for(int i = 0; i < n; i++){
        if(!mark[i]){
            getup[i] = -1;
            dfs(i);
            dfs2(i);
        }
    }
    sort(edge.begin(), edge.end(), cmp);
    for(int i = 0; i < m; i++){
        if(h[edge[i].f.f] < h[edge[i].f.s])
            swap(edge[i].f.f, edge[i].f.s);
        if(h[edge[i].f.f] - h[edge[i].f.s] == 1)
            top[edge[i].f.f] = i;
    }
    for(int i = 0; i < m; i++)
        check(i);
}

bool cmp(pair<pair<int, int>, int> A, pair<pair<int, int>, int> B){
    pair<int, int> a = A.f;
    pair<int, int> b = B.f;
    if(h[a.f] < h[a.s])
        swap(a.f, a.s);
    if(h[b.f] < h[b.s])
        swap(b.f, b.s);
    int modea = h[a.f] - h[a.s];
    int modeb = h[b.f] - h[b.s];
    if(modea == modeb)
        return h[a.s] < h[b.s];
    return modea < modeb;
}

void check(int e){
    int u = edge[e].f.s;
    int v = edge[e].f.f;
    bool fc = 0;
    if(h[v] - h[u] == 1){
        bool ec = 0;
        if(down[v][0].f <= h[u] && down[v][1].f > h[u]){
            if(down[v][0].f < h[u])
                ec = 1;
            int U = down[v][0].s.f;
            int V = down[v][0].s.s;
            if(getup[U] == h[V] && down[U][1].f >= h[U])
                fc = 1;
        }
        if(ec && !mk[top[u]])
            fc = 0;
    }
    else
        fc = mk[top[v]];
    if(fc){
        mk[e] = 1;
        ans.push_back(edge[e].s + 1);
    }
}

void dfs(int u){
    up[u] = -1;
    down[u][0] = {inf, {0, 0}};
    down[u][1] = {inf, {0, 0}};
    mark[u] = 1;
    for(auto v: adj[u]){
        if(!mark[v]){
            h[v] = h[u] + 1;
            dfs(v);
            upd(u, down[v][0], down[v][1]);
        }
        else if(h[u] - 1 > h[v]){
            up[u] = max(up[u], h[v]);
            upd(u, {h[v], {u, v}}, {inf, {0, 0}});
        }
    }
}

void dfs2(int u){
    getup[u] = max(getup[u], up[u]);
    mark[u] = 2;
    for(auto v: adj[u]){
        if(mark[v] == 1){
            getup[v] = getup[u];
            dfs2(v);
        }
    }
}

void upd(int i, pair<int, pair<int, int>> a, pair<int, pair<int, int>> b){
    tmp[0] = a;
    tmp[1] = b;
    tmp[2] = down[i][0];
    tmp[3] = down[i][1];
    sort(tmp, tmp + 4);
    down[i][0] = tmp[0];
    down[i][1] = tmp[1];
}

void out(){
    sort(ans.begin(), ans.end());
    cout << ans.size() << '\n';
    for(auto x: ans)
        cout << x << ' ';
}


#include<bits/stdc++.h>
using namespace std;

#define s second
#define f first

const int maxn = 1e5 + 10;
const int inf = 1e9 + 7;

int n, m;
int h[maxn];
int up[maxn];
int top[maxn];
bool mk[maxn];
int mark[maxn];
int getup[maxn];
vector<int> ans;
vector<int> adj[maxn];
vector<pair<pair<int, int>, int>> edge;
pair<int, pair<int, int>> tmp[4];
pair<int, pair<int, int>> down[maxn][2];

void in();
void solve();
void check(int);
void dfs(int);
void dfs2(int);
bool cmp(pair<pair<int, int>, int>, pair<pair<int, int>, int>);
void upd(int, pair<int, pair<int, int>>, pair<int, pair<int, int>>);
void out();

int main(){
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);
    in();
    solve();
    out();
}

void in(){
    cin >> n >> m;
    for(int i = 0; i < m; i++){
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        edge.push_back({{u, v}, i});
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
}

void solve(){
    for(int i = 0; i < n; i++){
        if(!mark[i]){
            getup[i] = -1;
            dfs(i);
            dfs2(i);
        }
    }
    sort(edge.begin(), edge.end(), cmp);
    for(int i = 0; i < m; i++){
        if(h[edge[i].f.f] < h[edge[i].f.s])
            swap(edge[i].f.f, edge[i].f.s);
        if(h[edge[i].f.f] - h[edge[i].f.s] == 1)
            top[edge[i].f.f] = i;
    }
    for(int i = 0; i < m; i++)
        check(i);
}

bool cmp(pair<pair<int, int>, int> A, pair<pair<int, int>, int> B){
    pair<int, int> a = A.f;
    pair<int, int> b = B.f;
    if(h[a.f] < h[a.s])
        swap(a.f, a.s);
    if(h[b.f] < h[b.s])
        swap(b.f, b.s);
    int modea = h[a.f] - h[a.s];
    int modeb = h[b.f] - h[b.s];
    if(modea == modeb)
        return h[a.s] < h[b.s];
    return modea < modeb;
}

void check(int e){
    int u = edge[e].f.s;
    int v = edge[e].f.f;
    bool fc = 0;
    if(h[v] - h[u] == 1){
        bool ec = 0;
        if(down[v][0].f <= h[u] && down[v][1].f > h[u]){
            if(down[v][0].f < h[u])
                ec = 1;
            int U = down[v][0].s.f;
            int V = down[v][0].s.s;
            if(getup[U] == h[V])
                fc = 1;
        }
        if(ec && !mk[top[u]])
            fc = 0;
    }
    else
        fc = mk[top[v]];
    if(fc){
        mk[e] = 1;
        ans.push_back(edge[e].s + 1);
    }
}

void dfs(int u){
    up[u] = -1;
    down[u][0] = {inf, {0, 0}};
    down[u][1] = {inf, {0, 0}};
    mark[u] = 1;
    for(auto v: adj[u]){
        if(!mark[v]){
            h[v] = h[u] + 1;
            dfs(v);
            upd(u, down[v][0], down[v][1]);
        }
        else if(h[u] - 1 > h[v]){
            up[u] = max(up[u], h[v]);
            upd(u, {h[v], {u, v}}, {inf, {0, 0}});
        }
    }
}

void dfs2(int u){
    getup[u] = max(getup[u], up[u]);
    mark[u] = 2;
    for(auto v: adj[u]){
        if(mark[v] == 1){
            getup[v] = getup[u];
            dfs2(v);
        }
    }
}

void upd(int i, pair<int, pair<int, int>> a, pair<int, pair<int, int>> b){
    tmp[0] = a;
    tmp[1] = b;
    tmp[2] = down[i][0];
    tmp[3] = down[i][1];
    sort(tmp, tmp + 4);
    down[i][0] = tmp[0];
    down[i][1] = tmp[1];
}

void out(){
    sort(ans.begin(), ans.end());
    cout << ans.size() << '\n';
    for(auto x: ans)
        cout << x << ' ';
}


#include<bits/stdc++.h>
using namespace std;

#define s second
#define f first

const int maxn = 1e5 + 10;
const int inf = 1e9 + 7;

int t;
int n, m;
int h[maxn];
int up[maxn];
int st[maxn];
int ft[maxn];
int top[maxn];
bool mk[maxn];
int mark[maxn];
int getup[maxn];
vector<int> ans;
vector<int> adj[maxn];
int partialmarshal[maxn];
vector<pair<pair<int, int>, int>> edge;
pair<int, pair<int, int>> tmp[4];
pair<int, pair<int, int>> down[maxn][2];

void in();
void solve();
void check(int);
void dfs(int);
void dfs2(int, int par = -1);
bool cmp(pair<pair<int, int>, int>, pair<pair<int, int>, int>);
void upd(int, pair<int, pair<int, int>>, pair<int, pair<int, int>>);
void out();

int main(){
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);
    in();
    solve();
    out();
}

void in(){
    cin >> n >> m;
    for(int i = 0; i < m; i++){
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        edge.push_back({{u, v}, i});
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
}

void solve(){
    for(int i = 0; i < n; i++){
        if(!mark[i]){
            getup[i] = -1;
            dfs(i);
            dfs2(i);
        }
    }
    sort(edge.begin(), edge.end(), cmp);
    for(int i = 0; i < m; i++){
        if(h[edge[i].f.f] < h[edge[i].f.s])
            swap(edge[i].f.f, edge[i].f.s);
        if(h[edge[i].f.f] - h[edge[i].f.s] == 1)
            top[edge[i].f.f] = i;
    }
    for(int i = 0; i < m; i++)
        check(i);
}

bool cmp(pair<pair<int, int>, int> A, pair<pair<int, int>, int> B){
    pair<int, int> a = A.f;
    pair<int, int> b = B.f;
    if(h[a.f] < h[a.s])
        swap(a.f, a.s);
    if(h[b.f] < h[b.s])
        swap(b.f, b.s);
    int modea = h[a.f] - h[a.s];
    int modeb = h[b.f] - h[b.s];
    if(modea == modeb)
        return h[a.s] < h[b.s];
    return modea < modeb;
}

void check(int e){
    int u = edge[e].f.s;
    int v = edge[e].f.f;
    bool fc = 0;
    if(h[v] - h[u] == 1){
        bool ec = 0;
        if(down[v][0].f <= h[u] && down[v][1].f > h[u]){
            if(down[v][0].f < h[u])
                ec = 1;
            int U = down[v][0].s.f;
            int V = down[v][0].s.s;
            if(getup[U] == h[V] && down[U][1].f >= h[U] && partialmarshal[U] - partialmarshal[V] == 1)
                fc = 1;
        }
        if(ec && !mk[top[u]])
            fc = 0;
    }
    else
        fc = mk[top[v]];
    if(fc){
        mk[e] = 1;
        ans.push_back(edge[e].s + 1);
    }
}

void dfs(int u){
    up[u] = -1;
    st[u] = t++;
    down[u][0] = {inf, {0, 0}};
    down[u][1] = {inf, {0, 0}};
    mark[u] = 1;
    for(auto v: adj[u]){
        if(!mark[v]){
            h[v] = h[u] + 1;
            dfs(v);
            upd(u, down[v][0], down[v][1]);
        }
        else if(h[u] - 1 > h[v]){
            up[u] = max(up[u], h[v]);
            upd(u, {h[v], {u, v}}, {inf, {0, 0}});
        }
    }
    ft[u] = t;
}

void dfs2(int u, int par){
    getup[u] = max(getup[u], up[u]);
    mark[u] = 2;
    if(par != -1){
        for(auto v: adj[par])
            if(h[v] > h[par] + 1 && st[u] < st[v] && ft[v] <= ft[u])
                partialmarshal[u]++;
    }
    for(auto v: adj[u]){
        if(mark[v] == 1){
            partialmarshal[v] = partialmarshal[u];
            getup[v] = getup[u];
            dfs2(v, u);
        }
    }
}

void upd(int i, pair<int, pair<int, int>> a, pair<int, pair<int, int>> b){
    tmp[0] = a;
    tmp[1] = b;
    tmp[2] = down[i][0];
    tmp[3] = down[i][1];
    sort(tmp, tmp + 4);
    down[i][0] = tmp[0];
    down[i][1] = tmp[1];
}

void out(){
    sort(ans.begin(), ans.end());
    cout << ans.size() << '\n';
    for(auto x: ans)
        cout << x << ' ';
}


#include<bits/stdc++.h>
using namespace std;

#pragma GCC target("avx,avx2,fma")
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")

#define s second
#define f first

const int maxn = 1e5 + 10;
const int inf = 1e9 + 7;
const int lg = 20;

int t;
int n, m;
int h[maxn];
int up[maxn];
int st[maxn];
int ft[maxn];
int top[maxn];
bool mk[maxn];
int mark[maxn];
int f[lg][maxn];
int getup[maxn];
vector<int> ans;
vector<int> adj[maxn];
int partialmarshal[maxn];
vector<pair<pair<int, int>, int>> edge;
pair<int, pair<int, int>> tmp[4];
pair<int, pair<int, int>> down[maxn][2];

void in();
void solve();
void check(int);
void dfs(int);
void dfs2(int, int par = -1);
bool cmp(pair<pair<int, int>, int>, pair<pair<int, int>, int>);
void upd(int, pair<int, pair<int, int>>, pair<int, pair<int, int>>);
void out();

int main(){
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);
    in();
    solve();
    out();
}

void in(){
    cin >> n >> m;
    for(int i = 0; i < m; i++){
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        edge.push_back({{u, v}, i});
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
}

void solve(){
    memset(f, -1, sizeof f);
    for(int i = 0; i < n; i++){
        if(!mark[i]){
            getup[i] = -1;
            dfs(i);
            dfs2(i);
        }
    }
    sort(edge.begin(), edge.end(), cmp);
    for(int i = 0; i < m; i++){
        if(h[edge[i].f.f] < h[edge[i].f.s])
            swap(edge[i].f.f, edge[i].f.s);
        if(h[edge[i].f.f] - h[edge[i].f.s] == 1)
            top[edge[i].f.f] = i;
    }
    for(int i = 0; i < m; i++)
        check(i);
}

bool cmp(pair<pair<int, int>, int> A, pair<pair<int, int>, int> B){
    pair<int, int> a = A.f;
    pair<int, int> b = B.f;
    if(h[a.f] < h[a.s])
        swap(a.f, a.s);
    if(h[b.f] < h[b.s])
        swap(b.f, b.s);
    int modea = h[a.f] - h[a.s];
    int modeb = h[b.f] - h[b.s];
    if(modea == modeb)
        return h[a.s] < h[b.s];
    return modea < modeb;
}

void check(int e){
    int u = edge[e].f.s;
    int v = edge[e].f.f;
    bool fc = 0;
    if(h[v] - h[u] == 1){
        bool ec = 0;
        if(down[v][0].f <= h[u] && down[v][1].f > h[u]){
            if(down[v][0].f < h[u])
                ec = 1;
            int U = down[v][0].s.f;
            int V = down[v][0].s.s;
            if(getup[U] == h[V] && down[U][1].f >= h[U] && partialmarshal[U] - partialmarshal[V] == 1)
                fc = 1;
        }
        if(ec && !mk[top[u]])
            fc = 0;
    }
    else
        fc = mk[top[v]];
    if(fc){
        mk[e] = 1;
        ans.push_back(edge[e].s + 1);
    }
}

void dfs(int u){
    for(int i = 1; i < lg; i++)
        if(f[i - 1][u] != -1)
            f[i][u] = f[i - 1][f[i - 1][u]];
    up[u] = -1;
    st[u] = t++;
    down[u][0] = {inf, {0, 0}};
    down[u][1] = {inf, {0, 0}};
    mark[u] = 1;
    for(auto v: adj[u]){
        if(!mark[v]){
            f[0][v] = u;
            h[v] = h[u] + 1;
            dfs(v);
            upd(u, down[v][0], down[v][1]);
        }
        else if(h[u] - 1 > h[v]){
            up[u] = max(up[u], h[v]);
            upd(u, {h[v], {u, v}}, {inf, {0, 0}});
        }
    }
    ft[u] = t;
}

int nxt(int u, int v){
    for(int i = lg - 1; i >= 0; i--)
        if(f[i][v] != -1 && h[u] < h[f[i][v]])
            v = f[i][v];
    return v;
}

void dfs2(int u, int par){
    getup[u] = max(getup[u], up[u]);
    mark[u] = 2;
    for(auto v: adj[u]){
        if(mark[v] == 1){
            partialmarshal[v] = partialmarshal[u];
            getup[v] = getup[u];
        }
    }
    for(auto v: adj[u])
        if(h[v] > h[u] + 1)
            partialmarshal[nxt(u, v)]++;
    for(auto v: adj[u])
        if(mark[v] == 1)
            dfs2(v, u);
}

void upd(int i, pair<int, pair<int, int>> a, pair<int, pair<int, int>> b){
    tmp[0] = a;
    tmp[1] = b;
    tmp[2] = down[i][0];
    tmp[3] = down[i][1];
    sort(tmp, tmp + 4);
    down[i][0] = tmp[0];
    down[i][1] = tmp[1];
}

void out(){
    sort(ans.begin(), ans.end());
    cout << ans.size() << '\n';
    for(auto x: ans)
        cout << x << ' ';
}


#include<bits/stdc++.h>
using namespace std;

#define s second
#define f first

const int maxn = 1e5 + 10;
const int inf = 1e9 + 7;

int n, m;
int h[maxn];
int getup[maxn];
bool mark[maxn];
vector<int> ans;
vector<int> adj[maxn];
vector<pair<int, int>> edge;
pair<int, pair<int, int>> tmp[4];
pair<int, pair<int, int>> down[maxn][2];

void in();
void solve();
void check(int);
void dfs(int);
void upd(int, pair<int, pair<int, int>>, pair<int, pair<int, int>>);
void out();

int main(){
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);
    in();
    solve();
    out();
}

void in(){
    cin >> n >> m;
    for(int i = 0; i < m; i++){
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        edge.push_back({u, v});
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
}

void solve(){
    for(int i = 0; i < n; i++){
        if(!mark[i]){
            getup[0] = -1;
            dfs(0);
        }
    }
    for(int i = 0; i < m; i++)
        check(i);
}

void check(int e){
    if(h[edge[e].f] < h[edge[e].s])
        swap(edge[e].f, edge[e].s);
    int u = edge[e].s;
    int v = edge[e].f;
    if(down[u][0].f <= h[u] && down[u][1].f > h[u] && down[v][0].f <= h[u] && down[v][1].f > h[u]){
        int U = down[u][0].s.f;
        int V = down[u][0].s.s;
        if(getup[U] == h[V])
            ans.push_back(e + 1);
    }
}

void dfs(int u){
    down[u][0] = {inf, {0, 0}};
    down[u][1] = {inf, {0, 0}};
    mark[u] = 1;
    for(auto v: adj[u]){
        if(!mark[v]){
            h[v] = h[u] + 1;
            getup[v] = getup[u];
            dfs(v);
            upd(u, down[v][0], down[v][1]);
        }
        else if(h[u] - 1 > h[v]){
            getup[u] = max(getup[u], h[v]);
            upd(u, {h[v], {u, v}}, {h[u], {0, 0}});
        }
    }
}

void upd(int i, pair<int, pair<int, int>> a, pair<int, pair<int, int>> b){
    tmp[0] = a;
    tmp[1] = b;
    tmp[2] = down[i][0];
    tmp[3] = down[i][1];
    sort(tmp, tmp + 4);
    down[i][0] = tmp[0];
    down[i][1] = tmp[1];
}

void out(){
    cout << ans.size() << '\n';
    for(auto x: ans)
        cout << x << ' ';
}


#include<bits/stdc++.h>
using namespace std;

#define s second
#define f first

const int maxn = 1e5 + 10;
const int inf = 1e9 + 7;

int n, m;
int h[maxn];
int up[maxn];
int top[maxn];
bool mk[maxn];
int mark[maxn];
int getup[maxn];
vector<int> ans;
vector<int> adj[maxn];
vector<pair<pair<int, int>, int>> edge;
pair<int, pair<int, int>> tmp[4];
pair<int, pair<int, int>> down[maxn][2];

void in();
void solve();
void check(int);
void dfs(int);
void dfs2(int);
bool cmp(pair<pair<int, int>, int>, pair<pair<int, int>, int>);
void upd(int, pair<int, pair<int, int>>, pair<int, pair<int, int>>);
void out();

int main(){
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);
    in();
    solve();
    out();
}

void in(){
    cin >> n >> m;
    for(int i = 0; i < m; i++){
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        edge.push_back({{u, v}, i});
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
}

void solve(){
    for(int i = 0; i < n; i++){
        if(!mark[i]){
            getup[i] = -1;
            dfs(i);
            dfs2(i);
        }
    }
    sort(edge.begin(), edge.end(), cmp);
    for(int i = 0; i < m; i++){
        if(h[edge[i].f.f] < h[edge[i].f.s])
            swap(edge[i].f.f, edge[i].f.s);
        if(h[edge[i].f.f] - h[edge[i].f.s] == 1)
            top[edge[i].f.f] = i;
    }
    for(int i = 0; i < m; i++)
        check(i);
}

bool cmp(pair<pair<int, int>, int> A, pair<pair<int, int>, int> B){
    pair<int, int> a = A.f;
    pair<int, int> b = B.f;
    if(h[a.f] < h[a.s])
        swap(a.f, a.s);
    if(h[b.f] < h[b.s])
        swap(b.f, b.s);
    int modea = h[a.f] - h[a.s];
    int modeb = h[b.f] - h[b.s];
    if(modea == modeb)
        return h[a.s] < h[b.s];
    return modea < modeb;
}

void check(int e){
    int u = edge[e].f.s;
    int v = edge[e].f.f;
    bool fc = 0;
    if(h[v] - h[u] == 1){
        bool ec = 0;
        if(down[v][0].f <= h[u] && down[v][1].f > h[u]){
            if(down[v][0].f < h[u])
                ec = 1;
            int U = down[v][0].s.f;
            int V = down[v][0].s.s;
            if(getup[U] - getup[V])
                fc = 1;
        }
        if(ec && !mk[top[u]])
            fc = 0;
    }
    else
        fc = mk[top[v]];
    if(fc){
        mk[e] = 1;
        ans.push_back(edge[e].s + 1);
    }
}

void dfs(int u){
    down[u][0] = {inf, {0, 0}};
    down[u][1] = {inf, {0, 0}};
    mark[u] = 1;
    for(auto v: adj[u]){
        if(!mark[v]){
            h[v] = h[u] + 1;
            dfs(v);
            upd(u, down[v][0], down[v][1]);
        }
        else if(h[u] - 1 > h[v]){
            up[v]++;
            upd(u, {h[v], {u, v}}, {inf, {0, 0}});
        }
    }
}

void dfs2(int u){
    mark[u] = 2;
    for(auto v: adj[u]){
        if(mark[v] == 1){
            getup[v] = getup[u] + up[u];
            dfs2(v);
        }
    }
}

void upd(int i, pair<int, pair<int, int>> a, pair<int, pair<int, int>> b){
    tmp[0] = a;
    tmp[1] = b;
    tmp[2] = down[i][0];
    tmp[3] = down[i][1];
    sort(tmp, tmp + 4);
    down[i][0] = tmp[0];
    down[i][1] = tmp[1];
}

void out(){
    sort(ans.begin(), ans.end());
    cout << ans.size() << '\n';
    for(auto x: ans)
        cout << x << ' ';
}


#include<bits/stdc++.h>
using namespace std;

#pragma GCC target("avx,avx2,fma")
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")

#define s second
#define f first

const int maxn = 1e5 + 10;
const int inf = 1e9 + 7;
const int lg = 20;

int t;
int n, m;
int h[maxn];
int up[maxn];
int st[maxn];
int ft[maxn];
int top[maxn];
bool mk[maxn];
int mark[maxn];
int f[lg][maxn];
int getup[maxn];
vector<int> ans;
vector<int> adj[maxn];
int partialmarshal[maxn];
vector<pair<pair<int, int>, int>> edge;
pair<int, pair<int, int>> tmp[4];
pair<int, pair<int, int>> down[maxn][2];

void in();
void solve();
void check(int);
void dfs(int);
void dfs2(int, int par = -1);
bool cmp(pair<pair<int, int>, int>, pair<pair<int, int>, int>);
void upd(int, pair<int, pair<int, int>>, pair<int, pair<int, int>>);
void out();

int main(){
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);
    in();
    solve();
    out();
}

void in(){
    cin >> n >> m;
    for(int i = 0; i < m; i++){
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        edge.push_back({{u, v}, i});
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
}

void solve(){
    memset(f, -1, sizeof f);
    for(int i = 0; i < n; i++){
        if(!mark[i]){
            getup[i] = -1;
            dfs(i);
            dfs2(i);
        }
    }
    sort(edge.begin(), edge.end(), cmp);
    for(int i = 0; i < m; i++){
        if(h[edge[i].f.f] < h[edge[i].f.s])
            swap(edge[i].f.f, edge[i].f.s);
        if(h[edge[i].f.f] - h[edge[i].f.s] == 1)
            top[edge[i].f.f] = i;
    }
    for(int i = 0; i < m; i++)
        check(i);
}

bool cmp(pair<pair<int, int>, int> A, pair<pair<int, int>, int> B){
    pair<int, int> a = A.f;
    pair<int, int> b = B.f;
    if(h[a.f] < h[a.s])
        swap(a.f, a.s);
    if(h[b.f] < h[b.s])
        swap(b.f, b.s);
    int modea = h[a.f] - h[a.s];
    int modeb = h[b.f] - h[b.s];
    if(modea == modeb)
        return h[a.s] < h[b.s];
    return modea < modeb;
}

void check(int e){
    int u = edge[e].f.s;
    int v = edge[e].f.f;
    bool fc = 0;
    if(h[v] - h[u] == 1){
        bool ec = 0;
        if(down[v][0].f <= h[u] && down[v][1].f > h[u]){
            if(down[v][0].f < h[u])
                ec = 1;
            int U = down[v][0].s.f;
            int V = down[v][0].s.s;
            if(getup[U] == h[V] && down[U][1].f >= h[U] && partialmarshal[U] - partialmarshal[V] == 1)
                fc = 1;
        }
        if(ec && !mk[top[u]])
            fc = 0;
    }
    else
        fc = mk[top[v]];
    if(fc){
        mk[e] = 1;
        ans.push_back(edge[e].s + 1);
    }
}

void dfs(int u){
    for(int i = 1; i < lg; i++)
        if(f[i][u] != -1)
            f[i][u] = f[i - 1][f[i - 1][u]];
    up[u] = -1;
    st[u] = t++;
    down[u][0] = {inf, {0, 0}};
    down[u][1] = {inf, {0, 0}};
    mark[u] = 1;
    for(auto v: adj[u]){
        if(!mark[v]){
            f[0][v] = u;
            h[v] = h[u] + 1;
            dfs(v);
            upd(u, down[v][0], down[v][1]);
        }
        else if(h[u] - 1 > h[v]){
            up[u] = max(up[u], h[v]);
            upd(u, {h[v], {u, v}}, {inf, {0, 0}});
        }
    }
    ft[u] = t;
}

int nxt(int u, int v){
    for(int i = lg - 1; i >= 0; i--)
        if(f[i][v] != -1 && h[u] < h[f[i][v]])
            v = f[i][v];
    return v;
}

void dfs2(int u, int par){
    getup[u] = max(getup[u], up[u]);
    mark[u] = 2;
    for(auto v: adj[u]){
        if(mark[v] == 1){
            partialmarshal[v] = partialmarshal[u];
            getup[v] = getup[u];
        }
    }
    for(auto v: adj[u])
        if(h[v] > h[u] + 1)
            partialmarshal[nxt(u, v)]++;
    for(auto v: adj[u])
        if(mark[v] == 1)
            dfs2(v, u);
}

void upd(int i, pair<int, pair<int, int>> a, pair<int, pair<int, int>> b){
    tmp[0] = a;
    tmp[1] = b;
    tmp[2] = down[i][0];
    tmp[3] = down[i][1];
    sort(tmp, tmp + 4);
    down[i][0] = tmp[0];
    down[i][1] = tmp[1];
}

void out(){
    sort(ans.begin(), ans.end());
    cout << ans.size() << '\n';
    for(auto x: ans)
        cout << x << ' ';
}


#include<bits/stdc++.h>
using namespace std;

#define s second
#define f first

const int maxn = 1e5 + 10;
const int inf = 1e9 + 7;

int n, m;
int h[maxn];
int top[maxn];
bool mk[maxn];
int getup[maxn];
bool mark[maxn];
vector<int> ans;
vector<int> adj[maxn];
vector<pair<pair<int, int>, int>> edge;
pair<int, pair<int, int>> tmp[4];
pair<int, pair<int, int>> down[maxn][2];

void in();
void solve();
void check(int);
void dfs(int);
bool cmp(pair<pair<int, int>, int>, pair<pair<int, int>, int>);
void upd(int, pair<int, pair<int, int>>, pair<int, pair<int, int>>);
void out();

int main(){
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);
    in();
    solve();
    out();
}

void in(){
    cin >> n >> m;
    for(int i = 0; i < m; i++){
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        edge.push_back({{u, v}, i});
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
}

void solve(){
    for(int i = 0; i < n; i++){
        if(!mark[i]){
            getup[0] = -1;
            dfs(0);
        }
    }
    sort(edge.begin(), edge.end(), cmp);
    for(int i = 0; i < m; i++){
        if(h[edge[i].f.f] < h[edge[i].f.s])
            swap(edge[i].f.f, edge[i].f.s);
        if(h[edge[i].f.f] - h[edge[i].f.s] == 1)
            top[edge[i].f.f] = i;
    }
    for(int i = 0; i < m; i++)
        check(i);
}

bool cmp(pair<pair<int, int>, int> A, pair<pair<int, int>, int> B){
    pair<int, int> a = A.f;
    pair<int, int> b = B.f;
    if(h[a.f] < h[a.s])
        swap(a.f, a.s);
    if(h[b.f] < h[b.s])
        swap(b.f, b.s);
    int modea = h[a.f] - h[a.s];
    int modeb = h[b.f] - h[b.s];
    if(modea == modeb)
        return h[a.s] < h[b.s];
    return modea < modeb;
}

void check(int e){
    int u = edge[e].f.s;
    int v = edge[e].f.f;
    bool fc = 0;
    if(h[v] - h[u] == 1){
        bool ec = 0;
        if(down[u][0].f <= h[u] && down[v][0].f <= h[u] && down[v][1].f > h[u]){
            if(down[v][0].f < h[u])
                ec = 1;
            int U = down[u][0].s.f;
            int V = down[u][0].s.s;
            if(getup[U] == h[V])
                fc = 1;
        }
        if(ec && !mk[top[u]])
            fc = 0;

    }
    else
        fc = mk[top[v]];
    if(fc){
        mk[e] = 1;
        ans.push_back(edge[e].s + 1);
    }
}

void dfs(int u){
    down[u][0] = {inf, {0, 0}};
    down[u][1] = {inf, {0, 0}};
    mark[u] = 1;
    for(auto v: adj[u]){
        if(!mark[v]){
            h[v] = h[u] + 1;
            getup[v] = getup[u];
            dfs(v);
            upd(u, down[v][0], down[v][1]);
        }
        else if(h[u] - 1 > h[v]){
            getup[u] = max(getup[u], h[v]);
            upd(u, {h[v], {u, v}}, {h[u], {0, 0}});
        }
    }
}

void upd(int i, pair<int, pair<int, int>> a, pair<int, pair<int, int>> b){
    tmp[0] = a;
    tmp[1] = b;
    tmp[2] = down[i][0];
    tmp[3] = down[i][1];
    sort(tmp, tmp + 4);
    down[i][0] = tmp[0];
    down[i][1] = tmp[1];
}

void out(){
    sort(ans.begin(), ans.end());
    cout << ans.size() << '\n';
    for(auto x: ans)
        cout << x << ' ';
}


#include<bits/stdc++.h>
using namespace std;

#define s second
#define f first

const int maxn = 1e5 + 10;
const int inf = 1e9 + 7;

int n, m;
int h[maxn];
int top[maxn];
bool mk[maxn];
int getup[maxn];
bool mark[maxn];
vector<int> ans;
vector<int> adj[maxn];
vector<pair<pair<int, int>, int>> edge;
pair<int, pair<int, int>> tmp[4];
pair<int, pair<int, int>> down[maxn][2];

void in();
void solve();
void check(int);
void dfs(int);
bool cmp(pair<pair<int, int>, int>, pair<pair<int, int>, int>);
void upd(int, pair<int, pair<int, int>>, pair<int, pair<int, int>>);
void out();

int main(){
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);
    in();
    solve();
    out();
}

void in(){
    cin >> n >> m;
    for(int i = 0; i < m; i++){
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        edge.push_back({{u, v}, i});
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
}

void solve(){
    for(int i = 0; i < n; i++){
        if(!mark[i]){
            getup[0] = -1;
            dfs(0);
        }
    }
    sort(edge.begin(), edge.end(), cmp);
    for(int i = 0; i < m; i++){
        if(h[edge[i].f.f] < h[edge[i].f.s])
            swap(edge[i].f.f, edge[i].f.s);
        if(h[edge[i].f.f] - h[edge[i].f.s] == 1)
            top[edge[i].f.f] = i;
    }
    for(int i = 0; i < m; i++)
        check(i);
}

bool cmp(pair<pair<int, int>, int> A, pair<pair<int, int>, int> B){
    pair<int, int> a = A.f;
    pair<int, int> b = B.f;
    if(h[a.f] < h[a.s])
        swap(a.f, a.s);
    if(h[b.f] < h[b.s])
        swap(b.f, b.s);
    int modea = h[a.f] - h[a.s];
    int modeb = h[b.f] - h[b.s];
    if(modea == modeb)
        return h[a.s] < h[b.s];
    return modea < modeb;
}

void check(int e){
    int u = edge[e].f.s;
    int v = edge[e].f.f;
    bool fc = 0;
    if(h[v] - h[u] == 1){
        bool ec = 0;
        if(down[v][0].f <= h[u] && down[v][1].f > h[u]){
            if(down[v][0].f < h[u])
                ec = 1;
            int U = down[v][0].s.f;
            int V = down[v][0].s.s;
            if(getup[U] == h[V])
                fc = 1;
        }
        if(ec && !mk[top[u]])
            fc = 0;
    }
    else
        fc = mk[top[v]];
    if(fc){
        mk[e] = 1;
        ans.push_back(edge[e].s + 1);
    }
}

void dfs(int u){
    down[u][0] = {inf, {0, 0}};
    down[u][1] = {inf, {0, 0}};
    mark[u] = 1;
    for(auto v: adj[u]){
        if(!mark[v]){
            h[v] = h[u] + 1;
            getup[v] = getup[u];
            dfs(v);
            upd(u, down[v][0], down[v][1]);
        }
        else if(h[u] - 1 > h[v]){
            getup[u] = max(getup[u], h[v]);
            upd(u, {h[v], {u, v}}, {inf, {0, 0}});
        }
    }
}

void upd(int i, pair<int, pair<int, int>> a, pair<int, pair<int, int>> b){
    tmp[0] = a;
    tmp[1] = b;
    tmp[2] = down[i][0];
    tmp[3] = down[i][1];
    sort(tmp, tmp + 4);
    down[i][0] = tmp[0];
    down[i][1] = tmp[1];
}

void out(){
    sort(ans.begin(), ans.end());
    cout << ans.size() << '\n';
    for(auto x: ans)
        cout << x << ' ';
}


#include<bits/stdc++.h>
using namespace std;

#define s second
#define f first

const int maxn = 1e5 + 10;
const int inf = 1e9 + 7;

int n, m;
int h[maxn];
int up[maxn];
int top[maxn];
bool mk[maxn];
int mark[maxn];
int getup[maxn];
vector<int> ans;
vector<int> adj[maxn];
vector<pair<pair<int, int>, int>> edge;
pair<int, pair<int, int>> tmp[4];
pair<int, pair<int, int>> down[maxn][2];

void in();
void solve();
void check(int);
void dfs(int);
void dfs2(int);
bool cmp(pair<pair<int, int>, int>, pair<pair<int, int>, int>);
void upd(int, pair<int, pair<int, int>>, pair<int, pair<int, int>>);
void out();

int main(){
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);
    in();
    solve();
    out();
}

void in(){
    cin >> n >> m;
    for(int i = 0; i < m; i++){
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        edge.push_back({{u, v}, i});
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
}

void solve(){
    for(int i = 0; i < n; i++){
        if(!mark[i]){
            dfs(i);
            dfs2(i);
        }
    }
    sort(edge.begin(), edge.end(), cmp);
    for(int i = 0; i < m; i++){
        if(h[edge[i].f.f] < h[edge[i].f.s])
            swap(edge[i].f.f, edge[i].f.s);
        if(h[edge[i].f.f] - h[edge[i].f.s] == 1)
            top[edge[i].f.f] = i;
    }
    for(int i = 0; i < m; i++)
        check(i);
}

bool cmp(pair<pair<int, int>, int> A, pair<pair<int, int>, int> B){
    pair<int, int> a = A.f;
    pair<int, int> b = B.f;
    if(h[a.f] < h[a.s])
        swap(a.f, a.s);
    if(h[b.f] < h[b.s])
        swap(b.f, b.s);
    int modea = h[a.f] - h[a.s];
    int modeb = h[b.f] - h[b.s];
    if(modea == modeb)
        return h[a.s] < h[b.s];
    return modea < modeb;
}

void check(int e){
    int u = edge[e].f.s;
    int v = edge[e].f.f;
    bool fc = 0;
    if(h[v] - h[u] == 1){
        bool ec = 0;
        if(down[v][0].f <= h[u] && down[v][1].f > h[u]){
            if(down[v][0].f < h[u])
                ec = 1;
            int U = down[v][0].s.f;
            int V = down[v][0].s.s;
            if(getup[U] - getup[V] == 1)
                fc = 1;
        }
        if(ec && !mk[top[u]])
            fc = 0;
    }
    else
        fc = mk[top[v]];
    if(fc){
        mk[e] = 1;
        ans.push_back(edge[e].s + 1);
    }
}

void dfs(int u){
    down[u][0] = {inf, {0, 0}};
    down[u][1] = {inf, {0, 0}};
    mark[u] = 1;
    for(auto v: adj[u]){
        if(!mark[v]){
            h[v] = h[u] + 1;
            dfs(v);
            upd(u, down[v][0], down[v][1]);
        }
        else if(h[u] - 1 > h[v]){
            up[v]++;
            upd(u, {h[v], {u, v}}, {inf, {0, 0}});
        }
    }
}

void dfs2(int u){
    mark[u] = 2;
    for(auto v: adj[u]){
        if(mark[v] == 1){
            getup[v] = getup[u] + up[u];
            dfs2(v);
        }
    }
    cout << u << ' ' << up[u] << ' ' << getup[u] << endl;
}

void upd(int i, pair<int, pair<int, int>> a, pair<int, pair<int, int>> b){
    tmp[0] = a;
    tmp[1] = b;
    tmp[2] = down[i][0];
    tmp[3] = down[i][1];
    sort(tmp, tmp + 4);
    down[i][0] = tmp[0];
    down[i][1] = tmp[1];
}

void out(){
    sort(ans.begin(), ans.end());
    cout << ans.size() << '\n';
    for(auto x: ans)
        cout << x << ' ';
}


#include<bits/stdc++.h>
using namespace std;

#define s second
#define f first

const int maxn = 1e5 + 10;
const int inf = 1e9 + 7;

int n, m;
int h[maxn];
int up[maxn];
int top[maxn];
bool mk[maxn];
int getup[maxn];
bool mark[maxn];
vector<int> ans;
vector<int> adj[maxn];
vector<pair<pair<int, int>, int>> edge;
pair<int, pair<int, int>> tmp[4];
pair<int, pair<int, int>> down[maxn][2];

void in();
void solve();
void check(int);
void dfs(int);
void dfs2(int);
bool cmp(pair<pair<int, int>, int>, pair<pair<int, int>, int>);
void upd(int, pair<int, pair<int, int>>, pair<int, pair<int, int>>);
void out();

int main(){
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);
    in();
    solve();
    out();
}

void in(){
    cin >> n >> m;
    for(int i = 0; i < m; i++){
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        edge.push_back({{u, v}, i});
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
}

void solve(){
    for(int i = 0; i < n; i++){
        if(!mark[i]){
            getup[i] = -1;
            dfs(i);
            dfs2(i);
        }
    }
    sort(edge.begin(), edge.end(), cmp);
    for(int i = 0; i < m; i++){
        if(h[edge[i].f.f] < h[edge[i].f.s])
            swap(edge[i].f.f, edge[i].f.s);
        if(h[edge[i].f.f] - h[edge[i].f.s] == 1)
            top[edge[i].f.f] = i;
    }
    for(int i = 0; i < m; i++)
        check(i);
}

bool cmp(pair<pair<int, int>, int> A, pair<pair<int, int>, int> B){
    pair<int, int> a = A.f;
    pair<int, int> b = B.f;
    if(h[a.f] < h[a.s])
        swap(a.f, a.s);
    if(h[b.f] < h[b.s])
        swap(b.f, b.s);
    int modea = h[a.f] - h[a.s];
    int modeb = h[b.f] - h[b.s];
    if(modea == modeb)
        return h[a.s] < h[b.s];
    return modea < modeb;
}

void check(int e){
    int u = edge[e].f.s;
    int v = edge[e].f.f;
    bool fc = 0;
    if(h[v] - h[u] == 1){
        bool ec = 0;
        if(down[v][0].f <= h[u] && down[v][1].f > h[u]){
            if(down[v][0].f < h[u])
                ec = 1;
            int U = down[v][0].s.f;
            int V = down[v][0].s.s;
            if(getup[U] == h[V])
                fc = 1;
        }
        if(ec && !mk[top[u]])
            fc = 0;
    }
    else
        fc = mk[top[v]];
    if(fc){
        mk[e] = 1;
        ans.push_back(edge[e].s + 1);
    }
}

void dfs(int u){
    up[u] = -1;
    down[u][0] = {inf, {0, 0}};
    down[u][1] = {inf, {0, 0}};
    mark[u] = 1;
    for(auto v: adj[u]){
        if(!mark[v]){
            h[v] = h[u] + 1;
            dfs(v);
            upd(u, down[v][0], down[v][1]);
        }
        else if(h[u] - 1 > h[v]){
            up[u] = max(up[u], h[v]);
            upd(u, {h[v], {u, v}}, {inf, {0, 0}});
        }
    }
}

void dfs2(int u){
    getup[u] = max(getup[u], up[u]);
    mark[u] = 0;
    for(auto v: adj[u]){
        if(mark[v]){
            getup[v] = getup[u];
            dfs2(v);
        }
    }
}

void upd(int i, pair<int, pair<int, int>> a, pair<int, pair<int, int>> b){
    tmp[0] = a;
    tmp[1] = b;
    tmp[2] = down[i][0];
    tmp[3] = down[i][1];
    sort(tmp, tmp + 4);
    down[i][0] = tmp[0];
    down[i][1] = tmp[1];
}

void out(){
    sort(ans.begin(), ans.end());
    cout << ans.size() << '\n';
    for(auto x: ans)
        cout << x << ' ';
}


#include<bits/stdc++.h>
using namespace std;

#define s second
#define f first

const int maxn = 1e5 + 10;
const int inf = 1e9 + 7;

int n, m;
int h[maxn];
int getup[maxn];
bool mark[maxn];
vector<int> ans;
vector<int> adj[maxn];
vector<pair<int, int>> edge;
pair<int, pair<int, int>> tmp[4];
pair<int, pair<int, int>> down[maxn][2];

void in();
void solve();
void check(int);
void dfs(int);
void upd(int, pair<int, pair<int, int>>, pair<int, pair<int, int>>);
void out();

int main(){
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);
    in();
    solve();
    out();
}

void in(){
    cin >> n >> m;
    for(int i = 0; i < m; i++){
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        edge.push_back({u, v});
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
}

void solve(){
    for(int i = 0; i < n; i++){
        if(!mark[i]){
            getup[0] = -1;
            dfs(0);
        }
    }
    for(int i = 0; i < m; i++)
        check(i);
}

void check(int e){
    if(h[edge[e].f] < h[edge[e].s])
        swap(edge[e].f, edge[e].s);
    int u = edge[e].s;
    if(down[u][0].f <= h[u] && down[u][1].f > h[u]){
        int U = down[u][0].s.f;
        int V = down[u][0].s.s;
        if(getup[U] == h[V])
            ans.push_back(e + 1);
    }
}

void dfs(int u){
    down[u][0] = {inf, {0, 0}};
    down[u][1] = {inf, {0, 0}};
    mark[u] = 1;
    for(auto v: adj[u]){
        if(!mark[v]){
            h[v] = h[u] + 1;
            getup[v] = getup[u];
            dfs(v);
            upd(u, down[v][0], down[v][1]);
        }
        else if(h[u] - 1 > h[v]){
            getup[u] = max(getup[u], h[v]);
            upd(u, {h[v], {u, v}}, {h[u], {0, 0}});
        }
    }
}

void upd(int i, pair<int, pair<int, int>> a, pair<int, pair<int, int>> b){
    tmp[0] = a;
    tmp[1] = b;
    tmp[2] = down[i][0];
    tmp[3] = down[i][1];
    sort(tmp, tmp + 4);
    down[i][0] = tmp[0];
    down[i][1] = tmp[1];
}

void out(){
    cout << ans.size() << '\n';
    for(auto x: ans)
        cout << x << ' ';
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<stack>
using namespace std;
#define LL long long
#define M 300005
#define N 20
#define lowbit(i) (i&(-i))
#define Mod 1000000007
#define IMax 0x7fffffffffffffff
void read(LL &x){
	x=0;char c=getchar();LL f=1;
	while(c<'0'||c>'9'){
		if(c=='-')
			f=-f;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=(x<<3)+(x<<1)+c-'0';
		c=getchar();
	}
	x*=f;
	return ;
}
void print(LL x){
	if(x<10){
		putchar(x+'0');
		return ;
	}
	print(x/10);
	putchar(x%10+'0');
}
void write(LL x){
	if(x<0)
		x=-x,putchar('-');
	print(x);
}
LL maxt(LL a,LL b){
	return a<b?b:a;
}
LL mint(LL a,LL b){
	return a<b?a:b;
}
struct node{
	LL v,id;
	node(LL V,LL Id){
		v=V,id=Id;
	}
};
vector<LL>R;
vector<node>G[M];
LL dfn[M],low[M],cnt,bel[M];
bool iscut[M];
void tarjan(LL u,LL fa){
	dfn[u]=low[u]=++cnt;
	for(int i=0;i<G[u].size();i++){
		LL v=G[u][i].v,id=G[u][i].id;
		if(!dfn[v]){
			tarjan(v,u);
			low[u]=mint(low[v],low[u]);
			if(low[v]>dfn[u])
				iscut[id]=1;
		}else if(v!=fa)
			low[u]=mint(low[u],dfn[v]);
	}
}
LL cnt1,cnt2;
bool visit[M],vis[M],col[M];
void dfs(LL u){
	cnt2++;
	vis[u]=1;
	for(int i=0;i<G[u].size();i++){
		LL v=G[u][i].v,id=G[u][i].id;
		if(!iscut[id]){
			if(!visit[id]){
				visit[id]=1;
				cnt1++;
				R.push_back(id);
			}
			if(!vis[v])
				dfs(v);
		}
	}
}
LL n,m;
int main(){
	read(n),read(m);
	for(int i=1;i<=m;i++){
		LL u,v;
		read(u),read(v);
		G[u].push_back(node(v,i));
		G[v].push_back(node(u,i));
	}
	for(int i=1;i<=n;i++)
		if(!dfn[i])
			tarjan(i,i);
	LL sum=0;
	for(int i=1;i<=n;i++)
		if(!vis[i]){
			cnt1=cnt2=0;
			R.clear();
			dfs(i);
			if(cnt1==cnt2){
				sum+=cnt1;
				for(int i=0;i<R.size();i++)
					col[R[i]]=1;
			}
		}
	write(sum);
	putchar('\n');
	for(int i=1;i<=m;i++)
		if(col[i])
			write(i),putchar(' ');
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<stack>
#include<set>
using namespace std;
#define LL long long
#define M 300005
#define N 20
#define lowbit(i) (i&(-i))
#define Mod 1000000007
#define IMax 0x7fffffffffffffff
void read(LL &x){
	x=0;char c=getchar();LL f=1;
	while(c<'0'||c>'9'){
		if(c=='-')
			f=-f;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=(x<<3)+(x<<1)+c-'0';
		c=getchar();
	}
	x*=f;
	return ;
}
void print(LL x){
	if(x<10){
		putchar(x+'0');
		return ;
	}
	print(x/10);
	putchar(x%10+'0');
}
void write(LL x){
	if(x<0)
		x=-x,putchar('-');
	print(x);
}
LL maxt(LL a,LL b){
	return a<b?b:a;
}
LL mint(LL a,LL b){
	return a<b?a:b;
}
struct node{
	LL v,id;
	node(LL V,LL Id){
		v=V,id=Id;
	}
};
set<LL>::iterator it;
stack<LL>q,q1;
set<LL>R[M],ans;
vector<node>G[M];
LL dfn[M],low[M],cnt,num[M],col;
LL visit[M];
bool iscut[M];
void tarjan(LL u,LL fa){
	q.push(u);
	dfn[u]=low[u]=++cnt;
	for(int i=0;i<G[u].size();i++){
		LL v=G[u][i].v,id=G[u][i].id;
		if(v==fa)
			continue;
		if(!visit[id])
		q1.push(id),visit[id]=1;
		if(!dfn[v]){
			tarjan(v,u);
			if(low[v]>=dfn[u]){
				col++;
				num[col]=1;
				while(q.top()!=v){
					num[col]++;
					q.pop();
				}
				num[col]++;
				q.pop();
				while(q1.top()!=id){
					R[col].insert(q1.top());
					q1.pop();
				}
				R[col].insert(id);
				q1.pop();
				if(num[col]==R[col].size()){
					ans.insert(R[col].begin(),R[col].end());
				}
			}
			low[u]=mint(low[v],low[u]);
		}else
			low[u]=mint(low[u],dfn[v]);
	}
}
LL n,m;
int main(){
	read(n),read(m);
	for(int i=1;i<=m;i++){
		LL u,v;
		read(u),read(v);
		G[u].push_back(node(v,i));
		G[v].push_back(node(u,i));
	}
	for(int i=1;i<=n;i++)
		if(!dfn[i])
			tarjan(i,i);
	write(ans.size());
	putchar('\n');
	for(it=ans.begin();it!=ans.end();it++)
		write(*it),putchar(' ');
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<stack>
#include<set>
using namespace std;
#define LL long long
#define M 300005
#define N 20
#define lowbit(i) (i&(-i))
#define Mod 1000000007
#define IMax 0x7fffffffffffffff
void read(LL &x){
	x=0;char c=getchar();LL f=1;
	while(c<'0'||c>'9'){
		if(c=='-')
			f=-f;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=(x<<3)+(x<<1)+c-'0';
		c=getchar();
	}
	x*=f;
	return ;
}
void print(LL x){
	if(x<10){
		putchar(x+'0');
		return ;
	}
	print(x/10);
	putchar(x%10+'0');
}
void write(LL x){
	if(x<0)
		x=-x,putchar('-');
	print(x);
}
LL maxt(LL a,LL b){
	return a<b?b:a;
}
LL mint(LL a,LL b){
	return a<b?a:b;
}
struct node{
	LL v,id;
	node(LL V,LL Id){
		v=V,id=Id;
	}
};
set<LL>::iterator it;
stack<LL>q,q1;
set<LL>R[M],ans;
vector<node>G[M];
LL dfn[M],low[M],cnt,num[M],col;
bool iscut[M];
void tarjan(LL u,LL fa){
	q.push(u);
	dfn[u]=low[u]=++cnt;
	for(int i=0;i<G[u].size();i++){
		LL v=G[u][i].v,id=G[u][i].id;
		if(v==fa)
			continue;
		q1.push(id);
		if(!dfn[v]){
			tarjan(v,u);
			if(low[v]>=dfn[u]){
				col++;
				num[col]=1;
				while(q.top()!=u){
					num[col]++;
					q.pop();
				}
				while(q1.top()!=id){
					R[col].insert(q1.top());
					q1.pop();
				}
				q1.top();
				R[col].insert(id);
				if(num[col]==R[col].size()){
					ans.insert(R[col].begin(),R[col].end());
				}
			}
			low[u]=mint(low[v],low[u]);
		}else
			low[u]=mint(low[u],dfn[v]);
	}
}
LL n,m;
int main(){
	read(n),read(m);
	for(int i=1;i<=m;i++){
		LL u,v;
		read(u),read(v);
		G[u].push_back(node(v,i));
		G[v].push_back(node(u,i));
	}
	for(int i=1;i<=n;i++)
		if(!dfn[i])
			tarjan(i,i);
	write(ans.size());
	putchar('\n');
	for(it=ans.begin();it!=ans.end();it++)
		write(*it),putchar(' ');
}


#include<bits/stdc++.h>
#define pb push_back
using namespace std;

const int mn=1e5+7;
int n,m,u[mn],v[mn],cnt,dph[mn],siz[mn],fa[mn];
bool vis[mn];
vector<int> to[mn],ans;

void dfs(int x,int f)
{
    dph[x]=dph[f]+1;fa[x]=f;vis[x]=1;
    for(int i=0;i<to[x].size();++i) {
        int t=to[x][i];
        if(vis[t]) {
            if(t!=f) {
                siz[t]--;
                siz[x]++;
            }
        }
        else dfs(t,x);
    }
}

void get_siz(int x)
{
    if(vis[x]) return ;
    vis[x]=1;
    for(int i=0;i<to[x].size();++i) {
        int t=to[x][i];
        if(vis[t]) continue;
        get_siz(t);
        siz[x]+=siz[t];
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;++i) {
        scanf("%d%d",&u[i],&v[i]);
        to[u[i]].pb(v[i]);
        to[v[i]].pb(u[i]);
    }
    dfs(1,0);
    get_siz(1);
    // for(int i=1;i<=m;++i) cout<<siz[i]<<" ";
    // puts("");
    for(int i=1;i<=m;++i) {
        if(dph[u[i]]<dph[v[i]]) swap(u[i],v[i]);
        if(fa[u[i]]==v[i]) {
            if(siz[u[i]]==1) {ans.pb(i);cnt++;}
        }
        else {
            int x=u[i],ed=v[i],flag=1;
            while(x!=ed) {
                if(siz[x]!=1) {flag=0;break;}
                x=fa[x];
            }
            if(flag) {ans.pb(i);cnt++;}
        }
    }
    printf("%d\n",cnt);
    for(int i=0;i<ans.size();++i) printf("%d ",ans[i]);
}


#include<bits/stdc++.h>
#define pb push_back
using namespace std;

const int mn=1e5+7;
int to[mn<<1],nxt[mn<<1],head[mn],_cnt=2;
void addedge(int u,int v) {to[_cnt]=v;nxt[_cnt]=head[u];head[u]=_cnt++;}

int n,m,cnt,dph[mn],siz[mn],fa[mn],id[mn];
bool vis[mn];
vector<int> ans;

void dfs(int x,int f)
{
    dph[x]=dph[f]+1;fa[x]=f;
    for(int i=head[x];i;i=nxt[i]) {
        int t=to[i];
        if(!dph[t]) {
            id[t]=i/2;
            dfs(t,x);
        }
    }
}

void get_siz(int x)
{
    if(vis[x]) return;
    vis[x]=1;
    for(int i=head[x];i;i=nxt[i]) {
        int t=to[i];
        if(fa[t]==x) {
            get_siz(t);
            siz[x]+=siz[t];
        }
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    int u,v;
    for(int i=1;i<=m;++i) {
        scanf("%d%d",&u,&v);
        addedge(u,v);
        addedge(v,u);
    }
    for(int i=1;i<=n;++i) if(!dph[i]) dfs(i,0);
    for(int i=2;i<_cnt;i+=2) {
        u=to[i],v=to[i^1];
        if(dph[u]<dph[v]) swap(u,v);
        if(fa[u]==v) continue;
        siz[u]++,siz[v]--;
    }
    for(int i=1;i<=n;++i) if(!vis[i]) get_siz(i);
    for(int i=2;i<_cnt;i+=2) {
        u=to[i],v=to[i^1];
        if(dph[u]<dph[v]) swap(u,v);
        if(fa[u]==v) continue;
        int x=u,ed=v,flag=1;
        while(x!=ed) {
            if(siz[x]!=1) {flag=0;break;}
            x=fa[x];
        }
        if(flag) {
            ans.pb(i/2);
            x=u,ed=v;
            while(x!=ed) {
                ans.pb(id[x]);
                x=fa[x];
            }
        }
    }
    printf("%d\n",ans.size());
    sort(ans.begin(),ans.end());
    for(int i=0;i<ans.size();++i) printf("%d ",ans[i]);
}


#include<bits/stdc++.h>
#define pb push_back
using namespace std;

const int mn=1e5+7;
int n,m,u[mn],v[mn],cnt,dph[mn],siz[mn],fa[mn];
bool vis[mn];
vector<int> to[mn],ans;

void dfs(int x,int f)
{
    dph[x]=dph[f]+1;fa[x]=f;
    for(int i=0;i<to[x].size();++i) {
        int t=to[x][i];
        if(t==f) continue;
        if(!dph[t]) dfs(t,x);
        else if(dph[t]<dph[x]) {
            siz[t]--;
            siz[x]++;
        }
    }
}

void get_siz(int x)
{
    if(vis[x]) return ;
    vis[x]=1;
    for(int i=0;i<to[x].size();++i) {
        int t=to[x][i];
        if(vis[t]) continue;
        get_siz(t);
        siz[x]+=siz[t];
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;++i) {
        scanf("%d%d",&u[i],&v[i]);
        to[u[i]].pb(v[i]);
        to[v[i]].pb(u[i]);
    }
    dfs(1,0);
    get_siz(1);
    for(int i=1;i<=m;++i) {
        if(dph[u[i]]<dph[v[i]]) swap(u[i],v[i]);
        if(fa[u[i]]==v[i]) {
            if(siz[u[i]]==1) {ans.pb(i);cnt++;}
        }
        else {
            int x=u[i],ed=v[i],flag=1;
            while(x!=ed) {
                if(siz[x]!=1) {flag=0;break;}
                x=fa[x];
            }
            if(flag) {ans.pb(i);cnt++;}
        }
    }
    printf("%d\n",cnt);
    for(int i=0;i<ans.size();++i) printf("%d ",ans[i]);
}


#pragma GCC optimize(3,"inline","Ofast")
#include<bits/stdc++.h>
using namespace std;
int n,tot=-1,m,tofa[200005],s[200005],tr[200005],f[200005],dep[200005],vis[100005],head[200005],go[200005],nex[200005];
vector <int> ans;
void add(int u,int v){
	nex[++tot]=head[u];head[u]=tot;go[tot]=v;
}
void build(int u,int fa,int dp)
{
	dep[u]=dep[fa]+1;vis[u]=1;f[u]=fa;
	for(int i=head[u];i!=-1;i=nex[i]){
		int v=go[i];if(v==fa||vis[v]) continue;
		tofa[v]=i;//cout<<i<<endl;
		tr[i]=1;build(v,u,dp+1);
	}
}
void dfs(int u,int fa){
	vis[u]=1;
	for(int i=head[u];i!=-1;i=nex[i])
	{
		int v=go[i];
		if(tr[i]){
			dfs(v,u);s[u]+=s[v];
		}
	}
}
int main()
{
	memset(head,-1,sizeof(head));
    memset(nex,-1,sizeof nex);
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v;scanf("%d%d",&u,&v);
		add(u,v);add(v,u);
	}
	for(int i=1;i<=n;i++)
	{
		if(!vis[i])
		build(i,0,0);
	}
    for(int i=0;i<=tot;i+=2){
    	if((!tr[i])&&(!tr[i+1]))
    	{
    		int u=go[i],v=go[i+1];
    		if(dep[u]<dep[v]) swap(u,v);//cout<<u<<" "<<v<<endl;
    		s[u]++;s[v]--;
    	}
    }
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++){
    	if(!vis[i]){
    		dfs(i,0);
    	}
    }
    for(int i=0;i<=tot;i+=2){
    	if(tr[i]||tr[i+1]) continue;
    	int u=go[i],v=go[i+1];

    	if(dep[u]<dep[v]) swap(u,v);
    	int tmp=u,bj=0;
    	while(1){
    		//cout<<tmp<<endl;
			if(tmp==v) break;
    		if(s[tmp]!=1){
    			bj=1;break;
    		}
    		tmp=f[tmp];
    	}
    	if(bj==0){
    		ans.push_back((i/2)+1);
    		while(1){
			    if(v==u) break;
    			ans.push_back((tofa[u]>>1)+1);
    			u=f[u];
    			if(v==u) break;
    		}
    	}
    }
    sort(ans.begin(),ans.end());
    cout<<ans.size()<<"\n";
    for(int i=0;i<ans.size();i++)
    {
    	cout<<ans[i]<<" ";
    }
	return 0;
}


#pragma GCC optimize (2)
#pragma GCC optimize(3,"inline","Ofast")
#include<bits/stdc++.h>
using namespace std;
int n,tot=1,m,tofa[200005],s[200005],tr[200005],f[200005],dep[200005],vis[100005],head[200005],go[200005],nex[200005];
vector <int> ans;
void add(int u,int v){
	nex[++tot]=head[u];head[u]=tot;go[tot]=v;
}
void build(int u,int fa,int dp)
{
	dep[u]=dep[fa]+1;vis[u]=1;f[u]=fa;
	for(int i=head[u];i;i=nex[i]){
		int v=go[i];if(v==fa||vis[v]) continue;
		tofa[v]=i;
		tr[i>>1]=1;build(v,u,dp+1);
	}
}
void dfs(int u,int fa){
	vis[u]=1;
	for(int i=head[u];i;i=nex[i])
	{
		int v=go[i];if(v==fa||vis[v]) continue;
		dfs(v,u);s[u]+=s[v];
	}
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v;scanf("%d%d",&u,&v);
		add(u,v);add(v,u);
	}
	for(int i=1;i<=n;i++)
	{
		if(!vis[i])
		build(i,0,0);
	}
    for(int i=1;i<=m;i++){
    	if(!tr[i])
    	{
    		int u=go[i*2],v=go[i*2+1];
    		if(dep[u]<dep[v]) swap(u,v);
    		s[u]++;s[v]--;
    	}
    }
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++){
    	if(!vis[i]){
    		dfs(i,0);
    	}
    }
    for(int i=1;i<=m;i++){
    	if(tr[i]) continue;
    	int u=go[i*2],v=go[i*2+1];
    	if(dep[u]<dep[v]) swap(u,v);
    	int tmp=u,bj=0;
    	while(1){
			if(tmp==v) break;
    		if(s[tmp]!=1){
    			bj=1;
    		}
    		tmp=f[tmp];
    	}
    	if(bj==0){
    		ans.push_back(i);
    		while(1){
    			ans.push_back(tofa[u]>>1);
    			u=f[u];
    			if(v==u) break;
    		}
    	}
    }
    sort(ans.begin(),ans.end());
    cout<<ans.size()<<"\n";
    for(int i=0;i<ans.size();i++)
    {
    	cout<<ans[i]<<" ";
    }
	return 0;
}


#pragma GCC optimize(3,"inline","Ofast")
#include<bits/stdc++.h>
using namespace std;
int n,tot=-1,m,tofa[200005],s[200005],tr[200005],f[200005],dep[200005],vis[100005],head[200005],go[200005],nex[200005];
vector <int> ans;
void add(int u,int v){
	nex[++tot]=head[u];head[u]=tot;go[tot]=v;
}
void build(int u,int fa,int dp)
{
	dep[u]=dep[fa]+1;vis[u]=1;f[u]=fa;
	for(int i=head[u];i!=-1;i=nex[i]){
		int v=go[i];if(v==fa||vis[v]) continue;
		tofa[v]=i;//cout<<i<<endl;
		tr[i]=1;build(v,u,dp+1);
	}
}
void dfs(int u,int fa){
	vis[u]=1;
	for(int i=head[u];i!=-1;i=nex[i])
	{
		int v=go[i];
		if(tr[i]){
			dfs(v,u);s[u]+=s[v];
		}
	}
}
int main()
{
	memset(head,-1,sizeof(head));
    memset(nex,-1,sizeof nex);
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v;scanf("%d%d",&u,&v);
		add(u,v);add(v,u);
	}
	for(int i=1;i<=n;i++)
	{
		if(!vis[i])
		build(i,0,0);
	}
    for(int i=0;i<=tot;i+=2){
    	if((!tr[i])&&(!tr[i+1]))
    	{
    		int u=go[i],v=go[i+1];
    		if(dep[u]<dep[v]) swap(u,v);//cout<<u<<" "<<v<<endl;
    		s[u]++;s[v]--;
    	}
    }
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++){
    	if(!vis[i]){
    		dfs(i,0);
    	}
    }
    for(int i=0;i<=tot;i+=2){
    	if(tr[i]||tr[i+1]) continue;
    	int u=go[i],v=go[i+1];

    	if(dep[u]<dep[v]) swap(u,v);
    	int tmp=u,bj=0;
    	while(1){
    		//cout<<tmp<<endl;
			if(tmp==v) break;
    		if(s[tmp]!=1){
    			bj=1;
    		}
    		tmp=f[tmp];
    	}
    	if(bj==0){
    		ans.push_back((i/2)+1);
    		while(1){
			    if(v==u) break;
    			ans.push_back((tofa[u]>>1)+1);
    			u=f[u];
    			if(v==u) break;
    		}
    	}
    }
    sort(ans.begin(),ans.end());
    cout<<ans.size()<<"\n";
    for(int i=0;i<ans.size();i++)
    {
    	cout<<ans[i]<<" ";
    }
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,low[1200005],tnum,ans,tot=1,tmp[1200005],f[1200005],vis[1200005],dfn[1200050],cnt=0,nex[2200005],go[2200005],head[2200005];
stack <int> q;
stack <int> qq;
vector <int> a[1200005];
void add(int u,int v)
{
	nex[++tot]=head[u];
	head[u]=tot;
	go[tot]=v;
}
void tar(int u)
{
	dfn[u]=low[u]=++tnum;qq.push(u);
	for(int i=head[u];i;i=nex[i])
	{
		int v=go[i];
		if(vis[i>>1]) continue;
		vis[i>>1]=1;
		q.push((i>>1));
		if(!dfn[v])
		{
			tar(v);
			low[u]=min(low[u],low[v]);
			if(low[v]<dfn[u]) continue;
			cnt++;
			tmp[cnt]++;
			while(1)
			{
				int tp=qq.top();
				qq.pop();
				tmp[cnt]++;
				if(tp==v) break;
			}
			while(1)
			{
				int tp=q.top();
				a[cnt].push_back(tp);
				q.pop();
				if(tp==(i>>1)) break;
			}
		}
		low[u]=min(low[u],dfn[v]);
	}
}
signed main()
{
	cin>>n>>m;
	for(int i=1,u,v;i<=m;i++)
	{
		scanf("%lld%lld",&u,&v);
		add(u,v);add(v,u);
	}
	for(int i=1;i<=n;i++)
	if(!dfn[i])
	tar(i);
	for(int i=1;i<=cnt;i++)
	{
		if(tmp[i]!=a[i].size()) continue;
		for(int j=0;j<a[i].size();j++)
		{
			f[a[i][j]]=1;
		}
	}

	for(int i=1;i<=m;i++)
	{
		if(f[i]) ans++;
	}
	cout<<ans<<endl;
	for(int i=1;i<=m;i++)
	if(f[i]) cout<<i<<" ";
	return 0;
}


#pragma GCC optimize(3,"inline","Ofast")
#pragma GCC optimize (2)
#include<bits/stdc++.h>
using namespace std;
vector<int>ans;
int tmp,tp,a,b,u,v,n,m,to[500010],deep[500010],nxt[500010],hd[500010],fa[100010],tofa[500010],num=-1,cf[500010];
bool tree[500010],vis[100010],flag;
void add(int u,int v)      //加边 (双向)
{
    nxt[++num]=hd[u],to[num]=v,hd[u]=num;
    nxt[++num]=hd[v],to[num]=u,hd[v]=num;
}
void dfs1(int pos,int f,int dp)//建搜索树
{
    fa[pos]=f;vis[pos]=1;deep[pos]=dp;
    for(int i=hd[pos];i!=-1;i=nxt[i])
    {
        if(!vis[to[i]])
        {
            tofa[to[i]]=i,tree[i]=1;dfs1(to[i],pos,dp+1);//记录是否为树边,以及到连接父亲节点边编号
        }
    }
}
void dfs(int pos)
{
    vis[pos]=1;
    for(int i=hd[pos];i!=-1;i=nxt[i])
    {
        if(tree[i])dfs(to[i]),cf[pos]+=cf[to[i]];//跑出差分
    }
}
int main()
{
    memset(hd,-1,sizeof hd);
    memset(nxt,-1,sizeof nxt);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&a,&b);
        add(a,b);
    }
    for(int i=1;i<=n;i++)
        if(!vis[i])dfs1(i,0,1);
    for(int i=0;i<=num;i+=2)
    {
        if(tree[i]||tree[i+1])continue;
        else u=to[i],v=to[i+1];
        if(deep[u]<deep[v])swap(u,v);
        cf[u]++;cf[v]--;//进行差分,注意在一个点上的差分值代表这个点到父亲的边的差分,因此在u,v上做,具体可画图理解
    }
    memset(vis,0,sizeof vis);
    for(int i=1;i<=n;i++)
        if(!vis[i])dfs(i);
    for(int i=0;i<=num;i+=2)
    {
        if(tree[i]||tree[i+1])continue;
        else u=to[i],v=to[i+1];
        if(deep[u]<deep[v])swap(u,v);
        flag=0;tmp=u;
        for(;fa[tmp]!=v;tmp=fa[tmp])//暴力跑路径
        {
            if(cf[tmp]!=1)
            {
                flag=1;break;
            }
        }
        if(!flag&&cf[tmp]==1)
        {
            ans.push_back((i+2)/2);//因为存的是双向边,故编号为+2再/2
            while(u!=v)
            {
                ans.push_back((tofa[u]+2)/2);
                u=fa[u];
            }
        }
    }
    sort(ans.begin(),ans.end());cout<<ans.size()<<endl;
    for(int i=0;i<ans.size();i++)cout<<ans[i]<<" ";//输出
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,low[1200005],tnum,ans,tot=1,tmp[1200005],f[1200005],vis[1200005],dfn[1200050],cnt=0,nex[2200005],go[2200005],head[2200005];
stack <int> q;
stack <int> qq;
vector <int> a[1200005];
void add(int u,int v)
{
	nex[++tot]=head[u];
	head[u]=tot;
	go[tot]=v;
}
void tar(int u)
{
	dfn[u]=low[u]=++tnum;qq.push(u);
	for(int i=head[u];i;i=nex[i])
	{
		int v=go[i];
		if(vis[i>>1]) continue;
		vis[i>>1]=1;
		q.push((i>>1));
		if(!dfn[v])
		{
			tar(v);
			low[u]=min(low[u],low[v]);
			if(low[v]<dfn[u]) continue;
			cnt++;
			tmp[cnt]++;
			while(1)
			{
				int tp=qq.top();
				qq.pop();
				tmp[cnt]++;
				if(tp==v) break;
			}
			while(1)
			{
				int tp=q.top();
				a[cnt].push_back(tp);
				q.pop();
				if(tp==(i>>1)) break;
			}
		}
		low[u]=min(low[u],dfn[v]);
	}
}
signed main()
{
	cin>>n>>m;
	for(int i=1,u,v;i<=m;i++)
	{
		scanf("%lld%lld",&u,&v);
		add(u,v);add(v,u);
	}
	tar(1);
	for(int i=1;i<=cnt;i++)
	{
		if(tmp[i]!=a[i].size()) continue;
		for(int j=0;j<a[i].size();j++)
		{
			f[a[i][j]]=1;
		}
	}

	for(int i=1;i<=m;i++)
	{
		if(f[i]) ans++;
	}
	cout<<ans<<endl;
	for(int i=1;i<=m;i++)
	if(f[i]) cout<<i<<" ";
	return 0;
}


#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
int n,m,low[1200005],tnum,ans,tot=1,tmp[1200005],f[1200005],vis[1200005],dfn[1200050],cnt=0,nex[2200005],go[2200005],head[2200005];
stack <int> q;
stack <int> qq;
vector <int> a;
void add(int u,int v)
{
	nex[++tot]=head[u];
	head[u]=tot;
	go[tot]=v;
}
void tar(int u)
{
	dfn[u]=low[u]=++tnum;qq.push(u);
	for(register int i=head[u];i;i=nex[i])
	{
		int v=go[i];
		if(vis[i>>1]) continue;
		vis[i>>1]=1;
		q.push((i>>1));
		if(!dfn[v])
		{
			tar(v);
			low[u]=min(low[u],low[v]);
			if(low[v]<dfn[u]) continue;
			a.clear();
			cnt++;
			tmp[cnt]++;
			while(1)
			{
				int tp=qq.top();
				qq.pop();
				tmp[cnt]++;
				if(tp==v) break;
			}
			while(1)
			{
				int tp=q.top();
				a.push_back(tp);
				q.pop();
				if(tp==(i>>1)) break;
			}
			if(a.size()==tmp[cnt])
			{
				for(int j=0;j<a.size();j++)
				f[a[j]]=1;
			}
		}
		low[u]=min(low[u],dfn[v]);
	}
}
signed main()
{
	//int size=80*1024*1024;
   // __asm__ ("movq %0,%%rsp\n"::"r"((char*)malloc(size)+size));
	cin>>n>>m;
	for(register int i=1,u,v;i<=m;i++)
	{
		scanf("%lld%lld",&u,&v);
		add(u,v);add(v,u);
	}
	tar(1);
	for(int i=1;i<=m;i++) if(f[i]) ans++;
	cout<<ans<<endl;
	for(int i=1;i<=m;i++) if(f[i]) cout<<i<<" ";
	//exit(0);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,tot=1,m,tofa[200005],s[200005],tr[200005],f[200005],dep[200005],vis[100005],head[200005],go[200005],nex[200005];
vector <int> ans;
void add(int u,int v){
	nex[++tot]=head[u];head[u]=tot;go[tot]=v;
}
void build(int u,int fa,int dp)
{
	dep[u]=dep[fa]+1;vis[u]=1;f[u]=fa;
	for(int i=head[u];i;i=nex[i]){
		int v=go[i];if(v==fa||vis[v]) continue;
		tofa[v]=i;
		tr[i>>1]=1;build(v,u,dp+1);
	}
}
void dfs(int u,int fa){
	vis[u]=1;
	for(int i=head[u];i;i=nex[i])
	{
		int v=go[i];if(v==fa||vis[v]) continue;
		dfs(v,u);s[u]+=s[v];
	}
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v;scanf("%d%d",&u,&v);
		add(u,v);add(v,u);
	}
	for(int i=1;i<=n;i++)
	{
		if(!vis[i])
		build(i,0,0);
	}
    for(int i=1;i<=m;i++){
    	if(!tr[i])
    	{
    		int u=go[i*2],v=go[i*2+1];
    		if(dep[u]<dep[v]) swap(u,v);
    		s[u]++;s[v]--;
    	}
    }
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++){
    	if(!vis[i]){
    		dfs(i,0);
    	}
    }
    for(int i=1;i<=m;i++){
    	if(tr[i]) continue;
    	int u=go[i*2],v=go[i*2+1];
    	if(dep[u]<dep[v]) swap(u,v);
    	int tmp=u,bj=0;
    	while(1){
			if(tmp==v) break;
    		if(s[tmp]!=1){
    			bj=1;
    		}
    		tmp=f[tmp];
    	}
    	if(bj==0){
    		ans.push_back(i);
    		while(1){
    			ans.push_back(tofa[u]>>1);
    			u=f[u];
    			if(v==u) break;
    		}
    	}
    }
    sort(ans.begin(),ans.end());
    cout<<ans.size()<<"\n";
    for(int i=0;i<ans.size();i++)
    {
    	cout<<ans[i]<<" ";
    }
	return 0;
}


#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
int n,m,low[1200005],tnum,ans,tot=1,tmp[1200005],f[1200005],vis[1200005],dfn[1200050],cnt=0,nex[2200005],go[2200005],head[2200005];
stack <int> q;
stack <int> qq;
vector <int> a;
void add(int u,int v)
{
	nex[++tot]=head[u];
	head[u]=tot;
	go[tot]=v;
}
void tar(int u)
{
	dfn[u]=low[u]=++tnum;qq.push(u);
	for(register int i=head[u];i;i=nex[i])
	{
		int v=go[i];
		if(vis[i>>1]) continue;
		vis[i>>1]=1;
		q.push((i>>1));
		if(!dfn[v])
		{
			tar(v);
			low[u]=min(low[u],low[v]);
			if(low[v]<dfn[u]) continue;
			a.clear();
			cnt++;
			tmp[cnt]++;
			while(1)
			{
				int tp=qq.top();
				qq.pop();
				tmp[cnt]++;
				if(tp==v) break;
			}
			while(1)
			{
				int tp=q.top();
				a.push_back(tp);
				q.pop();
				if(tp==(i>>1)) break;
			}
			if(a.size()==tmp[cnt])
			{
				for(int j=0;j<a.size();j++)
				f[a[j]]=1;
			}
		}
		low[u]=min(low[u],dfn[v]);
	}
}
signed main()
{
	int size=80*1024*1024;
    __asm__ ("movq %0,%%rsp\n"::"r"((char*)malloc(size)+size));
	cin>>n>>m;
	for(register int i=1,u,v;i<=m;i++)
	{
		scanf("%lld%lld",&u,&v);
		add(u,v);add(v,u);
	}
	tar(1);
	for(int i=1;i<=m;i++) if(f[i]) ans++;
	cout<<ans<<endl;
	for(int i=1;i<=m;i++) if(f[i]) cout<<i<<" ";
	exit(0);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,tot=1,m,tofa[200005],s[200005],tr[200005],f[200005],dep[200005],vis[100005],head[200005],go[200005],nex[200005];
vector <int> ans;
void add(int u,int v){
	nex[++tot]=head[u];head[u]=tot;go[tot]=v;
}
void build(int u,int fa,int dp)
{
	dep[u]=dep[fa]+1;vis[u]=1;f[u]=fa;
	for(int i=head[u];i;i=nex[i]){
		int v=go[i];if(v==fa||vis[v]) continue;
		tofa[v]=i;
		tr[i>>1]=1;build(v,u,dp+1);
	}
}
void dfs(int u,int fa){
	vis[u]=1;
	for(int i=head[u];i;i=nex[i])
	{
		int v=go[i];if(v==fa||vis[v]) continue;
		dfs(v,u);s[u]+=s[v];
	}
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v;scanf("%d%d",&u,&v);
		add(u,v);add(v,u);
	}
	for(int i=1;i<=n;i++)
	{
		if(!vis[i])
		build(i,0,0);
	}
    for(int i=1;i<=m;i++){
    	if(!tr[i])
    	{
    		int u=go[i*2],v=go[i*2+1];
    		if(dep[u]<dep[v]) swap(u,v);
    		s[u]++;s[v]--;
    	}
    }
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++){
    	if(!vis[i]){
    		dfs(i,0);
    	}
    }
    for(int i=1;i<=m;i++){
    	if(tr[i]) continue;
    	int u=go[i*2],v=go[i*2+1];
    	if(dep[u]<dep[v]) swap(u,v);
    	int tmp=u,bj=0;
    	while(1){
			if(tmp==v) break;
    		if(s[tmp]!=1){
    			bj=1;break;
    		}
    		tmp=f[tmp];
    	}
    	if(bj==0){
    		ans.push_back(i);
    		while(1){
    			ans.push_back(tofa[u]>>1);
    			u=f[u];
    			if(v==u) break;
    		}
    	}
    }
    sort(ans.begin(),ans.end());
    cout<<ans.size()<<"\n";
    for(int i=0;i<ans.size();i++)
    {
    	cout<<ans[i]<<" ";
    }
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

inline int rd() {
    int i=0, f=1; char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-')f=-1; ch=getchar();}
    while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=getchar();}
    return i*f;
}

const int N=1e6+50;
int n,m,dfnum,bcc,ans,num=1;
int h[N],dfn[N],low[N],sz[N];
bool f[N],used[N];

struct edge{
    int to,next;
} data[N<<1];

vector <int> a[N];
stack <int> qq;
stack <int> q;

inline void tarjan(int x){
    dfn[x]=low[x]=++dfnum;
	qq.push(x);
    for(int i=h[x];i;i=data[i].next){
        int y=data[i].to;
		if(used[i>>1]) continue;
        used[i>>1]=1;
		q.push(i>>1);
        if(!dfn[y]) {
            tarjan(y);
			low[x]=min(low[x],low[y]);
            if(low[y]<dfn[x]) continue;
			++bcc;
            while(1) {
                int z=qq.top(); qq.pop();
				sz[bcc]++;
                if(z==y) break;
            }
			sz[bcc]++;
            while(1) {
                int j=q.top(); q.pop();
				a[bcc].push_back(j);
                if(j==(i>>1)) break;
            }
        } low[x]=min(low[x],dfn[y]);
    }
}
int main(){
 	//freopen("graph.in","r",stdin);
 	//freopen("graph.out","w",stdout);
    n=rd(), m=rd();
    for(int i=1;i<=m;++i) {
        int x=rd(), y=rd();
        data[++num].to=y; data[num].next=h[x]; h[x]=num;
        data[++num].to=x; data[num].next=h[y]; h[y]=num;
    }
	tarjan(1);
    for(int i=1;i<=bcc;++i) {
        if(sz[i]!=a[i].size()) continue;
        for(int j=0;j<a[i].size();++j) f[a[i][j]]=1;
    }
    for(int i=1;i<=m;++i) if(f[i]){
    	ans++;
    }
    cout<<ans<<'\n';
    for(int i=1;i<=m;i++) if(f[i]) cout<<i<<" ";
}


#pragma GCC optimize(3,"inline","Ofast")
#include<bits/stdc++.h>
using namespace std;
int n,tot=-1,m,tofa[200005],s[200005],tr[200005],f[200005],dep[200005],vis[100005],head[200005],go[200005],nex[200005];
vector <int> ans;
void add(int u,int v){
	nex[++tot]=head[u];head[u]=tot;go[tot]=v;
}
void build(int u,int fa,int dp)
{
	dep[u]=dep[fa]+1;vis[u]=1;f[u]=fa;
	for(int i=head[u];i!=-1;i=nex[i]){
		int v=go[i];if(v==fa||vis[v]) continue;
		tofa[v]=i;//cout<<i<<endl;
		tr[i]=1;build(v,u,dp+1);
	}
}
void dfs(int u,int fa){
	vis[u]=1;
	for(int i=head[u];i!=-1;i=nex[i])
	{
		int v=go[i];
		if(tr[i]){
			dfs(v,u);s[u]+=s[v];
		}
	}
}
int main()
{
	memset(head,-1,sizeof(head));
    memset(nex,-1,sizeof nex);
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v;scanf("%d%d",&u,&v);
		add(u,v);add(v,u);
	}
	for(int i=1;i<=n;i++)
	{
		if(!vis[i])
		build(i,0,0);
	}
    for(int i=0;i<=tot;i+=2){
    	if((!tr[i])&&(!tr[i+1]))
    	{
    		int u=go[i],v=go[i+1];
    		if(dep[u]<dep[v]) swap(u,v);//cout<<u<<" "<<v<<endl;
    		s[u]++;s[v]--;
    	}
    }
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++){
    	if(!vis[i]){
    		dfs(i,0);
    	}
    }
    for(int i=0;i<=tot;i+=2){
    	if(tr[i]||tr[i+1]) continue;
    	int u=go[i],v=go[i+1];

    	if(dep[u]<dep[v]) swap(u,v);
    	int tmp=u,bj=0;
    	while(1){
    		//cout<<tmp<<endl;
			if(tmp==v) break;
    		if(s[tmp]!=1){
    			bj=1;
    		}
    		tmp=f[tmp];
    	}
    	if(bj==0){
    		ans.push_back(i+1);
    		while(1){
			    if(v==u) break;
    			ans.push_back((tofa[u]>>1)+1);
    			u=f[u];
    			if(v==u) break;
    		}
    	}
    }
    sort(ans.begin(),ans.end());
    cout<<ans.size()<<"\n";
    for(int i=0;i<ans.size();i++)
    {
    	cout<<ans[i]<<" ";
    }
	return 0;
}


#include<bits/stdc++.h>
#define cs const
#define re register
using namespace std;
cs int N=1e6+10;
namespace IO{
	cs int Rlen=1<<22|1;
	char buf[Rlen],*p1,*p2;
	inline char gc(){return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;}
	template<typename T>
	inline T get(){
		char ch;T x;
		while(!isdigit(ch=gc()));x=ch^48;
		while(isdigit(ch=gc())) x=((x+(x<<2))<<1)+(ch^48);
		return x;
	}
	inline int gi(){return get<int>();}
}
using namespace IO;
int n,m,t=1,tot,top,bcc_cnt;
int first[N],v[N<<1],nxt[N<<1];
struct edge{int u,v;}e[N];
inline void add(int x,int y){
	nxt[++t]=first[x],first[x]=t,v[t]=y;
}
int low[N],dfn[N],stk[N],belong[N],point[N],Size[N],val[N];
inline void Tarjan(int x,int pre){
	dfn[x]=low[x]=++tot;
	for(int re i=first[x],to=v[i];i;to=v[i=nxt[i]]) if(to!=pre){
		if(!dfn[to]){
			stk[++top]=i/2,Tarjan(to,x);
			low[x]=min(low[x],low[to]);
			if(low[to]>=dfn[x]){
				bcc_cnt++;
				while(1){
					int now=stk[top--];++Size[bcc_cnt],val[bcc_cnt]^=now;
					if(belong[e[now].u]!=bcc_cnt)  ++point[bcc_cnt],belong[e[now].u]=bcc_cnt;
					if(belong[e[now].v]!=bcc_cnt)  ++point[bcc_cnt],belong[e[now].v]=bcc_cnt;
					if((e[now].u==x&&e[now].v==to)||(e[now].u==to&&e[now].v==x))  break;
				}
			}
		}
		else  if(dfn[to]<dfn[x])  low[x]=min(low[x],dfn[to]),stk[++top]=i/2;
	}
}
int main(){
	//freopen("check.in","r",stdin);
	n=gi(),m=gi();
	for(int i=1;i<=m;++i){
		e[i].u=gi(),e[i].v=gi();
		add(e[i].u,e[i].v),add(e[i].v,e[i].u);
	}
	Tarjan(1,0);
	int ans=0;
	for(int i=1;i<=bcc_cnt;++i)
		if(point[i]==Size[i]){
			ans++;
		}
	printf("%d\n",ans);
	for(int i=1;i<=bcc_cnt;++i)
		if(point[i]==Size[i]){
			cout<<i<<" ";
		}
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<vector>
#include<set>
using namespace std;
const int maxn = 1e5+7;
struct EDGE{
	int to,next,id;
}edge[maxn*2];
int n,m,head[maxn],edge_num,Inx,dfn[maxn],low[maxn],used[maxn*2];
stack<int> stk;
vector<int> ans;
void add_edge(int u,int v,int id){
	edge[edge_num].to = v;
	edge[edge_num].next = head[u];
	edge[edge_num].id = id;
	head[u] = edge_num++;
}
void tarjan(int u,int fa){
	dfn[u] = low[u] = ++Inx;
	for(int i=head[u];i!=-1;i=edge[i].next){
		int v = edge[i].to;
		if(v==fa) continue;
		if(used[i]) continue;
		used[i] = used[i^1] = 1;
		stk.push(i);
		if(!dfn[v]){
			tarjan(v,u);
			low[u] = min(low[u],low[v]);
			if(dfn[u]<=low[v]){
				set<int> tmp_ver_set;
				set<int> tmp_edge_set;
				tmp_ver_set.insert(u);
				int x;
				do{
					x = stk.top();
					stk.pop();
					tmp_edge_set.insert(edge[x].id);
					tmp_ver_set.insert(edge[x].to);
				}while(x!=i);
				if(tmp_edge_set.size()==tmp_ver_set.size())
					for(set<int>::iterator it=tmp_edge_set.begin();it!=tmp_edge_set.end();it++)
						ans.push_back(*it);
			}
		}
		else low[u] = min(low[u],dfn[v]);
	}
}
int main(){
	scanf("%d %d",&n,&m);
	memset(head,255,sizeof(head));
	for(int i=1;i<=m;i++){
		int u,v;
		scanf("%d %d",&u,&v);
		add_edge(u,v,i);
		add_edge(v,u,i);
	}
	for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,i);
	sort(ans.begin(),ans.end());
	printf("%d\n",ans.size());
	for(int i=0;i<(int)ans.size();i++) printf("%d ",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,m,cnt=0,id=0,top=0,sum=0;
struct node{
	int to,next,id;
};node e[200005];
int head[200005],dfn[100005],low[100005],ans[100005],s[100005],use[200005];
void add(int u,int v,int id){
	e[cnt].to=v;
	e[cnt].next=head[u];
	e[cnt].id=id;
	head[u]=cnt++;
}
void dfs(int u,int fa){
	dfn[u]=low[u]=++id;
//	cout<<u<<"s";
	for(int i=head[u];i!=-1;i=e[i].next){
	//	cout<<"kkk";
		int v=e[i].to;
		if(v==fa) continue;
		if(use[i]) continue;
		use[i]=use[i^1]=1;
		s[++top]=i;
		if(!dfn[v]){
			dfs(v,u);
			low[u]=min(low[u],low[v]);
			if(dfn[u]<=low[v]){
				set <int> q1;
				set <int> q2;
				q1.insert(u);
				int x;
				do{
					x=s[top--];
					q2.insert(e[x].id);
					q1.insert(e[x].to);
				}while(x!=i);
				if(q1.size()==q2.size()){
					for(set<int>::iterator it=q2.begin();it!=q2.end();it++)
						ans[++sum]=*it;
				}
			}
		}
		else low[u]=min(low[u],dfn[v]);
	//	cout<<"www";
	}
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++) head[i]=-1;
	for(int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y,i);add(y,x,i);
	}
	for(int i=1;i<=n;i++){
	//	cout<<"ppp";
		if(!dfn[i]) dfs(i,i);
	//	cout<<"kkk";
	}
	sort(ans+1,ans+sum+1);
	cout<<sum<<endl;
	for(int i=1;i<=sum;i++) printf("%d ",ans[i]);
}


#include<bits/stdc++.h>
using namespace std;
int n,m,cnt=0,id=0,top=0,sum=0;
struct node{
	int to,next,id;
};node e[200005];
int head[200005],dfn[100005],low[100005],ans[100005],s[100005],use[200005];
void add(int u,int v,int id){
	e[cnt].to=v;
	e[cnt].next=head[u];
	e[cnt].id=id;
	head[u]=cnt++;
}
void dfs(int u,int fa){
	dfn[u]=low[u]=++id;
//	cout<<u<<"s";
	for(int i=head[u];i!=-1;i=e[i].next){
	//	cout<<"kkk";
		int v=e[i].to;
		if(v==fa) continue;
		if(use[i]) continue;
		use[i]=use[i^1]=1;
		s[++top]=i;
		if(!dfn[v]){
			dfs(v,u);
			low[u]=min(low[u],low[v]);
			if(dfn[u]<=low[v]){
				set <int> q1;
				set <int> q2;
				q1.insert(u);
				int x;
				do{
					x=s[top--];
					q2.insert(e[x].id);
					q1.insert(e[x].to);
				}while(x!=i);
				if(q1.size()==q2.size()){
					for(set<int>::iterator it=q2.begin();it!=q2.end();it++)
						ans[++sum]=*it;
				}
			}
		}
		else low[u]=min(low[u],low[v]);
	//	cout<<"www";
	}
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++) head[i]=-1;
	for(int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y,i);add(y,x,i);
	}
	for(int i=1;i<=n;i++){
	//	cout<<"ppp";
		if(!dfn[i]) dfs(i,i);
	//	cout<<"kkk";
	}
	sort(ans+1,ans+sum+1);
	cout<<sum<<endl;
	for(int i=1;i<=sum;i++) printf("%d ",ans[i]);
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <random>
#include <chrono>

using namespace std;
using namespace __gnu_pbds;

#define endl '\n'

typedef long long ll;
typedef pair<ll, ll> pii;
typedef tree<int, null_type,less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

template<typename T>
static T randint(T lo, T hi){
	return uniform_int_distribution<T>(lo, hi)(rng);
}

const int maxn = 1e5 + 5;
struct edge
{
	int u, v, comp;
};

vector<edge> edges;
vector<int> g[maxn];

int B[maxn], D[maxn], t = 0, sz = 0;
stack<int> st;

void dfs(int u, int p){
	B[u] = D[u] = t++;
	for(auto &e : g[u]){
		if(e == p)
			continue;

		int v = edges[e].v ^ edges[e].u ^ u;

		// cerr << u << " " << v << " " << e << endl;

		if(D[v] == -1){
			st.push(e);
			dfs(v, e);

			if(B[v] >= D[u]){
				int cur = -1;

				// cerr << "art " << u << endl;
				do{
					cur = st.top();st.pop();
					// cerr << cur << endl;
					edges[cur].comp = sz;
				}while(cur != e);
				sz++;
			}

			B[u] = min(B[u], B[v]);
		}
		else if(D[v] < D[u]){
			st.push(e);
			B[u] = min(B[u], D[v]);
		}
	}
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	// freopen("settling.in", "r", stdin);
	// freopen("settling.out", "w", stdout);

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

	for(int i = 0, a, b; i < m; i++){
		cin >> a >> b;
		a--, b--;
		g[a].push_back(i);
		g[b].push_back(i);
		edges.push_back({a, b, -1});
	}

	memset(D, -1, sizeof(D));
	t = 0, sz = 0;

	for(int i = 0; i < n; i++)
		if(D[i] == -1)
			dfs(i, -1);

	// cerr << "end" << endl;

	vector<set<int>> A(sz), B(sz);
	for(int i = 0; i < m; i++){
		int a = edges[i].u;
		int b = edges[i].v;
		int cmp = edges[i].comp;

		// cerr << i << " " << a << " " << b << " " << cmp << endl;

		A[cmp].insert(i);
		B[cmp].insert(a);
		B[cmp].insert(b);
	}

	// cerr << "here" << endl;

	vector<int> ans;
	for(int i = 0; i < sz; i++)
		if(A[i].size() == B[i].size())
			for(auto &e : A[i])
				ans.push_back(e);

	sort(ans.begin(), ans.end());
	cout << ans.size() << endl;
	for(int i = 0; i < ans.size(); i++)
		cout << ans[i] + 1 << " \n"[i + 1 == ans.size()];

	return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <random>
#include <chrono>

using namespace std;
using namespace __gnu_pbds;

#define endl '\n'

typedef long long ll;
typedef pair<ll, ll> pii;
typedef tree<int, null_type,less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

template<typename T>
static T randint(T lo, T hi){
	return uniform_int_distribution<T>(lo, hi)(rng);
}

struct graph
{
	int n;
	vector<vector<int>> adj;

	graph(int n) : n(n), adj(n) {}

	void add_edge(int u, int v)
	{
		adj[u].push_back(v);
		adj[v].push_back(u);
	}

	int add_node()
	{
		adj.push_back({});
		return n++;
	}

	vector<int>& operator[](int u) { return adj[u]; }
};

pair<vector<vector<int>>, vector<int>> biconnected_components(graph &adj)
{
	int n = adj.n;

	vector<int> num(n), low(n), art(n), stk;
	vector<vector<int>> comps;

	function<void(int, int, int&)> dfs = [&](int u, int p, int &t)
	{
		num[u] = low[u] = ++t;
		stk.push_back(u);

		for (int v : adj[u]) if (v != p)
		{
			if (!num[v])
			{
				dfs(v, u, t);
				low[u] = min(low[u], low[v]);

				if (low[v] >= num[u])
				{
					art[u] = (num[u] > 1 || num[v] > 2);

					comps.push_back({u});
					while (comps.back().back() != v)
						comps.back().push_back(stk.back()),
						stk.pop_back();
				}
			}
			else low[u] = min(low[u], num[v]);
		}
	};

	for (int u = 0, t; u < n; ++u)
		if (!num[u]) dfs(u, -1, t = 0);

	// build the block cut tree
	function<graph()> build_tree = [&]()
	{
		graph tree(0);
		vector<int> id(n);

		for (int u = 0; u < n; ++u)
			if (art[u]) id[u] = tree.add_node();

		for (auto &comp : comps)
		{
			int node = tree.add_node();
			for (int u : comp)
				if (!art[u]) id[u] = node;
				else tree.add_edge(node, id[u]);
		}

		return tree;
	};

	return {comps, art};
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	// freopen("settling.in", "r", stdin);
	// freopen("settling.out", "w", stdout);

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

	vector<pair<int, pii>> edges(m);
	graph g(n);
	for(int i = 0, a, b; i < m; i++){
		cin >> a >> b;
		a--, b--;
		edges[i] = {i, {a, b}};
		g.add_edge(a, b);
	}

	auto S = biconnected_components(g);

	auto comps = S.first;
	auto art = S.second;

	vector<int> c(n), cnt(comps.size());
	for(int i = 0; i < comps.size(); i++)
		for(auto &u : comps[i])
			c[u] = i;

	vector<int> ans;

	for(auto &e : edges){
		int a = e.second.first;
		int b = e.second.second;

		if(art[a] && art[b])
			continue;

		if(!art[a] && !art[b]){
			if(c[a] == c[b])
				cnt[c[a]]++;
		}
		else{
			int cmp = art[a] ? c[b] : c[a];
			cnt[cmp]++;
		}

	}

	for(auto &e : edges){
		int a = e.second.first;
		int b = e.second.second;
		int idx = e.first;

		if(art[a] && art[b])
			continue;

		if(!art[a] && !art[b]){
			if(c[a] == c[b] && cnt[c[a]] == comps[c[a]].size())
				ans.push_back(idx);
		}
		else{
			int cmp = art[a] ? c[b] : c[a];
			if(cnt[cmp] == comps[cmp].size())
				ans.push_back(idx);
		}
	}

	sort(ans.begin(), ans.end());

	cout << ans.size() << endl;
	for(int i = 0; i < ans.size(); i++)
		cout << ans[i] + 1 << " \n"[i + 1 == ans.size()];

	return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <random>
#include <chrono>

using namespace std;
using namespace __gnu_pbds;

#define endl '\n'

typedef long long ll;
typedef pair<ll, ll> pii;
typedef tree<int, null_type,less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

template<typename T>
static T randint(T lo, T hi){
	return uniform_int_distribution<T>(lo, hi)(rng);
}

struct graph
{
	int n;
	vector<vector<int>> adj;

	graph(int n) : n(n), adj(n) {}

	void add_edge(int u, int v)
	{
		adj[u].push_back(v);
		adj[v].push_back(u);
	}

	vector<int>& operator[](int u) { return adj[u]; }
};

vector<vector<int>> bridge_blocks(graph &adj)
{
	int n = adj.n;

	vector<int> num(n), low(n), stk;
	vector<vector<int>> comps;
	vector<pair<int, int>> bridges;

	function<void(int, int, int&)> dfs = [&](int u, int p, int &t)
	{
		num[u] = low[u] = ++t;
		stk.push_back(u);

		// remove if there isn't parallel edges
		sort(adj[u].begin(), adj[u].end());

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

			if (v == p)
			{
				if (i + 1 < sz && adj[u][i + 1] == v)
					low[u] = min(low[u], num[v]);
				continue;
			}

			if (!num[v])
			{
				dfs(v, u, t);
				low[u] = min(low[u], low[v]);

				if (low[v] == num[v])
					bridges.push_back({u, v});
			}
			else low[u] = min(low[u], num[v]);
		}

		if (num[u] == low[u])
		{
			comps.push_back({});
			for (int v = -1; v != u; stk.pop_back())
				comps.back().push_back(v = stk.back());
		}
	};

	for (int u = 0, t; u < n; ++u)
		if (!num[u]) dfs(u, -1, t = 0);

	// this is for build the bridge-block tree
	function<graph()> build_tree = [&]()
	{
		vector<int> id(n);

		for (int i = 0; i < (int) comps.size(); ++i)
			for (int u : comps[i]) id[u] = i;

		graph tree(comps.size());

		for (auto &e : bridges)
			tree.add_edge(id[e.first], id[e.second]);

		return tree;
	};

	return comps;
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	// freopen("settling.in", "r", stdin);
	// freopen("settling.out", "w", stdout);

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

	vector<pair<int, pii>> edges(m);
	graph g(n);
	for(int i = 0, a, b; i < m; i++){
		cin >> a >> b;
		a--, b--;
		edges[i] = {i, {a, b}};
		g.add_edge(a, b);
	}

	auto comps = bridge_blocks(g);
	vector<int> c(n), cnt(comps.size());
	for(int i = 0; i < comps.size(); i++)
		for(auto &u : comps[i])
			c[u] = i;

	vector<int> ans;

	for(auto &e : edges){
		int a = e.second.first;
		int b = e.second.second;

		if(c[a] == c[b])
			cnt[c[a]]++;
	}

	for(auto &e : edges){
		int a = e.second.first;
		int b = e.second.second;
		int idx = e.first;

		if(c[a] == c[b] && cnt[c[a]] == comps[c[a]].size())
			ans.push_back(idx);
	}

	sort(ans.begin(), ans.end());

	cout << ans.size() << endl;
	for(int i = 0; i < ans.size(); i++)
		cout << ans[i] + 1 << " \n"[i + 1 == ans.size()];

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int ed[100100],l[100100],ff[100100],a[100100],n,m,father[100100],x,y,num,head[100100],siz[100100],ans,f[100100];
bool b[100100],bb[100100];
struct node{
	int to,next,from;
}edge[200200];
void add(int x,int y)
{
	num++;
	edge[num].from=x;
	edge[num].to=y;
	edge[num].next=head[x];
	head[x]=num;
	return;
}
void dfs(int now,int fa,int pp)
{
	if(b[now])return;
	b[now]=true;
	siz[now]=1;
	father[now]=fa;
	l[now]=l[fa]+1;
	ed[now]=(pp-1)/2+1;
	int p=head[now];
	while(p)
	{
		int to=edge[p].to,id=p;
		p=edge[p].next;
		if(to==fa)continue;
	//	printf("%d %d\n",now,to);
		if(b[to]&&l[to]<l[now])
		{
			f[to]--;
			f[now]++;
			continue;
		}
		dfs(to,now,id);
		siz[now]+=siz[to];
	}
	return;
}
void df1(int now,int an)
{
	if(father[now]==-1)return;
	bb[ed[now]]=true;
	ff[now]=an+f[now];
	df1(father[now],an+f[now]);
	return;
}
int main()
{
	scanf("%d%d",&n,&m);
	memset(father,-1,sizeof(father));
	for(int i=1;i<=m;i++)
	{
		scanf("%d %d",&x,&y);
		add(x,y);
		add(y,x);
	}
	for(int i=1;i<=n;i++)
	if(!b[i])
	{
		dfs(i,-1,0);
		ed[i]=0;
	}
//	for(int i=1;i<=n;i++)
//		printf("%d ",f[i]);
	for(int i=1;i<=n;i++)
		if(siz[i]==1)df1(i,0);
	for(int i=1;i<=m;i++)
		if(!bb[i])
		{
//			printf("i=%d",i);
			int x=edge[i*2].from,y=edge[i*2].to,o=1,an=ans;
			if(l[x]>l[y])swap(x,y);
			while(x!=y)
			{
				o=max(o,ff[y]);
				a[++ans]=ed[y];
				y=father[y];
			}
			if(o!=1)
			{
				ans=an;
			}
			else
			{
				a[++ans]=i;
			}
		}
//	cout<<endl;
//	for(int i=1;i<=n;i++)
//		printf("%d ",ed[i]);
//	cout<<endl;
	printf("%d\n",ans);
	sort(a+1,a+ans+1);
	for(int i=1;i<=ans;i++)
		printf("%d ",a[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int ed[100100],l[100100],a[100100],n,m,father[100100],x,y,num,head[100100],siz[100100],ans,f[100100];
bool b[100100],bb[100100];
struct node{
	int to,next,from;
}edge[200200];
void add(int x,int y)
{
	num++;
	edge[num].from=x;
	edge[num].to=y;
	edge[num].next=head[x];
	head[x]=num;
	return;
}
void dfs(int now,int fa,int pp)
{
	if(b[now])return;
//	printf("i=%d %d \n",now,(pp-1)/2+1);
	b[now]=true;
	siz[now]=1;
	father[now]=fa;
	l[now]=l[fa]+1;
	if(fa!=-1)bb[(pp-1)/2+1]=true;
	ed[now]=(pp-1)/2+1;
	int p=head[now];
	while(p)
	{
		int to=edge[p].to,id=p;
		p=edge[p].next;
		if(to==fa)continue;
	//	printf("%d %d\n",now,to);
		if(b[to]&&l[to]<l[now])
		{
			f[to]--;
			f[now]++;
			continue;
		}
		dfs(to,now,id);
		siz[now]+=siz[to];
	}
	return;
}
void df1(int now,int fa)
{
//	printf("%d %d\n",now,fa);
	b[now]=true;
	int p=head[now];
	while(p)
	{
		int to=edge[p].to,id=p;
		p=edge[p].next;
		if(!bb[(id-1)/2+1])continue;
	//	printf("p=%d\n",(id-1)/2+1);
		if(to==fa)continue;
		if(b[to])continue;
		df1(to,now);
		f[now]+=f[to];
	}
	return;
}
int main()
{
	scanf("%d%d",&n,&m);
	memset(father,-1,sizeof(father));
	for(int i=1;i<=m;i++)
	{
		scanf("%d %d",&x,&y);
		add(x,y);
		add(y,x);
	}
	for(int i=1;i<=n;i++)
	if(!b[i])
	{
		l[i]=0;
		dfs(i,-1,0);
		ed[i]=0;
	}
//	for(int i=1;i<=n;i++)
//		printf("%d ",f[i]);
//	cout<<endl;
	memset(b,false,sizeof(b));
	for(int i=1;i<=n;i++)
		if(!b[i])df1(i,-1);
//	for(int i=1;i<=n;i++)
//		printf("%d ",f[i]);
	for(int i=1;i<=m;i++)
		if(!bb[i])
		{
//			printf("i=%d",i);
			int x=edge[i*2].from,y=edge[i*2].to,o=1,an=ans;
			if(l[x]>l[y])swap(x,y);
			while(x!=y)
			{
				o=max(o,f[y]);
				a[++ans]=ed[y];
				y=father[y];
			}
			if(o!=1)
			{
				ans=an;
			}
			else
			{
				a[++ans]=i;
			}
		}
//	cout<<endl;
//	for(int i=1;i<=n;i++)
//		printf("%d ",ed[i]);
//	cout<<endl;
	printf("%d\n",ans);
	sort(a+1,a+ans+1);
	for(int i=1;i<=ans;i++)
		printf("%d ",a[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int ed[100100],l[100100],a[100100],n,m,father[100100],x,y,num,head[100100],siz[100100],ans,f[100100];
bool b[100100],bb[100100];
struct node{
	int to,next,from;
}edge[200200];
void add(int x,int y)
{
	num++;
	edge[num].from=x;
	edge[num].to=y;
	edge[num].next=head[x];
	head[x]=num;
	return;
}
void dfs(int now,int fa,int pp)
{
	if(b[now])return;
//	printf("i=%d %d \n",now,(pp-1)/2+1);
	b[now]=true;
	siz[now]=1;
	father[now]=fa;
	l[now]=l[fa]+1;
	if(fa!=-1)bb[(pp-1)/2+1]=true;
	ed[now]=(pp-1)/2+1;
	int p=head[now];
	while(p)
	{
		int to=edge[p].to,id=p;
		p=edge[p].next;
		if(to==fa)continue;
	//	printf("%d %d\n",now,to);
		if(b[to]&&l[to]<l[now])
		{
			f[to]--;
			f[now]++;
			continue;
		}
		dfs(to,now,id);
		siz[now]+=siz[to];
	}
	return;
}
void df1(int now,int fa)
{
//	printf("%d %d\n",now,fa);
	b[now]=true;
	int p=head[now];
	while(p)
	{
		int to=edge[p].to,id=p;
		p=edge[p].next;
		if(!bb[(id-1)/2+1])continue;
	//	printf("p=%d\n",(id-1)/2+1);
		if(to==fa)continue;
		if(b[to])continue;
		df1(to,now);
		f[now]+=f[to];
	}
	return;
}
int main()
{
	scanf("%d%d",&n,&m);
	memset(father,-1,sizeof(father));
	for(int i=1;i<=m;i++)
	{
		scanf("%d %d",&x,&y);
		add(x,y);
		add(y,x);
	}
	for(int i=1;i<=n;i++)
	if(!b[i])
	{
		l[i]=0;
		dfs(i,-1,0);
		ed[i]=0;
	}
//	for(int i=1;i<=n;i++)
//		printf("%d ",f[i]);
//	cout<<endl;
	memset(b,false,sizeof(b));
	for(int i=1;i<=n;i++)
		if(!b[i])df1(i,-1);
//	for(int i=1;i<=n;i++)
//		printf("%d ",f[i]);
	for(int i=1;i<=m;i++)
		if(!bb[i])
		{
//			printf("i=%d",i);
			int x=edge[i*2].from,y=edge[i*2].to,o=1,an=ans;
			if(l[x]>l[y])swap(x,y);
			while(x!=y)
			{
				o=max(o,f[y]);
				if(o!=1)break;
				a[++ans]=ed[y];
				y=father[y];
			}
			if(o!=1)
			{
				ans=an;
			}
			else
			{
				a[++ans]=i;
			}
		}
//	cout<<endl;
//	for(int i=1;i<=n;i++)
//		printf("%d ",ed[i]);
//	cout<<endl;
	printf("%d\n",ans);
	sort(a+1,a+ans+1);
	for(int i=1;i<=ans;i++)
		printf("%d ",a[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define mp(x,y)(make_pair(x,y))
const int N=1e5+1;
struct Tarjan{
    vector<pair<int,int>>g[N],edge;
    int n,m,tot;
    bool instack[N];
    vector<int> in_edge[N],in_edge1[N];
    int dfn[N],low[N];
    vector<int>edge_on_simple_circle,d,stack[N];
    void read(){
        cin>>n>>m;
        edge.clear();
        edge.push_back(mp(0,0));
        for (int i=1;i<=m;i++){
            int x,y;
            cin>>x>>y;
            edge.push_back(mp(x,y));
            g[x].push_back(mp(y,i));
            g[y].push_back(mp(x,i));
        }
    }
    inline bool edge_out(int x){
        return !instack[edge[x].first]&&!instack[edge[x].second];
    }
    void dfs(int x,int lastedge){
        dfn[x]=low[x]=++tot;
        instack[x]=1;
        for (auto y:g[x]){
            if (y.second==lastedge)continue;
            if (!dfn[y.first]){
                dfs(y.first,y.second);
                in_edge[low[y.first]].push_back(y.second);
                /*if (dfn[x]<low[y.first]){
                    //bridge
                   in_edge[low[y.first]].pop_back();
                }*/
                int calc=1;
                int sig=dfn[x];
                while (stack[sig].size()){
                    instack[*stack[sig].rbegin()]=0;
                    stack[sig].pop_back();
                    ++calc;
                }
                d.clear();
                int tail=in_edge[sig].size()-1;
                instack[x]=0;
                while (tail>=0&&edge_out(in_edge[sig][tail]))d.push_back(in_edge[sig][tail]),in_edge[sig].pop_back(),tail--;
                instack[x]=1;
                if (d.size()==calc)
                    for (auto e:d)
                        edge_on_simple_circle.push_back(e);
                low[x]=min(low[x],low[y.first]);
            }else{
                if (instack[y.first]){
                    in_edge1[x].push_back(y.second);
                    if (low[x]>=dfn[y.first])
                        low[x]=dfn[y.first];
                }
            }
        }
        for (auto y:in_edge1[x])
            in_edge[low[x]].push_back(y);
        in_edge1[x].clear();
        if (low[x]!=dfn[x])
            stack[low[x]].push_back(x);
        else
            instack[x]=0;
    }
    void build(){
        for (int i=1;i<=n;i++)
            if (!dfn[i])
                tot=0,dfs(i,0);
    }
    void output(){
        sort(edge_on_simple_circle.begin(),edge_on_simple_circle.end());
        cout<<edge_on_simple_circle.size()<<endl;
        for (auto e:edge_on_simple_circle)
            cout<<e<<' ';
    }
}f;
int main(){
    ios::sync_with_stdio(false);
    f.read();
    f.build();
    f.output();
    return 0;
}