#include <bits/stdc++.h>
using namespace std;
inline int gi() {
  char c;
  int num = 0, flg = 1;
  while ((c = getchar()) < '0' || c > '9')
    if (c == '-') flg = -1;
  while (c >= '0' && c <= '9') {
    num = num * 10 + c - 48;
    c = getchar();
  }
  return num * flg;
}
int n, m;
int fir[200005], cur[200005], to[5000005], nxt[5000005], cap[5000005],
    id[2 * 200005], cnt;
void adde(int a, int b, int c, int d = 0) {
  to[++cnt] = b;
  nxt[cnt] = fir[a];
  fir[a] = cnt;
  cap[cnt] = c;
  if (d) id[cnt] = d;
  to[++cnt] = a;
  nxt[cnt] = fir[b];
  fir[b] = cnt;
  cap[cnt] = 0;
  if (d) id[cnt] = d;
}
int fa[200005], son[200005], sonp[200005], siz[200005], top[200005],
    dep[200005];
void dfs1(int u) {
  dep[u] = dep[fa[u]] + 1;
  siz[u] = 1;
  for (int v, p = fir[u]; p; p = nxt[p]) {
    if ((v = to[p]) != fa[u]) {
      fa[v] = u;
      dfs1(v);
      siz[u] += siz[v];
      if (siz[son[u]] < siz[v]) son[u] = v, sonp[u] = p;
    }
  }
}
int pos[200005], dc, dfn[200005];
void dfs2(int u, int fro) {
  pos[u] = ++dc;
  dfn[dc] = id[fro];
  if (son[u]) top[son[u]] = top[u], dfs2(son[u], sonp[u]);
  for (int v, p = fir[u]; p; p = nxt[p])
    if ((v = to[p]) != fa[u] && v != son[u]) top[v] = v, dfs2(v, p);
}
int S, T, sz;
const int INF = 0x3f3f3f3f;
struct node {
  int l, r;
} a[200005];
int rt;
void build(int &i, int l, int r) {
  if (l == r) {
    i = dfn[l];
    return;
  }
  i = ++sz;
  int mid = (l + r) >> 1;
  build(a[i].l, l, mid);
  build(a[i].r, mid + 1, r);
  adde(i, a[i].l, INF);
  adde(i, a[i].r, INF);
}
void insert(int i, int l, int r, int ql, int qr, int p) {
  if (l > qr || r < ql) return;
  if (ql <= l && r <= qr) {
    adde(p, i, INF);
    return;
  }
  int mid = (l + r) >> 1;
  insert(a[i].l, l, mid, ql, qr, p);
  insert(a[i].r, mid + 1, r, ql, qr, p);
}
void QP(int x, int y, int p) {
  while (top[x] != top[y]) {
    if (dep[top[x]] < dep[top[y]]) swap(x, y);
    insert(rt, 1, n, pos[top[x]], pos[x], p);
    x = fa[top[x]];
  }
  if (dep[x] > dep[y]) swap(x, y);
  insert(rt, 1, n, pos[x] + 1, pos[y], p);
}
queue<int> q;
int dis[200005];
bool bfs() {
  for (int i = 1; i <= sz; i++) dis[i] = -1;
  q.push(T);
  dis[T] = 0;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int v, p = fir[u]; p; p = nxt[p]) {
      v = to[p];
      if (cap[p ^ 1] > 0 && dis[v] == -1) {
        dis[v] = dis[u] + 1;
        q.push(v);
      }
    }
  }
  return dis[S] != -1;
}
int sap(int u, int aug) {
  if (u == T) return aug;
  int tmp, ret = 0;
  for (int v, &p = cur[u]; p; p = nxt[p]) {
    v = to[p];
    if (cap[p] > 0 && dis[u] == dis[v] + 1) {
      tmp = sap(v, min(cap[p], aug));
      cap[p] -= tmp;
      aug -= tmp;
      cap[p ^ 1] += tmp;
      ret += tmp;
      if (!aug) break;
    }
  }
  return ret;
}
int flow;
void maxflow() {
  flow = 0;
  while (bfs()) {
    for (int i = 1; i <= sz; i++) cur[i] = fir[i];
    flow += sap(S, INF);
  }
}
int main() {
  int i, u, v;
  n = gi();
  m = gi();
  for (i = 1; i < n; i++) {
    u = gi();
    v = gi();
    adde(u, v, 0, i);
  }
  dfs1(1);
  top[1] = 1;
  dfs2(1, 0);
  memset(fir, 0, sizeof(fir));
  cnt = 1;
  sz = n;
  build(rt, 1, n);
  for (i = 1; i <= m; i++) {
    u = gi();
    v = gi();
    QP(u, v, sz + i);
  }
  S = sz + m + 1;
  T = sz + m + 2;
  int tot = sz;
  for (i = 1; i < n; i++) adde(i, T, 1);
  for (i = 1; i <= m; i++) adde(S, sz + i, 1);
  sz = T;
  maxflow();
  printf("%d\n", flow);
  int cnt1 = 0, cnt2 = 0;
  for (i = 1; i <= m; i++)
    if (dis[tot + i] != -1) cnt1++;
  for (i = 1; i < n; i++)
    if (dis[i] == -1) cnt2++;
  printf("%d", cnt1);
  for (i = 1; i <= m; i++)
    if (dis[tot + i] != -1) printf(" %d", i);
  printf("\n");
  printf("%d", cnt2);
  for (i = 1; i < n; i++)
    if (dis[i] == -1) printf(" %d", i);
  printf("\n");
}
