#include <bits/stdc++.h>
using namespace std;
const int MAXN = 300050;
long long inp1, inp2, inp3, s, ans1, ans2;
long long n, m, head[MAXN], vis1[MAXN], vis2[MAXN], evis1[MAXN << 1],
    evis2[MAXN << 1], cnt = 1;
struct EDGE {
  long long to, w, nxt;
} edge[MAXN << 1];
void add_edge(long long u, long long v, long long w) {
  edge[++cnt] = (EDGE){v, w, head[u]};
  head[u] = cnt;
}
int main() {
  scanf("%lld%lld%lld", &n, &m, &s);
  for (long long i = 1; i <= m; i++) {
    scanf("%lld%lld%lld", &inp3, &inp1, &inp2);
    add_edge(inp1, inp2, inp3);
    if (inp3 == 2)
      add_edge(inp2, inp1, inp3);
    else
      add_edge(inp2, inp1, -1);
  }
  queue<long long> Q;
  Q.push(s);
  vis1[s] = 1;
  while (!Q.empty()) {
    long long u = Q.front();
    Q.pop();
    ans1++;
    for (long long i = head[u]; i; i = edge[i].nxt) {
      if (edge[i].w == -1) continue;
      if (evis1[i] || evis1[i ^ 1]) continue;
      evis1[i] = 1;
      long long v = edge[i].to;
      if (!vis1[v]) {
        vis1[v] = 1;
        Q.push(v);
      }
    }
  }
  Q.push(s);
  vis2[s] = 1;
  while (!Q.empty()) {
    long long u = Q.front();
    Q.pop();
    ans2++;
    for (long long i = head[u]; i; i = edge[i].nxt) {
      if (edge[i].w == -1) continue;
      if (evis2[i] || evis2[i ^ 1]) continue;
      if (edge[i].w == 1)
        evis2[i] = 1;
      else if (edge[i].w == 2) {
        evis2[i ^ 1] = 1;
        continue;
      }
      long long v = edge[i].to;
      if (!vis2[v]) {
        vis2[v] = 1;
        Q.push(v);
      }
    }
  }
  printf("%lld\n", ans1);
  for (long long i = 2; i <= cnt; i += 2) {
    if (edge[i].w != 2) continue;
    if (evis1[i])
      printf("+");
    else
      printf("-");
  }
  printf("\n%lld\n", ans2);
  for (long long i = 2; i <= cnt; i += 2) {
    if (edge[i].w != 2) continue;
    if (evis2[i])
      printf("+");
    else
      printf("-");
  }
  return 0;
}
