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

#include <queue>

#include <cstring>

using namespace std;



const int MAXV = 300;

const int MAXE = MAXV * MAXV;

const int MAXF = (1<<29);

typedef int F;



struct MaxFlow {

    F cap[MAXE], flow[MAXE];

    int V, E, level[MAXV], prev[MAXE], edge[MAXV], to[MAXE];

    MaxFlow(int n) : E(0) {

        V = n;

        memset(flow, 0, sizeof(flow));

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

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

    }

    void add_edge(int s, int t, F f, F g = 0) {

        cap[E] = f; to[E] = t; prev[E] = edge[s]; edge[s] = E; E++;

        cap[E] = g; to[E] = s; prev[E] = edge[t]; edge[t] = E; E++;

    }

    void make_level(int s) { // make level graph (bfs)

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

        queue<int> q; q.push(s); level[s] = 0;

        while(!q.empty()) {

            int v = q.front(); q.pop();

            for (int e = edge[v]; e != -1; e = prev[e]) {

                if (cap[e] - flow[e] > 0 && level[to[e]] == -1)

                    q.push(to[e]), level[to[e]] = level[v]+1;

            }

        }

    }

    int augment(int s, int t, F f) { // find augment path (dfs)

        if (s == t || f == 0) return f;

        for (int e = edge[s]; e != -1; e = prev[e]) {

            if (level[to[e]] > level[s] && cap[e] - flow[e] > 0) {

                F g = augment(to[e], t, min(f, cap[e] - flow[e]));

                if (g > 0) {

                    flow[e] += g, flow[e^1] -= g;

                    return g;

                }

            }

        }

        return 0;

    }

    int max_flow(int s, int t) {

        int f, ret = 0;

        for (bool cont = true; cont; ) {

            cont = false;

            make_level(s);

            while ((f = augment(s, t, MAXF)) > 0) {

                cont = true;

                ret += f;

            }

        }

        return ret;

    }

};



int main() {

    ios::sync_with_stdio(false);

    int x[MAXE], y[MAXE];

    int N,M,a,b;

    cin>>N>>M;

    MaxFlow mf(N);

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

        cin>>a>>b; a--, b--;

        mf.add_edge(a, b, 1, 1);

        x[i] = a, y[i] = b;

    }

    cin>>a>>b; a--, b--;

    cout<<mf.max_flow(a, b)<<endl;

    vector<int> rev;

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

        int e = mf.edge[y[i]];

        while(e != -1) {

            if (mf.to[e] == x[i] && mf.flow[e] > 0) rev.push_back(i);

            e = mf.prev[e];

        }

    }

    cout<<rev.size()<<endl;

    for (int i=0; i<rev.size(); ++i) cout<<rev[i]+1<<endl;

}

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

#include <queue>

#include <cstring>

using namespace std;



const int MAXV = 300;

const int MAXE = MAXV * MAXV;

const int MAXF = (1<<29);

typedef int F;



struct MaxFlow {

    F cap[MAXE], flow[MAXE];

    int V, E, level[MAXV], prev[MAXE], edge[MAXV], to[MAXE];

    MaxFlow(int n) : E(0), V(n) {

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

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

    }

    void add_edge(int s, int t, F f, F g = 0) {

        flow[E] = 0; cap[E] = f; to[E] = t; prev[E] = edge[s]; edge[s] = E; E++;

        flow[E] = 0; cap[E] = g; to[E] = s; prev[E] = edge[t]; edge[t] = E; E++;

    }

    void make_level(int s) { // make level graph (bfs)

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

        queue<int> q; q.push(s); level[s] = 0;

        while(!q.empty()) {

            int v = q.front(); q.pop();

            for (int e = edge[v]; e != -1; e = prev[e]) {

                if (cap[e] - flow[e] > 0 && level[to[e]] == -1)

                    q.push(to[e]), level[to[e]] = level[v]+1;

            }

        }

    }

    int augment(int s, int t, F f) { // find augment path (dfs)

        if (s == t || f == 0) return f;

        for (int e = edge[s]; e != -1; e = prev[e]) {

            if (level[to[e]] > level[s] && cap[e] - flow[e] > 0) {

                F g = augment(to[e], t, min(f, cap[e] - flow[e]));

                if (g > 0) {

                    flow[e] += g, flow[e^1] -= g;

                    return g;

                }

            }

        }

        return 0;

    }

    int max_flow(int s, int t) {

        int f, ret = 0;

        for (bool cont = true; cont; ) {

            cont = false;

            make_level(s);

            while ((f = augment(s, t, MAXF)) > 0) {

                cont = true;

                ret += f;

            }

        }

        return ret;

    }

};



int main() {

    ios::sync_with_stdio(false);

    int x[MAXE], y[MAXE];

    int N,M,a,b;

    cin>>N>>M;

    MaxFlow mf(N);

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

        cin>>a>>b; a--, b--;

        mf.add_edge(a, b, 1, 1);

        x[i] = a, y[i] = b;

    }

    cin>>a>>b; a--, b--;

    cout<<mf.max_flow(a, b)<<endl;

    vector<int> rev;

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

        int e = mf.edge[y[i]];

        while(e != -1) {

            if (mf.to[e] == x[i] && mf.flow[e] > 0) rev.push_back(i);

            e = mf.prev[e];

        }

    }

    cout<<rev.size()<<endl;

    for (int i=0; i<rev.size(); ++i) cout<<rev[i]+1<<endl;

}

// Fastest known solution for this problem: