#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:500000000")
using namespace std;
struct Edge {
  int a, b;
  char c;
};
vector<int> g[200009], rg[200009];
bool used[200009];
vector<int> order, comp;
void top_sort(int v) {
  used[v] = true;
  for (auto to : g[v]) {
    if (!used[to]) top_sort(to);
  }
  order.push_back(v);
}
void dfs(int v, int c) {
  comp[v] = c;
  for (auto to : rg[v]) {
    if (comp[to] == -1) dfs(to, c);
  }
}
int sz;
void add_edge(int a, int sa, int b, int sb) {
  int s = a + sz * sa;
  int t = b + sz * sb;
  g[s].push_back(t);
  rg[t].push_back(s);
}
void add_or(int a, int sa, int b, int sb) {
  add_edge(a, 1 - sa, b, sb);
  add_edge(b, 1 - sb, a, sa);
}
void solve1(vector<Edge> E, vector<vector<int> > &res) {
  int i, j;
  int n = 2 * sz;
  for (i = 0; i < n; i++) {
    g[i].clear();
    rg[i].clear();
  }
  order.clear();
  for (auto e : E) {
    if (e.c == 'B') {
      add_or(e.a, 0, e.b, 1);
      add_or(e.a, 1, e.b, 0);
    } else {
      add_or(e.a, 0, e.b, 0);
      add_or(e.a, 1, e.b, 1);
    }
  }
  memset(used, 0, n * sizeof(used[0]));
  for (i = 0; i < n; i++)
    if (!used[i]) top_sort(i);
  comp = vector<int>(n, -1);
  for (i = 0, j = 0; i < n; i++) {
    auto v = order[n - i - 1];
    if (comp[v] == -1) dfs(v, j++);
  }
  for (i = 0; i < sz; i++) {
    if (comp[i] == comp[i + sz]) return;
  }
  res.push_back({});
  for (i = 0; i < sz; i++)
    if (comp[i] > comp[i + sz]) res.back().push_back(i);
  res.push_back({});
  for (i = 0; i < sz; i++)
    if (comp[i] < comp[i + sz]) res.back().push_back(i);
}
vector<int> gg[200009];
void dfs2(int v) {
  comp.push_back(v);
  used[v] = 1;
  for (auto to : gg[v])
    if (!used[to]) dfs2(to);
}
bool solve(int n, vector<Edge> E, vector<int> &res) {
  ::sz = n;
  vector<vector<int> > cands;
  solve1(E, cands);
  if (cands.empty()) return false;
  for (int j = 1; j < (int)cands.size(); j++)
    if (cands[j].size() < cands[0].size()) swap(cands[0], cands[j]);
  res = cands[0];
  return true;
}
int main() {
  int n, m;
  char c[3];
  scanf("%d %d", &n, &m);
  vector<Edge> E(m);
  for (auto &e : E) {
    scanf("%d %d %s", &e.a, &e.b, c);
    e.a--;
    e.b--;
    e.c = c[0];
    gg[e.a].push_back(e.b);
    gg[e.b].push_back(e.a);
  }
  vector<int> vc(n);
  int csz = 0;
  for (int i = 0; i < n; i++) {
    if (!used[i]) {
      comp.clear();
      dfs2(i);
      for (auto w : comp) vc[w] = csz;
      csz++;
    }
  }
  vector<vector<Edge> > ee(csz);
  for (auto e : E) ee[vc[e.a]].push_back(e);
  vector<int> gres;
  bool has = false;
  for (int round = 0; round < 2; round++) {
    vector<int> res;
    bool ok = true;
    for (auto comp : ee) {
      if (round)
        for (auto &e : comp) e.c ^= 'R' ^ 'B';
      map<int, int> NX;
      for (auto &e : comp) NX[e.a] = NX[e.b] = 0;
      vector<int> RX;
      int cnt = 0;
      for (auto &p : NX) {
        RX.push_back(p.first);
        p.second = cnt++;
      }
      for (auto &e : comp) e.a = NX[e.a], e.b = NX[e.b];
      vector<int> r;
      if (!solve(cnt, comp, r)) {
        ok = false;
        break;
      }
      for (auto &rr : r) res.push_back(RX[rr]);
    }
    if (!ok) continue;
    if (!has || gres.size() > res.size()) gres = res;
    has = true;
  }
  if (!has) {
    puts("-1");
    return 0;
  }
  printf("%d\n", gres.size());
  for (auto q : gres) printf("%d ", q + 1);
  puts("");
  return 0;
}
