#include <bits/stdc++.h>
using namespace std;
vector<int>::iterator it;
int n, m, f[20010][15], id[20010][15], num, fc[15];
int edge_id[20010];
namespace IO {
int read() {
  int ret = 0;
  char c = getchar();
  while (!isdigit(c)) c = getchar();
  while (isdigit(c)) ret = ret * 10 + (c ^ 48), c = getchar();
  return ret;
}
void write(int x) {
  if (x > 9) write(x / 10);
  putchar(x % 10 ^ 48);
}
void writeln(int x) {
  write(x);
  putchar('\n');
}
void writesp(int x) {
  write(x);
  putchar(' ');
}
}  // namespace IO
using namespace IO;
namespace Flow {
int tot, S, T, head[320010], cur[320010], dis[320010], vis[320010];
vector<int> ans1, ans2;
queue<int> q;
struct Tway {
  int v, w, nex;
} e[1260010];
void addedge(int u, int v, int w) {
  e[++tot] = (Tway){v, w, head[u]};
  head[u] = tot;
  e[++tot] = (Tway){u, 0, head[v]};
  head[v] = tot;
}
bool bfs() {
  memset(dis, -1, sizeof(dis));
  memcpy(cur, head, sizeof(head));
  while (!q.empty()) q.pop();
  q.push(S);
  dis[S] = 0;
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    for (int i = head[x]; i; i = e[i].nex) {
      int v = e[i].v;
      if (!e[i].w || ~dis[v]) continue;
      dis[v] = dis[x] + 1;
      q.push(v);
    }
  }
  return ~dis[T];
}
int dfs(int x, int flow) {
  int used = 0, u;
  if (x == T || !flow) return flow;
  for (int &i = cur[x]; i; i = e[i].nex) {
    int v = e[i].v;
    if (dis[v] != dis[x] + 1 || !(u = dfs(v, min(flow - used, e[i].w))))
      continue;
    used += u;
    e[i].w -= u;
    e[i ^ 1].w += u;
    if (used == flow) break;
  }
  return used;
}
void dfsans(int x) {
  vis[x] = 1;
  for (int i = head[x]; i; i = e[i].nex) {
    if (!vis[e[i].v] && e[i].w) dfsans(e[i].v);
  }
}
void getans() {
  int res = 0;
  while (bfs()) res += dfs(S, 0x3f3f3f3f);
  dfsans(S);
  writeln(res);
  for (int i = 1; i <= m; ++i)
    if (!vis[i]) ans1.push_back(i);
  for (int i = 2; i <= n; ++i)
    if (vis[id[i][0]]) ans2.push_back(edge_id[i]);
  printf("%d ", (int)ans1.size());
  for (int i = 0; i < (int)ans1.size(); ++i) printf("%d ", ans1[i]);
  puts("");
  printf("%d ", (int)ans2.size());
  for (int i = 0; i < (int)ans2.size(); ++i) printf("%d ", ans2[i]);
  puts("");
}
}  // namespace Flow
namespace Tree {
int tot, head[20015], dep[20015], fa[20015][15];
struct Tway {
  int id, v, nex;
} e[20015 * 2];
void addedge(int i, int u, int v) {
  e[++tot] = (Tway){i, v, head[u]};
  head[u] = tot;
  e[++tot] = (Tway){i, u, head[v]};
  head[v] = tot;
}
void dfs(int x) {
  id[x][0] = ++num;
  for (int i = 1; fc[i] <= dep[x]; ++i) {
    fa[x][i] = fa[fa[x][i - 1]][i - 1];
    id[x][i] = ++num;
    Flow::addedge(id[x][i], id[x][i - 1], 0x3f3f3f3f);
    Flow::addedge(id[x][i], id[fa[x][i - 1]][i - 1], 0x3f3f3f3f);
  }
  for (int i = head[x]; i; i = e[i].nex) {
    int v = e[i].v;
    if (v == fa[x][0]) continue;
    dep[v] = dep[x] + 1;
    fa[v][0] = x;
    edge_id[v] = e[i].id;
    dfs(v);
  }
}
int lca(int x, int y) {
  if (dep[x] < dep[y]) swap(x, y);
  for (int t = dep[x] - dep[y], i = 0; i < 15; ++i)
    if (fc[i] & t) x = fa[i][x];
  for (int i = 14; ~i; --i)
    if (fa[x][i] ^ fa[y][i]) x = fa[x][i], y = fa[y][i];
  return x == y ? x : fa[x][0];
}
void tagedge(int f, int x, int y) {
  int t = dep[x] - dep[y];
  for (int i = 14; ~i; --i)
    if (t & fc[i]) Flow::addedge(f, id[x][i], 0x3f3f3f3f), x = fa[x][i];
}
void tag(int i, int x, int y) {
  if (dep[x] < dep[y]) swap(x, y);
  for (int j = 14, t = dep[x] - dep[y]; j >= 0; --j) {
    if (t & fc[j]) {
      Flow::addedge(i, id[x][j], 0x3f3f3f3f);
      x = fa[x][j];
    }
  }
  if (x != y) {
    for (int j = 14; j >= 0; --j) {
      if (fa[x][j] != fa[y][j]) {
        Flow::addedge(i, id[x][j], 0x3f3f3f3f);
        Flow::addedge(i, id[y][j], 0x3f3f3f3f);
        x = fa[x][j];
        y = fa[y][j];
      }
    }
    Flow::addedge(i, id[x][0], 0x3f3f3f3f);
    Flow::addedge(i, id[y][0], 0x3f3f3f3f);
  }
}
}  // namespace Tree
namespace DreamLolita {
void solution() {
  fc[0] = 1;
  for (int i = 1; i < 15; ++i) fc[i] = fc[i - 1] << 1;
  n = read();
  m = read();
  num = m;
  for (int i = 1; i < n; ++i) Tree::addedge(i, read(), read());
  Flow::S = 0;
  Flow::tot = 1;
  for (int i = 1; i <= m; ++i) Flow::addedge(Flow::S, i, 1);
  Tree::dfs(1);
  Flow::T = num + 1;
  for (int i = 2; i <= n; ++i) Flow::addedge(id[i][0], Flow::T, 1);
  for (int i = 1; i <= m; ++i) {
    int x = read(), y = read();
    Tree::tag(i, x, y);
  }
  Flow::getans();
}
}  // namespace DreamLolita
int main() {
  DreamLolita::solution();
  return 0;
}
