#include <bits/stdc++.h>
using namespace std;
const int N = (int)1e6 + 10;
int v1[N], v2[N], v[N], tp[N], op1[N], op2[N];
int n;
struct UF {
  int p[N], r[N];
  void init() {
    for (int i = 1; i <= n; i++) {
      p[i] = i;
      r[i] = 0;
    }
  }
  int find(int x) {
    if (p[x] == x) return x;
    return p[x] = find(p[x]);
  }
  void merge(int u, int v) {
    u = find(u);
    v = find(v);
    if (u == v) return;
    if (r[u] < r[v]) swap(u, v);
    p[v] = u;
    if (r[u] == r[v]) ++r[u];
  }
} uf;
void dfs(int u) {
  if (tp[u] == 1) {
    v1[u] = op1[u];
    v[u] = op1[u];
    return;
  }
  if (tp[u] == 4) {
    dfs(op1[u]);
    v1[u] = v[u] = !v[op1[u]];
    uf.merge(u, op1[u]);
    return;
  }
  dfs(op1[u]);
  dfs(op2[u]);
  v1[u] = v[op1[u]];
  v2[u] = v[op2[u]];
  if (tp[u] == 2) {
    v[u] = v1[u] & v2[u];
    if (v1[u]) uf.merge(u, op2[u]);
    if (v2[u]) uf.merge(u, op1[u]);
  } else if (tp[u] == 3) {
    v[u] = v1[u] ^ v2[u];
    uf.merge(u, op1[u]);
    uf.merge(u, op2[u]);
  } else {
    v[u] = v1[u] | v2[u];
    if (!v1[u]) uf.merge(u, op2[u]);
    if (!v2[u]) uf.merge(u, op1[u]);
  }
}
int main() {
  scanf("%d", &n);
  char cmd[30];
  for (int i = 1; i <= n; i++) {
    scanf("%s", cmd);
    if (cmd[0] == 'I') {
      tp[i] = 1;
      scanf("%d", op1 + i);
    } else if (cmd[0] == 'A') {
      tp[i] = 2;
      scanf("%d%d", op1 + i, op2 + i);
    } else if (cmd[0] == 'X') {
      tp[i] = 3;
      scanf("%d%d", op1 + i, op2 + i);
    } else if (cmd[0] == 'N') {
      tp[i] = 4;
      scanf("%d", op1 + i);
    } else {
      tp[i] = 5;
      scanf("%d%d", op1 + i, op2 + i);
    }
  }
  uf.init();
  dfs(1);
  int t = uf.find(1);
  for (int i = 1; i <= n; i++) {
    if (tp[i] == 1) {
      if (uf.find(i) == t)
        printf("%d", v[1] ^ 1);
      else
        printf("%d", v[1]);
    }
  }
  puts("");
}
