#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define dd double
#define endl "\n"
#define pb push_back
#define all(v) v.begin(),v.end()
#define mp make_pair
#define fi first
#define se second
#define vll vector<ll>
#define pll pair<ll,ll>
#define fo(i,n) for(int i=0;i<n;i++)
#define fo1(i,n) for(int i=1;i<=n;i++)
ll mod=1000000007;
ll n,k,t,m,q,flag=0;
ll power(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
// #define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
// ordered_set s ; s.order_of_key(a) -- no. of elements strictly less than a
// s.find_by_order(i) -- itertor to ith element (0 indexed)
ll min(ll a,ll b){if(a>b)return b;else return a;}
ll max(ll a,ll b){if(a>b)return a;else return b;}
ll gcd(ll a , ll b){ if(b > a) return gcd(b , a) ; if(b == 0) return a ; return gcd(b , a%b) ;}
int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    #ifdef NOOBxCODER
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #else
    #define NOOBxCODER 0
    #endif
    cin>>t;
    //t=1;
    while(t--){
        cin>>n>>m;
        char a[n][m];
        fo(i,n)fo(j,m)cin>>a[i][j];
        vector<vll>v;
        for(int i=0;i<n-1;i++){
            for(int j=0;j<m-1;j+=2){

                if(a[i][j]=='0' && a[i][j+1]=='0')continue;
                vll v1;
                v1.pb(i+1);
                v1.pb(j);
                a[i+1][j]='1'+'0'-a[i+1][j];

                if(a[i][j]=='1' && a[i][j+1]=='0'){
                    v1.pb(i);
                    v1.pb(j);
                    v1.pb(i+1);
                    v1.pb(j+1);
                    a[i+1][j+1]='1'+'0'-a[i+1][j+1];
                }
                else if(a[i][j]=='0' && a[i][j+1]=='1'){
                    v1.pb(i);
                    v1.pb(j+1);
                    v1.pb(i+1);
                    v1.pb(j+1);
                    a[i+1][j+1]='1'+'0'-a[i+1][j+1];
                }
                else {
                    v1.pb(i);
                    v1.pb(j);
                    v1.pb(i);
                    v1.pb(j+1);
                }
                a[i][j]='0';a[i][j+1]='0';
                v.pb(v1);
                //cout<<i<<j<<endl;
                //fo(i,n){fo(j,m)cout<<a[i][j]; cout<<endl;}cout<<endl;
            }
        }
        //fo(i,n){fo(j,m)cout<<a[i][j]; cout<<endl;}
        if(n%2==1 && m%2==1){
            if(a[n-1][m-1]=='1'){
                vll v1;
                v1.pb(n-1);
                v1.pb(m-1);
                v1.pb(n-2);
                v1.pb(m-1);
                v1.pb(n-1);
                v1.pb(m-2);
                a[n-1][m-1]='0';
                a[n-2][m-1]='1'+'0'-a[n-2][m-1];
                a[n-1][m-2]='1'+'0'-a[n-1][m-2];
            }

        }

            for(int i=0;i<m-1;i+=2){
                if(a[n-1][i]=='1'  && a[n-1][i+1]=='1'){
                    vll v1;
                    v1.pb(n-2);v1.pb(i);v1.pb(n-2);v1.pb(i+1);v1.pb(n-1);v1.pb(i);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(n-2);v1.pb(i);v1.pb(n-2);v1.pb(i+1);v1.pb(n-1);v1.pb(i+1);
                    v.pb(v1);
                }
                else if(a[n-1][i]=='0' && a[n-1][i+1]=='1'){
                    vll v1;
                    v1.pb(n-2);v1.pb(i);v1.pb(n-1);v1.pb(i+1);v1.pb(n-1);v1.pb(i);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(n-2);v1.pb(i);v1.pb(n-2);v1.pb(i+1);v1.pb(n-1);v1.pb(i+1);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(n-1);v1.pb(i);v1.pb(n-2);v1.pb(i+1);v1.pb(n-1);v1.pb(i+1);
                    v.pb(v1);
                }
                else if(a[n-1][i]=='1' && a[n-1][i+1]=='0'){
                    vll v1;
                    v1.pb(n-2);v1.pb(i);v1.pb(n-1);v1.pb(i+1);v1.pb(n-1);v1.pb(i);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(n-2);v1.pb(i);v1.pb(n-2);v1.pb(i+1);v1.pb(n-1);v1.pb(i);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(n-1);v1.pb(i);v1.pb(n-2);v1.pb(i+1);v1.pb(n-1);v1.pb(i+1);
                    v.pb(v1);
                }
            }
            if(m%2==1)for(int i=0;i<n-1;i+=2){
                if(a[i][m-1]=='1' && a[i+1][m-1]=='1'){
                    vll v1;
                    v1.pb(i);v1.pb(m-2);v1.pb(i+1);v1.pb(m-2);v1.pb(i);v1.pb(m-1);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(i);v1.pb(m-2);v1.pb(i+1);v1.pb(m-2);v1.pb(i+1);v1.pb(m-1);
                    v.pb(v1);
                }
                else if(a[i][m-1]=='0' && a[i+1][m-1]=='1'){
                    vll v1;
                    v1.pb(i);v1.pb(m-2);v1.pb(i+1);v1.pb(m-2);v1.pb(i+1);v1.pb(m-1);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(i);v1.pb(m-1);v1.pb(i+1);v1.pb(m-2);v1.pb(i+1);v1.pb(m-1);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(i);v1.pb(m-2);v1.pb(i);v1.pb(m-1);v1.pb(i+1);v1.pb(m-1);
                    v.pb(v1);
                }
                else if(a[i][m-1]=='1' && a[i+1][m-1]=='0'){
                    vll v1;
                    v1.pb(i);v1.pb(m-2);v1.pb(i+1);v1.pb(m-2);v1.pb(i);v1.pb(m-1);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(i);v1.pb(m-1);v1.pb(i+1);v1.pb(m-2);v1.pb(i+1);v1.pb(m-1);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(i);v1.pb(m-2);v1.pb(i);v1.pb(m-1);v1.pb(i+1);v1.pb(m-1);
                    v.pb(v1);
                }
                //a[i][m-1]=0;  a[i+1][m-1]=0;
            }
            cout<<v.size()<<endl;
            fo(i,v.size()){
                fo(j,6)cout<<v[i][j]+1<<" ";
                cout<<endl;
            }

    }
    cerr << "Time : " << 1000 * ((double)clock()) / (double)CLOCKS_PER_SEC << "ms\n";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define dd double
#define endl "\n"
#define pb push_back
#define all(v) v.begin(),v.end()
#define mp make_pair
#define fi first
#define se second
#define vll vector<ll>
#define pll pair<ll,ll>
#define fo(i,n) for(int i=0;i<n;i++)
#define fo1(i,n) for(int i=1;i<=n;i++)
ll mod=1000000007;
ll n,k,t,m,q,flag=0;
ll power(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
// #define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
// ordered_set s ; s.order_of_key(a) -- no. of elements strictly less than a
// s.find_by_order(i) -- itertor to ith element (0 indexed)
ll min(ll a,ll b){if(a>b)return b;else return a;}
ll max(ll a,ll b){if(a>b)return a;else return b;}
ll gcd(ll a , ll b){ if(b > a) return gcd(b , a) ; if(b == 0) return a ; return gcd(b , a%b) ;}
int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    #ifdef NOOBxCODER
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #else
    #define NOOBxCODER 0
    #endif
    cin>>t;
    //t=1;
    while(t--){
        cin>>n>>m;
        char a[n][m];
        fo(i,n)fo(j,m)cin>>a[i][j];
        vector<vll>v;
        for(int i=0;i<n-1;i++){
            for(int j=0;j<m-1;j+=2){

                if(a[i][j]=='0' && a[i][j+1]=='0')continue;
                vll v1;
                v1.pb(i+1);
                v1.pb(j);
                a[i+1][j]='1'+'0'-a[i+1][j];

                if(a[i][j]=='1' && a[i][j+1]=='0'){
                    v1.pb(i);
                    v1.pb(j);
                    v1.pb(i+1);
                    v1.pb(j+1);
                    a[i+1][j+1]='1'+'0'-a[i+1][j+1];
                }
                else if(a[i][j]=='0' && a[i][j+1]=='1'){
                    v1.pb(i);
                    v1.pb(j+1);
                    v1.pb(i+1);
                    v1.pb(j+1);
                    a[i+1][j+1]='1'+'0'-a[i+1][j+1];
                }
                else {
                    v1.pb(i);
                    v1.pb(j);
                    v1.pb(i);
                    v1.pb(j+1);
                }
                a[i][j]='0';a[i][j+1]='0';
                v.pb(v1);
                //cout<<i<<j<<endl;
                //fo(i,n){fo(j,m)cout<<a[i][j]; cout<<endl;}cout<<endl;
            }
        }
        //fo(i,n){fo(j,m)cout<<a[i][j]; cout<<endl;}

        if(n%2==1 && m%2==1){
            if(a[n-1][m-1]=='1'){
                //cout<<444<<endl;
                vll v1;
                v1.pb(n-1);
                v1.pb(m-1);
                v1.pb(n-2);
                v1.pb(m-1);
                v1.pb(n-1);
                v1.pb(m-2);
                v.pb(v1);
                a[n-1][m-1]='0';
                a[n-2][m-1]='1'+'0'-a[n-2][m-1];
                a[n-1][m-2]='1'+'0'-a[n-1][m-2];
            }

        }
            if(m%2==1)for(int i=0;i<n-1;i+=2){
                if(i==n-2){
                    if(a[i][m-1]=='1' && a[i+1][m-1]=='1'){
                    vll v1;
                    v1.pb(i+1);v1.pb(m-2);v1.pb(i+1);v1.pb(m-1);v1.pb(i);v1.pb(m-1);
                    v.pb(v1);

                }
                else if(a[i][m-1]=='0' && a[i+1][m-1]=='1'){
                    vll v1;
                    v1.pb(i);v1.pb(m-2);v1.pb(i);v1.pb(m-1);v1.pb(i+1);v1.pb(m-1);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(i);v1.pb(m-2);v1.pb(i);v1.pb(m-1);v1.pb(i+1);v1.pb(m-2);
                    v.pb(v1);
                }
                else if(a[i][m-1]=='1' && a[i+1][m-1]=='0'){
                    vll v1;
                    v1.pb(i);v1.pb(m-2);v1.pb(i+1);v1.pb(m-1);v1.pb(i);v1.pb(m-1);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(i);v1.pb(m-2);v1.pb(i+1);v1.pb(m-1);v1.pb(i+1);v1.pb(m-2);
                    v.pb(v1);
                }
                    continue;
                }
                if(a[i][m-1]=='1' && a[i+1][m-1]=='1'){
                    vll v1;
                    v1.pb(i);v1.pb(m-2);v1.pb(i+1);v1.pb(m-2);v1.pb(i);v1.pb(m-1);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(i);v1.pb(m-2);v1.pb(i+1);v1.pb(m-2);v1.pb(i+1);v1.pb(m-1);
                    v.pb(v1);
                }
                else if(a[i][m-1]=='0' && a[i+1][m-1]=='1'){
                    vll v1;
                    v1.pb(i);v1.pb(m-2);v1.pb(i+1);v1.pb(m-2);v1.pb(i+1);v1.pb(m-1);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(i);v1.pb(m-1);v1.pb(i+1);v1.pb(m-2);v1.pb(i+1);v1.pb(m-1);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(i);v1.pb(m-2);v1.pb(i);v1.pb(m-1);v1.pb(i+1);v1.pb(m-1);
                    v.pb(v1);
                }
                else if(a[i][m-1]=='1' && a[i+1][m-1]=='0'){
                    vll v1;
                    v1.pb(i);v1.pb(m-2);v1.pb(i+1);v1.pb(m-2);v1.pb(i);v1.pb(m-1);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(i);v1.pb(m-1);v1.pb(i+1);v1.pb(m-2);v1.pb(i+1);v1.pb(m-1);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(i);v1.pb(m-2);v1.pb(i);v1.pb(m-1);v1.pb(i+1);v1.pb(m-1);
                    v.pb(v1);
                }
                //a[i][m-1]=0;  a[i+1][m-1]=0;
            }

            for(int i=0;i<m-1;i+=2){
                if(a[n-1][i]=='1'  && a[n-1][i+1]=='1'){
                    vll v1;
                    v1.pb(n-2);v1.pb(i);v1.pb(n-2);v1.pb(i+1);v1.pb(n-1);v1.pb(i);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(n-2);v1.pb(i);v1.pb(n-2);v1.pb(i+1);v1.pb(n-1);v1.pb(i+1);
                    v.pb(v1);
                }
                else if(a[n-1][i]=='0' && a[n-1][i+1]=='1'){
                    vll v1;
                    v1.pb(n-2);v1.pb(i);v1.pb(n-1);v1.pb(i+1);v1.pb(n-1);v1.pb(i);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(n-2);v1.pb(i);v1.pb(n-2);v1.pb(i+1);v1.pb(n-1);v1.pb(i+1);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(n-1);v1.pb(i);v1.pb(n-2);v1.pb(i+1);v1.pb(n-1);v1.pb(i+1);
                    v.pb(v1);
                }
                else if(a[n-1][i]=='1' && a[n-1][i+1]=='0'){
                    vll v1;
                    v1.pb(n-2);v1.pb(i);v1.pb(n-1);v1.pb(i+1);v1.pb(n-1);v1.pb(i);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(n-2);v1.pb(i);v1.pb(n-2);v1.pb(i+1);v1.pb(n-1);v1.pb(i);
                    v.pb(v1);
                    v1.clear();
                    v1.pb(n-1);v1.pb(i);v1.pb(n-2);v1.pb(i+1);v1.pb(n-1);v1.pb(i+1);
                    v.pb(v1);
                }
            }

            cout<<v.size()<<endl;
            fo(i,v.size()){
                fo(j,6)cout<<v[i][j]+1<<" ";
                cout<<endl;
            }

    }
    cerr << "Time : " << 1000 * ((double)clock()) / (double)CLOCKS_PER_SEC << "ms\n";
    return 0;
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;

template<typename T>
using ordered_set=tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;

#define ll long long
#define ull unsigned long long
#define pi pair<ll,ll>
#define pii pair<ll,pi>
#define inf 1000000000000000000
#define iinf -1000000000000000000
#define __   ios_base::sync_with_stdio(0);cin.tie();cout.tie();
#define mod 1000000007
#define base 1949313259
#define en '\n'

ll Set(ll N,ll pos){ return N=N | (1LL<<pos); }
ll reset(ll N,ll pos){ return N= N & ~(1LL<<pos); }
bool check(ll N,ll pos){ return (bool)(N & (1LL<<pos)); }

ll ar[]={0,0,1,-1};
ll br[]={1,-1,0,0};

ll bigmod(ll n,ll pow){
if(pow==0) return 1;
if(pow==1) return n%mod;

ll ans=bigmod(n,pow/2);
ans=(ans*ans)%mod;

if(pow%2==1){ans=(ans*n)%mod;}
return ans%mod;
}

ll fact[1000005];

ll nCr(ll n,ll r){

ll ans=fact[n];
ans=(ans*bigmod(fact[r],mod-2))%mod;
ans=(ans*bigmod(fact[n-r],mod-2))%mod;
return ans;
}

string s[510],s1,s2;
ll n,m;
ll arr[510][510];
ll brr[500010];
vector<pi>v,v1;

map<ll,ll>mp;
ll vis[500005];

void fnc(ll x,ll y){
                        if(s[x][y]=='0'){v.push_back({x,y});s[x][y]='1';}
                        if(s[x+1][y]=='0'){v.push_back({x+1,y});s[x+1][y]='1';}
                        if(s[x][y+1]=='0'){v.push_back({x,y+1});s[x][y+1]='1';}
                        if(s[x+1][y+1]=='0'){v.push_back({x+1,y+1});s[x+1][y+1]='1';}
return ;
}

int main()
{__
        ll i,j,a,b,c,d,e,f,g,x,y,z,t,k,l,r;
        fact[0]=1;

      //  for(i=1;i<=1000000;i++) fact[i]=(fact[i-1]*i)%mod;
        ll ans=0,sum=0,temp,cnt=0;

        cin>>t;

        for(ll cz=0;cz<t;cz++){
            cin>>n>>m;

            for(i=0;i<n;i++){
                cin>>s[i];
            }
            v.clear();
            for(i=0;i<n-2;i++){
                for(j=0;j<m-1;j++){
                    if(j==m-2&&s[i][j]=='0'){
                        if(s[i][j+1]=='0'){
                            continue;
                        }
                        else{
                                v.push_back({i,j});v.push_back({i,j+1});
                                s[i][j]='0';
                                s[i][j+1]='0';
                                if(s[i+1][j]=='1') {s[i+1][j]='0';v.push_back({i+1,j});}
                                else {
                                 v.push_back({i+1,j+1});
                                 if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                                }
                        }
                    }
                    else{
                        if(s[i][j]=='0') continue;
                        else{
                            if(s[i][j+1]=='0'){
                                v.push_back({i,j}); v.push_back({i+1,j});v.push_back({i+1,j+1});
                                s[i][j]='0';
                                if(s[i+1][j]=='1') s[i+1][j]='0'; else s[i+1][j]='1';
                                if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                            }
                            else{
                                v.push_back({i,j});v.push_back({i,j+1});
                                s[i][j]='0';
                                s[i][j+1]='0';
                                if(s[i+1][j]=='1') {s[i+1][j]='0';v.push_back({i+1,j});}
                                else {
                                 v.push_back({i+1,j+1});
                                 if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                                }
                            }
                        }
                    }
                }
            }

                for(j=0;j<m-1;){
                    //if(s[i][j]=='0'&&j!=m-2&&i!=n-2) continue;
                    if(s[i][j]-'0'+s[i+1][j]-'0'+s[i][j+1]-'0'+s[i+1][j+1]-'0'==4){
                        if(s[i][j]=='1'){v.push_back({i,j});s[i][j]='0';}
                        if(s[i+1][j]=='1'){v.push_back({i+1,j});s[i+1][j]='0';}
                        if(s[i][j+1]=='1'){v.push_back({i,j+1});s[i][j+1]='0';}
                       // if(s[i+1][j+1]=='1'){v.push_back({i+1,j+1});s[i+1][j+1]='0';}
                       // j++;
                    }
                    else if(s[i][j]-'0'+s[i+1][j]-'0'+s[i][j+1]-'0'+s[i+1][j+1]-'0'==3){
                        if(s[i][j]=='1'){v.push_back({i,j});s[i][j]='0';}
                        if(s[i+1][j]=='1'){v.push_back({i+1,j});s[i+1][j]='0';}
                        if(s[i][j+1]=='1'){v.push_back({i,j+1});s[i][j+1]='0';}
                        if(s[i+1][j+1]=='1'){v.push_back({i+1,j+1});s[i+1][j+1]='0';}
                        j++; if(j!=m-2) j++;
                    }
                    else if(s[i][j]-'0'+s[i+1][j]-'0'+s[i][j+1]-'0'+s[i+1][j+1]-'0'==2){
                        if(s[i][j]=='1'){v.push_back({i,j});fnc(i,j);s[i][j]='0';}
                        else if(s[i+1][j]=='1'){v.push_back({i+1,j});fnc(i,j);s[i+1][j]='0';}
                        else if(s[i][j+1]=='1'){v.push_back({i,j+1});fnc(i,j);s[i][j+1]='0';}
                        else if(s[i+1][j+1]=='1'){v.push_back({i+1,j+1});fnc(i,j);s[i+1][j+1]='0';}
                    }
                    else if(s[i][j]-'0'+s[i+1][j]-'0'+s[i][j+1]-'0'+s[i+1][j+1]-'0'==1){
                        if(s[i][j]=='1'){v.push_back({i,j});v.push_back({i+1,j});v.push_back({i+1,j+1});s[i+1][j+1]='1';s[i+1][j]='1';s[i][j]='0';}
                        else if(s[i+1][j]=='1'){v.push_back({i,j});v.push_back({i+1,j});v.push_back({i+1,j+1});s[i+1][j+1]='1';s[i+1][j]='0';s[i][j]='1';}
                        else if(s[i][j+1]=='1'){v.push_back({i,j+1});v.push_back({i+1,j});v.push_back({i+1,j+1});s[i+1][j+1]='1';s[i+1][j]='1';s[i][j+1]='0';}
                        else if(s[i+1][j+1]=='1'){v.push_back({i,j});v.push_back({i+1,j});v.push_back({i+1,j+1});s[i+1][j+1]='0';s[i+1][j]='1';s[i][j]='1';}
                    }
                    else {j++;if(j!=m-2)j++;}

                //    cout<<s[0]<<endl<<s[1]<<endl<<endl;
                }

            cout<<v.size()/3<<endl;
            k=0;
            for(i=0;i<v.size()/3;i++){
                for(j=0;j<3;j++){
                    cout<<v[k].first+1<<" "<<v[k].second+1<<" ";
                    k++;
                }
                cout<<endl;
            }
            v.clear();
        }
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;

template<typename T>
using ordered_set=tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;

#define ll long long
#define ull unsigned long long
#define pi pair<ll,ll>
#define pii pair<ll,pi>
#define inf 1000000000000000000
#define iinf -1000000000000000000
#define __   ios_base::sync_with_stdio(0);cin.tie();cout.tie();
#define mod 1000000007
#define base 1949313259
#define en '\n'

ll Set(ll N,ll pos){ return N=N | (1LL<<pos); }
ll reset(ll N,ll pos){ return N= N & ~(1LL<<pos); }
bool check(ll N,ll pos){ return (bool)(N & (1LL<<pos)); }

ll ar[]={0,0,1,-1};
ll br[]={1,-1,0,0};

ll bigmod(ll n,ll pow){
if(pow==0) return 1;
if(pow==1) return n%mod;

ll ans=bigmod(n,pow/2);
ans=(ans*ans)%mod;

if(pow%2==1){ans=(ans*n)%mod;}
return ans%mod;
}

ll fact[1000005];

ll nCr(ll n,ll r){

ll ans=fact[n];
ans=(ans*bigmod(fact[r],mod-2))%mod;
ans=(ans*bigmod(fact[n-r],mod-2))%mod;
return ans;
}

string s[510],s1,s2;
ll n,m;
ll arr[510][510];
ll brr[500010];
vector<pi>v,v1;

map<ll,ll>mp;
ll vis[500005];

void fnc(ll x,ll y){
                        if(s[x][y]=='0'){v.push_back({x,y});s[x][y]='1';}
                        if(s[x+1][y]=='0'){v.push_back({x+1,y});s[x+1][y]='1';}
                        if(s[x][y+1]=='0'){v.push_back({x,y+1});s[x][y+1]='1';}
                        if(s[x+1][y+1]=='0'){v.push_back({x+1,y+1});s[x+1][y+1]='1';}
return ;
}

int main()
{__
        ll i,j,a,b,c,d,e,f,g,x,y,z,t,k,l,r;
        fact[0]=1;

      //  for(i=1;i<=1000000;i++) fact[i]=(fact[i-1]*i)%mod;
        ll ans=0,sum=0,temp,cnt=0;

        cin>>t;

        for(ll cz=0;cz<t;cz++){
            cin>>n>>m;

            for(i=0;i<n;i++){
                cin>>s[i];
            }
            v.clear();
            for(i=0;i<n-2;i++){
                for(j=0;j<m-1;j++){
                    if(j==m-2&&s[i][j]=='0'){
                        if(s[i][j+1]=='0'){
                            continue;
                        }
                        else{
                                v.push_back({i,j});v.push_back({i,j+1});
                                s[i][j]='0';
                                s[i][j+1]='0';
                                if(s[i+1][j]=='1') {s[i+1][j]='0';v.push_back({i+1,j});}
                                else {
                                 v.push_back({i+1,j+1});
                                 if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                                }
                        }
                    }
                    else{
                        if(s[i][j]=='0') continue;
                        else{
                            if(s[i][j+1]=='0'){
                                v.push_back({i,j}); v.push_back({i+1,j});v.push_back({i+1,j+1});
                                s[i][j]='0';
                                if(s[i+1][j]=='1') s[i+1][j]='0'; else s[i+1][j]='1';
                                if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                            }
                            else{
                                v.push_back({i,j});v.push_back({i,j+1});
                                s[i][j]='0';
                                s[i][j+1]='0';
                                if(s[i+1][j]=='1') {s[i+1][j]='0';v.push_back({i+1,j});}
                                else {
                                 v.push_back({i+1,j+1});
                                 if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                                }
                            }
                        }
                    }
                }
            }

                for(j=0;j<m-1;){

                    if(j!=m-2){
                        if(s[i][j]=='0'&&s[i+1][j]=='0') j++;
                        else if(s[i][j]=='0'&&s[i+1][j]=='1'){
                                v.push_back({i,j+1}); v.push_back({i+1,j});v.push_back({i+1,j+1});
                                s[i+1][j]='0';
                                if(s[i][j+1]=='1') s[i][j+1]='0'; else s[i][j+1]='1';
                                if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                        }
                        else if(s[i][j]=='1'&&s[i+1][j]=='0'){
                            v.push_back({i,j}); v.push_back({i+1,j});v.push_back({i+1,j+1});
                                s[i][j]='0';
                                if(s[i+1][j]=='1') s[i+1][j]='0'; else s[i+1][j]='1';
                                if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                        }
                        else{
                                v.push_back({i,j});v.push_back({i+1,j});
                                s[i][j]='0';
                                s[i+1][j]='0';
                                if(s[i][j+1]=='1') {s[i][j+1]='0';v.push_back({i,j+1});}
                                else {
                                 v.push_back({i+1,j+1});
                                 if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                                }
                        }
                    }
                    //if(s[i][j]=='0'&&j!=m-2&&i!=n-2) continue;
                    else if(s[i][j]-'0'+s[i+1][j]-'0'+s[i][j+1]-'0'+s[i+1][j+1]-'0'==4){
                        if(s[i][j]=='1'){v.push_back({i,j});s[i][j]='0';}
                        if(s[i+1][j]=='1'){v.push_back({i+1,j});s[i+1][j]='0';}
                        if(s[i][j+1]=='1'){v.push_back({i,j+1});s[i][j+1]='0';}
                       // if(s[i+1][j+1]=='1'){v.push_back({i+1,j+1});s[i+1][j+1]='0';}
                       // j++;
                    }
                    else if(s[i][j]-'0'+s[i+1][j]-'0'+s[i][j+1]-'0'+s[i+1][j+1]-'0'==3){
                        if(s[i][j]=='1'){v.push_back({i,j});s[i][j]='0';}
                        if(s[i+1][j]=='1'){v.push_back({i+1,j});s[i+1][j]='0';}
                        if(s[i][j+1]=='1'){v.push_back({i,j+1});s[i][j+1]='0';}
                        if(s[i+1][j+1]=='1'){v.push_back({i+1,j+1});s[i+1][j+1]='0';}
                        j++;
                    }
                    else if(s[i][j]-'0'+s[i+1][j]-'0'+s[i][j+1]-'0'+s[i+1][j+1]-'0'==2){
                        if(s[i][j]=='1'){v.push_back({i,j});fnc(i,j);s[i][j]='0';}
                        else if(s[i+1][j]=='1'){v.push_back({i+1,j});fnc(i,j);s[i+1][j]='0';}
                        else if(s[i][j+1]=='1'){v.push_back({i,j+1});fnc(i,j);s[i][j+1]='0';}
                        else if(s[i+1][j+1]=='1'){v.push_back({i+1,j+1});fnc(i,j);s[i+1][j+1]='0';}
                    }
                    else if(s[i][j]-'0'+s[i+1][j]-'0'+s[i][j+1]-'0'+s[i+1][j+1]-'0'==1){
                        if(s[i][j]=='1'){v.push_back({i,j});v.push_back({i+1,j});v.push_back({i+1,j+1});s[i+1][j+1]='1';s[i+1][j]='1';s[i][j]='0';}
                        else if(s[i+1][j]=='1'){v.push_back({i,j});v.push_back({i+1,j});v.push_back({i+1,j+1});s[i+1][j+1]='1';s[i+1][j]='0';s[i][j]='1';}
                        else if(s[i][j+1]=='1'){v.push_back({i,j+1});v.push_back({i+1,j});v.push_back({i+1,j+1});s[i+1][j+1]='1';s[i+1][j]='1';s[i][j+1]='0';}
                        else if(s[i+1][j+1]=='1'){v.push_back({i,j});v.push_back({i+1,j});v.push_back({i+1,j+1});s[i+1][j+1]='0';s[i+1][j]='1';s[i][j]='1';}
                    }
                    else {j++;}

                //    cout<<s[0]<<endl<<s[1]<<endl<<endl;
                }

            cout<<v.size()/3<<endl;
            k=0;
            for(i=0;i<v.size()/3;i++){
                for(j=0;j<3;j++){
                    cout<<v[k].first+1<<" "<<v[k].second+1<<" ";
                    k++;
                }
                cout<<endl;
            }
            v.clear();
        }
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;

template<typename T>
using ordered_set=tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;

#define ll long long
#define ull unsigned long long
#define pi pair<ll,ll>
#define pii pair<ll,pi>
#define inf 1000000000000000000
#define iinf -1000000000000000000
#define __   ios_base::sync_with_stdio(0);cin.tie();cout.tie();
#define mod 1000000007
#define base 1949313259
#define en '\n'

ll Set(ll N,ll pos){ return N=N | (1LL<<pos); }
ll reset(ll N,ll pos){ return N= N & ~(1LL<<pos); }
bool check(ll N,ll pos){ return (bool)(N & (1LL<<pos)); }

ll ar[]={0,0,1,-1};
ll br[]={1,-1,0,0};

ll bigmod(ll n,ll pow){
if(pow==0) return 1;
if(pow==1) return n%mod;

ll ans=bigmod(n,pow/2);
ans=(ans*ans)%mod;

if(pow%2==1){ans=(ans*n)%mod;}
return ans%mod;
}

ll fact[1000005];

ll nCr(ll n,ll r){

ll ans=fact[n];
ans=(ans*bigmod(fact[r],mod-2))%mod;
ans=(ans*bigmod(fact[n-r],mod-2))%mod;
return ans;
}

string s[510],s1,s2;
ll n,m;
ll arr[510][510];
ll brr[500010];
vector<pi>v,v1;

map<ll,ll>mp;
ll vis[500005];

void fnc(ll x,ll y){
                        if(s[x][y]=='0'){v.push_back({x,y});s[x][y]='1';}
                        if(s[x+1][y]=='0'){v.push_back({x+1,y});s[x+1][y]='1';}
                        if(s[x][y+1]=='0'){v.push_back({x,y+1});s[x][y+1]='1';}
                        if(s[x+1][y+1]=='0'){v.push_back({x+1,y+1});s[x+1][y+1]='1';}
return ;
}

int main()
{__
        ll i,j,a,b,c,d,e,f,g,x,y,z,t,k,l,r;
        fact[0]=1;

      //  for(i=1;i<=1000000;i++) fact[i]=(fact[i-1]*i)%mod;
        ll ans=0,sum=0,temp,cnt=0;

        cin>>t;

        for(ll cz=0;cz<t;cz++){
            cin>>n>>m;

            for(i=0;i<n;i++){
                cin>>s[i];
            }
            v.clear();
            for(i=0;i<n-2;i++){
                for(j=0;j<m-1;j++){
                    if(j==m-2&&s[i][j]=='0'){
                        if(s[i][j+1]=='0'){
                            continue;
                        }
                        else{
                                v.push_back({i+1,j});v.push_back({i,j+1});v.push_back({i+1,j+1});

                                s[i][j+1]='0';
                                if(s[i+1][j]=='1') {s[i+1][j]='0';} else s[i+1][j]='1';

                                if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';

                        }
                    }
                    else{
                        if(s[i][j]=='0') continue;
                        else{
                            if(s[i][j+1]=='0'){
                                v.push_back({i,j}); v.push_back({i+1,j});v.push_back({i+1,j+1});
                                s[i][j]='0';
                                if(s[i+1][j]=='1') s[i+1][j]='0'; else s[i+1][j]='1';
                                if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                            }
                            else{
                                v.push_back({i,j});v.push_back({i,j+1});
                                s[i][j]='0';
                                s[i][j+1]='0';
                                if(s[i+1][j]=='1') {s[i+1][j]='0';v.push_back({i+1,j});}
                                else {
                                 v.push_back({i+1,j+1});
                                 if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                                }
                            }
                        }
                    }
                }
            }

                for(j=0;j<m-1;){

                    if(j!=m-2){
                        if(s[i][j]=='0'&&s[i+1][j]=='0') j++;
                        else if(s[i][j]=='0'&&s[i+1][j]=='1'){
                                v.push_back({i,j+1}); v.push_back({i+1,j});v.push_back({i+1,j+1});
                                s[i+1][j]='0';
                                if(s[i][j+1]=='1') s[i][j+1]='0'; else s[i][j+1]='1';
                                if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                                j++;
                        }
                        else if(s[i][j]=='1'&&s[i+1][j]=='0'){
                            v.push_back({i,j}); v.push_back({i,j+1});v.push_back({i+1,j+1});
                                s[i][j]='0';
                                if(s[i][j+1]=='1') s[i][j+1]='0'; else s[i][j+1]='1';
                                if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                        j++;
                        }
                        else{
                                v.push_back({i,j});v.push_back({i+1,j});
                                s[i][j]='0';
                                s[i+1][j]='0';
                                if(s[i][j+1]=='1') {s[i][j+1]='0';v.push_back({i,j+1});}
                                else {
                                 v.push_back({i+1,j+1});
                                 if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                                }
                        j++;
                        }
                    }
                    //if(s[i][j]=='0'&&j!=m-2&&i!=n-2) continue;
                    else if(s[i][j]-'0'+s[i+1][j]-'0'+s[i][j+1]-'0'+s[i+1][j+1]-'0'==4){
                        if(s[i][j]=='1'){v.push_back({i,j});s[i][j]='0';}
                        if(s[i+1][j]=='1'){v.push_back({i+1,j});s[i+1][j]='0';}
                        if(s[i][j+1]=='1'){v.push_back({i,j+1});s[i][j+1]='0';}
                       // if(s[i+1][j+1]=='1'){v.push_back({i+1,j+1});s[i+1][j+1]='0';}
                       // j++;
                    }
                    else if(s[i][j]-'0'+s[i+1][j]-'0'+s[i][j+1]-'0'+s[i+1][j+1]-'0'==3){
                        if(s[i][j]=='1'){v.push_back({i,j});s[i][j]='0';}
                        if(s[i+1][j]=='1'){v.push_back({i+1,j});s[i+1][j]='0';}
                        if(s[i][j+1]=='1'){v.push_back({i,j+1});s[i][j+1]='0';}
                        if(s[i+1][j+1]=='1'){v.push_back({i+1,j+1});s[i+1][j+1]='0';}
                        j++;
                    }
                    else if(s[i][j]-'0'+s[i+1][j]-'0'+s[i][j+1]-'0'+s[i+1][j+1]-'0'==2){
                        if(s[i][j]=='1'){v.push_back({i,j});fnc(i,j);s[i][j]='0';}
                        else if(s[i+1][j]=='1'){v.push_back({i+1,j});fnc(i,j);s[i+1][j]='0';}
                        else if(s[i][j+1]=='1'){v.push_back({i,j+1});fnc(i,j);s[i][j+1]='0';}
                        else if(s[i+1][j+1]=='1'){v.push_back({i+1,j+1});fnc(i,j);s[i+1][j+1]='0';}
                    }
                    else if(s[i][j]-'0'+s[i+1][j]-'0'+s[i][j+1]-'0'+s[i+1][j+1]-'0'==1){
                        if(s[i][j]=='1'){v.push_back({i,j});v.push_back({i+1,j});v.push_back({i+1,j+1});s[i+1][j+1]='1';s[i+1][j]='1';s[i][j]='0';}
                        else if(s[i+1][j]=='1'){v.push_back({i,j});v.push_back({i+1,j});v.push_back({i+1,j+1});s[i+1][j+1]='1';s[i+1][j]='0';s[i][j]='1';}
                        else if(s[i][j+1]=='1'){v.push_back({i,j+1});v.push_back({i+1,j});v.push_back({i+1,j+1});s[i+1][j+1]='1';s[i+1][j]='1';s[i][j+1]='0';}
                        else if(s[i+1][j+1]=='1'){v.push_back({i,j});v.push_back({i+1,j});v.push_back({i+1,j+1});s[i+1][j+1]='0';s[i+1][j]='1';s[i][j]='1';}
                    }
                    else {j++;}

                   // cout<<s[0]<<endl<<s[1]<<endl<<endl;
                }

            cout<<v.size()/3<<endl;
            k=0;
            for(i=0;i<v.size()/3;i++){
                for(j=0;j<3;j++){
                    cout<<v[k].first+1<<" "<<v[k].second+1<<" ";
                    k++;
                }
                cout<<endl;
            }
            v.clear();
        }
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;

template<typename T>
using ordered_set=tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;

#define ll long long
#define ull unsigned long long
#define pi pair<ll,ll>
#define pii pair<ll,pi>
#define inf 1000000000000000000
#define iinf -1000000000000000000
#define __   ios_base::sync_with_stdio(0);cin.tie();cout.tie();
#define mod 1000000007
#define base 1949313259
#define en '\n'

ll Set(ll N,ll pos){ return N=N | (1LL<<pos); }
ll reset(ll N,ll pos){ return N= N & ~(1LL<<pos); }
bool check(ll N,ll pos){ return (bool)(N & (1LL<<pos)); }

ll ar[]={0,0,1,-1};
ll br[]={1,-1,0,0};

ll bigmod(ll n,ll pow){
if(pow==0) return 1;
if(pow==1) return n%mod;

ll ans=bigmod(n,pow/2);
ans=(ans*ans)%mod;

if(pow%2==1){ans=(ans*n)%mod;}
return ans%mod;
}

ll fact[1000005];

ll nCr(ll n,ll r){

ll ans=fact[n];
ans=(ans*bigmod(fact[r],mod-2))%mod;
ans=(ans*bigmod(fact[n-r],mod-2))%mod;
return ans;
}

string s[510],s1,s2;
ll n,m;
ll arr[510][510];
ll brr[500010];
vector<pi>v,v1;

map<ll,ll>mp;
ll vis[500005];

void fnc(ll x,ll y){
                        if(s[x][y]=='0'){v.push_back({x,y});s[x][y]='1';}
                        if(s[x+1][y]=='0'){v.push_back({x+1,y});s[x+1][y]='1';}
                        if(s[x][y+1]=='0'){v.push_back({x,y+1});s[x][y+1]='1';}
                        if(s[x+1][y+1]=='0'){v.push_back({x+1,y+1});s[x+1][y+1]='1';}
return ;
}

int main()
{__
        ll i,j,a,b,c,d,e,f,g,x,y,z,t,k,l,r;
        fact[0]=1;

      //  for(i=1;i<=1000000;i++) fact[i]=(fact[i-1]*i)%mod;
        ll ans=0,sum=0,temp,cnt=0;

        cin>>t;

        for(ll cz=0;cz<t;cz++){
            cin>>n>>m;

            for(i=0;i<n;i++){
                cin>>s[i];
            }
            v.clear();
            for(i=0;i<n-2;i++){
                for(j=0;j<m-1;j++){
                    if(j==m-2&&s[i][j]=='0'){
                        if(s[i][j+1]=='0'){
                            continue;
                        }
                        else{
                                v.push_back({i,j});v.push_back({i,j+1});
                                s[i][j]='0';
                                s[i][j+1]='0';
                                if(s[i+1][j]=='1') {s[i+1][j]='0';v.push_back({i+1,j});}
                                else {
                                 v.push_back({i+1,j+1});
                                 if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                                }
                        }
                    }
                    else{
                        if(s[i][j]=='0') continue;
                        else{
                            if(s[i][j+1]=='0'){
                                v.push_back({i,j}); v.push_back({i+1,j});v.push_back({i+1,j+1});
                                s[i][j]='0';
                                if(s[i+1][j]=='1') s[i+1][j]='0'; else s[i+1][j]='1';
                                if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                            }
                            else{
                                v.push_back({i,j});v.push_back({i,j+1});
                                s[i][j]='0';
                                s[i][j+1]='0';
                                if(s[i+1][j]=='1') {s[i+1][j]='0';v.push_back({i+1,j});}
                                else {
                                 v.push_back({i+1,j+1});
                                 if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                                }
                            }
                        }
                    }
                }
            }

                for(j=0;j<m-1;){

                    if(j!=m-2){
                        if(s[i][j]=='0'&&s[i+1][j]=='0') j++;
                        else if(s[i][j]=='0'&&s[i+1][j]=='1'){
                                v.push_back({i,j+1}); v.push_back({i+1,j});v.push_back({i+1,j+1});
                                s[i+1][j]='0';
                                if(s[i][j+1]=='1') s[i][j+1]='0'; else s[i][j+1]='1';
                                if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                                j++;
                        }
                        else if(s[i][j]=='1'&&s[i+1][j]=='0'){
                            v.push_back({i,j}); v.push_back({i,j+1});v.push_back({i+1,j+1});
                                s[i][j]='0';
                                if(s[i][j+1]=='1') s[i][j+1]='0'; else s[i][j+1]='1';
                                if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                        j++;
                        }
                        else{
                                v.push_back({i,j});v.push_back({i+1,j});
                                s[i][j]='0';
                                s[i+1][j]='0';
                                if(s[i][j+1]=='1') {s[i][j+1]='0';v.push_back({i,j+1});}
                                else {
                                 v.push_back({i+1,j+1});
                                 if(s[i+1][j+1]=='1') s[i+1][j+1]='0'; else s[i+1][j+1]='1';
                                }
                        j++;
                        }
                    }
                    //if(s[i][j]=='0'&&j!=m-2&&i!=n-2) continue;
                    else if(s[i][j]-'0'+s[i+1][j]-'0'+s[i][j+1]-'0'+s[i+1][j+1]-'0'==4){
                        if(s[i][j]=='1'){v.push_back({i,j});s[i][j]='0';}
                        if(s[i+1][j]=='1'){v.push_back({i+1,j});s[i+1][j]='0';}
                        if(s[i][j+1]=='1'){v.push_back({i,j+1});s[i][j+1]='0';}
                       // if(s[i+1][j+1]=='1'){v.push_back({i+1,j+1});s[i+1][j+1]='0';}
                       // j++;
                    }
                    else if(s[i][j]-'0'+s[i+1][j]-'0'+s[i][j+1]-'0'+s[i+1][j+1]-'0'==3){
                        if(s[i][j]=='1'){v.push_back({i,j});s[i][j]='0';}
                        if(s[i+1][j]=='1'){v.push_back({i+1,j});s[i+1][j]='0';}
                        if(s[i][j+1]=='1'){v.push_back({i,j+1});s[i][j+1]='0';}
                        if(s[i+1][j+1]=='1'){v.push_back({i+1,j+1});s[i+1][j+1]='0';}
                        j++;
                    }
                    else if(s[i][j]-'0'+s[i+1][j]-'0'+s[i][j+1]-'0'+s[i+1][j+1]-'0'==2){
                        if(s[i][j]=='1'){v.push_back({i,j});fnc(i,j);s[i][j]='0';}
                        else if(s[i+1][j]=='1'){v.push_back({i+1,j});fnc(i,j);s[i+1][j]='0';}
                        else if(s[i][j+1]=='1'){v.push_back({i,j+1});fnc(i,j);s[i][j+1]='0';}
                        else if(s[i+1][j+1]=='1'){v.push_back({i+1,j+1});fnc(i,j);s[i+1][j+1]='0';}
                    }
                    else if(s[i][j]-'0'+s[i+1][j]-'0'+s[i][j+1]-'0'+s[i+1][j+1]-'0'==1){
                        if(s[i][j]=='1'){v.push_back({i,j});v.push_back({i+1,j});v.push_back({i+1,j+1});s[i+1][j+1]='1';s[i+1][j]='1';s[i][j]='0';}
                        else if(s[i+1][j]=='1'){v.push_back({i,j});v.push_back({i+1,j});v.push_back({i+1,j+1});s[i+1][j+1]='1';s[i+1][j]='0';s[i][j]='1';}
                        else if(s[i][j+1]=='1'){v.push_back({i,j+1});v.push_back({i+1,j});v.push_back({i+1,j+1});s[i+1][j+1]='1';s[i+1][j]='1';s[i][j+1]='0';}
                        else if(s[i+1][j+1]=='1'){v.push_back({i,j});v.push_back({i+1,j});v.push_back({i+1,j+1});s[i+1][j+1]='0';s[i+1][j]='1';s[i][j]='1';}
                    }
                    else {j++;}

                   // cout<<s[0]<<endl<<s[1]<<endl<<endl;
                }

            cout<<v.size()/3<<endl;
            k=0;
            for(i=0;i<v.size()/3;i++){
                for(j=0;j<3;j++){
                    cout<<v[k].first+1<<" "<<v[k].second+1<<" ";
                    k++;
                }
                cout<<endl;
            }
            v.clear();
        }
}


#include <bits/stdc++.h>

class Solver {
 public:
  Solver() {
    scanf("%d%d", &n_, &m_);
    grid_.reserve(n_);
    for (int i = 0; i < n_; ++i) {
      std::string str;
      std::cin >> str;
      grid_.emplace_back(str);
    }
  }

  void Solve() {
    for (int x = 0; x + 1 < n_; x += 2) {
      for (int y = 0; y + 1 < m_; y += 2) {
        SolveSubGrid(x, y);
      }
    }
    for (int x = n_ - 2; x >= 0; x -= 2) {
      for (int y = m_ - 2; y >= 0; y -= 2) {
        SolveSubGrid(x, y);
      }
    }
    printf("%d\n", static_cast<int>(ans_.size()));
    for (const auto &item : ans_) {
      printf("%d %d %d %d %d %d\n",
             std::get<0>(item),
             std::get<1>(item),
             std::get<2>(item),
             std::get<3>(item),
             std::get<4>(item),
             std::get<5>(item));
    }
  }

 private:
  void SolveSubGrid(int x, int y) {
    std::vector<std::pair<int, int>> black;
    std::vector<std::pair<int, int>> white;
    for (int dx = 0; dx < 2; ++dx) {
      for (int dy = 0; dy < 2; ++dy) {
        if (grid_[x + dx][y + dy] == '1') {
          black.emplace_back(x + dx + 1, y + dy + 1);
        } else {
          white.emplace_back(x + dx + 1, y + dy + 1);
        }
        grid_[x + dx][y + dy] = '0';
      }
    }
    switch (black.size()) {
      case 1: {
        for (int i = 0; i < 3; ++i) {
          ans_.emplace_back(black[0].first,
                            black[0].second,
                            white[i].first,
                            white[i].second,
                            white[(i + 1) % 3].first,
                            white[(i + 1) % 3].second);
        }
        break;
      }
      case 2: {
        for (int i = 0; i < 2; ++i) {
          ans_.emplace_back(
              black[i].first,
              black[i].second,
              white[0].first,
              white[0].second,
              white[1].first,
              white[1].second);
        }
        break;
      }
      case 3: {
        ans_.emplace_back(
            black[0].first,
            black[0].second,
            black[1].first,
            black[1].second,
            black[2].first,
            black[2].second);
        break;
      }
      case 4: {
        ans_.emplace_back(
            black[0].first,
            black[0].second,
            black[1].first,
            black[1].second,
            black[2].first,
            black[2].second);
        ans_.emplace_back(
            black[0].first,
            black[0].second,
            black[2].first,
            black[2].second,
            black[3].first,
            black[3].second);
        ans_.emplace_back(
            black[0].first,
            black[0].second,
            black[1].first,
            black[1].second,
            black[3].first,
            black[3].second);
        ans_.emplace_back(
            black[1].first,
            black[1].second,
            black[2].first,
            black[2].second,
            black[3].first,
            black[3].second);
        break;
      }
    }
  }

  int n_, m_;
  std::vector<std::string> grid_;
  std::vector<std::tuple<int, int, int, int, int, int>> ans_;
};

int main() {
  int t;
  scanf("%d", &t);
  while (t--) {
    Solver solver;
    solver.Solve();
  }
}


#include <bits/stdc++.h>

class Solver {
 public:
  Solver() {
    scanf("%d%d", &n_, &m_);
    grid_.reserve(n_);
    for (int i = 0; i < n_; ++i) {
      std::string str;
      std::cin >> str;
      grid_.emplace_back(str);
    }
  }

  void Solve() {
    for (int x = 0; x + 1 < n_; x += 2) {
      for (int y = 0; y + 1 < m_; y += 2) {
        SolveSubGrid(x, y);
      }
    }
    if (n_ & 1) {
      for (int y = 0; y + 1 < m_; y += 2) {
        SolveSubGrid(n_ - 2, y);
      }
    }
    if (m_ & 1) {
      for (int x = 0; x + 1 < n_; x += 2) {
        SolveSubGrid(x, m_ - 2);
      }
    }
    if ((n_ & 1) && (m_ & 1)) {
      SolveSubGrid(n_ - 2, m_ - 2);
    }
    printf("%d\n", static_cast<int>(ans_.size()));
    for (const auto &item : ans_) {
      printf("%d %d %d %d %d %d\n",
             std::get<0>(item),
             std::get<1>(item),
             std::get<2>(item),
             std::get<3>(item),
             std::get<4>(item),
             std::get<5>(item));
    }
  }

 private:
  void SolveSubGrid(int x, int y) {
    std::vector<std::pair<int, int>> black;
    std::vector<std::pair<int, int>> white;
    for (int dx = 0; dx < 2; ++dx) {
      for (int dy = 0; dy < 2; ++dy) {
        if (grid_[x + dx][y + dy] == '1') {
          black.emplace_back(x + dx + 1, y + dy + 1);
        } else {
          white.emplace_back(x + dx + 1, y + dy + 1);
        }
        grid_[x + dx][y + dy] = '0';
      }
    }
    switch (black.size()) {
      case 1: {
        for (int i = 0; i < 3; ++i) {
          ans_.emplace_back(black[0].first,
                            black[0].second,
                            white[i].first,
                            white[i].second,
                            white[(i + 1) % 3].first,
                            white[(i + 1) % 3].second);
        }
        break;
      }
      case 2: {
        for (int i = 0; i < 2; ++i) {
          ans_.emplace_back(
              black[i].first,
              black[i].second,
              white[0].first,
              white[0].second,
              white[1].first,
              white[1].second);
        }
        break;
      }
      case 3: {
        ans_.emplace_back(
            black[0].first,
            black[0].second,
            black[1].first,
            black[1].second,
            black[2].first,
            black[2].second);
        break;
      }
      case 4: {
        ans_.emplace_back(
            black[0].first,
            black[0].second,
            black[1].first,
            black[1].second,
            black[2].first,
            black[2].second);
        ans_.emplace_back(
            black[0].first,
            black[0].second,
            black[2].first,
            black[2].second,
            black[3].first,
            black[3].second);
        ans_.emplace_back(
            black[0].first,
            black[0].second,
            black[1].first,
            black[1].second,
            black[3].first,
            black[3].second);
        ans_.emplace_back(
            black[1].first,
            black[1].second,
            black[2].first,
            black[2].second,
            black[3].first,
            black[3].second);
        break;
      }
    }
  }

  int n_, m_;
  std::vector<std::string> grid_;
  std::vector<std::tuple<int, int, int, int, int, int>> ans_;
};

int main() {
  int t;
  scanf("%d", &t);
  while (t--) {
    Solver solver;
    solver.Solve();
  }
}


#include <bits/stdc++.h>

class Solver {
 public:
  Solver() {
    scanf("%d%d", &n_, &m_);
    grid_.reserve(n_);
    for (int i = 0; i < n_; ++i) {
      std::string str;
      std::cin >> str;
      grid_.emplace_back(str);
    }
  }

  void Solve() {
    for (int x = 0; x + 1 < n_; ++x) {
      for (int y = 0; y + 1 < m_; ++y) {
        SolveSubGrid(x, y);
      }
    }
    printf("%d\n", static_cast<int>(ans_.size()));
    for (const auto &item : ans_) {
      printf("%d %d %d %d %d %d\n",
             std::get<0>(item),
             std::get<1>(item),
             std::get<2>(item),
             std::get<3>(item),
             std::get<4>(item),
             std::get<5>(item));
    }
  }

 private:
  void SolveSubGrid(int x, int y) {
    std::vector<std::pair<int, int>> black;
    std::vector<std::pair<int, int>> white;
    for (int dx = 0; dx < 2; ++dx) {
      for (int dy = 0; dy < 2; ++dy) {
        if (grid_[x + dx][y + dy] == '1') {
          black.emplace_back(x + dx + 1, y + dy + 1);
        } else {
          white.emplace_back(x + dx + 1, y + dy + 1);
        }
        grid_[x + dx][y + dy] = '0';
      }
    }
    switch (black.size()) {
      case 1: {
        for (int i = 0; i < 3; ++i) {
          ans_.emplace_back(black[0].first,
                            black[0].second,
                            white[i].first,
                            white[i].second,
                            white[(i + 1) % 3].first,
                            white[(i + 1) % 3].second);
        }
        break;
      }
      case 2: {
        for (int i = 0; i < 2; ++i) {
          ans_.emplace_back(
              black[i].first,
              black[i].second,
              white[0].first,
              white[0].second,
              white[1].first,
              white[1].second);
        }
        break;
      }
      case 3: {
        ans_.emplace_back(
            black[0].first,
            black[0].second,
            black[1].first,
            black[1].second,
            black[2].first,
            black[2].second);
        break;
      }
      case 4: {
        ans_.emplace_back(
            black[0].first,
            black[0].second,
            black[1].first,
            black[1].second,
            black[2].first,
            black[2].second);
        ans_.emplace_back(
            black[0].first,
            black[0].second,
            black[2].first,
            black[2].second,
            black[3].first,
            black[3].second);
        ans_.emplace_back(
            black[0].first,
            black[0].second,
            black[1].first,
            black[1].second,
            black[3].first,
            black[3].second);
        ans_.emplace_back(
            black[1].first,
            black[1].second,
            black[2].first,
            black[2].second,
            black[3].first,
            black[3].second);
        break;
      }
    }
  }

  int n_, m_;
  std::vector<std::string> grid_;
  std::vector<std::tuple<int, int, int, int, int, int>> ans_;
};

int main() {
  int t;
  scanf("%d", &t);
  while (t--) {
    Solver solver;
    solver.Solve();
  }
}


#include <bits/stdc++.h>

class Solver {
 public:
  Solver() {
    scanf("%d%d", &n_, &m_);
    grid_.reserve(n_);
    for (int i = 0; i < n_; ++i) {
      std::string str;
      std::cin >> str;
      grid_.emplace_back(str);
    }
  }

  void Solve() {
    for (int x = n_ - 1; x >= 2; --x) {
      for (int y = 0; y + 1 < m_; ++y) {
        if (grid_[x][y] == '0') {
          continue;
        }
        ans_.emplace_back(x + 1, y + 1, x, y + 1, x, y + 2);
        Flip(x, y);
        Flip(x - 1, y);
        Flip(x - 1, y + 1);
      }
      if (grid_[x][m_ - 1] == '1') {
        ans_.emplace_back(x + 1, m_, x, m_ - 1, x, m_);
        Flip(x, m_ - 1);
        Flip(x - 1, m_ - 1);
        Flip(x - 1, m_ - 2);
      }
    }
    for (int y = m_ - 1; y >= 2; --y) {
      if (grid_[0][y] == '1') {
        ans_.emplace_back(1, y + 1, 1, y, 2, y);
        Flip(0, y);
        Flip(0, y - 1);
        Flip(1, y - 1);
      }
      if (grid_[1][y] == '1') {
        ans_.emplace_back(2, y + 1, 1, y, 2, y);
        Flip(1, y);
        Flip(0, y - 1);
        Flip(1, y - 1);
      }
    }
    SolveSubGrid(0, 0);
    printf("%d\n", static_cast<int>(ans_.size()));
    for (const auto &item : ans_) {
      printf("%d %d %d %d %d %d\n",
             std::get<0>(item),
             std::get<1>(item),
             std::get<2>(item),
             std::get<3>(item),
             std::get<4>(item),
             std::get<5>(item));
    }
  }

 private:
  void Flip(int x, int y) {
    if (grid_[x][y] == '0') {
      grid_[x][y] = '1';
    } else {
      grid_[x][y] = '0';
    }
  }

  void SolveSubGrid(int x, int y) {
    std::vector<std::pair<int, int>> black;
    std::vector<std::pair<int, int>> white;
    for (int dx = 0; dx < 2; ++dx) {
      for (int dy = 0; dy < 2; ++dy) {
        if (grid_[x + dx][y + dy] == '1') {
          black.emplace_back(x + dx + 1, y + dy + 1);
        } else {
          white.emplace_back(x + dx + 1, y + dy + 1);
        }
        grid_[x + dx][y + dy] = '0';
      }
    }
    switch (black.size()) {
      case 1: {
        for (int i = 0; i < 3; ++i) {
          ans_.emplace_back(black[0].first,
                            black[0].second,
                            white[i].first,
                            white[i].second,
                            white[(i + 1) % 3].first,
                            white[(i + 1) % 3].second);
        }
        break;
      }
      case 2: {
        for (int i = 0; i < 2; ++i) {
          ans_.emplace_back(
              black[i].first,
              black[i].second,
              white[0].first,
              white[0].second,
              white[1].first,
              white[1].second);
        }
        break;
      }
      case 3: {
        ans_.emplace_back(
            black[0].first,
            black[0].second,
            black[1].first,
            black[1].second,
            black[2].first,
            black[2].second);
        break;
      }
      case 4: {
        ans_.emplace_back(
            black[0].first,
            black[0].second,
            black[1].first,
            black[1].second,
            black[2].first,
            black[2].second);
        ans_.emplace_back(
            black[0].first,
            black[0].second,
            black[2].first,
            black[2].second,
            black[3].first,
            black[3].second);
        ans_.emplace_back(
            black[0].first,
            black[0].second,
            black[1].first,
            black[1].second,
            black[3].first,
            black[3].second);
        ans_.emplace_back(
            black[1].first,
            black[1].second,
            black[2].first,
            black[2].second,
            black[3].first,
            black[3].second);
        break;
      }
    }
  }

  int n_, m_;
  std::vector<std::string> grid_;
  std::vector<std::tuple<int, int, int, int, int, int>> ans_;
};

int main() {
  int t;
  scanf("%d", &t);
  while (t--) {
    Solver solver;
    solver.Solve();
  }
}


#include <stdio.h>
#include <memory.h>
#include <stack>
#include <queue>
#include <deque>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
const int INF = 1e9;
const int MOD = 1e9 + 7;

char input[110][110];
int arr[110][110];
vector< vector<int> > ans;

void make_up0(int x, int y){
	if (arr[x][y] == 0 && arr[x][y + 1] == 0) return;
	if (arr[x][y] == 0){
		ans.push_back({ x, y + 1, x + 1, y, x + 1, y + 1 });
		arr[x][y + 1] ^= 1;
		arr[x + 1][y] ^= 1;
		arr[x + 1][y + 1] ^= 1;
		return;
	}
	if (arr[x][y + 1] == 0){
		ans.push_back({ x, y, x + 1, y, x + 1, y + 1 });
		arr[x][y] ^= 1;
		arr[x + 1][y] ^= 1;
		arr[x + 1][y + 1] ^= 1;
		return;
	}
	ans.push_back({ x, y, x, y + 1, x + 1, y + 1 });
	arr[x][y] ^= 1;
	arr[x][y + 1] ^= 1;
	arr[x + 1][y + 1] ^= 1;
}

void make_le0(int x, int y){
	if (arr[x][y] == 0 && arr[x + 1][y] == 0) return;
	if (arr[x][y] == 0){
		ans.push_back({ x + 1, y, x, y + 1, x + 1, y + 1 });
		arr[x + 1][y] ^= 1;
		arr[x][y + 1] ^= 1;
		arr[x + 1][y + 1] ^= 1;
		return;
	}
	if (arr[x + 1][y] == 0){
		ans.push_back({ x, y, x, y + 1, x + 1, y + 1 });
		arr[x][y] ^= 1;
		arr[x][y + 1] ^= 1;
		arr[x + 1][y + 1] ^= 1;
		return;
	}
	ans.push_back({ x, y, x + 1, y, x + 1, y + 1 });
	arr[x][y] ^= 1;
	arr[x + 1][y] ^= 1;
	arr[x + 1][y + 1] ^= 1;
}

void last(int x, int y){
	int dx[] = { 0, 0, 1, 1 };
	int dy[] = { 0, 1, 0, 1 };

	while (1){
		int sum = arr[x][y] + arr[x][y + 1] + arr[x + 1][y] + arr[x + 1][y + 1];
		if (sum == 0) break;
		ans.push_back(vector<int>());

		if (sum == 4){
			for (int d = 0; d < 3; d++){
				arr[x + dx[d]][y + dy[d]] ^= 1;
				ans.back().push_back(x + dx[d]);
				ans.back().push_back(y + dy[d]);
			}
		}
		if (sum == 1){
			for (int d = 0; d < 4; d++){
				int nx = x + dx[d];
				int ny = y + dy[d];
				if (arr[nx][ny] == 1){
					arr[nx][ny] ^= 1;
					ans.back().push_back(nx);
					ans.back().push_back(ny);
					break;
				}
			}
			int tmp = 2;
			for (int d = 0; d < 4; d++){
				if (tmp == 0) break;
				int nx = x + dx[d];
				int ny = y + dy[d];
				if (arr[nx][ny] == 0){
					arr[nx][ny] ^= 1;
					ans.back().push_back(nx);
					ans.back().push_back(ny);
					tmp--;
				}
			}
		}
		if (sum == 2){
			for (int d = 0; d < 4; d++){
				int nx = x + dx[d];
				int ny = y + dy[d];
				if (arr[nx][ny] == 0){
					arr[nx][ny] ^= 1;
					ans.back().push_back(nx);
					ans.back().push_back(ny);
				}
			}
			for (int d = 0; d < 4; d++){
				int nx = x + dx[d];
				int ny = y + dy[d];
				if (arr[nx][ny] == 1){
					arr[nx][ny] ^= 1;
					ans.back().push_back(nx);
					ans.back().push_back(ny);
					break;
				}
			}
		}
		if (sum == 3){
			int tmp = 3;
			for (int d = 0; d < 4; d++){
				if (tmp == 0) break;
				int nx = x + dx[d];
				int ny = y + dy[d];
				if (arr[nx][ny] == 1){
					arr[nx][ny] ^= 1;
					ans.back().push_back(nx);
					ans.back().push_back(ny);
					tmp--;
				}
			}
		}
	}
}

int main()
{
	int t;

	scanf("%d", &t);

	while (t--){
		int n, m;

		ans.clear();

		scanf("%d %d", &n, &m);
		for (int i = 0; i < n; i++){
			scanf("%s", input[i]);
			for (int j = 0; j < m; j++){
				arr[i][j] = input[i][j] - '0';
			}
		}

		for (int i = 0; i < n - 2; i++){
			for (int j = 0; j < m - 1; j++){
				make_up0(i, j);
			}
		}

		for (int j = 0; j < m - 2; j++){
			make_le0(n - 2, j);
		}

		last(n - 2, m - 2);

		printf("%d\n", ans.size());
		for (int i = 0; i < ans.size(); i++){
			for (int j = 0; j < 6; j++){
				printf("%d ", ans[i][j] + 1);
			}
			printf("\n");
		}
	}

	return 0;
}


#include <stdio.h>
#include <memory.h>
#include <stack>
#include <queue>
#include <deque>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
const int INF = 1e9;
const int MOD = 1e9 + 7;

char input[110][110];
int arr[110][110];
vector< vector<int> > ans;

void make_up0(int x, int y){
	if (arr[x][y] == 0 && arr[x][y + 1] == 0) return;
	if (arr[x][y] == 0){
		ans.push_back({ x, y + 1, x + 1, y, x + 1, y + 1 });
		arr[x][y + 1] ^= 1;
		arr[x + 1][y] ^= 1;
		arr[x + 1][y + 1] ^= 1;
		return;
	}
	if (arr[x][y + 1] == 0){
		ans.push_back({ x, y, x + 1, y, x + 1, y + 1 });
		arr[x][y] ^= 1;
		arr[x + 1][y] ^= 1;
		arr[x + 1][y + 1] ^= 1;
		return;
	}
	ans.push_back({ x, y, x, y + 1, x + 1, y + 1 });
	arr[x][y] ^= 1;
	arr[x][y + 1] ^= 1;
	arr[x + 1][y + 1] ^= 1;
}

void make_le0(int x, int y){
	if (arr[x][y] == 0 && arr[x + 1][y] == 0) return;
	if (arr[x][y] == 0){
		ans.push_back({ x + 1, y, x, y + 1, x + 1, y + 1 });
		arr[x + 1][y] ^= 1;
		arr[x][y + 1] ^= 1;
		arr[x + 1][y + 1] ^= 1;
		return;
	}
	if (arr[x + 1][y] == 0){
		ans.push_back({ x, y, x, y + 1, x + 1, y + 1 });
		arr[x][y] ^= 1;
		arr[x][y + 1] ^= 1;
		arr[x + 1][y + 1] ^= 1;
		return;
	}
	ans.push_back({ x, y, x + 1, y, x + 1, y + 1 });
	arr[x][y] ^= 1;
	arr[x + 1][y] ^= 1;
	arr[x + 1][y + 1] ^= 1;
}

void last(int x, int y){
	int dx[] = { 0, 0, 1, 1 };
	int dy[] = { 0, 1, 0, 1 };

	while (1){
		int sum = arr[x][y] + arr[x][y + 1] + arr[x + 1][y] + arr[x + 1][y + 1];
		if (sum == 0) break;
		ans.push_back(vector<int>());

		if (sum == 4){
			for (int d = 0; d < 3; d++){
				arr[x + dx[d]][y + dy[d]] ^= 1;
				ans.back().push_back(x + dx[d]);
				ans.back().push_back(y + dy[d]);
			}
		}
		if (sum == 1){
			for (int d = 0; d < 4; d++){
				int nx = x + dx[d];
				int ny = y + dy[d];
				if (arr[nx][ny] == 1){
					//arr[nx][ny] ^= 1;
					ans.back().push_back(nx);
					ans.back().push_back(ny);
					break;
				}
			}
			int tmp = 2;
			for (int d = 0; d < 4; d++){
				if (tmp == 0) break;
				int nx = x + dx[d];
				int ny = y + dy[d];
				if (arr[nx][ny] == 0){
					//arr[nx][ny] ^= 1;
					ans.back().push_back(nx);
					ans.back().push_back(ny);
					tmp--;
				}
			}
			for (int i = 0; i < 3; i++){
				int nx = ans.back()[i * 2];
				int ny = ans.back()[i * 2 + 1];
				arr[nx][ny] ^= 1;
			}
		}
		if (sum == 2){
			for (int d = 0; d < 4; d++){
				int nx = x + dx[d];
				int ny = y + dy[d];
				if (arr[nx][ny] == 0){
					//arr[nx][ny] ^= 1;
					ans.back().push_back(nx);
					ans.back().push_back(ny);
				}
			}
			for (int d = 0; d < 4; d++){
				int nx = x + dx[d];
				int ny = y + dy[d];
				if (arr[nx][ny] == 1){
					//arr[nx][ny] ^= 1;
					ans.back().push_back(nx);
					ans.back().push_back(ny);
					break;
				}
			}
			for (int i = 0; i < 3; i++){
				int nx = ans.back()[i * 2];
				int ny = ans.back()[i * 2 + 1];
				arr[nx][ny] ^= 1;
			}
		}
		if (sum == 3){
			for (int d = 0; d < 4; d++){
				int nx = x + dx[d];
				int ny = y + dy[d];
				if (arr[nx][ny] == 1){
					arr[nx][ny] ^= 1;
					ans.back().push_back(nx);
					ans.back().push_back(ny);
				}
			}
		}
	}
}

int main()
{
	int t;

	scanf("%d", &t);

	while (t--){
		int n, m;

		ans.clear();

		scanf("%d %d", &n, &m);
		for (int i = 0; i < n; i++){
			scanf("%s", input[i]);
			for (int j = 0; j < m; j++){
				arr[i][j] = input[i][j] - '0';
			}
		}

		for (int i = 0; i < n - 2; i++){
			for (int j = 0; j < m - 1; j++){
				make_up0(i, j);
			}
		}

		for (int j = 0; j < m - 2; j++){
			make_le0(n - 2, j);
		}

		last(n - 2, m - 2);

		printf("%d\n", ans.size());
		for (int i = 0; i < ans.size(); i++){
			for (int j = 0; j < 6; j++){
				printf("%d ", ans[i][j] + 1);
			}
			printf("\n");
		}
	}

	return 0;
}


/* In the name of Allah */

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define pii pair<int, int>
#define pll pair<long long, long long>
#define pb push_back
#define YES printf("YES\n")
#define NO printf("NO\n")
#define LL_INF 1LL << 62
#define INF 1 << 30
#define SetBit(x, k) (x |= (1LL << k))
#define ClearBit(x, k) (x &= ~(1LL << k))
#define CheckBit(x, k) (x & (1LL << k))
#define mod 1000000007

ll x[100005];
ll ans = 0;
vector<int> tree[100005];

map<ll, ll> dfs(int u, int p){
  map<ll, ll> res;
  for(auto v: tree[u]){
    if(v==p) continue;
    map<ll, ll> mp = dfs(v, u);
    for(auto it: mp){
      ll g = __gcd(it.first, x[u]);
      ans = (ans + (g*it.second)%mod)%mod;
      res[g] += it.second;
    }
  }
  res[x[u]]++;
  ans = (ans + x[u])%mod;

  return res;
}

int main()
{
  int n;
  cin >> n;
  for(int i = 1; i <= n; i++)
    cin >> x[i];

  for(int i = 0; i < n-1; i++){
    int u, v;
    cin >> u >> v;
    tree[u].pb(v);
    tree[v].pb(u);
  }

  dfs(1, 0);

  cout << ans << "\n";

  return 0;
}


/* In the name of Allah */

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define pii pair<int, int>
#define pll pair<long long, long long>
#define pb push_back
#define YES printf("YES\n")
#define NO printf("NO\n")
#define LL_INF 1LL << 62
#define INF 1 << 30
#define SetBit(x, k) (x |= (1LL << k))
#define ClearBit(x, k) (x &= ~(1LL << k))
#define CheckBit(x, k) (x & (1LL << k))
#define mod 1000000007

ll x[100005];
ll ans = 0;
vector<int> tree[100005];

map<ll, ll> dfs(int u, int p){
  map<ll, ll> res;
  for(auto v: tree[u]){
    if(v==p) continue;
    map<ll, ll> mp = dfs(v, u);
    map<ll, ll>::iterator it;
    for(it = mp.begin(); it != mp.end(); ++it){
      ll g = __gcd(it->first, x[u]);
      ans = (ans + (g*it->second)%mod)%mod;
      res[g] += it->second;
    }
  }
  res[x[u]]++;
  ans = (ans + x[u])%mod;

  return res;
}

int main()
{
  int n;
  cin >> n;
  for(int i = 1; i <= n; i++)
    cin >> x[i];

  for(int i = 0; i < n-1; i++){
    int u, v;
    scanf("%d %d", &u, &v);
    tree[u].pb(v);
    tree[v].pb(u);
  }

  dfs(1, 0);

  cout << ans << "\n";

  return 0;
}


/* In the name of Allah */

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define pii pair<int, int>
#define pll pair<long long, long long>
#define pb push_back
#define YES printf("YES\n")
#define NO printf("NO\n")
#define LL_INF 1LL << 62
#define INF 1 << 30
#define SetBit(x, k) (x |= (1LL << k))
#define ClearBit(x, k) (x &= ~(1LL << k))
#define CheckBit(x, k) (x & (1LL << k))
#define mod 1000000007

ll x[100005];
ll ans = 0;
vector<int> tree[100005];
map<ll, ll> m[100005];

void dfs(int u, int p){
  for(auto v: tree[u]){
    if(v==p) continue;
    dfs(v, u);
  }

  map<ll, ll>::iterator it;
  for(it = m[u].begin(); it != m[u].end(); ++it){
    ll g = __gcd(it->first, x[u]);
    m[p][g] += it->second;
    ans = (ans + (g * it->second)%mod)%mod;
  }

  m[p][x[u]]++;
  ans = (ans + x[u])%mod;
  m[u].clear();
}

int main()
{
  int n;
  cin >> n;
  for(int i = 1; i <= n; i++)
    cin >> x[i];

  for(int i = 0; i < n-1; i++){
    int u, v;
    scanf("%d %d", &u, &v);
    tree[u].pb(v);
    tree[v].pb(u);
  }

  dfs(1, 0);

  cout << ans << "\n";

  return 0;
}


/* In the name of Allah */

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define pii pair<int, int>
#define pll pair<long long, long long>
#define pb push_back
#define YES printf("YES\n")
#define NO printf("NO\n")
#define LL_INF 1LL << 62
#define INF 1 << 30
#define SetBit(x, k) (x |= (1LL << k))
#define ClearBit(x, k) (x &= ~(1LL << k))
#define CheckBit(x, k) (x & (1LL << k))
#define mod 1000000007

ll x[100005];
ll ans = 0;
vector<int> tree[100005];

map<ll, ll> dfs(int u, int p){
  map<ll, ll> res;
  for(auto v: tree[u]){
    if(v==p) continue;
    map<ll, ll> mp = dfs(v, u);
    map<ll, ll>::iterator it;
    for(it = mp.begin(); it != mp.end(); ++it){
      ll g = __gcd(it->first, x[u]);
      ans = (ans + (g*it->second)%mod)%mod;
      res[g] += it->second;
    }
  }
  res[x[u]]++;
  ans = (ans + x[u])%mod;

  return res;
}

int main()
{
  int n;
  cin >> n;
  for(int i = 1; i <= n; i++)
    cin >> x[i];

  for(int i = 0; i < n-1; i++){
    int u, v;
    cin >> u >> v;
    tree[u].pb(v);
    tree[v].pb(u);
  }

  dfs(1, 0);

  cout << ans << "\n";

  return 0;
}


/* In the name of Allah */

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define pii pair<int, int>
#define pll pair<long long, long long>
#define pb push_back
#define YES printf("YES\n")
#define NO printf("NO\n")
#define LL_INF 1LL << 62
#define INF 1 << 30
#define SetBit(x, k) (x |= (1LL << k))
#define ClearBit(x, k) (x &= ~(1LL << k))
#define CheckBit(x, k) (x & (1LL << k))
#define mod 1000000007

ll x[100005];
ll ans = 0;
vector<int> tree[100005];
map<ll, int> m[100005];

void dfs(int u, int p){
  for(auto v: tree[u]){
    if(v==p) continue;
    dfs(v, u);
  }

  map<ll, int>::iterator it;
  for(it = m[u].begin(); it != m[u].end(); ++it){
    ll g = __gcd(it->first, x[u]);
    m[p][g] += it->second;
    ans = (ans + (g * it->second)%mod)%mod;
  }

  m[p][x[u]]++;
  ans = (ans + x[u])%mod;
}

int main()
{
  int n;
  cin >> n;
  for(int i = 1; i <= n; i++)
    cin >> x[i];

  for(int i = 0; i < n-1; i++){
    int u, v;
    scanf("%d %d", &u, &v);
    tree[u].pb(v);
    tree[v].pb(u);
  }

  dfs(1, 0);

  cout << ans << "\n";

  return 0;
}


/* In the name of Allah */

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define pii pair<int, int>
#define pll pair<long long, long long>
#define pb push_back
#define YES printf("YES\n")
#define NO printf("NO\n")
#define LL_INF 1LL << 62
#define INF 1 << 30
#define SetBit(x, k) (x |= (1LL << k))
#define ClearBit(x, k) (x &= ~(1LL << k))
#define CheckBit(x, k) (x & (1LL << k))
#define mod 1000000007

ll x[100005];
ll ans = 0;
vector<int> tree[100005];
map<ll, int> m[100005];

void dfs(int u, int p){
  for(auto v: tree[u]){
    if(v==p) continue;
    dfs(v, u);
  }

  map<ll, ll>::iterator it;
  for(it = m[u].begin(); it != m[u].end(); ++it){
    ll g = __gcd(it->first, x[u]);
    m[p][g] += it->second;
    ans = (ans + (g * it->second)%mod)%mod;
  }

  m[p][x[u]]++;
  ans = (ans + x[u])%mod;
}

int main()
{
  int n;
  cin >> n;
  for(int i = 1; i <= n; i++)
    cin >> x[i];

  for(int i = 0; i < n-1; i++){
    int u, v;
    scanf("%d %d", &u, &v);
    tree[u].pb(v);
    tree[v].pb(u);
  }

  dfs(1, 0);

  cout << ans << "\n";

  return 0;
}


// clang-format off
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define mp make_pair
#define fst first
#define snd second
#define forn(i,n) for (int i = 0; i < int(n); i++)
#define forn1(i,n) for (int i = 1; i <= int(n); i++)
#define popcnt __builtin_popcount
#define ffs __builtin_ffs
#define ctz __builtin_ctz
#define clz __builtin_clz
#define all(a) (a).begin(), (a).end()

using namespace std;
using namespace __gnu_pbds;

using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
using pli = pair<ll,int>;
using pil = pair<int,ll>;
using pll = pair<ll,ll>;
template <typename T> using vec = vector<T>;
using vi = vec<int>;
using vl = vec<ll>;
template <typename T> using que = queue<T>;
template <typename T> using deq = deque<T>;

template <typename T> T id(T b) {return b;};
template <typename T> void chmax(T &x, T y) {if (x < y) x = y;}
template <typename T> void chmin(T &x, T y) {if (x > y) x = y;}
template <typename S, typename K> bool contains(S &s, K k) { return s.find(k) != s.end(); }
void fastio() { ios_base::sync_with_stdio(false); cin.tie(nullptr); }
constexpr ll TEN(int n) { if (n == 0) return 1LL; else return 10LL*TEN(n-1); }
template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename K, typename V> using ordered_map = tree<K, V, less<K>, rb_tree_tag, tree_order_statistics_node_update>;
// clang-format on

const int MAX_N = 100000;
const ll MOD = TEN(9) + 7;
int n;
ll x[MAX_N];
vi t[MAX_N];

map<ll, ll> ans;
void dfs(int u, int p, const map<ll, ll> cur) {
    map<ll, ll> sub;
    sub[x[u]] = 1;
    ans[x[u]] = (ans[x[u]] + 1) % MOD;
    for (auto [y, c] : cur) {
        ll g = gcd(x[u], y);
        sub[g] = (sub[g] + c) % MOD;
        ans[g] = (ans[g] + c) % MOD;
    }

    for (auto v : t[u]) {
        if (v != p) {
            dfs(v, u, sub);
        }
    }
}

int main() {
    fastio();

    cin >> n;
    forn(i, n) cin >> x[i];
    forn(i, n - 1) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        t[a].push_back(b);
        t[b].push_back(a);
    }

    map<ll, ll> dummy;
    dfs(0, -1, dummy);

    ll v = 0;
    for (auto [y, c] : ans) {
        v = (v + y % MOD * c % MOD) % MOD;
    }

    cout << v << endl;

    return 0;
}


// clang-format off
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define mp make_pair
#define fst first
#define snd second
#define forn(i,n) for (int i = 0; i < int(n); i++)
#define forn1(i,n) for (int i = 1; i <= int(n); i++)
#define popcnt __builtin_popcount
#define ffs __builtin_ffs
#define ctz __builtin_ctz
#define clz __builtin_clz
#define all(a) (a).begin(), (a).end()

using namespace std;
using namespace __gnu_pbds;

using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
using pli = pair<ll,int>;
using pil = pair<int,ll>;
using pll = pair<ll,ll>;
template <typename T> using vec = vector<T>;
using vi = vec<int>;
using vl = vec<ll>;
template <typename T> using que = queue<T>;
template <typename T> using deq = deque<T>;

template <typename T> T id(T b) {return b;};
template <typename T> void chmax(T &x, T y) {if (x < y) x = y;}
template <typename T> void chmin(T &x, T y) {if (x > y) x = y;}
template <typename S, typename K> bool contains(S &s, K k) { return s.find(k) != s.end(); }
void fastio() { ios_base::sync_with_stdio(false); cin.tie(nullptr); }
constexpr ll TEN(int n) { if (n == 0) return 1LL; else return 10LL*TEN(n-1); }
template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename K, typename V> using ordered_map = tree<K, V, less<K>, rb_tree_tag, tree_order_statistics_node_update>;
// clang-format on

const int MAX_N = 100000;
const ll MOD = TEN(9) + 7;
int n;
ll x[MAX_N];
vi t[MAX_N];

map<ll, ll> ans;
void dfs(int u, int p, const map<ll, ll> cur) {
    map<ll, ll> sub;
    sub[x[u]] = 1;
    ans[x[u]] = (ans[x[u]] + 1) % MOD;
    for (auto [y, c] : cur) {
        ll g = gcd(x[u], y);
        sub[g] = (sub[g] + c) % MOD;
        ans[g] = (ans[g] + c) % MOD;
    }

    for (auto v : t[u]) {
        if (v != p) {
            dfs(v, u, sub);
        }
    }
}

int main() {
    fastio();

    cin >> n;
    forn(i, n) cin >> x[i];
    forn(i, n - 1) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        t[a].push_back(b);
        t[b].push_back(a);
    }

    map<ll, ll> dummy;
    dfs(0, -1, dummy);

    ll v = 0;
    for (auto [y, c] : ans) {
        v = (v + y * c % MOD) % MOD;
    }

    cout << v << endl;

    return 0;
}


// clang-format off
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define mp make_pair
#define fst first
#define snd second
#define forn(i,n) for (int i = 0; i < int(n); i++)
#define forn1(i,n) for (int i = 1; i <= int(n); i++)
#define popcnt __builtin_popcount
#define ffs __builtin_ffs
#define ctz __builtin_ctz
#define clz __builtin_clz
#define all(a) (a).begin(), (a).end()

using namespace std;
using namespace __gnu_pbds;

using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
using pli = pair<ll,int>;
using pil = pair<int,ll>;
using pll = pair<ll,ll>;
template <typename T> using vec = vector<T>;
using vi = vec<int>;
using vl = vec<ll>;
template <typename T> using que = queue<T>;
template <typename T> using deq = deque<T>;

template <typename T> T id(T b) {return b;};
template <typename T> void chmax(T &x, T y) {if (x < y) x = y;}
template <typename T> void chmin(T &x, T y) {if (x > y) x = y;}
template <typename S, typename K> bool contains(S &s, K k) { return s.find(k) != s.end(); }
void fastio() { ios_base::sync_with_stdio(false); cin.tie(nullptr); }
constexpr ll TEN(int n) { if (n == 0) return 1LL; else return 10LL*TEN(n-1); }
template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename K, typename V> using ordered_map = tree<K, V, less<K>, rb_tree_tag, tree_order_statistics_node_update>;
// clang-format on

const int MAX_N = 100000;
const ll MOD = TEN(9) + 7;
int n;
ll x[MAX_N];
vi t[MAX_N];

map<ll, int> ans;
map<ll, int> dfs(int u, int p) {
    map<ll, int> sub;

    sub[x[u]] = 1;
    for (auto v : t[u]) {
        if (v != p) {
            map<ll, int> temp = dfs(v, u);
            for (auto [y, c] : temp) {
                sub[y] = (sub[y] + c) % MOD;
            }
        }
    }

    map<ll, int> res;
    for (auto [y, c] : sub) {
        ll g = gcd(x[u], y);
        res[g] = (res[g] + c) % MOD;
        ans[g] = (ans[g] + c) % MOD;
    }

    return res;
}

int main() {
    fastio();

    cin >> n;
    forn(i, n) cin >> x[i];
    forn(i, n - 1) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        t[a].push_back(b);
        t[b].push_back(a);
    }

    dfs(0, -1);

    ll v = 0;
    for (auto [y, c] : ans) {
        v = (v + y * c % MOD) % MOD;
    }

    cout << v << endl;

    return 0;
}


// clang-format off
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define mp make_pair
#define fst first
#define snd second
#define forn(i,n) for (int i = 0; i < int(n); i++)
#define forn1(i,n) for (int i = 1; i <= int(n); i++)
#define popcnt __builtin_popcount
#define ffs __builtin_ffs
#define ctz __builtin_ctz
#define clz __builtin_clz
#define all(a) (a).begin(), (a).end()

using namespace std;
using namespace __gnu_pbds;

using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
using pli = pair<ll,int>;
using pil = pair<int,ll>;
using pll = pair<ll,ll>;
template <typename T> using vec = vector<T>;
using vi = vec<int>;
using vl = vec<ll>;
template <typename T> using que = queue<T>;
template <typename T> using deq = deque<T>;

template <typename T> T id(T b) {return b;};
template <typename T> void chmax(T &x, T y) {if (x < y) x = y;}
template <typename T> void chmin(T &x, T y) {if (x > y) x = y;}
template <typename S, typename K> bool contains(S &s, K k) { return s.find(k) != s.end(); }
void fastio() { ios_base::sync_with_stdio(false); cin.tie(nullptr); }
constexpr ll TEN(int n) { if (n == 0) return 1LL; else return 10LL*TEN(n-1); }
template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename K, typename V> using ordered_map = tree<K, V, less<K>, rb_tree_tag, tree_order_statistics_node_update>;
// clang-format on

const int MAX_N = 100000;
const ll MOD = TEN(9) + 7;
int n;
ll x[MAX_N];
vi t[MAX_N];

map<ll, ll> ans;
void dfs(int u, int p, const map<ll, ll> cur) {
    map<ll, ll> sub;
    sub[x[u]] = 1;
    ans[x[u]]++;
    for (auto [y, c] : cur) {
        ll g = gcd(x[u], y);
        sub[g] += c;
        ans[g] += c;
    }

    for (auto v : t[u]) {
        if (v != p) {
            dfs(v, u, sub);
        }
    }
}

int main() {
    fastio();

    cin >> n;
    forn(i, n) cin >> x[i];
    forn(i, n - 1) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        t[a].push_back(b);
        t[b].push_back(a);
    }

    map<ll, ll> dummy;
    dfs(0, -1, dummy);

    ll v = 0;
    for (auto [y, c] : ans) {
        v = (v + y * c % MOD) % MOD;
    }

    cout << v << endl;

    return 0;
}


#include<bits/stdc++.h>
#define fo(i,a,b) for(int i=(a);i<=(b);++i)
#define rv(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
typedef long long ll;
const int M = 120000;
const int inf = 0x3f3f3f3f;
const int md=1e9+7;
int n,k;
namespace io{
const int L=(1<<21)+1;
char ibuf[L],*iS,*iT,obuf[L],*oS=obuf,*oT=obuf+L-1,c,st[65];int f,tp;
#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,L,stdin),(iS==iT?EOF:*iS++)):*iS++)
inline void flush(){fwrite(obuf,1,oS-obuf,stdout);oS=obuf;}
inline void putc(char x){*oS++=x;if(oS==oT)flush();}
inline void read(ll&x){
	for(f=1,c=gc();c<'0'||c>'9';c=gc())if(c=='-')f=-1;
	for(x=0;c<='9'&&c>='0';c=gc())x=x*10+(c&15);x*=f;
}
inline void read(int&x){
	for(f=1,c=gc();c<'0'||c>'9';c=gc())if(c=='-')f=-1;
	for(x=0;c<='9'&&c>='0';c=gc())x=x*10+(c&15);x*=f;
}
inline void print(int x){
	if(!x)putc('0');if(x<0)putc('-'),x=-x;
	while(x)st[++tp]=x%10+'0',x/=10;
	while(tp)putc(st[tp--]);
}
};
using io::read;
using io::print;
using io::putc;
ll v[M];
vector<int> g[M];
const int m=19;
int f[M][m+1];
ll cd[M][m+1];
int d[M];
void dfs(int u,int fa,int dep){
	f[u][1]=fa;
	f[u][0]=u;
	cd[u][0]=v[u];
	d[u]=dep;
	for(int to:g[u]){
		if(to!=fa) dfs(to,u,dep+1);
	}
}
void init(){
	fo(i,1,n) cd[i][1]=__gcd(cd[i][0],cd[f[i][1]][0]);
	fo(i,2,m){
		fo(j,1,n) {
			f[j][i]=f[f[j][i-1]][i-1];
			cd[j][i]=__gcd(cd[j][i-1],cd[f[j][i-1]][i-1]);
		}
	}
}
ll ans=0;
ll add(ll u,ll b){return (u+=b)<md?u:u-md;}
void solve(int u){
	ll cur=v[u];
	while(u!=1){
		ans=add(ans,cur);
		u=f[u][1];
		cur=__gcd(cur,v[u]);
	}
	ans=add(ans,cur);
}
void cal(int u){
	ll cur=v[u];
	while(1){
		if(cur==1){
			ans=add(ans,d[u]);
			return;
		}
		ll to=u;
		rv(i,m,1){
			if(__gcd(cur,cd[to][i])==cur){
				to=f[to][i];
			}
		}
		if(__gcd(cur,v[f[to][1]])==cur) to=f[to][1];
		ans=add(ans,cur*(d[u]-d[to]+1)%md);
		if(to==1) return;
		u=f[to][1];
		cur=__gcd(cur,v[u]);
	}
}
int main() {
	read(n);
	fo(i,1,n) read(v[i]);
	int x,y;
	fo(i,2,n){
		read(x);read(y);
		g[x].push_back(y);
		g[y].push_back(x);
	}
	dfs(1,1,1);
	init();
	fo(i,1,n){
		if(d[i]<200)
			solve(i);
		else
			cal(i);
	}
	cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
#define fo(i,a,b) for(int i=(a);i<=(b);++i)
#define rv(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
typedef long long ll;
const int M = 120000;
const int inf = 0x3f3f3f3f;
const int md=1e9+7;
int n,k;
namespace io{
const int L=(1<<21)+1;
char ibuf[L],*iS,*iT,obuf[L],*oS=obuf,*oT=obuf+L-1,c,st[65];int f,tp;
#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,L,stdin),(iS==iT?EOF:*iS++)):*iS++)
inline void flush(){fwrite(obuf,1,oS-obuf,stdout);oS=obuf;}
inline void putc(char x){*oS++=x;if(oS==oT)flush();}
inline void read(ll&x){
	for(f=1,c=gc();c<'0'||c>'9';c=gc())if(c=='-')f=-1;
	for(x=0;c<='9'&&c>='0';c=gc())x=x*10+(c&15);x*=f;
}
inline void read(int&x){
	for(f=1,c=gc();c<'0'||c>'9';c=gc())if(c=='-')f=-1;
	for(x=0;c<='9'&&c>='0';c=gc())x=x*10+(c&15);x*=f;
}
inline void print(int x){
	if(!x)putc('0');if(x<0)putc('-'),x=-x;
	while(x)st[++tp]=x%10+'0',x/=10;
	while(tp)putc(st[tp--]);
}
};
using io::read;
using io::print;
using io::putc;
ll v[M];
vector<int> g[M];
const int m=19;
int f[M][m+1];
ll cd[M][m+1];
int d[M];
void dfs(int u,int fa,int dep){
	f[u][1]=fa;
	f[u][0]=u;
	cd[u][0]=v[u];
	d[u]=dep;
	for(int to:g[u]){
		if(to!=fa) dfs(to,u,dep+1);
	}
}
void init(){
	fo(i,1,n) cd[i][1]=__gcd(cd[i][0],cd[f[i][1]][0]);
	fo(i,2,m){
		fo(j,1,n) {
			f[j][i]=f[f[j][i-1]][i-1];
			cd[j][i]=__gcd(cd[j][i-1],cd[f[j][i-1]][i-1]);
		}
	}
}
ll ans=0;
ll add(ll u,ll b){return (u+=b)%=md;}
void solve(int u){
	ll cur=v[u];
	while(u!=1){
		ans=add(ans,cur);
		u=f[u][1];
		cur=__gcd(cur,v[u]);
	}
	ans=add(ans,cur);
}
void cal(int u){
	ll cur=v[u];
	while(1){
		if(cur==1){
			ans=add(ans,d[u]);
			return;
		}
		ll to=u;
		rv(i,m,1){
			if(__gcd(cur,cd[to][i])==cur){
				to=f[to][i];
			}
		}
		if(__gcd(cur,v[f[to][1]])==cur) to=f[to][1];
		ans=add(ans,cur*(d[u]-d[to]+1)%md);
		if(to==1) return;
		u=f[to][1];
		cur=__gcd(cur,v[u]);
	}
}
int main() {
	read(n);
	fo(i,1,n) read(v[i]);
	int x,y;
	fo(i,2,n){
		read(x);read(y);
		g[x].push_back(y);
		g[y].push_back(x);
	}
	dfs(1,1,1);
	init();
	fo(i,1,n){
		if(d[i]<200)
			solve(i);
		else
			cal(i);
	}
	cout<<ans<<endl;
	return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define SPEED ios_base::sync_with_stdio(false); cin.tie(NULL);
#define FOR(i, a, b) for (ll i = a; i < b; ++i)
#define RFOR(i, b, a) for (ll i = b; i >= a; --i)
#define ALL(x) x.begin(), x.end()
#define DEBUG(args...) { string _s = #args; replace(ALL(_s), ' ', '\0');\
replace(ALL(_s), ',', ' ');\
stringstream _ss(_s); istream_iterator<string> _it(_ss); _debug(_it, args);}
#define endl "\n"
#define F first
#define S second
#define pb(x) push_back(x)a
#define mp(x, y) make_pair(x, y)

using namespace std;
using namespace __gnu_pbds;

template<typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

void _debug(istream_iterator<string>) {}
template<typename T, typename... Args>
void _debug(istream_iterator<string> it, T first, Args... args) {
    cerr << ">> " << *it << " : " << first << endl; _debug(++it, args...);
}
template <typename T1, typename T2>
inline ostream& operator << (ostream& out, const pair<T1, T2>& p) {
    return out << "(" << p.F << ", " << p.S << ")";
}
template<typename T>
inline ostream& operator << (ostream& out, const vector<T>& v) {
    if (v.empty()) return out << "[]";
    else { out << '['; for (auto& e : v) { out << e << ", "; } return out << "\b\b]"; }
}
template<typename T>
inline ostream& operator << (ostream& out, const set<T>& s) {
    if (s.empty()) return out << "{}";
    else { out << '{'; for (auto& e : s) { out << e << ", "; } return out << "\b\b}"; }
}
template<typename T>
inline ostream& operator << (ostream& out, const unordered_set<T>& s) {
    return out << set<T>(ALL(s));
}
template<typename T1, typename T2>
inline ostream& operator << (ostream& out, const map<T1, T2>& m) {
    if (m.empty()) return out << "{}";
    out << '{'; for (auto& p : m) { out << p << ", "; } return out << "\b\b}";
}
template<typename T1, typename T2>
inline ostream& operator << (ostream& out, const unordered_map<T1, T2>& m) {
    return out << map<T1, T2>(ALL(m));
}
template<typename T>
inline ostream& operator << (ostream& out, const ordered_set<T>& s) {
    return out << set<T>(ALL(s));
}

typedef long long ll;
typedef long double ld;
typedef vector<long long> vll;
typedef pair<ll, ll> pll;
typedef vector<pair<ll, ll>> vpll;
typedef unordered_map<ll, ll> STll;
/************************************** MAIN PROGRAM ********************************************/
const int MAX = 1e5 + 1;
const int MOD = 1e9 + 7;
#define int ll
ll a[MAX];
vector<int> adj[MAX];
ll ans = 0;

void dfs(int v, int u, map<ll, int> mp) {
    map<ll, int> new_mp;

    for (auto [e, f] : mp) {
        new_mp[__gcd(e, a[v])] += f;
    }
    new_mp[a[v]]++;
    for (auto [e, f] : new_mp) {
        ans += e * f % MOD;
        if (ans >= MOD) ans -= MOD;
    }
   // DEBUG(new_mp, v)
    for (int w : adj[v]) {
        if (w == u) continue;
        dfs(w, v, new_mp);
    }
}

main()
{
   // freopen("input.txt", "r", stdin);
    SPEED
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) cin >> a[i];
    for (int i = 0; i < n - 1; ++i) {
        int u, v;
        cin >> u >> v; u--, v--;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(0, 0, map<ll, int>());
    cout << ans;
}
/************************************** END OF PROGRAM ******************************************/
/** Stuff you should look for:
 * int overflow, array bounds, over-counting
 * special cases (n=1?), set/unordered_set TLE, multi-set/set error
 * do something instead of nothing and stay organized
 */


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define SPEED ios_base::sync_with_stdio(false); cin.tie(NULL);
#define FOR(i, a, b) for (ll i = a; i < b; ++i)
#define RFOR(i, b, a) for (ll i = b; i >= a; --i)
#define ALL(x) x.begin(), x.end()
#define DEBUG(args...) { string _s = #args; replace(ALL(_s), ' ', '\0');\
replace(ALL(_s), ',', ' ');\
stringstream _ss(_s); istream_iterator<string> _it(_ss); _debug(_it, args);}
#define endl "\n"
#define F first
#define S second
#define pb(x) push_back(x)a
#define mp(x, y) make_pair(x, y)

using namespace std;
using namespace __gnu_pbds;

template<typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

void _debug(istream_iterator<string>) {}
template<typename T, typename... Args>
void _debug(istream_iterator<string> it, T first, Args... args) {
    cerr << ">> " << *it << " : " << first << endl; _debug(++it, args...);
}
template <typename T1, typename T2>
inline ostream& operator << (ostream& out, const pair<T1, T2>& p) {
    return out << "(" << p.F << ", " << p.S << ")";
}
template<typename T>
inline ostream& operator << (ostream& out, const vector<T>& v) {
    if (v.empty()) return out << "[]";
    else { out << '['; for (auto& e : v) { out << e << ", "; } return out << "\b\b]"; }
}
template<typename T>
inline ostream& operator << (ostream& out, const set<T>& s) {
    if (s.empty()) return out << "{}";
    else { out << '{'; for (auto& e : s) { out << e << ", "; } return out << "\b\b}"; }
}
template<typename T>
inline ostream& operator << (ostream& out, const unordered_set<T>& s) {
    return out << set<T>(ALL(s));
}
template<typename T1, typename T2>
inline ostream& operator << (ostream& out, const map<T1, T2>& m) {
    if (m.empty()) return out << "{}";
    out << '{'; for (auto& p : m) { out << p << ", "; } return out << "\b\b}";
}
template<typename T1, typename T2>
inline ostream& operator << (ostream& out, const unordered_map<T1, T2>& m) {
    return out << map<T1, T2>(ALL(m));
}
template<typename T>
inline ostream& operator << (ostream& out, const ordered_set<T>& s) {
    return out << set<T>(ALL(s));
}

typedef long long ll;
typedef long double ld;
typedef vector<long long> vll;
typedef pair<ll, ll> pll;
typedef vector<pair<ll, ll>> vpll;
typedef unordered_map<ll, ll> STll;
/************************************** MAIN PROGRAM ********************************************/
const int MAX = 1e5 + 1;
#define int ll
ll a[MAX];
vector<int> adj[MAX];
ll ans = 0;

void dfs(int v, int u, map<ll, int> mp) {
    map<ll, int> new_mp;

    for (auto [e, f] : mp) {
        new_mp[__gcd(e, a[v])] += f;
    }
    new_mp[a[v]]++;
    for (auto [e, f] : new_mp) {
        ans += e * f;
    }
   // DEBUG(new_mp, v)
    for (int w : adj[v]) {
        if (w == u) continue;
        dfs(w, v, new_mp);
    }
}

main()
{
   // freopen("input.txt", "r", stdin);
    SPEED
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) cin >> a[i];
    for (int i = 0; i < n - 1; ++i) {
        int u, v;
        cin >> u >> v; u--, v--;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(0, 0, map<ll, int>());
    cout << ans;
}
/************************************** END OF PROGRAM ******************************************/
/** Stuff you should look for:
 * int overflow, array bounds, over-counting
 * special cases (n=1?), set/unordered_set TLE, multi-set/set error
 * do something instead of nothing and stay organized
 */


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define SPEED ios_base::sync_with_stdio(false); cin.tie(NULL);
#define FOR(i, a, b) for (ll i = a; i < b; ++i)
#define RFOR(i, b, a) for (ll i = b; i >= a; --i)
#define ALL(x) x.begin(), x.end()
#define DEBUG(args...) { string _s = #args; replace(ALL(_s), ' ', '\0');\
replace(ALL(_s), ',', ' ');\
stringstream _ss(_s); istream_iterator<string> _it(_ss); _debug(_it, args);}
#define endl "\n"
#define F first
#define S second
#define pb(x) push_back(x)a
#define mp(x, y) make_pair(x, y)

