#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

template <class T>
struct Polynomial {
  vector<T> coefficient;
  Polynomial() : coefficient(1, 1) {;}
  Polynomial(int s, T ini) : coefficient(s, ini) {;}
  int size() const { return coefficient.size(); }
  void normalize() {
    int s = 1;
    for (int i = size() - 1; i >= 0; i--) {
      if (coefficient[i] != 0) { s = i + 1; break; }
    }
    coefficient.resize(s);
  }
  T operator[](int index) const {
    return coefficient[index];
  }
  T &operator[](int index) {
    return coefficient[index];
  }
  Polynomial operator+(const Polynomial &rhs) const {
    Polynomial ret = *this;
    ret.coefficient.resize(max(size(), rhs.size()));
    for (int i = 0; i < rhs.size(); i++) {
      ret[i] += rhs[i];
    }
    ret.normalize();
    return ret;
  }
  Polynomial operator-(const Polynomial &rhs) const {
    Polynomial ret = *this;
    ret.coefficient.resize(max(size(), rhs.size()));
    for (int i = 0; i < rhs.size(); i++) {
      ret[i] -= rhs[i];
    }
    ret.normalize();
    return ret;
  }
  Polynomial operator*(const Polynomial &rhs) const {
    Polynomial ret(size() + rhs.size(), 0);
    for (int i = 0; i < size(); i++) {
      for (int j = 0; j < rhs.size(); j++) {
        ret[i + j] += coefficient[i] * rhs[j];
      }
    }
    ret.normalize();
    return ret;
  }
  Polynomial operator*(const T &rhs) const {
    Polynomial ret = *this;
    for (int i = 0; i < size(); i++) {
      ret[i] *= rhs;
    }
    ret.normalize();
    return ret;
  }
  Polynomial operator/(const Polynomial &rhs) const {
    return divmod(rhs).first;
  }
  Polynomial operator%(const Polynomial &rhs) const {
    return divmod(rhs).second;
  }
  Polynomial operator/(const T &rhs) const {
    assert(rhs != 0);
    return *this * (1.0 / rhs);
  }
  Polynomial operator+=(const Polynomial &rhs) {
    return *this = *this + rhs;
  }
  Polynomial operator-=(const Polynomial &rhs) {
    return *this = *this - rhs;
  }
  Polynomial operator*=(const Polynomial &rhs) {
    return *this = *this * rhs;
  }
  Polynomial operator/=(const Polynomial &rhs) {
    return *this = *this / rhs;
  }
  Polynomial operator%=(const Polynomial &rhs) {
    return *this = *this % rhs;
  }
  Polynomial operator*=(const T &rhs) {
    return *this = *this * rhs;
  }
  Polynomial operator/=(const T &rhs) {
    return *this = *this / rhs;
  }
  Polynomial operator-() {
    return *this * Polynomial(1, -1);
  }
  pair<Polynomial, Polynomial> divmod(const Polynomial &rhs) const {
    int ls = size();
    int rs = rhs.size();
    int s = ls - rs + 1;
    if (s < 0) { return make_pair(Polynomial(1, 0), *this); }
    Polynomial div(s, 0);
    Polynomial rest = *this;
    assert(rhs[rs - 1] != 0);
    for (int i = 0; i < s; i++) {
      T d = rest[ls - i - 1] / rhs[rs - 1];
      div[s - i - 1] = d;
      for (int j = 0; j < rs; j++) {
        rest[ls - i - j - 1] -= rhs[rs - j - 1] * d;
      }
    }
    div.normalize();
    rest.normalize();
    return make_pair(div, rest);
  }
  Polynomial pow(int power) const {
    Polynomial base = *this;
    Polynomial ret;
    while (power > 0) {
      if (power & 1) { ret *= base; }
      base *= base;
      power >>= 1;
    }
    return ret;
  }
  Polynomial differential() const {
    if (coefficient.size() == 1) { return Polynomial(1, 0); }
    Polynomial ret(coefficient.size() - 1, 0);
    FOR(i, 1, coefficient.size()) {
      ret[i - 1] = coefficient[i] * i;
    }
    return ret;
  }
  T calc(T x) const {
    T ans = 0;
    for (int i = coefficient.size() - 1; i >= 0; i--) {
      ans *= x;
      ans += coefficient[i];
    }
    return ans;
  }
  void Print() const {
    REP(i, coefficient.size()) { cout << coefficient[i] << " "; }
    cout << endl;
  }
};

