#include <bits/stdc++.h>
using namespace std;
struct po {
  int to, next, w;
} E[160005], e[600000];
struct po2 {
  int l, r;
} t[160005];
int n, m, a, b, ans, top[160005], dfn[160005], size[160005], deep[160005],
    son[160005], fa[160005];
int head[100005], cnt = 1, Head[160005], Cnt, cur[100005], qwq, st = 0, en, ind;
int ans1[160005], ans2[160005], edg[160005], wa[160005], nfd[160005];
void Add(int x, int y, int z) {
  E[++Cnt].to = y, E[Cnt].w = z, E[Cnt].next = Head[x], Head[x] = Cnt;
  E[++Cnt].to = x, E[Cnt].w = z, E[Cnt].next = Head[y], Head[y] = Cnt;
}
void addedge(int x, int y, int z) {
  e[++cnt].to = y, e[cnt].w = z, e[cnt].next = head[x], head[x] = cnt;
  e[++cnt].to = x, e[cnt].w = 0, e[cnt].next = head[y], head[y] = cnt;
}
void dfs1(int x, int y) {
  size[x] = 1, fa[x] = y, deep[x] = deep[y] + 1;
  int mx = 0;
  for (int i = Head[x]; i; i = E[i].next)
    if (E[i].to != y) {
      dfs1(E[i].to, x), size[x] += size[E[i].to];
      if (size[E[i].to] > mx) mx = size[E[i].to], son[x] = E[i].to, edg[x] = i;
    }
}
void dfs2(int x, int y, int z) {
  top[x] = z;
  if (son[x]) nfd[(dfn[son[x]] = ++ind)] = E[edg[x]].w, dfs2(son[x], x, z);
  for (int i = Head[x]; i; i = E[i].next)
    if (E[i].to != y && E[i].to != son[x])
      nfd[(dfn[E[i].to] = ++ind)] = E[i].w, dfs2(E[i].to, x, E[i].to);
}
void build(int l, int r, int k) {
  t[k].l = l, t[k].r = r;
  if (l == r) {
    wa[l] = k, addedge(k, en, 1);
    return;
  }
  int mid = (l + r) >> 1;
  addedge(k, k << 1, 0x3f3f3f3f), addedge(k, k << 1 | 1, 0x3f3f3f3f);
  build(l, mid, k << 1), build(mid + 1, r, k << 1 | 1);
}
void add(int l, int r, int k) {
  if (l == t[k].l && r == t[k].r) {
    addedge(qwq, k, 0x3f3f3f3f);
    return;
  }
  int mid = (t[k].l + t[k].r) >> 1;
  if (r <= mid)
    add(l, r, k << 1);
  else if (l > mid)
    add(l, r, k << 1 | 1);
  else
    add(l, mid, k << 1), add(mid + 1, r, k << 1 | 1);
}
void change(int x, int y) {
  int prol[160005], pror[160005], tot = 0;
  while (top[x] != top[y]) {
    if (deep[top[x]] > deep[top[y]]) swap(x, y);
    tot++, prol[tot] = dfn[top[y]], pror[tot] = dfn[y], y = fa[top[y]];
  }
  if (deep[x] > deep[y]) swap(x, y);
  if (dfn[x] + 1 <= dfn[y]) tot++, prol[tot] = dfn[x] + 1, pror[tot] = dfn[y];
  for (int i = 2; i <= tot; i++)
    if (pror[i - 1] == prol[i] - 1)
      prol[i] = prol[i - 1], prol[i - 1] = pror[i - 1] = 0;
  for (int i = 1; i <= tot; i++)
    if (prol[i] && pror[i]) add(prol[i], pror[i], 1);
}
bool bfs() {
  queue<int> q;
  while (!q.empty()) q.pop();
  memset(deep, -1, sizeof(deep)), deep[st] = 0, q.push(st);
  while (!q.empty()) {
    int now = q.front();
    q.pop();
    for (int i = head[now]; i; i = e[i].next)
      if (e[i].w && deep[e[i].to] == -1)
        deep[e[i].to] = deep[now] + 1, q.push(e[i].to);
  }
  return (deep[en] != -1);
}
int dfs(int x, int w) {
  if (x == en || !w) return w;
  int pro, flow = 0;
  for (int &i = cur[x]; i && flow < w; i = e[i].next)
    if (e[i].w && deep[e[i].to] == deep[x] + 1) {
      if ((pro = dfs(e[i].to, min(w - flow, e[i].w))) > 0)
        flow += pro, e[i].w -= pro, e[i ^ 1].w += pro;
      if (flow == w) break;
    }
  if (!flow) deep[x] = -1;
  return flow;
}
int main() {
  scanf("%d%d", &n, &m), en = m + (n << 2) + 1;
  for (int i = 1; i < n; i++) scanf("%d%d", &a, &b), Add(a, b, i);
  build(1, n - 1, 1), dfs1(1, 0), dfs2(1, 0, 1);
  for (qwq = 1 + (n << 2); qwq <= m + (n << 2); qwq++)
    addedge(st, qwq, 1), scanf("%d%d", &a, &b), change(a, b);
  int pro;
  while (bfs()) {
    memcpy(cur, head, sizeof(head));
    while ((pro = dfs(st, 0x3f3f3f3f)) > 0) ans += pro;
  }
  printf("%d", ans);
  for (int i = 1; i <= m; i++)
    if (deep[i + (n << 2)] == -1) ans1[++ans1[0]] = i;
  for (int i = 1; i < n; i++)
    if (deep[wa[i]] != -1) ans2[++ans2[0]] = nfd[i];
  printf("\n%d ", ans1[0]);
  for (int i = 1; i <= ans1[0]; i++) printf("%d ", ans1[i]);
  printf("\n%d ", ans2[0]);
  for (int i = 1; i <= ans2[0]; i++) printf("%d ", ans2[i]);
  return 0;
}
