#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline bool smin(T &a, const T &b) {
  return b < a ? a = b, 1 : 0;
}
template <typename T>
inline bool smax(T &a, const T &b) {
  return a < b ? a = b, 1 : 0;
}
const long long M = (long long)1e5 + 10, N = (long long)1e3 + 10;
long long n, m, par[N];
vector<long long> e[2];
struct edges {
  long long u, v, typ;
} edge[M];
inline void fail() {
  cout << -1 << '\n';
  exit(0);
}
long long root(long long v) {
  return par[v] = (par[v] == v ? v : root(par[v]));
}
bool merge(long long u, long long v) {
  if ((u = root(u)) == (v = root(v))) return false;
  par[u] = v;
  return true;
}
void do_find_edge(long long typ) {
  iota(par, par + N, 0);
  for (long long i = 0; i < m; ++i) {
    if (edge[i].typ == typ) {
      merge(edge[i].u, edge[i].v);
    }
  }
  for (long long i = 0; i < m; ++i) {
    if (edge[i].typ == typ) continue;
    if (merge(edge[i].u, edge[i].v)) {
      e[typ ^ 1].push_back(i);
    }
  }
}
int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m;
  if (n % 2 == 0) fail();
  long long need = (n - 1) >> 1;
  for (long long j = 0; j < m; ++j) {
    char typ;
    cin >> edge[j].u >> edge[j].v >> typ;
    edge[j].typ = (typ == 'S');
    --edge[j].u, --edge[j].v;
  }
  for (long long j = 0; j < 2; ++j) do_find_edge(j);
  for (long long j = 0; j < 2; ++j)
    if ((long long)e[j].size() > need) fail();
  iota(par, par + N, 0);
  for (long long j = 0; j < 2; ++j)
    for (long long ed : e[j]) merge(edge[ed].u, edge[ed].v);
  for (long long i = 0; i < m; ++i) {
    if (e[edge[i].typ].size() < need && merge(edge[i].v, edge[i].u)) {
      e[edge[i].typ].push_back(i);
    }
  }
  m = 0;
  for (long long j = 0; j < 2; ++j) m += (long long)e[j].size();
  if (m != n - 1) fail();
  cout << m << '\n';
  for (long long j = 0; j < 2; ++j) {
    for (long long x : e[j]) cout << ++x << ' ';
  }
}
