#include <iostream>
#include <sstream>
#include <stack>
#include <iomanip>
#include <numeric>
#include <string>
#include <cstring>
#include <algorithm>
#include <functional>
#include <cstdlib>
#include <cassert>
#include <map>
#include <set>
#include <vector>
#include <utility>
#include <queue>
#include <cmath>

#define BEGIN(x) x.begin()
#define END(x) x.end()
#define ALL(x) BEGIN(x), END(x)
#define PAIR make_pair
#define VEC(type) vector<type >
#define endl '\n'
#define FIR first
#define SEC second
#define PB push_back
#define SZ(x) ((int)x.size())

#define FOR(i, A, B) for(auto i = (A);i != (B); i++)
#define FORD(i, A, B) for(auto i = (A);i != (B); i--)

#define READRANGE(begin, end) FOR(it, begin, end) cin >> *it
#define READVEC(V) READRANGE(BEGIN(V), END(V))

using namespace std;

typedef long long lint;
typedef pair<int, int> Pii;
typedef pair<int, lint> Pil;
typedef pair<lint, lint> Pll;
typedef pair<lint, int> Pli;

template<class U, class V>
istream& operator >>(istream& in, pair<U, V>& pr) {
    return in >> pr.first >> pr.second;
}

template<class U, class V>
ostream& operator <<(ostream& out, pair<U, V>& p) {
    return out << p.first << " " << p.second;
}

template<class T>
ostream& operator <<(ostream& out, vector<T> vec) {
    for (T& e : vec)
        out << e << " ";
    return out << endl;
}

// ---- BEGIN LIBRARY CODE ----
// ---- END LIBRARY CODE ----
void io_init()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
};

VEC(Pll) split(lint n, int X)
{
    VEC(Pll) ret;
    // 1, ... n
    if (X == 1) {
        ret.PB(Pll(2, n + 1));
        return ret;
    }
    else if (n < X) {
        ret.PB(Pll(1, n));
        return ret;
    }

    // 2 <= X <= n
    ret.PB(Pll(1, X - 1));
    ret.PB(Pll(X + 1, n + 1));
    return ret;
};

lint getMax(Pll a, Pll b)
{
    lint x1 = a.FIR, y1 = a.SEC;
    lint x2 = b.FIR, y2 = b.SEC;

    if (y1 - x1 + 1 > y2 - x2 + 1) {
        swap(x1, x2);
        swap(y1, y2);
    }

    // x1 .. y1 has less elements.
    lint n = y1 - x1;
    y2 = x2 + n;

    // x1..y1 and x2..y2 has same elements.
    // MAX (x1 + t) * (y2 - t), 0 <= t <= n
    // MAX (x1 * y2 + t * (y2 - x1) - t * t, 0 <= t <= n)

    lint ret = 0;
    FOR(t, 0, 4) {
        if (t <= n)
            ret = max(ret, (x1 + t) * (y2 - t));
    }

    FOR(t, n - 3, n + 1)
        if (t >= 0)
            ret = max(ret, (x1 + t) * (y2 - t));

    lint td = (y2 - x1) / 2;
    FOR(t, td - 3, td + 4) if (t >= 0 && t <= n) {
        ret = max(ret, (x1 + t) * (y2 - t));
    }

    return ret;
};