using namespace std;
using namespace __gnu_pbds;

template<typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

void _debug(istream_iterator<string>) {}
template<typename T, typename... Args>
void _debug(istream_iterator<string> it, T first, Args... args) {
    cerr << ">> " << *it << " : " << first << endl; _debug(++it, args...);
}
template <typename T1, typename T2>
inline ostream& operator << (ostream& out, const pair<T1, T2>& p) {
    return out << "(" << p.F << ", " << p.S << ")";
}
template<typename T>
inline ostream& operator << (ostream& out, const vector<T>& v) {
    if (v.empty()) return out << "[]";
    else { out << '['; for (auto& e : v) { out << e << ", "; } return out << "\b\b]"; }
}
template<typename T>
inline ostream& operator << (ostream& out, const set<T>& s) {
    if (s.empty()) return out << "{}";
    else { out << '{'; for (auto& e : s) { out << e << ", "; } return out << "\b\b}"; }
}
template<typename T>
inline ostream& operator << (ostream& out, const unordered_set<T>& s) {
    return out << set<T>(ALL(s));
}
template<typename T1, typename T2>
inline ostream& operator << (ostream& out, const map<T1, T2>& m) {
    if (m.empty()) return out << "{}";
    out << '{'; for (auto& p : m) { out << p << ", "; } return out << "\b\b}";
}
template<typename T1, typename T2>
inline ostream& operator << (ostream& out, const unordered_map<T1, T2>& m) {
    return out << map<T1, T2>(ALL(m));
}
template<typename T>
inline ostream& operator << (ostream& out, const ordered_set<T>& s) {
    return out << set<T>(ALL(s));
}

