Problem: ICP city has an express company whose trucks run from the crossing S to the crossing T. The president of the company is feeling upset because all the roads in the city are one-way, and are severely congested. So, he planned to improve the maximum flow (edge disjoint paths) from the crossing S to the crossing T by reversing the traffic direction on some of the roads.

Your task is writing a program to calculate the maximized flow from S to T by reversing some roads, and the list of the reversed roads.



Input

The first line of a data set contains two integers N (2 \leq N \leq 300) and M (0 \leq M \leq {\rm min} (1\,000,\ N(N-1)/2)). N is the number of crossings in the city and M is the number of roads.

The following M lines describe one-way roads in the city. The i-th line (1-based) contains two integers X_i and Y_i (1 \leq X_i, Y_i \leq N, X_i \neq Y_i). X_i is the ID number (1-based) of the starting point of the i-th road and Y_i is that of the terminal point. The last line contains two integers S and T (1 \leq S, T \leq N, S \neq T, 1-based).

The capacity of each road is 1. You can assume that i \neq j implies either X_i \neq X_j or Y_i \neq Y_j, and either X_i \neq Y_j or X_j \neq Y_i.

Output

In the first line, print the maximized flow by reversing some roads. In the second line, print the number R of the reversed roads. In each of the following R lines, print the ID number (1-based) of a reversed road. You may not print the same ID number more than once.

If there are multiple answers which would give us the same flow capacity, you can print any of them.

Examples

Input

2 1
2 1
2 1


Output

1
0


Input

2 1
1 2
2 1


Output

1
1
1


Input

3 3
3 2
1 2
3 1
1 3


Output

2
2
1
3

Solution (in CPP):

Solution:
#include <bits/stdc++.h> // {{{
// clang-format off
#pragma GCC optimize "O3,omit-frame-pointer,inline"
#pragma GCC target "tune=native"
#define ARG4(_1, _2, _3, _4, ...) _4
#define rep(...) ARG4(__VA_ARGS__, FOR, REP)(__VA_ARGS__)
#define REP(i, a) FOR(i, 0, a)
#define FOR(i, a, b) for (int i = (a); i < (int)(b); ++i)
#define rrep(...) ARG4(__VA_ARGS__, RFOR, RREP)(__VA_ARGS__)
#define RREP(i, a) RFOR(i, 0, a)
#define RFOR(i, a, b) for (int i = (b)-1; i >= (int)(a); --i)
#define ALL(c) (c).begin(), (c).end()
#define TEN(n) ((ll)(1e##n))
#define pb emplace_back
#define mp make_pair
#define fi first
#define se second
#define USE1(T) template<typename T>inline
#define USE2(T, U) template<typename T,typename U>inline
#define mygc(c) (c)=getchar_unlocked()
#define mypc(c) putchar_unlocked(c)

template<typename T>using duo=std::pair<T,T>;
template<typename T>using vec=std::vector<T>;
using ll=long long;
using pii=duo<int>;
USE2(T,U)bool chmax(T&x,U a){return x<a&&(x=a,1);}
USE2(T,U)bool chmin(T&x,U a){return a<x&&(x=a,1);}
USE1(T=int)T in(){T x;std::cin>>x;return x;}
USE1(T=int)vec<T>in(int n){vec<T>v;v.reserve(n);rep(i,n)v.pb(in<T>());return v;}
USE1(T=int)vec<T>in(int n,T a){vec<T>v;v.reserve(n);rep(i,n)v.pb(in<T>()+a);return v;}
USE1(T)vec<std::pair<T,int>>enume(const vec<T>&x,int s=0){int N=x.size();vec<std::pair<T,int>>v;v.reserve(N);rep(i,N)v.pb(x[i],s+i);return v;}
USE1(T)vec<T>ndvec(T v,int n){return vec<T>(n,v);}
USE2(T,...Ts)auto ndvec(T v,int n,Ts...ns)->vec<decltype(ndvec(v,ns...))>{return ndvec(ndvec(v,ns...),n);}
USE1(T)void pr(T x){std::cout<<x<<'\n';}
USE2(T,...Ts)void pr(T x,Ts...xs){std::cout<<x<<' ';pr(xs...);}
USE1(T=int)T rd(){T x=0,m=0,k;for(;;){mygc(k);if(k=='-'){m=1;break;}if('0'<=k&&k<='9'){x=k-'0';break;}}for(;;){mygc(k);if(k<'0'||'9'<k)break;x=x*10+k-'0';}return x;}
USE1(T=int)void wr(T x,char c='\n'){int s=0,m=0;char b[32];if(x<0)m=1,x=-x;for(;x;x/=10)b[s++]=x%10;if(!s)b[s++]=0;if(m)mypc('-');for(;s--;)mypc(b[s]+'0');mypc(c);}
// clang-format on
// }}}
struct IoSetup { // {{{
  IoSetup() {
    std::ios::sync_with_stdio(0);
    std::cin.tie(0);
    std::cout.precision(10);
    std::cerr.precision(10);
  }
} iosetup; //}}}
#include <vector>
namespace copr {
template <typename GraphType>
struct graph_traits {
  using value_type = typename GraphType::value_type;
  using vertex_type = typename value_type::value_type;
  using edge_type = typename vertex_type::value_type;
  using path_type = vertex_type;
};
} // namespace copr
namespace copr {
template <typename CapacityType>
struct ResidualGraph {
  struct REdge;
  using REdges = std::vector<REdge>;
  using RGraph = std::vector<REdges>;
  using value_type = RGraph;
  struct REdge {
    using value_type = CapacityType;
    value_type cap;
    int to, rev;
    const bool is_rev;
    REdge(int to, value_type cap, int rev, bool is_rev)
        : to(to), cap(cap), rev(rev), is_rev(is_rev) {}
  };
  const int V;
  RGraph G;

