#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <set>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

typedef vector<int> Edges;
typedef vector<Edges> Graph;

struct Node {
  int state;
  int from;
  int cost;
  Node(int state, int from, int cost) :
    state(state), from(from), cost(cost) {;}
  bool operator<(const Node &rhs) const {
    return cost > rhs.cost;
  }
};

int natume;
int lennon;
int n, m;
Graph mainG;
Graph nekoG;
bool end[100010];
int dist[100010];
bool visit[2][100010];

int main() {
  int test;
  scanf("%d", &test);
  while (test--) {
    MEMSET(dist, 0x0f);
    MEMSET(end, false);
    scanf("%d %d", &n, &m);
    scanf("%d %d", &natume, &lennon);
    mainG = Graph(n + 1);
    nekoG = Graph(n + 1);
    REP(i, m) {
      int f, t;
      char c;
      scanf("%d %d %c", &f, &t, &c);
      if (c == 'N') {
        mainG[f].push_back(t);
        mainG[t].push_back(f);
      } else {
        nekoG[f].push_back(t);
        nekoG[t].push_back(f);
      }
    }

    // clac end
    {
      queue<int> que;
      que.push(lennon);
      end[lennon] = true;
      while (!que.empty()) {
        int from = que.front();
        que.pop();
        FORIT(it, nekoG[from]) {
          int to = *it;
          if (end[to]) { continue; }
          end[to] = true;
          que.push(to);
        }
      }
    }
    if (end[0]) {
      puts("0");
      continue;
    }

    // calc dist
    {
      queue<pair<int, int> > que;
      que.push(make_pair(natume, 0));
      MEMSET(visit, false);
      while (!que.empty()) {
        int from = que.front().first;
        int cost = que.front().second;
        que.pop();
        if (visit[0][from]) { continue; }
        visit[0][from] = true;
        dist[from] = cost;
        FORIT(it, mainG[from]) {
          int to = *it;
          if (visit[0][to]) { continue; }
          que.push(make_pair(to, cost + 1));
        }
      }
    }


    priority_queue<Node> pque;
    // push pque
    {
      queue<int> que;
      que.push(0);
      MEMSET(visit, false);
      visit[0][0] = true;
      while (!que.empty()) {
        int from = que.front();
        que.pop();
        pque.push(Node(0, from, 0));
        FORIT(it, nekoG[from]) {
          int to = *it;
          if (visit[0][to]) { continue; }
          visit[0][to] = true;
          que.push(to);
        }
      }
    }

    // calc ans
    MEMSET(visit, false);
    while (!pque.empty()) {
      int state = pque.top().state;
      int from = pque.top().from;
      int cost = pque.top().cost;
      pque.pop();
      if (visit[state][from]) { continue; }
      visit[state][from] = true;
      if (state == 1 && end[from]) {
        printf("%d\n", cost);
        break;
      }
      FORIT(it, mainG[from]) {
        int to = *it;
        if (visit[state][to]) { continue; }
        int ncost = cost + 1;
        pque.push(Node(state, to, ncost));
      }
      if (state == 0) {
        pque.push(Node(1, from, cost + dist[from]));
      }
    }
  }
}

Measured memory_bytes: 7584