typedef long long ll;
typedef long double ld;
typedef vector<long long> vll;
typedef pair<ll, ll> pll;
typedef vector<pair<ll, ll>> vpll;
typedef unordered_map<ll, ll> STll;
/************************************** MAIN PROGRAM ********************************************/
const int MAX = 1e5 + 1;
ll a[MAX];
vector<int> adj[MAX];
ll ans = 0;

void dfs(int v, int u, map<ll, int> mp) {
    map<ll, int> new_mp;

    for (auto [e, f] : mp) {
        new_mp[__gcd(e, a[v])] += f;
    }
    new_mp[a[v]]++;
    for (auto [e, f] : new_mp) {
        ans += e * f;
    }
   // DEBUG(new_mp, v)
    for (int w : adj[v]) {
        if (w == u) continue;
        dfs(w, v, new_mp);
    }
}

int main()
{
   // freopen("input.txt", "r", stdin);
    SPEED
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) cin >> a[i];
    for (int i = 0; i < n - 1; ++i) {
        int u, v;
        cin >> u >> v; u--, v--;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(0, 0, map<ll, int>());
    cout << ans;
}
/************************************** END OF PROGRAM ******************************************/
/** Stuff you should look for:
 * int overflow, array bounds, over-counting
 * special cases (n=1?), set/unordered_set TLE, multi-set/set error
 * do something instead of nothing and stay organized
 */


