#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
#define int ll

#define REP(i,n) for(ll i=0;i<n;++i)
#define SORT(name) sort(name.begin(), name.end())
#define ZERO(p) memset(p, 0, sizeof(p))
#define MINUS(p) memset(p, -1, sizeof(p))
#if 1
#  define DBG(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#  define DBG(fmt, ...)
#endif

const ll LLINF = (1LL<<60);
const int INF = (1LL<<30);
const int MOD = 1000000007;
#define MAX_N 100010
#define MAX_V MAX_N

class FordFullkerson {
    public:
        // 辺を表す構造体(行先、容量、m_G[i]における逆辺のインデックス)
        struct Edge {int to, cap, rev; };

        // from から to へ向かう容量 cap の辺をグラフに追加する
        void add_edge(int from, int to, int cap) {
            m_G[from].push_back((Edge){to, cap, static_cast<int>(m_G[to].size())});
            m_G[to].push_back((Edge){from, 0, static_cast<int>(m_G[from].size() - 1)});
        }

        // 増加パスを DFS で探す
        int dfs(int v, int t, int f) {
            if (v == t) { return f; }
            m_Used[v] = true;
            for(int i = 0; i < m_G[v].size(); ++i) {
                Edge &e = m_G[v][i];  // v から延びるエッジ i
                if(!m_Used[e.to] && e.cap > 0) {
                    int d = dfs(e.to, t, min(f, e.cap));
                    if(d > 0) {
                        e.cap -= d;
                        m_G[e.to][e.rev].cap += d;
                        return d;
                    }
                }
            }
            return 0;
        }

        // s から t への最大流を求める
        int max_flow(int s, int t) {
            int flow = 0;
            for(;;) {
                memset(m_Used, 0, sizeof(m_Used));
                int f = dfs(s, t, INF);
                if(f == 0) { return flow; }
                flow += f;
            }
            return flow;
        }
    public:
        vector<Edge> m_G[MAX_V];  // グラフの隣接リスト表現 (index: ノード番号)
        bool m_Used[MAX_V];       // DFS で既に調べたかのグラフ
};

ll solve(ll A, ll B) {
    ll score = A * B;
    double sq = sqrt((double)A * (double) B);
    ll sq_ll = (ll)sq;
    if(sq_ll * sq_ll == score) {
        if(sq_ll == A) {
            return (sq_ll - 1) * 2;
        } else {
            ll base = (sq_ll - 1) * 2;
            return base - 1;
        }
    } else {
        ll base = (sq_ll - 1) * 2;
        if((sq_ll + 1) * sq_ll < score) { base++; }
        return base;
    }
}

ll Q;

signed main()
{
    cin >> Q;
    REP(q, Q) {
        ll A, B;
        cin >> A >> B;
        printf("%lld\n", solve(A, B));
    }
    return 0;
    ll limit = 20;
    for(ll A = 1; A <= limit; ++A) {
        for(ll B = 1; B <= limit; ++B) {
            FordFullkerson* ff = new FordFullkerson();
            ll score = A * B;
            ll start = 0;
            ll end = 100000;
            ll max_node = 10000;
            for(ll i = 1; i < score; ++i) {
                if(i != B) { ff->add_edge(i + max_node, end, 1); }
                if(i == A) { continue; }
                ff->add_edge(start, i, 1);
                for(ll j = 1 + max_node; j < score + max_node; ++j) {
                    if((j - max_node) == B) { continue; }
                    if(i * (j - max_node) < score) { ff->add_edge(i, j, 1); }
                }
            }
            ll ans = ff->max_flow(start, end);
            //printf("A: %lld B: %lld ans: %lld\n", A, B, ans);
            //printf("%lld", ans);
            //if(B == limit) { printf("\n"); }
            //else { printf(", "); }
            ll cand = solve(A, B);
            if(ans != cand) {
                printf("A: %lld B: %lld ans: %lld cand:%lld\n", A, B, ans, cand);
                return 0;
            }

            delete ff;
        }
    }
    return 0;
}


Measured memory_bytes: 256