#include <bits/stdc++.h>
using namespace std;
char buf[(1 << 21) + 5], *p1 = buf, *p2 = buf;
inline int qread() {
  char c =
      (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2)
           ? EOF
           : *p1++);
  int x = 0, f = 1;
  while (c < '0' || c > '9') {
    if (c == '-') f = -1;
    c = (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2)
             ? EOF
             : *p1++);
  }
  while (c >= '0' && c <= '9') {
    x = x * 10 + c - '0';
    c = (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2)
             ? EOF
             : *p1++);
  }
  return x * f;
}
struct Edge {
  int to, nxt, cap;
  Edge() { nxt = -1; }
};
Edge e[10000005];
int n, hd[120005], pnt, m, x[20005], y[20005], siz[20005], son[20005],
    dfn[20005], _time, top[20005], fa[20005], fe[20005], seq[20005];
int dep[20005];
namespace Dinic {
int lv[120005], iter[120005];
inline void Bfs(int s) {
  queue<int> que;
  memset(lv, -1, sizeof(lv));
  lv[s] = 0;
  que.push(s);
  while (!que.empty()) {
    int u = que.front();
    que.pop();
    for (int i = hd[u]; ~i; i = e[i].nxt) {
      if (e[i].cap && !~lv[e[i].to]) {
        lv[e[i].to] = lv[u] + 1;
        que.push(e[i].to);
      }
    }
  }
}
inline int Dfs(int u, int t, int f) {
  if (u == t) return f;
  int flw = 0;
  for (int &i = iter[u]; ~i; i = e[i].nxt) {
    if (e[i].cap && lv[e[i].to] == lv[u] + 1) {
      int d = Dfs(e[i].to, t, min(f - flw, e[i].cap));
      if (d) {
        flw += d;
        e[i].cap -= d;
        e[i ^ 1].cap += d;
      } else
        lv[e[i].to] = -1;
      if (flw == f) break;
    }
  }
  return flw;
}
inline int Flow(int s, int t) {
  int ans = 0;
  for (;;) {
    Bfs(s);
    if (!~lv[t]) break;
    memcpy(iter, hd, sizeof(iter));
    ans += Dfs(s, t, 0x3f3f3f3f);
  }
  return ans;
}
}  // namespace Dinic
inline void AddEdge(int u, int v, int w) {
  e[pnt].to = v;
  e[pnt].cap = w;
  e[pnt].nxt = hd[u];
  hd[u] = pnt;
  pnt++;
  e[pnt].to = u;
  e[pnt].cap = 0;
  e[pnt].nxt = hd[v];
  hd[v] = pnt;
  pnt++;
}
vector<pair<int, int> > g[20005];
inline void Read() {
  n = qread();
  m = qread();
  for (int i = 1; i < n; i++) {
    int u = qread(), v = qread();
    g[u].push_back(make_pair(v, i));
    g[v].push_back(make_pair(u, i));
    AddEdge(m + i, m + 5 * n + 1, 1);
  }
  for (int i = 1; i <= m; i++) {
    x[i] = qread();
    y[i] = qread();
    AddEdge(0, i, 1);
  }
}
inline void Dfs1(int u) {
  if (fe[u]) AddEdge(m + u + n, m + fe[u], 0x3f3f3f3f);
  int gsiz = g[u].size();
  siz[u] = 1;
  for (int i = 0; i < gsiz; i++) {
    int v = g[u][i].first;
    if (v != fa[u]) {
      fa[v] = u;
      fe[v] = g[u][i].second;
      dep[v] = dep[u] + 1;
      Dfs1(v);
      siz[u] += siz[v];
      if (siz[v] > siz[son[u]]) son[u] = v;
    }
  }
}
inline void Dfs2(int u, int tp) {
  AddEdge(m + u + 2 * n, m + u + n, 0x3f3f3f3f);
  dfn[u] = ++_time;
  top[u] = tp;
  seq[_time] = u;
  if (son[u]) {
    AddEdge(m + son[u] + 2 * n, m + u + 2 * n, 0x3f3f3f3f);
    Dfs2(son[u], tp);
  }
  int siz = g[u].size();
  for (int i = 0; i < siz; i++) {
    int v = g[u][i].first;
    if (v != fa[u] && v != son[u]) Dfs2(v, v);
  }
}
inline int buildSeg(int p, int l, int r) {
  if (l == r) return m + seq[l] + n;
  int mid = l + r >> 1;
  AddEdge(m + 3 * n + p, buildSeg(p << 1, l, mid), 0x3f3f3f3f);
  AddEdge(m + 3 * n + p, buildSeg(p << 1 | 1, mid + 1, r), 0x3f3f3f3f);
  return m + 3 * n + p;
}
inline void AddSeg(int p, int pl, int pr, int l, int r, int u) {
  if (pl == l && pr == r) {
    if (l == r)
      AddEdge(u, m + n + seq[l], 0x3f3f3f3f);
    else
      AddEdge(u, m + 3 * n + p, 0x3f3f3f3f);
    return;
  }
  int mid = pl + pr >> 1;
  if (mid >= r)
    AddSeg(p << 1, pl, mid, l, r, u);
  else if (mid + 1 <= l)
    AddSeg(p << 1 | 1, mid + 1, pr, l, r, u);
  else {
    AddSeg(p << 1, pl, mid, l, mid, u);
    AddSeg(p << 1 | 1, mid + 1, pr, mid + 1, r, u);
  }
}
inline void AddRoute(int u, int v, int st) {
  while (top[u] != top[v]) {
    if (dep[top[u]] < dep[top[v]]) swap(u, v);
    AddEdge(st, m + 2 * n + u, 0x3f3f3f3f);
    u = fa[top[u]];
  }
  if (dfn[u] > dfn[v]) swap(u, v);
  if (u != v) AddSeg(1, 1, n, dfn[u] + 1, dfn[v], st);
}
inline void Solve() {
  for (int i = 1; i <= m; i++) AddRoute(x[i], y[i], i);
  printf("%d\n", Dinic::Flow(0, m + 5 * n + 1));
  vector<int> ans;
  for (int i = hd[0]; ~i; i = e[i].nxt) {
    if (Dinic::lv[e[i].to] < 0) ans.push_back(e[i].to);
  }
  printf("%d", ans.size());
  for (int i = 0; i < ans.size(); i++) printf(" %d", ans[i]);
  puts("");
  ans.clear();
  for (int i = hd[m + 5 * n + 1]; ~i; i = e[i].nxt) {
    if (Dinic::lv[e[i].to] > 0) ans.push_back(e[i].to - m);
  }
  printf("%d", ans.size());
  for (int i = 0; i < ans.size(); i++) printf(" %d", ans[i]);
  puts("");
}
int main() {
  memset(hd, -1, sizeof(hd));
  Read();
  dep[1] = 1;
  Dfs1(1);
  Dfs2(1, 1);
  buildSeg(1, 1, n);
  Solve();
  return 0;
}