#include<bits/stdc++.h>
#define f(i,a,b) for( int i=a;i<=b;++i)
#define ff(i,a,b) for( int i=a;i>=b;--i)
#define debug(x) cerr << #x << " : " << x << " " << endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<string, string> pss;
const ll mod = 1e9 + 7;
const ll mod2 = 998244353;
const int inf = 0x3f3f3f3f;
const double tiaohe = 0.57721566490153286060651209;
ll oula(ll x) { ll res = x;f(i, 2, x / i) { if (x % i == 0) { res = res / i * (i - 1);while (x % i == 0) x /= i; } }if (x > 1) res = res / x * (x - 1);return res; }
ll quickmod(ll a, ll n, ll m) { ll s = 1;while (n) { if (n & 1) { s = s * a % m; }a = (a*a) % m;n = n / 2; }return s; }
ll gcd(ll a, ll b) { return b ? gcd(b, a%b) : a; }
void ex_gcd(ll a, ll b, ll &x, ll &y, ll &d) { if (!b) { d = a, x = 1, y = 0; } else { ex_gcd(b, a % b, y, x, d);y -= x * (a / b); } }
ll inv(ll t, ll p) { ll d, x, y;ex_gcd(t, p, x, y, d);return d == 1 ? (x % p + p) % p : -1; }
bool isPrime(ll x) { if (x == 2)return true;if (x % 2 == 0)return false;for (ll i = 2;i*i <= x;i++) if (x % i == 0)return false; return true; }
inline int in() { char ch = getchar();int x = 0, f = 1;while (ch<'0' || ch>'9') { if (ch == '-')f = -1;ch = getchar(); }while (ch >= '0'&&ch <= '9') { x = x * 10 + ch - '0';ch = getchar(); }return x * f; }
//double a = log(n) +tiaohe + 1.0 / (2 * n);
double eqa = (1 + sqrt(5.0)) / 2.0;
const double eps = 1e-6;
const int N = 1e5 + 5;
vector<pii> d[N];//到每个点的上一层路径的gcd
vector<int> G[N];
int a[N];
ll ans = 0;
void dfs(int u,int fa)
{
	unordered_map<int,int> mp;
	mp[a[u]]++;
	ans += a[u];
	for (auto j : d[u])
	{
		int nx_gcd = gcd(j.first, a[u]);
		mp[nx_gcd] += j.second;
		ans += (ll)nx_gcd * j.second;
	}
	for (auto i : G[u])
	{
		if (i == fa)continue;
		for (auto I : mp)
		{
			d[i].emplace_back(pii{ I.first,I.second });
		}
		dfs(i, u);
	}
}
int main()
{
//	freopen("in.txt", "r", stdin);
	int n = in();
	f(i, 1, n)a[i] = in();
	f(i, 1, n - 1)
	{
		int x = in();
		int y = in();
		G[x].emplace_back(y);
		G[y].emplace_back(x);
	}
	dfs(1, -1);
	cout << ans << endl;
	return 0;
}