#include <bits/stdc++.h>
using namespace std;
inline int _Int() {
  int x;
  scanf("%d", &x);
  return x;
}
long long int bigMod(long long int A, long long int P, int M) {
  long long int R = 1;
  for (A %= M; P; P >>= 1) {
    if (P & 1) R = (R * A) % M;
    A = (A * A) % M;
  }
  return R;
}
long long int bigMul(long long int A, long long int B, long long int M) {
  long long int R = 0;
  for (A %= M; B; B >>= 1) {
    if (B & 1) R = (R + A) % M;
    A = (A + A) % M;
  }
  return R;
}
long long int negMod(long long int A, long long int B) {
  return (((A % B) + B) % B);
}
long long int invMod(long long int A, long long int M) {
  return bigMod(A, M - 2, M);
}
unsigned long long int _pow(unsigned long long int A, int P) {
  unsigned long long int R = 1;
  for (; P; P >>= 1) {
    if (P & 1) R = (R * A);
    A = (A * A);
  }
  return R;
}
template <class T>
T GCD(T x, T y) {
  while (x) x ^= y ^= x ^= y %= x;
  return y;
}
template <class T>
bool inRng(T u, T v, T x) {
  return u <= x && x <= v;
}
const int M = 300000 + 7;
int n, edges, source;
vector<int> graph[M];
struct edge {
  int type;
  int u, v;
  void scan(int i) {
    scanf("%d%d%d", &type, &u, &v);
    graph[u].push_back(i);
    if (type == 2) graph[v].push_back(i);
  }
} eee[M];
char ans[M];
bool vis[M];
void bfs() {
  queue<int> qe;
  qe.push(source);
  vis[source] = 1;
  while (qe.size()) {
    int u = qe.front();
    qe.pop();
    for (int i = graph[u].size() - 1; i >= 0; i--) {
      int first = graph[u][i], v;
      if (eee[first].u == u)
        v = eee[first].v;
      else
        v = eee[first].u;
      if (eee[first].type == 2 && !ans[first]) {
        if (eee[first].u == u)
          ans[first] = '+';
        else
          ans[first] = '-';
      }
      if (!vis[v]) qe.push(v);
      vis[v] = 1;
    }
  }
  for (int i = 0; i < edges; i++) {
    if (eee[i].type == 2 && !ans[i]) ans[i] = '+';
  }
}
void bfs_again() {
  queue<int> qe;
  qe.push(source);
  vis[source] = 1;
  while (qe.size()) {
    int u = qe.front();
    qe.pop();
    for (int i = graph[u].size() - 1; i >= 0; i--) {
      int first = graph[u][i], v;
      if (eee[first].u == u)
        v = eee[first].v;
      else
        v = eee[first].u;
      if (eee[first].type == 2 && !ans[first]) {
        if (eee[first].u == u)
          ans[first] = '-';
        else
          ans[first] = '+';
      }
      if (eee[first].type == 1 && !vis[v]) {
        qe.push(v);
        vis[v] = 1;
      }
    }
  }
  for (int i = 0; i < edges; i++) {
    if (eee[i].type == 2 && !ans[i]) ans[i] = '+';
  }
}
void Main() {
  scanf("%d%d%d", &n, &edges, &source);
  for (int i = 0; i < edges; i++) eee[i].scan(i);
  bfs();
  int cnt = 0;
  for (int i = 1; i <= n; i++) cnt += vis[i];
  printf("%d\n", cnt);
  for (int i = 0; i < edges; i++) {
    if (eee[i].type == 2) printf("%c", ans[i]);
  }
  putchar(10);
  memset(vis, 0, sizeof vis);
  memset(ans, 0, sizeof ans);
  bfs_again();
  cnt = 0;
  for (int i = 1; i <= n; i++) cnt += vis[i];
  printf("%d\n", cnt);
  for (int i = 0; i < edges; i++) {
    if (eee[i].type == 2) printf("%c", ans[i]);
  }
  putchar(10);
}
int main() {
  Main();
  return 0;
}
