#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5e5 + 5;
const long long INF = 0x3f3f3f3f;
int id[MAXN / 10][25];
int fa[MAXN / 10][25];
vector<int> adj[MAXN];
vector<int> G[MAXN];
int last[MAXN];
int dep[MAXN];
int lg[MAXN];
map<pair<int, int>, int> sav;
struct Edge {
  int from, to;
  long long flow;
  Edge(int _from = 0, int _to = 0, long long _flow = 0)
      : from(_from), to(_to), flow(_flow) {}
} Edges[MAXN * 10];
int cnt, tot, n, m;
int s, t, gap[MAXN], cur[MAXN], d[MAXN];
void addEdge(int from, int to, long long flow) {
  Edges[cnt] = Edge(from, to, flow);
  G[from].push_back(cnt);
  cnt++;
  Edges[cnt] = Edge(to, from, 0);
  G[to].push_back(cnt);
  cnt++;
}
void dfs(int u, int f) {
  dep[u] = dep[f] + 1;
  fa[u][0] = f;
  if (f) id[u][0] = sav[make_pair(u, f)];
  for (int i = 1; i <= lg[dep[u]]; i++) {
    fa[u][i] = fa[fa[u][i - 1]][i - 1];
    id[u][i] = ++tot;
    addEdge(id[u][i], id[u][i - 1], INF);
    addEdge(id[u][i], id[fa[u][i - 1]][i - 1], INF);
  }
  for (int v : adj[u])
    if (f != v) {
      dfs(v, u);
    }
}
int addLca(int u, int x, int y) {
  if (dep[x] < dep[y]) swap(x, y);
  for (int i = lg[dep[x]]; i >= 0; i--) {
    if (dep[fa[x][i]] >= dep[y]) {
      addEdge(u, id[x][i], INF);
      x = fa[x][i];
    }
  }
  if (x == y) return x;
  for (int i = lg[dep[y]]; i >= 0; i--) {
    if (fa[x][i] != fa[y][i]) {
      addEdge(u, id[x][i], INF);
      addEdge(u, id[y][i], INF);
      x = fa[x][i];
      y = fa[y][i];
    }
  }
  addEdge(u, id[x][0], INF);
  addEdge(u, id[y][0], INF);
  return fa[x][0];
}
long long aug(int u, long long flow) {
  if (u == t) return flow;
  long long use = 0;
  for (int &i = cur[u]; i < G[u].size(); i++) {
    Edge &e = Edges[G[u][i]];
    if (e.flow > 0 && d[e.to] + 1 == d[u]) {
      long long tmp = aug(e.to, min(flow - use, e.flow));
      e.flow -= tmp, Edges[G[u][i] ^ 1].flow += tmp, use += tmp;
      if (use == flow || d[s] == t + 1) return use;
    }
  }
  if (!(--gap[d[u]])) d[s] = t + 1;
  ++gap[++d[u]];
  cur[u] = 0;
  return use;
}
int avai[MAXN];
void find(int x) {
  avai[x] = 1;
  for (int i = 0; i < G[x].size(); i++) {
    Edge &e = Edges[G[x][i]];
    if (!avai[e.to] && e.flow > 0) find(e.to);
  }
}
vector<int> p, g;
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 2; i <= n; i++) lg[i] = lg[i >> 1] + 1;
  for (int i = 1; i < n; i++) {
    int f, t;
    scanf("%d%d", &f, &t);
    adj[f].push_back(t);
    adj[t].push_back(f);
    sav[make_pair(f, t)] = sav[make_pair(t, f)] = i;
  }
  tot = n;
  dep[0] = -1;
  dfs(1, 0);
  for (int i = 1; i <= m; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    addEdge(s, i + tot, 1);
    addLca(i + tot, x, y);
  }
  t = tot + m + 1;
  for (int i = 1; i <= n; i++) {
    addEdge(i, t, 1);
  }
  gap[0] = t + 1;
  long long ans = 0;
  for (; d[s] < t + 1; ans += aug(s, INF))
    ;
  printf("%lld\n", ans);
  find(s);
  for (int i = 0; i < G[s].size(); i++) {
    Edge &e = Edges[G[s][i]];
    if (!avai[e.to]) p.push_back(e.to - tot);
  }
  printf("%d", p.size());
  for (int i : p) printf(" %d", i);
  for (int i = 0; i < G[t].size(); i++) {
    Edge &e = Edges[G[t][i]];
    if (avai[e.to]) g.push_back(e.to);
  }
  printf("\n%d", g.size());
  for (int i : g) printf(" %d", i);
  return 0;
}
