#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:216000000")
using namespace std;
const long long MAX = numeric_limits<long long>::max();
const long long MIN = numeric_limits<long long>::min();
const double PI = 3.1415926535;
const long long MOD = 1000000007;
template <class T>
ostream& operator<<(ostream& out, vector<T>& v) {
  for (int i = 0; i < v.size(); ++i) out << v[i] << " ";
  out << endl;
  return out;
}
template <class T>
istream& operator>>(istream& in, vector<T>& v) {
  for (int i = 0; i < v.size(); ++i) in >> v[i];
  return in;
}
template <class T>
T lexical_cast(string& s) {
  stringstream ss(s);
  T t;
  ss >> t;
  return t;
}
long long gcd(long long a, long long b) {
  if (b == 0) return a;
  return gcd(b, a % b);
}
long long ceil(long long a, long long b) {
  if (a % b) return a / b + 1;
  return a / b;
}
struct var {
  bool isconst;
  vector<bool> digits;
  string op;
  int op1, op2;
  int order;
};
int main() {
  ios_base::sync_with_stdio(false);
  int n, m;
  cin >> n >> m;
  vector<var> vars;
  unordered_map<string, int> names;
  for (int i = 0; i < n; ++i) {
    string name;
    cin >> name;
    string tmp;
    cin >> tmp;
    string op1;
    cin >> op1;
    if (isdigit(op1[0])) {
      var v;
      v.isconst = true;
      v.digits = vector<bool>(m, false);
      for (int j = 0; j < m; ++j) {
        if (op1[j] == '1') v.digits[j] = true;
      }
      v.order = i;
      vars.push_back(v);
      names[name] = i;
    } else {
      string op2, op;
      cin >> op >> op2;
      var v;
      v.isconst = false;
      v.op = op;
      v.op1 = (op1 == "?") ? -1 : names[op1];
      v.op2 = (op2 == "?") ? -1 : names[op2];
      v.order = i;
      vars.push_back(v);
      names[name] = i;
    }
  }
  vector<bool> pete1;
  vector<bool> pete2;
  for (int i = 0; i < m; ++i) {
    int sum1 = 100000, index1 = 0, sum2 = -1, index2 = 0;
    for (int petebit = 0; petebit < 2; ++petebit) {
      int cursum = 0;
      vector<bool> curbit(n);
      for (int j = 0; j < n; ++j) {
        var& v = vars[j];
        if (v.isconst) {
          curbit[j] = v.digits[i];
          cursum += curbit[j];
        } else {
          bool bit1, bit2;
          bit1 = (v.op1 == -1) ? petebit : curbit[v.op1];
          bit2 = (v.op2 == -1) ? petebit : curbit[v.op2];
          bool ansbit = true;
          if (v.op == "OR") {
            ansbit = bit1 | bit2;
          } else if (v.op == "AND") {
            ansbit = bit1 & bit2;
          } else {
            ansbit = bit1 ^ bit2;
          }
          cursum += ansbit;
          curbit[j] = ansbit;
        }
      }
      if (cursum > sum2) {
        sum2 = cursum;
        index2 = petebit;
      }
      if (cursum < sum1) {
        sum1 = cursum;
        index1 = petebit;
      }
    }
    pete1.push_back(index1);
    pete2.push_back(index2);
  }
  for (int i = 0; i < m; ++i) {
    cout << (int)pete1[i];
  }
  cout << endl;
  for (int i = 0; i < m; ++i) {
    cout << (int)pete2[i];
  }
  cout << endl;
}