template <class T>
Polynomial<T> PolynomialGCD(Polynomial<T> a, Polynomial<T> b) {
  if (b.size() == 1 && b[0] == 0) { return a; }
  return PolynomialGCD(b, a % b);
}

template <class T>
Polynomial<T> pow(const Polynomial<T> &base, int power) {
  return base.pos(power);
}

template <class T>
Polynomial<T> divmod(const Polynomial<T> &lhs, const Polynomial<T> &rhs) {
  return lhs.divmod(rhs);
}

// find max point [left, right]
double ts(const Polynomial<double> &poly, double left, double right) {
  REP(iter, 300) {
    double lmid = (left * 2.0 + right) / 3.0;
    double rmid = (left + right * 2.0) / 3.0;
    double lans = poly.calc(lmid);
    double rans = poly.calc(rmid);
    assert(!isnan(lans) && !isnan(rans));
    if (lans < rans) {
      left = lmid;
    } else {
      right = rmid;
    }
  }
  return left;
}

// find 0 point [left, right]
// poly must monotonic increase in [left, right]
double bs(const Polynomial<double> &poly, double left, double right) {
  REP(iter, 200) {
    double mid = (left + right) / 2.0;
    double ans = poly.calc(mid);
    if (ans < 0) {
      left = mid;
    } else {
      right = mid;
    }
  }
  return left;
}

pair<int, int> solve1(Polynomial<double> poly) {
  Polynomial<double> dif = -poly.differential();
  double center = ts(dif, -1000, 1000);
  double leftLocalMax = ts(poly, -1000, center);
  double rightLocalMin = ts(-poly, center, 1000);
  double ans[3];
  ans[0] = bs(poly, -1000, leftLocalMax);
  ans[1] = bs(-poly, leftLocalMax, rightLocalMin);
  ans[2] = bs(poly, rightLocalMin, 1000);
  int minusans = 0;
  int plusans = 0;
  REP(i, 3) {
    if (fabs(poly.calc(ans[i])) < EPS) {
      if (ans[i] < -EPS) { minusans++; }
      if (ans[i] > EPS) { plusans++; }
    }
  }
  return make_pair(plusans, minusans);
}

pair<int, int> solve2(Polynomial<double> poly) {
  double ans[3];
  ans[0] = bs(poly, -100, 1000);
  Polynomial<double> dpoly(2, 1);
  dpoly[0] = -ans[0];
  Polynomial<double> npoly = poly.divmod(dpoly).first;
  npoly /= npoly[2];
  double b = npoly[1];
  double c = npoly[0];
  if (fabs(b * b - 4 * c) < EPS) {
    ans[1] = ans[2] = -b / 2.0;
  } else if (b * b - 4 * c < 0) {
    ans[1] = ans[2] = 0;
  } else {
    ans[1] = (-b + sqrt(b * b - 4 * c)) / 2.0;
    ans[2] = (-b - sqrt(b * b - 4 * c)) / 2.0;
  }
  int minusans = 0;
  int plusans = 0;
  REP(i, 3) {
    if (fabs(poly.calc(ans[i])) < EPS) {
      if (ans[i] < -EPS) { minusans++; }
      if (ans[i] > EPS) { plusans++; }
    }
  }
  return make_pair(plusans, minusans);
}

char str[1000];
int main() {
  int test;
  scanf("%d", &test);
  while (test--) {
    Polynomial<double> poly(4, 0);
    scanf("%lf %lf %lf %lf", &poly[3], &poly[2], &poly[1], &poly[0]);
    assert(-100 <= poly[0] && poly[0] <= 100);
    assert(-100 <= poly[1] && poly[1] <= 100);
    assert(-100 <= poly[2] && poly[2] <= 100);
    assert(-100 <= poly[3] && poly[3] <= 100);
    assert(poly[3] != 0);
    if (poly[3] < 0) { poly *= -1.0; }
    pair<int, int> ans1 = solve1(poly);
    pair<int, int> ans2 = solve2(poly);
    assert(ans1.first == ans2.first);
    assert(ans1.second == ans2.second);
    printf("%d %d\n", ans1.first, ans1.second);
  }
  assert(scanf("%s", str) == EOF);
}

Measured memory_bytes: 968