#include <bits/stdc++.h>
template <typename T>
inline void read(T &x) {
  x = 0;
  char c = getchar();
  while (!isdigit(c)) c = getchar();
  while (isdigit(c)) x = x * 10 + (c ^ 48), c = getchar();
}
using namespace std;
const int inf = 987654321;
int n, m, s, t;
int dedfn[40100];
namespace Flow {
struct edge {
  int nxt, to, val;
} e[5001000];
int head[151000], hcur[151000], ecnt = 1;
inline void addedge(int from, int to, int val) {
  e[++ecnt] = (edge){head[from], to, val};
  head[from] = ecnt;
}
inline void Addedge(int u, int v, int w) {
  if (!u || !v) return;
  addedge(u, v, w), addedge(v, u, 0);
}
int dep[151000], que[151000], front, rear;
inline bool bfs() {
  memset(dep, 0x3f, sizeof(dep));
  front = rear = 0;
  for (int i = 1; i <= t; ++i) hcur[i] = head[i];
  dep[s] = 0;
  que[++rear] = s;
  while (front < rear) {
    int cur = que[++front];
    for (int i = head[cur]; i; i = e[i].nxt) {
      int to = e[i].to;
      if (!e[i].val || dep[to] <= inf) continue;
      dep[to] = dep[cur] + 1;
      que[++rear] = to;
    }
  }
  return dep[t] <= inf;
}
int dfs(int cur, int limi) {
  if (cur == t || !limi) return limi;
  int flow = 0;
  for (int i = hcur[cur]; i; i = e[i].nxt) {
    int to = e[i].to;
    hcur[cur] = i;
    if (dep[to] != dep[cur] + 1) continue;
    int tmp = dfs(to, min(e[i].val, limi));
    if (!tmp) continue;
    e[i].val -= tmp;
    e[i ^ 1].val += tmp;
    limi -= tmp;
    flow += tmp;
    if (!limi) break;
  }
  return flow;
}
bool vis[151000];
void dfs_find(int cur) {
  vis[cur] = true;
  for (int i = head[cur]; i; i = e[i].nxt)
    if (e[i].val) {
      int to = e[i].to;
      if (vis[to]) continue;
      dfs_find(to);
    }
}
int jzp[40100], jtot, zzz[40100], ztot;
inline void Run_flow() {
  int res = 0;
  while (bfs()) res += dfs(s, inf);
  dfs_find(s);
  for (int i = 1; i <= m; ++i)
    if (!vis[i]) jzp[++jtot] = i;
  for (int i = 1; i < n; ++i)
    if (vis[i + m]) zzz[++ztot] = i;
  printf("%d\n", res);
  printf("%d ", jtot);
  for (int i = 1; i <= jtot; ++i) printf("%d ", jzp[i]);
  puts("");
  printf("%d ", ztot);
  for (int i = 1; i <= ztot; ++i) printf("%d ", zzz[i]);
  puts("");
}
}  // namespace Flow
struct edge {
  int nxt, to, id;
} e[40100 << 1];
int head[40100], ecnt;
inline void addedge(int from, int to, int id) {
  e[++ecnt] = (edge){head[from], to, id};
  head[from] = ecnt;
}
int siz[40100], dep[40100], fa[40100], son[40100], ine[40100];
void dfs_son(int cur, int faa) {
  fa[cur] = faa;
  dep[cur] = dep[faa] + 1;
  siz[cur] = 1;
  int mx = 0;
  for (int i = head[cur]; i; i = e[i].nxt) {
    int to = e[i].to;
    if (to == faa) continue;
    ine[to] = e[i].id;
    dfs_son(to, cur);
    siz[cur] += siz[to];
    if (siz[to] > mx) mx = siz[to], son[cur] = to;
  }
}
int top[40100], dfn[40100], dcnt;
void dfs_chain(int cur, int topp) {
  dfn[cur] = ++dcnt;
  dedfn[dcnt] = ine[cur];
  top[cur] = topp;
  if (!son[cur]) return;
  dfs_chain(son[cur], topp);
  for (int i = head[cur]; i; i = e[i].nxt) {
    int to = e[i].to;
    if (to == fa[cur] || to == son[cur]) continue;
    dfs_chain(to, to);
  }
}
int ls[151000], rs[151000], ttot, root;
void build(int L, int R, int &cur) {
  cur = ++ttot;
  if (L == R) {
    if (L > 1) Flow::Addedge(cur + m + n, m + dedfn[L], inf);
    return;
  }
  int mid = (L + R) >> 1;
  build(L, mid, ls[cur]);
  build(mid + 1, R, rs[cur]);
  Flow::Addedge(cur + m + n, ls[cur] + m + n, inf);
  Flow::Addedge(cur + m + n, rs[cur] + m + n, inf);
}
void Aded(int L, int R, int l, int r, int yuan, int cur) {
  if (l <= L && R <= r) return Flow::Addedge(yuan, cur + m + n, inf), void();
  int mid = (L + R) >> 1;
  if (l <= mid) Aded(L, mid, l, r, yuan, ls[cur]);
  if (r > mid) Aded(mid + 1, R, l, r, yuan, rs[cur]);
}
inline void Aded(int l, int r, int yuan) { Aded(1, n, l, r, yuan, root); }
int main() {
  read(n), read(m);
  for (int i = 1; i < n; ++i) {
    int u, v;
    read(u), read(v);
    addedge(u, v, i), addedge(v, u, i);
  }
  dfs_son(1, 0);
  dfs_chain(1, 1);
  build(1, n, root);
  s = n + m + ttot + 1, t = s + 1;
  for (int i = 1; i <= m; ++i) {
    int x, y;
    read(x), read(y);
    while (top[x] != top[y]) {
      if (dep[top[x]] < dep[top[y]]) swap(x, y);
      Aded(dfn[top[x]], dfn[x], i);
      x = fa[top[x]];
    }
    if (x == y) continue;
    if (dep[x] > dep[y]) swap(x, y);
    Aded(dfn[x] + 1, dfn[y], i);
  }
  for (int i = 1; i <= m; ++i) Flow::Addedge(s, i, 1);
  for (int i = m + 1; i < m + n; ++i) Flow::Addedge(i, t, 1);
  Flow::Run_flow();
  return 0;
}
