#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC optimize("no-stack-protector")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("unroll-loops")
using namespace std;
using matrix = vector<vector<long long>>;
const int MAXN = 3e5 + 100;
char ans[MAXN];
bool used[MAXN];
vector<int> gd[MAXN];
vector<tuple<int, int, int>> gud[MAXN];
int cnt = 0;
void dfs(int u, bool invert) {
  used[u] = true;
  cnt++;
  for (int to : gd[u]) {
    if (!used[to]) {
      dfs(to, invert);
    }
  }
  for (tuple<int, int, int> x : gud[u]) {
    int to, type, index;
    tie(to, type, index) = x;
    if (used[to]) {
      continue;
    }
    if (!invert) {
      if (type == 1) {
        ans[index] = '+';
      } else {
        ans[index] = '-';
      }
      dfs(to, invert);
    } else {
      if (type == 1) {
        ans[index] = '-';
      } else {
        ans[index] = '+';
      }
    }
  }
}
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n, m, s;
  cin >> n >> m >> s;
  int id = 0;
  for (int i = 0; i < m; ++i) {
    int t, u, v;
    cin >> t >> u >> v;
    if (t == 1) {
      gd[u].push_back(v);
    } else {
      gud[u].push_back(make_tuple(v, 1, id));
      gud[v].push_back(make_tuple(u, -1, id));
      id++;
    }
  }
  fill(used, used + MAXN, false);
  fill(ans, ans + MAXN, '+');
  dfs(s, false);
  cout << cnt << '\n';
  for (int i = 0; i < id; ++i) {
    cout << ans[i];
  }
  cout << '\n';
  cnt = 0;
  fill(used, used + MAXN, false);
  fill(ans, ans + MAXN, '+');
  dfs(s, true);
  cout << cnt << '\n';
  for (int i = 0; i < id; ++i) {
    cout << ans[i];
  }
  cout << '\n';
}
