#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, M = 1e6 + 10, K = 2e4 + 10;
int head[N], h2[N], cur[N], dep[N], to[M], lim[M], nxt[M], vis[N], cnt = 1, n,
                                                                   m, s, t;
void add_edge(int u, int v, int l, int *head) {
  nxt[++cnt] = head[u], head[u] = cnt, lim[cnt] = l, to[cnt] = v;
  nxt[++cnt] = head[v], head[v] = cnt, lim[cnt] = 0, to[cnt] = u;
}
bool bfs() {
  queue<int> q;
  memset(dep, 0x3f, sizeof(dep));
  memset(vis, 0, sizeof(vis));
  memcpy(cur, head, sizeof(cur));
  dep[s] = 0;
  q.push(s);
  while (!q.empty()) {
    int h = q.front();
    vis[h] = 0;
    q.pop();
    for (int i = head[h]; i; i = nxt[i])
      if ((dep[to[i]] > dep[h] + 1) && lim[i]) {
        dep[to[i]] = dep[h] + 1;
        if (!vis[to[i]]) vis[to[i]] = 1, q.push(to[i]);
      }
  }
  if (dep[t] != 0x3f3f3f3f) return true;
  return false;
}
long long dfs(int rt = s, long long flow = 1e18) {
  if (rt == t) return flow;
  long long f = 0, ans = 0;
  for (int i = cur[rt]; i; i = nxt[i]) {
    cur[rt] = i;
    if (lim[i] && dep[to[i]] == dep[rt] + 1) {
      f = dfs(to[i], min(flow - ans, 1ll * lim[i]));
      if (f) {
        lim[i] -= f;
        lim[i ^ 1] += f;
        ans += f;
        if (ans == flow) break;
      }
    }
  }
  return ans;
}
long long dinic() {
  long long ans = 0, flow;
  while (bfs()) {
    while (flow = dfs()) ans += flow;
  }
  return ans;
}
vector<int> ans, edg;
int nd, P[N], Q[N], Dep[K], fa[K], siz[K], son[K], top[K], id[K], tim, eid[N];
bool _vis[N];
void dfs1(int rt, int f, int e = 0) {
  fa[rt] = f, siz[rt] = 1, Dep[rt] = Dep[f] + 1, eid[rt] = e;
  for (int i = h2[rt]; i; i = nxt[i])
    if (to[i] != f) {
      dfs1(to[i], rt, lim[i]);
      siz[rt] += siz[to[i]];
      if (siz[to[i]] > top[rt]) top[rt] = siz[to[i]], son[rt] = to[i];
    }
}
void dfs2(int rt, int t) {
  top[rt] = t, id[rt] = ++tim;
  if (son[rt]) dfs2(son[rt], t);
  for (int i = h2[rt]; i; i = nxt[i])
    if (to[i] != fa[rt] && to[i] != son[rt]) dfs2(to[i], to[i]);
}
void dfs3(int rt) {
  vis[rt] = 1;
  for (int i = head[rt]; i; i = nxt[i])
    if (lim[i] && !vis[to[i]]) dfs3(to[i]);
}
void build(int l = 1, int r = n, int rt = 1) {
  P[rt] = ++nd;
  if (l == r) return Q[l] = P[rt], add_edge(P[rt], t, 1, head);
  int mid = (l + r) >> 1;
  build(l, mid, (rt << 1)), build(mid + 1, r, ((rt << 1) | 1));
  add_edge(P[rt], P[(rt << 1)], 1e9, head),
      add_edge(P[rt], P[((rt << 1) | 1)], 1e9, head);
}
void _add_edges(int L, int R, int u, int l = 1, int r = n, int rt = 1) {
  if (L <= l && r <= R) return add_edge(u, P[rt], 1e9, head);
  int mid = (l + r) >> 1;
  if (L <= mid) _add_edges(L, R, u, l, mid, (rt << 1));
  if (R > mid) _add_edges(L, R, u, mid + 1, r, ((rt << 1) | 1));
}
void add_edges(int u, int v, int from) {
  while (top[u] != top[v]) {
    if (Dep[top[u]] < Dep[top[v]]) swap(u, v);
    _add_edges(id[top[u]], id[u], from);
    u = fa[top[u]];
  }
  if (Dep[u] > Dep[v]) swap(u, v);
  if (u == v) return;
  _add_edges(id[u] + 1, id[v], from);
}
int main() {
  ios::sync_with_stdio(false);
  cin >> n >> m;
  int u, v;
  for (int i = 1; i < n; ++i)
    cin >> u >> v, add_edge(u, v, i, h2), lim[cnt] = i;
  dfs1(1, 0);
  dfs2(1, 1);
  nd = m;
  s = ++nd, t = ++nd;
  build();
  for (int i = 1; i <= m; ++i) add_edge(s, i, 1, head);
  for (int i = 1; i <= m; ++i) {
    cin >> u >> v;
    add_edges(u, v, i);
  }
  cout << dinic() << endl;
  dfs3(s);
  for (int i = 1; i <= m; ++i)
    if (!vis[i]) ans.push_back(i);
  for (int i = 2; i <= n; ++i)
    if (vis[Q[id[i]]]) edg.push_back(eid[i]);
  cout << ans.size() << " ";
  for (auto i : ans) cout << i << " ";
  cout << endl << edg.size() << " ";
  for (auto i : edg) cout << i << " ";
}
