#include <bits/stdc++.h>
using namespace std;
using namespace rel_ops;
struct Vector {
  long long x, y, z;
  Vector(long long x_, long long y_, long long z_) : x(x_), y(y_), z(z_) {}
};
bool operator<(const Vector& l, const Vector& r) {
  return make_tuple(l.x, l.y, l.z) < make_tuple(r.x, r.y, r.z);
}
bool operator==(const Vector& l, const Vector& r) {
  return make_tuple(l.x, l.y, l.z) == make_tuple(r.x, r.y, r.z);
}
inline long long absll(long long a) { return a < 0 ? -a : a; }
long long GCD(long long a, long long b) {
  a = absll(a);
  b = absll(b);
  if (!a || !b) return a + b;
  while (b) {
    a %= b;
    swap(a, b);
  }
  return a;
}
Vector& Norm(Vector& a) {
  if (a.x == 0) {
    if (a.y == 0)
      a.z = absll(a.z);
    else if (a.y < 0) {
      a.y *= -1;
      a.z *= -1;
    }
  } else if (a.x < 0) {
    a.x *= -1;
    a.y *= -1;
    a.z *= -1;
  }
  long long g = GCD(a.x, GCD(a.y, a.z));
  if (g) {
    a.x /= g;
    a.y /= g;
    a.z /= g;
  }
  return a;
}
inline istream& operator>>(istream& in, Vector& a) {
  long long x, y, z;
  cin >> x >> y >> z;
  a = Vector(x, y, z);
  return in;
}
inline Vector Cross(const Vector& a, const Vector& b) {
  Vector r(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
  long long g = GCD(r.x, GCD(r.y, r.z));
  if (g) {
    r.x /= g;
    r.y /= g;
    r.z /= g;
  }
  return r;
}
struct Frac {
  long long a, b;
  Frac(long long a_, long long b_) : a(a_), b(b_) {}
  bool operator<(Frac r) const {
    if ((b < 0) ^ (r.b < 0)) {
      r.a *= -1;
      r.b *= -1;
    }
    return a * r.b < r.a * b;
  }
  Frac operator/(const Frac& r) const { return Frac(a * r.b, b * r.a); }
  Frac operator*(const Frac& r) const { return Frac(a * r.a, b * r.b); }
  Frac operator-() const { return Frac(-a, b); }
  Frac operator-(const Frac& r) const {
    Frac res(a * r.b - r.a * b, b * r.b);
    long long g = GCD(res.a, res.b);
    if (g) {
      res.a /= g;
      res.b /= g;
    }
    return res;
  }
  operator long double() const { return (long double)a / (long double)b; }
};
bool operator==(Frac& l, Frac& r) {
  long long g = GCD(l.a, l.b);
  if (g) {
    l.a /= g;
    l.b /= g;
  }
  g = GCD(r.a, r.b);
  if (g) {
    r.a /= g;
    r.b /= g;
  }
  return l.a == r.a && l.b == r.b;
}
ostream& operator<<(ostream& out, Frac a) { return out << a.a << "/" << a.b; }
struct Point {
  Frac x, y;
  Point(const Frac& x_, const Frac& y_) : x(x_), y(y_) {}
  bool operator==(const Point& r) const { return x == r.x && y == r.y; }
  int part() const {
    static Frac zer(0, 1);
    int px = 1, py = 1;
    if (x < zer)
      px = -1;
    else if (x == zer)
      px = 0;
    if (y < zer)
      py = -1;
    else if (y == zer)
      py = 0;
    if (px < 0) return py < 0 ? 5 : (py == 0 ? 4 : 3);
    if (px == 0) return py < 0 ? 6 : 2;
    return py < 0 ? 7 : (py == 0 ? 0 : 1);
  }
  Point operator-() const { return Point(-x, -y); }
};
struct CycComp {
  bool operator()(Point l, Point r) const {
    if (l == r) return false;
    int lp = l.part(), rp = r.part();
    if (lp != rp) return lp < rp;
    if (l.x == Frac(0, 1) && r.x == Frac(0, 1)) return false;
    if (l.y == Frac(0, 1) && r.y == Frac(0, 1)) return false;
    return l.y / (long double)l.x < r.y / (long double)r.x;
  }
};
bool Near(const Point& a, const Point& b) {
  if (a.x * b.y == a.y * b.x) return true;
  if (CycComp()(a, b)) {
    int negapart = (-a).part(), bpart = b.part();
    for (int i = a.part(); i != negapart; i = (i + 1) % 8)
      if (bpart == i) return true;
    if (negapart == bpart) return CycComp()(b, -a);
    return false;
  }
  return !Near(b, a);
}
Point PointInHull(const Vector& target, const Vector& a) {
  long long asum = a.x + a.y + a.z;
  long long tsum = target.x + target.y + target.z;
  return Point(Frac(a.x, asum) - Frac(target.x, tsum),
               Frac(a.y, asum) - Frac(target.y, tsum));
}
long double triangle_area_2(long double x1, long double y1, long double x2,
                            long double y2, long double x3, long double y3) {
  return absll((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1));
}
long double Area(Point a, Point b, Point c) {
  return triangle_area_2(a.x, a.y, b.x, b.y, c.x, c.y);
}
int Brutos(Vector target, const multiset<Point, CycComp>& hull) {
  if (hull.size() < 3) return 0;
  for (auto it1 = hull.begin(); it1 != hull.end() && next(it1) != hull.end();
       ++it1)
    if (!Near(*it1, *next(it1))) return 0;
  if (!Near(*hull.rbegin(), *hull.begin())) return 0;
  Point a = *hull.rbegin(), b = *hull.begin();
  if (!CycComp()(a, b) && !CycComp()(b, a)) return 0;
  return 3;
  for (auto it1 = hull.begin(); it1 != hull.end() && next(it1) != hull.end();
       ++it1) {
    Point p = *it1;
    for (auto it2 = next(it1); it2 != hull.end() && next(it2) != hull.end();
         ++it2) {
      Point q = *it2;
      if (!CycComp()(p, q) && !CycComp()(q, p)) continue;
      if (!CycComp()(p, q)) throw;
      for (auto it3 = next(it2); it3 != hull.end(); ++it3) {
        Point r = *it3;
        if (!CycComp()(p, r) && !CycComp()(r, p)) continue;
        if (!CycComp()(q, r) && !CycComp()(r, q)) continue;
        if (!CycComp()(q, r)) throw;
        Point zer(Frac(0, 1), Frac(0, 1));
        const long double eps = 0.000001L;
        long double s1 = Area(zer, p, q) + Area(zer, q, r) + Area(zer, r, p);
        long double s2 = Area(p, q, r);
        long double delta = absll(s2 - s1);
        if (!Near(p, q)) continue;
        if (!Near(q, r)) continue;
        if (!Near(r, p)) continue;
        if (delta < eps) return 3;
      }
    }
  }
  return 0;
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  Vector target(0, 0, 0);
  cin >> target;
  Norm(target);
  int n;
  cin >> n;
  vector<Vector> a;
  a.reserve(n);
  multiset<Vector> b;
  map<Vector, pair<int, int>> c;
  multiset<Point, CycComp> hull;
  int gaps = 0;
  int anscnt = 0;
  while (n--) {
    char type;
    cin >> type;
    if (type == 'A') {
      Vector r(0, 0, 0);
      cin >> r;
      Norm(r);
      a.push_back(r);
      b.insert(r);
      Vector q = Cross(r, target);
      Vector qq = q;
      Norm(qq);
      if (q == qq) {
        if (++c[qq].first == 1 && c[qq].second) ++anscnt;
      } else {
        if (++c[qq].second == 1 && c[qq].first) ++anscnt;
      }
      Point point = PointInHull(target, r);
      if (point.x != Frac(0, 1) || point.y != Frac(0, 1)) {
        auto it = hull.insert(point);
        if (hull.size() > 1) {
          auto prv = (it == hull.begin() ? prev(hull.end()) : prev(it));
          auto nxt = (next(it) == hull.end() ? hull.begin() : next(it));
          if (!Near(*prv, *nxt)) --gaps;
          if (!Near(*prv, *it)) ++gaps;
          if (!Near(*it, *nxt)) ++gaps;
        }
      }
    } else {
      int j;
      cin >> j;
      --j;
      Vector r = a[j];
      b.erase(b.find(r));
      Vector q = Cross(r, target);
      Vector qq = q;
      Norm(qq);
      if (q == qq) {
        if (--c[qq].first == 0 && c[qq].second) --anscnt;
      } else {
        if (--c[qq].second == 0 && c[qq].first) --anscnt;
      }
      Point point = PointInHull(target, r);
      if (point.x != Frac(0, 1) || point.y != Frac(0, 1)) {
        auto it = hull.find(point);
        if (hull.size() > 1) {
          auto prv = (it == hull.begin() ? prev(hull.end()) : prev(it));
          auto nxt = (next(it) == hull.end() ? hull.begin() : next(it));
          if (!Near(*prv, *nxt)) ++gaps;
          if (!Near(*prv, *it)) --gaps;
          if (!Near(*it, *nxt)) --gaps;
        }
        hull.erase(it);
      }
    }
    int ans = -1;
    if (b.find(target) != b.end())
      cout << "1\n";
    else if (anscnt)
      cout << "2\n";
    else if (b.size() < 3 || gaps)
      cout << "0\n";
    else if (hull.size()) {
      Point p = *hull.rbegin(), q = *hull.begin();
      if (!CycComp()(p, q) && !CycComp()(q, p))
        cout << "0\n";
      else
        cout << "3\n";
    } else
      cout << "3\n";
  }
  cin >> n;
}
