/*
author: Maksim1744
created: 17.02.2024 12:19:04
*/
#include "bits/stdc++.h"
using namespace std;
using ll = long long;
using ld = long double;
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define sum(a) ( accumulate ((a).begin(), (a).end(), 0ll))
#define mine(a) (*min_element((a).begin(), (a).end()))
#define maxe(a) (*max_element((a).begin(), (a).end()))
#define mini(a) ( min_element((a).begin(), (a).end()) - (a).begin())
#define maxi(a) ( max_element((a).begin(), (a).end()) - (a).begin())
#define lowb(a, x) ( lower_bound((a).begin(), (a).end(), (x)) - (a).begin())
#define uppb(a, x) ( upper_bound((a).begin(), (a).end(), (x)) - (a).begin())
template<typename T> vector<T>& operator-- (vector<T> &v){for (auto& i : v) --i; return v;}
template<typename T> vector<T>& operator++ (vector<T> &v){for (auto& i : v) ++i; return v;}
template<typename T> istream& operator>>(istream& is, vector<T> &v){for (auto& i : v) is >> i; return is;}
template<typename T> ostream& operator<<(ostream& os, vector<T> v){for (auto& i : v) os << i << ' '; return os;}
template<typename T, typename U> pair<T,U>& operator-- (pair<T, U> &p){--p.first; --p.second; return p;}
template<typename T, typename U> pair<T,U>& operator++ (pair<T, U> &p){++p.first; ++p.second; return p;}
template<typename T, typename U> istream& operator>>(istream& is, pair<T, U> &p){is >> p.first >> p.second; return is;}
template<typename T, typename U> ostream& operator<<(ostream& os, pair<T, U> p){os << p.first << ' ' << p.second; return os;}
template<typename T, typename U> pair<T,U> operator-(pair<T,U> a, pair<T,U> b){return mp(a.first-b.first, a.second-b.second);}
template<typename T, typename U> pair<T,U> operator+(pair<T,U> a, pair<T,U> b){return mp(a.first+b.first, a.second+b.second);}
template<typename T, typename U> void umin(T& a, U b){if (a > b) a = b;}
template<typename T, typename U> void umax(T& a, U b){if (a < b) a = b;}
#ifdef HOME
#define SHOW_COLORS
#include "/mnt/c/Libs/tools/print.cpp"
#else
#define show(...) void(0)
#define debugf(fun) fun
#define debugv(var) var
#define mclock void(0)
#define shows void(0)
#define debug if (false)
#define OSTREAM(...) ;
#define OSTREAM0(...) ;
#endif
map<pair<string, char>, vector<pair<int, int>>> paths;
void test_case(int test) {
string a, b;
cin >> a >> b;
if (b.size() == 1) {
if (a.size() == 1) {
cout << 0 << '\n';
return;
} else {
cout << -1 << '\n';
return;
}
}
if (a.size() == 1) {
cout << -1 << '\n';
return;
}
vector<pair<int, int>> ans;
auto op_to_string = [&](string& s, int l, int r) {
int num = 0;
for (int i = l; i <= r; ++i)
num = num * 3 + (s[i] - '0');
static string tmp;
tmp.clear();
while (num || tmp.empty()) {
tmp.pb('0' + num % 2);
num /= 2;
}
reverse(tmp.begin(), tmp.end());
s.erase(s.begin() + l, s.begin() + r + 1);
s.insert(s.begin() + l, tmp.begin(), tmp.end());
};
auto op = [&](int l, int r) {
ans.eb(l, r);
op_to_string(a, l, r);
};
auto get_path_to = [&](string s, auto is_good) {
queue<string> q;
map<string, pair<string, pair<int, int>>> par;
par[s] = mp("", mp(0, 0));
q.push(s);
string found;
while (!q.empty()) {
string s = q.front();
if (is_good(s)) {
found = s;
break;
}
q.pop();
for (int l = 0; l < s.size(); ++l) {
for (int r = l + 1; r < s.size(); ++r) {
auto t = s;
op_to_string(t, l, r);
if (par.count(t)) continue;
par[t] = mp(s, mp(l, r));
q.push(t);
}
}
}
assert(!found.empty());
vector<pair<int, int>> path;
while (found != s) {
const auto& t = par[found];
found = t.first;
path.pb(t.second);
}
reverse(path.begin(), path.end());
return path;
};
auto get_path_to_string = [&](string s, string t) {
return get_path_to(std::move(s), [&](const string& u) {
return t == u;
});
};
auto get_path = [&](string s, char to) -> const vector<pair<int, int>>& {
auto it = paths.find(make_pair(s, to));
if (it != paths.end())
return it->second;
return paths[{s, to}] = get_path_to(s, [&](const string& t) {
return t.size() == 4 && t[0] == '1' && t.back() == to;
});
};
// for (int i = 0; i < 4; ++i) {
// for (int j = 1; j < 4; j += 2) {
// string s = "1";
// for (int t = 0; t < 2; ++t) {
// s.pb('0' + ((i >> t) & 1));
// }
// string t;
// for (int u = 0; u < 2; ++u) {
// t.pb('0' + ((j >> u) & 1));
// }
// cerr << "for " << s << " -> " << t << endl;
// show(get_path_to_string(s, t));
// }
// }
if (a.size() == 2) {
if (a == "10") {
op(0, 1);
}
op(0, 1);
}
while (b.size() > 2) {
if (a.back() == b.back() && a.size() >= 4) {
a.pop_back();
b.pop_back();
continue;
}
assert(a.size() >= 3);
if (a[a.size() - 3] == '0') {
int ind = a.size() - 3;
while (a[ind] == '0')
--ind;
op(ind + 1, a.size() - 2);
}
assert(a.size() >= 3);
assert(a[a.size() - 3] == '1');
const auto& v = get_path(a.substr(a.size() - 3, 3), b.back());
for (auto [l, r] : v) {
op(l + a.size()-3, r + a.size()-3);
}
assert(a.back() == b.back());
assert(a.size() >= 4);
}
auto path = get_path_to_string(a, b);
for (auto [l, r] : path)
op(l, r);
assert(a == b);
cout << ans.size() << '\n';
++ans;
for (auto p : ans)
cout << p << '\n';
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(NULL);
int T;
cin >> T;
for (int test = 1; test <= T; ++test) {
test_case(test);
}
return 0;
}