#include <bits/stdc++.h>
// #include<ext/pb_ds/assoc_container.hpp>
// #include<ext/pb_ds/tree_policy.hpp>
using namespace std;
// using namespace __gnu_pbds;
#define fast_io ios_base::sync_with_stdio(false); cin.tie(NULL);
#define ll long long
#define int ll
#define endll "\n"
#define read(x) int x; cin>>x;
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define ff first
#define ss second
#define all(x) (x).begin(), (x).end()
#define py cout << "YES\n"
#define pn cout << "NO\n"
#define fr(i, a, b) for (int i = a; i < b; i++)
#define fer(i, a, b) for (int i = a; i <= b; i++)
#define frr(i, a, b) for (int i = a; i >= b; i--)
#define rev(v) v.rbegin(), v.rend()
#define sz(v) (int)v.size()
#define vecin(v, n) vll v(n); for (int &x : v) cin >> x
#define vecin1(v, n) vll v(n + 1); v[0] = 0; fer (i, 1, n) cin >> v[i]
#define vecp(v) { for (auto x : v) cout << x << ' '; cout << endl; }
using vll = vector<int>;
using vbl = vector<bool>;
using pll = pair<int, int>;
using vpll = vector<pll>;
using vvll = vector<vll>;
using vgr = vector<vpll>;
using stll = set<int>;
using mpll = map<int, int>;
using mpvll = map<int, vll>;
// typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> pbds; 
// a.find_by_order(num) iterator dega uss no ka , a.order_of_key(num)(number of element smaller that that num)
 
#define inf numeric_limits<long long>::max()
const long long MOD = 1000000007;




long long power(long long a, long long b)
{
    long long res = 1;
    while (b) {
        if (b & 1) res = res * a;
        a = a * a;
        b >>= 1;
    }
    return res;
}



bool sortByCond(const pair<ll, ll> &a, const pair<ll, ll> &b)
{
    /*
        if (a.ff == b.ff)
            return a.ss < b.ss;
        else
            return a.ff < b.ff;
    */
    return a.ss < b.ss;
}


vector<int> divisors(int num)
{
    vector<int>d;
    fer(i,1,sqrt(num))
    {
        if(num % i == 0)d.pb(i);
        if(i != num/i)d.pb(num/i);
    }

    return d;
}


bool bfs(int num,vvll &v)
{
    int n = v.size();
    int m = v[0].size();
    queue<pair<int,int>>q;
    vector<vbl>vis(n,vbl(m,0));
    q.push({0,0});
    int dx[] = {1,0};
    int dy[] = {0,1};
    vis[0][0] = 1;
    while (!q.empty())
    {
        int x = q.front().ff;
        int y = q.front().ss;
        q.pop();
        fr(i,0,2)
        {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if(nx < n && ny < m && !vis[nx][ny] && v[nx][ny]%num == 0)
            {
                if(nx == n-1 && ny == m-1)return true;
                vis[nx][ny] = 1;
                q.push({nx,ny});
            }
                
        }
    }
    return false;
}


void solve()
{
    int n,m;
    cin>>n>>m;
    vvll v(n, vll(m, 0));
    fr(i,0,n)
    {
        fr(j,0,m)
        {
            cin>>v[i][j];
        }
    }
    vll div = divisors(__gcd(v[0][0],v[n-1][m-1]));
    int val = sqrt(__gcd(v[0][0],v[n-1][m-1]));
    int ans = 1;
    if (sqrt(val)==(int)sqrt(val))
            if(bfs(sqrt(val),v))ans = max(ans,val);
    sort(all(div));
    frr(i,div.size()-1,0)
    {
        if(bfs(div[i],v))
        {
            ans = max(div[i],ans);
            break;
        }
    }
    cout<<ans<<endll;
}




int32_t main()
{
    fast_io;
    int t = 1;
    cin >> t;
    fer (i, 1, t)
    {
        // cout << "Test Case " << i << endl;
        solve();
    }
    return 0;
}