#include using namespace std; using ll = long long; const ll INF = 1LL << 60; // 間隔 d の状態から、片側を合計 x だけ逆向きに動かすための最小操作回数 ll calc(ll x, ll d) { ll sum = 0; int k = 0; while (sum < x) { sum = sum * 2 + d; ++k; } return k; } // RL ペアのメモ化再帰 map, ll> memo; ll solve_pair(ll A, ll B, ll D) { if (A == 0) return calc(B, D); if (B == 0) return calc(A, D); auto key = make_tuple(A, B, D); if (memo.count(key)) return memo[key]; ll res = INF; // 次に左側を動かす if (A <= D) { res = min(res, 1 + calc(B, D + A)); } else { res = min(res, 1 + solve_pair(A - D, B, 2 * D)); } // 次に右側を動かす if (B <= D) { res = min(res, 1 + calc(A, D + B)); } else { res = min(res, 1 + solve_pair(A, B - D, 2 * D)); } return memo[key] = res; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int Q; cin >> Q; while (Q--) { int N, M; cin >> N >> M; vector> A(M); for (auto& [s, g] : A) cin >> s; for (auto& [s, g] : A) cin >> g; sort(A.begin(), A.end()); bool ok = true; for (int i = 1; i < M; ++i) { auto [s1, g1] = A[i - 1]; auto [s2, g2] = A[i]; if (g1 > g2 || (g1 == g2 && !(s1 == s2 && s1 == g1))) { ok = false; break; } } if (!ok) { cout << -1 << '\n'; continue; } // 1: R, -1: L, 0: S vector type(M); for (int i = 0; i < M; ++i) { auto [s, g] = A[i]; if (s < g) type[i] = 1; if (s > g) type[i] = -1; } vector paired(M); ll ans = 0; // RL ペア for (int i = 0; i + 1 < M; ++i) { if (type[i] == 1 && type[i + 1] == -1) { paired[i] = paired[i + 1] = true; auto [s1, g1] = A[i]; auto [s2, g2] = A[i + 1]; ll X = g1 - s1; ll Y = s2 - g2; ll D = g2 - g1; ans += solve_pair(X, Y, D); } } // RL ペアに含まれないもの for (int i = 0; i < M; ++i) { if (paired[i]) continue; auto [s, g] = A[i]; if (type[i] == 1) { if (i + 1 == M) { ++ans; } else { ans += calc(g - s, A[i + 1].second - g); } } if (type[i] == -1) { if (i == 0) { ++ans; } else { ans += calc(s - g, g - A[i - 1].second); } } } cout << ans << '\n'; } }