#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cmath>
#include <cassert>
using namespace std;

struct Node {
  Node* left;
  Node* right;
  Node(Node* l, Node* r): left(l), right(r) {}
};

Node dummy(NULL, NULL);

pair<int, Node*> parse(const string& str, int k)
{
  pair<int, Node*> r1, r2;
  assert(str[k] == '(');
  if (str[k + 1] == '(') {
    r1 = parse(str, k + 1);
  } else {
    r1 = make_pair(k + 1, (Node*)NULL);
  }
  assert(str[r1.first] == ',');
  if (str[r1.first + 1] == '(') {
    r2 = parse(str, r1.first + 1);
  } else {
    r2 = make_pair(r1.first + 1, (Node*)NULL);
  }
  assert(str[r2.first] == ')');
  return make_pair(r2.first + 1, new Node(r1.second, r2.second));
}

Node* intersection_or_union(char op, Node* node1, Node* node2)
{
  if (!node1) { node1 = &dummy; }
  if (!node2) { node2 = &dummy; }
  bool b1 = (op == 'i') ? (node1->left && node2->left) : (node1->left || node2->left);
  bool b2 = (op == 'i') ? (node1->right && node2->right) : (node1->right || node2->right);
  Node* left = b1 ? intersection_or_union(op, node1->left, node2->left) : NULL;
  Node* right = b2 ? intersection_or_union(op, node1->right, node2->right) : NULL;
  return new Node(left, right);
}

void print_tree(Node* node)
{
  cout << "(";
  if (node->left) {
    print_tree(node->left);
  }
  cout << ",";
  if (node->right) {
    print_tree(node->right);
  }
  cout << ")";
}

int main()
{
  char op;
  string str1, str2;
  while (cin >> op >> str1 >> str2) {
    Node* tree1 = parse(str1, 0).second;
    Node* tree2 = parse(str2, 0).second;
    print_tree(intersection_or_union(op, tree1, tree2));
    cout << endl;
  }
}