  ResidualGraph(int V) : V(V), G(V) {}
  inline REdge& rev(const REdge& e) { return G[e.to][e.rev]; }
  void add_edge(int from, int to, CapacityType cap) {
    G[from].emplace_back(to, cap, G[to].size(), false);
    G[to].emplace_back(from, 0, G[from].size() - 1, true);
  }
};
} // namespace copr

#include <algorithm>
#include <limits>
#include <queue>

namespace copr {
template <typename T>
struct Dinic {
  using graph_type = ResidualGraph<T>;
  using edge_type = typename graph_traits<graph_type>::edge_type;
  using capacity_type = typename edge_type::value_type;

  static constexpr auto inf = std::numeric_limits<capacity_type>::max();
  const int UNREACHABLE = -1;

  graph_type& Gf;
  std::vector<int> level, iter;
  Dinic(graph_type& Gf) : Gf(Gf), level(Gf.V), iter(Gf.V) {}

  capacity_type max_flow_value(int s, int t) {
    capacity_type value = 0;
    while (labeling(s), level[t] != UNREACHABLE) {
      std::fill(iter.begin(), iter.end(), 0);
      capacity_type bf;
      while (bf = blocking_flow(s, t, inf), bf > 0) {
        value += bf;
      }
    }
    return value;
  }
  bool labeling(int s) {
    std::fill(level.begin(), level.end(), UNREACHABLE);
    level[s] = 0;
    static std::queue<int> Q;
    Q.push(s);
    for (; not Q.empty(); Q.pop()) {
      auto v = Q.front();
      for (auto& e : Gf.G[v]) {
        if (level[e.to] != UNREACHABLE) continue;
        if (e.cap == 0) continue;
        level[e.to] = level[v] + 1;
        Q.push(e.to);
      }
    }
    return true;
  }
  capacity_type blocking_flow(int v, int t, capacity_type f) {
    if (v == t) return f;
    auto& V = Gf.G[v];
    for (int& i = iter[v]; i < V.size(); ++i) {
      auto& e = V[i];
      if (e.cap == 0) continue;
      if (level[v] >= level[e.to]) continue;
      auto bf = blocking_flow(e.to, t, std::min(f, e.cap));
      if (bf > 0) {
        e.cap -= bf;
        Gf.rev(e).cap += bf;
        return bf;
      }
    }
    return 0;
  }
};
template <typename T>
Dinic<T> dinic(ResidualGraph<T>& Gf) {
  return Dinic<T>(Gf);
}
} // namespace copr
using namespace std;
const int inf = 1001001001;
const ll infl = 1001001001001001001ll;
const int dd[] = {0, 1, 0, -1, 0};

signed main() { //
  int V = in(), E = in();
  copr::ResidualGraph<int> G(V);
  int s[1010], t[1010];
  int r[1010];
  rep(i, E) {
    s[i] = in() - 1, t[i] = in() - 1;
    G.add_edge(s[i], t[i], 1);
    G.add_edge(t[i], s[i], 1);
    r[i] = G.G[t[i]].size() - 1;
  }
  int src = in() - 1, sink = in() - 1;
  pr(copr::dinic(G).max_flow_value(src, sink));
  vec<int> ans;
  rep(i, E) {
    if (G.G[t[i]][r[i]].cap == 0) { ans.emplace_back(i + 1); }
  }
  pr(ans.size());
  for (int x : ans)
    pr(x);

  return 0;
}