#include <bits/stdc++.h>
using namespace std;
template <class T>
inline void read(T &x) {
  x = 0;
  char ch;
  ch = getchar();
  while (ch > '9' || ch < '0') ch = getchar();
  while (ch <= '9' && ch >= '0') {
    x = (x << 3) + (x << 1) + ch - '0';
    ch = getchar();
  }
}
struct edge {
  int v, nxt, flow;
} e[5000005];
int ecnt, head[2500005];
void adde(int u, int v, int flow) {
  e[ecnt].v = v;
  e[ecnt].nxt = head[u];
  head[u] = ecnt;
  e[ecnt].flow = flow;
  ecnt++;
}
int s, t;
int dep[2500050];
bool bfs() {
  queue<int> que;
  memset(dep, -1, sizeof(dep));
  dep[t] = 0;
  que.push(t);
  while (!que.empty()) {
    int u = que.front();
    que.pop();
    if (u == s) return true;
    for (int i = head[u]; ~i; i = e[i].nxt) {
      int v = e[i].v;
      if (e[i ^ 1].flow && dep[v] == -1) {
        dep[v] = dep[u] + 1;
        que.push(v);
      }
    }
  }
  return false;
}
int curedge[2500050];
int dfs(int s, int t, int flow) {
  if (s == t) return flow;
  int delta = flow;
  for (int &i = curedge[s]; ~i; i = e[i].nxt) {
    int v = e[i].v;
    if (dep[v] == dep[s] - 1 && e[i].flow) {
      int g = dfs(v, t, min((int)e[i].flow, delta));
      delta -= g;
      e[i].flow -= g;
      e[i ^ 1].flow += g;
      if (!delta) return flow;
    }
  }
  return flow - delta;
}
int dinic() {
  int ans = 0;
  while (bfs()) {
    memcpy(curedge, head, sizeof(head));
    ans += dfs(s, t, 0x3f3f3f3f);
  }
  return ans;
}
int n, m, k;
int cur;
struct edge2 {
  int v, nxt;
} e2[1000050];
int ecnt2, head2[500050];
void adde2(int u, int v) {
  e2[++ecnt2].v = v;
  e2[ecnt2].nxt = head2[u];
  head2[u] = ecnt2;
}
int rnk[500500], idx[500500], fa[500050], son[500050], sz[500050], top[500050],
    pcnt;
int dy[500050];
void dfs(int pos, int lst) {
  dep[pos] = dep[lst] + 1;
  fa[pos] = lst;
  sz[pos] = 1;
  for (int i = head2[pos]; i; i = e2[i].nxt) {
    int v = e2[i].v;
    if (v != lst) {
      dy[v] = (i - 1) / 2 + 1;
      dfs(v, pos);
      sz[pos] += sz[v];
      if (sz[v] > sz[son[pos]]) son[pos] = v;
    }
  }
}
bool vis[500050];
int totc;
void dfs2(int pos, int tp) {
  top[pos] = tp;
  if (!vis[tp]) vis[tp] = 1, totc++;
  idx[pos] = ++pcnt;
  rnk[pcnt] = pos;
  if (son[pos]) dfs2(son[pos], tp);
  for (int i = head2[pos]; i; i = e2[i].nxt) {
    int v = e2[i].v;
    if (v != fa[pos] && v != son[pos]) dfs2(v, v);
  }
}
struct Segment_Tree {
  int base;
  void Build(int rt, int l, int r) {
    if (l == r) {
      adde(rt + base, rnk[l] + m, 0x3f3f3f3f), adde(rnk[l] + m, rt + base, 0);
      return;
    }
    int mid = (l + r) >> 1;
    Build(rt << 1, l, mid);
    Build(rt << 1 | 1, mid + 1, r);
    adde(rt + base, (rt << 1) + base, 0x3f3f3f3f);
    adde((rt << 1) + base, rt + base, 0);
    adde(rt + base, (rt << 1 | 1) + base, 0x3f3f3f3f);
    adde((rt << 1 | 1) + base, rt + base, 0);
  }
  void Update(int ori, int rt, int l, int r, int ll, int rr) {
    if (ll <= l && r <= rr) {
      adde(ori, rt + base, 0x3f3f3f3f), adde(rt + base, ori, 0);
      return;
    }
    int mid = (l + r) >> 1;
    if (mid >= ll) Update(ori, rt << 1, l, mid, ll, rr);
    if (mid < rr) Update(ori, rt << 1 | 1, mid + 1, r, ll, rr);
  }
} tree;
bool fucked[2500500];
void dfs(int pos) {
  if (fucked[pos]) return;
  fucked[pos] = 1;
  for (int i = head[pos]; ~i; i = e[i].nxt) {
    int v = e[i].v;
    if (e[i].flow) dfs(v);
  }
}
void suck(int ori, int u, int v) {
  while (top[u] != top[v]) {
    if (dep[top[u]] < dep[top[v]]) swap(u, v);
    tree.Update(ori, 1, 1, n, idx[top[u]], idx[u]);
    u = fa[top[u]];
  }
  if (u == v) return;
  tree.Update(ori, 1, 1, n, min(idx[u], idx[v]) + 1, max(idx[u], idx[v]));
}
int main() {
  memset(head, -1, sizeof(head));
  scanf("%d%d", &n, &m);
  s = 0;
  t = 2500000;
  for (int i = 1; i <= m; ++i) adde(s, i, 1), adde(i, s, 0);
  for (int i = 1; i <= n; ++i) adde(i + m, t, 1), adde(t, i + m, 0);
  for (int i = 1; i < n; ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    adde2(u, v), adde2(v, u);
  }
  dfs(1, 1);
  dfs2(1, 1);
  tree.base = n + m;
  tree.Build(1, 1, n);
  for (int i = 1; i <= m; ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    suck(i, u, v);
  }
  printf("%d\n", dinic());
  dfs(s);
  int cnt = 0;
  for (int i = 1; i <= m; ++i)
    if (!fucked[i]) cnt++;
  printf("%d ", cnt);
  for (int i = 1; i <= m; ++i)
    if (!fucked[i]) printf("%d ", i);
  printf("\n");
  cnt = 0;
  for (int i = 1; i <= n; ++i)
    if (fucked[m + i]) cnt++;
  printf("%d ", cnt);
  for (int i = 1; i <= n; ++i)
    if (fucked[m + i]) printf("%d ", dy[i]);
  printf("\n");
  return 0;
}
