#include <vector>
#include <algorithm>
#include <queue>
#include <utility>
#include <tuple>
#include <iostream>
#include <cstdio>
#include <cassert>
using namespace std;
const int INF = 1 << 29;

struct Edge {
  int to, cap, cost, rev;
  Edge(int t, int ca, int co, int r) : to(t), cap(ca), cost(co), rev(r) {}
};

using Graph = vector< vector<Edge> >;

struct Flow {
  vector< vector<Edge> > G;
  const int MAXC = 1 << 29;
  int n;
  vector<bool> used;
  vector<int> prevv, preve, dist;
  Flow(int n_) : G(n_), n(n_), used(n_, false),
                 prevv(n_), preve(n_), dist(n_, MAXC) {}

  void add_edge(int from, int to, int cap, int cost) {
    G[from].push_back(Edge(to, cap, cost, G[to].size()));
    G[to  ].push_back(Edge(from, 0, -cost, G[from].size() - 1));
  }

  int dfs(int v, int t, int f) {
    if(v == t) return f;
    used[v] = true;
    for(int i=0; i<G[v].size(); i++) {
      Edge &e = G[v][i];
      if(!used[e.to] and e.cap > 0) {
        int d = dfs(e.to, t, min(f, e.cap));
        if(d > 0) {
          e.cap -= d;
          G[e.to][e.rev].cap += d;
          return d;
        }
      }
    }
    return 0;
  }

  int max_flow(int s, int t) {
    int flow = 0;
    while(1) {
      fill(used.begin(), used.end(), false);
      int f = dfs(s, t, INF);
      if(f == 0) return flow;
      flow += f;
    }
  }

  int mincost_flow(int s, int t, int f) {
    int res = 0;
    int ma = MAXC;
    while(f > 0) {
      fill(dist.begin(), dist.end(), ma);
      dist[s] = 0;
      bool update = true;
      while(update) {
        update = false;
        for(int v=0; v<n; v++) {
          if(dist[v] == ma) continue;
          for(int i=0; i<G[v].size(); i++) {
            Edge &e = G[v][i];
            if(e.cap > 0 and dist[e.to] > dist[v] + e.cost) {
              dist[e.to ] = dist[v] + e.cost;
              prevv[e.to] = v;
              preve[e.to] = i;
              update = true;
            }
          }
        }
      }
      if(dist[t] == ma) return -1;
      int d = f;
      for(int v=t; v!=s; v=prevv[v]) {
        d = min(d, G[prevv[v]][preve[v]].cap);
      }
      f -= d;
      res += d * dist[t];
      for(int v=t; v!=s; v=prevv[v]) {
        Edge &e = G[prevv[v]][preve[v]];
        e.cap -= d;
        G[v][e.rev].cap += d;
      }
    }
    return res;
  }
};

int main() {
  int N, M; cin >> N >> M;

  Flow fl1(N), fl2(N);
  vector< vector< pair<int, int> > > rec(N);
  vector<int> cnt(N);
  for(int i=0; i<M; i++) {
    int u, v; cin >> u >> v;
    u--; v--;
    
    fl1.add_edge(u, v, 1, 0);
    fl1.add_edge(v, u, 1, 1);
    
    fl2.add_edge(u, v, 1, 0);
    cnt[u]++; cnt[v]++;

    {
      int k = cnt[v];
      rec[v].emplace_back(i, k);
    }
    fl2.add_edge(v, u, 1, 1);
    cnt[u]++; cnt[v]++;
  }

  int source, sink; cin >> source >> sink;
  source--, sink--;

  int flow = fl1.max_flow(source, sink);
  cout << flow << endl;

  int edges = fl2.mincost_flow(source, sink, flow);
  cout << edges << endl;

  vector<int> ans;
  for(int i=0; i<N; i++) {
    for(auto e : rec[i]) {
      int edge_id, rev_id; tie(edge_id, rev_id) = e;
      if(fl2.G[i][rev_id].cap == 0) {
        Edge e = fl2.G[i][rev_id];
        // fprintf(stderr, "cap = %d, cost = %d, rev = %d\n", e.cap, e.cost, e.rev);
        // fprintf(stderr, "u = %d, v = %d\n", i + 1, e.to + 1);
        ans.emplace_back(edge_id);
      }
    }
  }

  assert(edges == ans.size());

  for(auto e : ans) cout << e + 1 << endl;
  return 0;
}



Measured memory_bytes: 3316