bool good(lint n, int X, int Y)
{
    if (n == 0)
        return true;

    const lint LIMIT = X * 1LL * Y;
    VEC(Pll) p1 = split(n, X), p2 = split(n, Y);

    if (SZ(p1) == 1 && SZ(p2) == 1) {
        return getMax(p1[0], p2[0]) < LIMIT;
    } else if (SZ(p1) == 1 && SZ(p2) == 2) {
        lint x1 = p1[0].FIR, y1 = p1[0].SEC;
        lint n1 = p2[1].SEC - p2[1].FIR + 1;

        Pll pp1(x1, x1 + n1 - 1), pp2(x1 + n1, y1);
        if (getMax(pp1, p2[1]) >= LIMIT || getMax(pp2, p2[0]) >= LIMIT)
            return false;
    } else if (SZ(p1) == 2 && SZ(p2) == 1) {
        swap(p1, p2);
        lint x1 = p1[0].FIR, y1 = p1[0].SEC;
        lint n1 = p2[1].SEC - p2[1].FIR + 1;

        Pll pp1(x1, x1 + n1 - 1), pp2(x1 + n1, y1);
        if (getMax(pp1, p2[1]) >= LIMIT || getMax(pp2, p2[0]) >= LIMIT)
            return false;
    } else {
        // both have 2 parts.
        if (p1[0].SEC - p1[0].FIR <= p2[1].SEC - p2[1].FIR) {
            lint d = p1[0].SEC - p1[0].FIR;
            if (getMax(p1[0], Pll(p2[1].SEC - d, p2[1].SEC)) >= LIMIT)
                return false;

            if (d < p2[1].SEC - p2[1].FIR) {
                lint d2 = p2[1].SEC - p2[1].FIR - d;
                lint xt = X + 1, yt = X + d2;
                lint xt2 = Y + 1, yt2 = Y + d2;
                if (getMax(Pll(xt, yt), Pll(xt2, yt2)) >= LIMIT)
                    return false;
            }
        } else {
            lint d = p2[1].SEC - p2[1].FIR;
            if (getMax(Pll(p1[0].FIR, p1[0].FIR + d), p2[1]) >= LIMIT)
                return false;

            if (d < p1[0].SEC - p1[0].FIR) {
                lint d2 = p1[0].SEC - p1[0].FIR - d;
                lint yt = X - 1, xt = X - d;
                lint yt2 = Y - 1, xt2 = Y - d;
                if (getMax(Pll(xt, yt), Pll(xt2, yt2)) >= LIMIT)
                    return false;
            }
        }

        if (p1[1].SEC - p1[1].FIR <= p2[0].SEC - p2[0].FIR) {
            lint xt = X + 1, yt = p1[1].SEC;
            lint xt2 = 1, yt2 = yt - xt + 1;
            if (getMax(Pll(xt, yt), Pll(xt2, yt2)) >= LIMIT)
                return false;

            if (p1[1].SEC - p1[1].FIR < p2[0].SEC - p2[0].FIR) {
                lint take = p2[0].SEC - p2[0].FIR - p1[1].SEC + p1[1].FIR;
                yt = X - 1;xt = X - take;
                yt2 = Y - 1;xt2 = Y - take;
                if (getMax(Pll(xt, yt), Pll(xt2, yt2)) >= LIMIT)
                    return false;
            }
        } else {
            lint take = p2[0].SEC - p2[0].FIR + 1;
            lint yt = p2[0].SEC, xt = p2[0].SEC - take + 1;
            lint yt2 = take, xt2 = 1;
            if (getMax(Pll(xt, yt), Pll(xt2, yt2)) >= LIMIT)
                return false;

            take = p1[1].SEC - p1[1].FIR + 1 - take;
            xt2 = Y + 1, yt2 = Y + take;
            xt = X + 1, yt = X + take;
            if (getMax(Pll(xt, yt), Pll(xt2, yt2)) >= LIMIT)
                return false;
        }
    }
    return true;
};

void solveSingleCase(int caseNo)
{
    int X, Y;
    cin >> X >> Y;
    if (X > Y)
        swap(X, Y);

    // X <= Y;
    //
    lint lo = 0, hi = 1LL << 31;
    while (hi - lo > 1) {
        lint mid = (hi + lo) / 2;
        if (good(mid, X, Y))
            lo = mid;
        else
            hi = mid - 1;
    }

    if (!good(hi, X, Y))
        hi = lo;

    cout << hi << endl;
};

int main(int argc, char **argv)
{
    io_init();

    // Actual program code starts here.
    int T = 1;
    cin >> T;
    FOR(tcase, 1, T + 1) {
        solveSingleCase(tcase);
    }
    return 0;
};


Measured memory_bytes: 256