#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);
const int mod = 998244353;
void reduce(int &a) { a += a >> 31 & mod; }
int Mod(int x) { return x >= mod ? x - mod : x; }
int read() {
  int x = 0;
  int f = 1;
  char ch = getchar();
  for (; !isdigit(ch); ch = getchar())
    if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) x = x * 10 + (ch ^ 48);
  return x * f;
}
void print(long long x) {
  if (x < 0) putchar('-'), x = -x;
  if (x > 9) print(x / 10);
  putchar(x % 10 + '0');
}
const int N = 20010, M = N;
struct Net_Flow {
  static const int N = 1000010, M = 1000010;
  int S, T;
  ;
  struct edge {
    int nxt, to, w;
  } e[M << 1];
  int head[N], ecnt = 1;
  void add(int u, int v, long long w = 0) {
    e[++ecnt].w = w, e[ecnt].to = v, e[ecnt].nxt = head[u];
    head[u] = ecnt;
  }
  void add_edge(int u, int v, long long w = 0) {
    add(u, v, w), add(v, u, w * 0);
  };
  int cur[N], dis[N];
  queue<int> q;
  bool BFS() {
    memset(dis, -1, sizeof(dis));
    q.push(S), dis[S] = 0;
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      for (int i = cur[u] = head[u], v; i; i = e[i].nxt)
        if (e[i].w && !~dis[v = e[i].to]) q.push(v), dis[v] = dis[u] + 1;
    }
    return ~dis[T];
  }
  int DFS(int u, int exp) {
    if (u == T) return exp;
    int f, flow = 0;
    for (int &i = cur[u], v; i && exp; i = e[i].nxt)
      if (e[i].w && dis[v = e[i].to] == dis[u] + 1)
        f = DFS(v, min(exp, e[i].w)), flow += f, exp -= f, e[i].w -= f,
        e[i ^ 1].w += f;
    return flow;
  }
  int Dinic() {
    int flow = 0;
    while (BFS()) flow += DFS(S, 1061109567);
    return flow;
  }
  bool vis[N];
  void dfs(int u) {
    vis[u] = 1;
    for (int i = head[u], v; i; i = e[i].nxt)
      if (e[i].w && !vis[v = e[i].to]) dfs(v);
  }
} G;
int n, m, cnt, x[N], y[N];
;
struct edge {
  int nxt, to, w;
} e[M << 1];
int head[N], ecnt = 1;
void add(int u, int v, long long w = 0) {
  e[++ecnt].w = w, e[ecnt].to = v, e[ecnt].nxt = head[u];
  head[u] = ecnt;
}
void add_edge(int u, int v, long long w = 0) {
  add(u, v, w), add(v, u, w * 1);
};
int lg[N], f[N][20], fe[N], dep[N], id[N][20];
void dfs(int u) {
  dep[u] = dep[f[u][0]] + 1;
  if (f[u][0]) id[u][0] = ++cnt;
  for (int i = head[u], v; i; i = e[i].nxt)
    if ((v = e[i].to) != f[u][0]) f[v][0] = u, fe[v] = i >> 1, dfs(v);
}
void init() {
  dfs(1);
  lg[0] = -1;
  for (int i = 1; i <= n; i++) lg[i] = lg[i >> 1] + 1;
  for (int j = 1; j <= lg[n]; j++)
    for (int i = 1; i <= n; i++) {
      f[i][j] = f[f[i][j - 1]][j - 1];
      if (!f[i][j]) continue;
      id[i][j] = ++cnt;
      G.add_edge(id[i][j], id[i][j - 1], 1061109567),
          G.add_edge(id[i][j], id[f[i][j - 1]][j - 1], 1061109567);
    }
}
void jump(int &u, int d) {
  for (int i = 0; i <= lg[d]; i++)
    if ((1 << i) & d) u = f[u][i];
}
int lca(int u, int v) {
  if (dep[u] < dep[v]) swap(u, v);
  jump(u, dep[u] - dep[v]);
  if (u == v) return u;
  for (int i = lg[n]; ~i; i--)
    if (f[u][i] != f[v][i]) u = f[u][i], v = f[v][i];
  return f[u][0];
}
void cover(int x, int top, int p) {
  int y = x, d = dep[x] - dep[top];
  if (!d) return;
  int k = lg[d];
  jump(y, d - (1 << k));
  G.add_edge(p, id[x][k], 1061109567);
  if (id[x][k] != id[y][k]) G.add_edge(p, id[y][k], 1061109567);
}
int main() {
  n = read(), m = read();
  for (int i = 1; i < n; i++) add_edge(read(), read());
  cnt = m, init();
  G.S = 0, G.T = ++cnt;
  for (int i = 2; i <= n; i++) G.add_edge(id[i][0], G.T, 1);
  for (int i = 1; i <= m; i++) {
    x[i] = read(), y[i] = read();
    int z = lca(x[i], y[i]);
    cover(x[i], z, i), cover(y[i], z, i);
    G.add_edge(G.S, i, 1);
  }
  print(G.Dinic()), putchar('\n');
  G.dfs(0);
  vector<int> v1, v2;
  for (int i = 1; i <= m; i++)
    if (!G.vis[i]) v1.push_back(i);
  for (int i = 2; i <= n; i++)
    if (G.vis[id[i][0]]) v2.push_back(fe[i]);
  print(v1.size()), putchar(' ');
  for (int i : v1) print(i), putchar(' ');
  putchar('\n');
  print(v2.size()), putchar(' ');
  for (int i : v2) print(i), putchar(' ');
  putchar('\n');
  return 0;
}
