#include <bits/stdc++.h>
using namespace std;
namespace TYC {
const int N = 4, INF = 0x3f3f3f3f;
int answer, Dir[N];
struct point {
  int x, y;
} Node[N], R[N];
namespace BF0 {
int D, Y[N], A[N], Pos[N];
inline int calc(const int x) {
  int mx = 0;
  for (int i = 0; i < N; i++) mx = max(mx, abs(A[i] - x));
  return mx;
}
inline void getans(const int x1, const int x2, int l, int r) {
  int lmid, rmid, y = INF, res = INF, len;
  while (l <= r) {
    len = max(1, (r - l + 1) / 3);
    lmid = l + len;
    rmid = r - len;
    int v0 = calc(lmid), v1 = calc(rmid);
    if (v0 < res) res = v0, y = lmid;
    if (v1 < res) res = v1, y = rmid;
    if (v0 < v1)
      r = rmid;
    else
      l = lmid;
  }
  if (res < answer) {
    answer = res;
    R[0] = {x1, y}, R[1] = {x1, y + D};
    R[2] = {x2, y}, R[3] = {x2, y + D};
  }
}
void update(const int x1, const int x2) {
  for (int i = 0; i < N; i++) A[i] = Y[i] - (i & 1 ? D : 0);
  sort(Pos, Pos + N);
  for (int i = 0; i <= N; i++)
    getans(x1, x2, !i ? -INF : Pos[i - 1], i == N ? INF : Pos[i]);
}
void solve(const int x1, const int x2) {
  D = x2 - x1;
  int c = 0;
  for (int i = 0; i < N; i++)
    if (Node[i].x == x1) Y[c++] = Node[i].y;
  for (int i = 0; i < N; i++)
    if (Node[i].x == x2) Y[c++] = Node[i].y;
  update(x1, x2);
  swap(Y[0], Y[1]), update(x1, x2);
  swap(Y[2], Y[3]), update(x1, x2);
  swap(Y[0], Y[1]), update(x1, x2);
}
}  // namespace BF0
namespace BF2 {
int ID[N];
inline bool check(const int i, const int x, const int y) {
  return !Dir[ID[i]] ? Node[ID[i]].x == x : Node[ID[i]].y == y;
}
inline int calc(const int i, const int x, const int y) {
  return !Dir[ID[i]] ? abs(Node[ID[i]].y - y) : abs(Node[ID[i]].x - x);
}
void solve(const int x1, const int x2, const int y1, const int y2) {
  if (x2 - x1 != y2 - y1) return;
  for (int i = 0; i < N; i++) ID[i] = i;
  int minv = INF;
  point T[N];
  T[0] = {x1, y1}, T[1] = {x1, y2}, T[2] = {x2, y1}, T[3] = {x2, y2};
  do {
    int mx = 0;
    for (int i = 0; i < N; i++)
      mx = max(mx, check(i, T[i].x, T[i].y) ? calc(i, T[i].x, T[i].y) : INF);
    minv = min(minv, mx);
  } while (next_permutation(ID, ID + N));
  if (minv < answer) {
    answer = minv;
    R[0] = {x1, y1}, R[1] = {x1, y2};
    R[2] = {x2, y1}, R[3] = {x2, y2};
  }
}
}  // namespace BF2
namespace BF1 {
void solve(const int x1, const int x2, const int y) {
  int d = x2 - x1;
  BF2::solve(x1, x2, y - d, y);
  BF2::solve(x1, x2, y, y + d);
}
}  // namespace BF1
void solve() {
  set<int> X, Y;
  for (int i = 0; i < N; i++)
    !Dir[i] ? X.insert(Node[i].x) : Y.insert(Node[i].y);
  if (int(X.size()) != 2) return;
  switch (int(Y.size())) {
    case 0:
      BF0::solve(*X.begin(), *next(X.begin()));
      return;
    case 1:
      BF1::solve(*X.begin(), *next(X.begin()), *Y.begin());
      return;
    case 2:
      BF2::solve(*X.begin(), *next(X.begin()), *Y.begin(), *next(Y.begin()));
      return;
    default:
      return;
  }
}
void dfs(const int i) {
  if (i == N) return solve();
  Dir[i] = 0, dfs(i + 1);
  Dir[i] = 1, dfs(i + 1);
}
namespace Print {
using namespace BF2;
bool solve() {
  for (int i = 0; i < N; i++) ID[i] = i;
  do {
    int mx = 0;
    for (int i = 0; i < N; i++)
      mx = max(mx, check(i, R[i].x, R[i].y) ? calc(i, R[i].x, R[i].y) : INF);
    if (mx == answer) {
      static point tmp[N];
      memcpy(tmp, R, sizeof(R));
      for (int i = 0; i < N; i++) R[ID[i]] = tmp[i];
      return true;
    }
  } while (next_permutation(ID, ID + N));
  return false;
}
bool get_dir(const int i) {
  if (i == N) return solve();
  Dir[i] = 0;
  if (get_dir(i + 1)) return true;
  Dir[i] = 1;
  if (get_dir(i + 1)) return true;
  return false;
}
}  // namespace Print
void work() {
  int T;
  scanf("%d", &T);
  while (T--) {
    for (int i = 0; i < N; i++) scanf("%d%d", &Node[i].x, &Node[i].y);
    answer = INF;
    dfs(0);
    int ans0 = answer;
    for (int i = 0; i < N; i++) swap(Node[i].x, Node[i].y);
    dfs(0);
    if (answer == INF)
      puts("-1");
    else {
      printf("%d\n", answer);
      if (ans0 == answer) {
        for (int i = 0; i < N; i++) swap(Node[i].x, Node[i].y);
        Print::get_dir(0);
      } else {
        Print::get_dir(0);
        for (int i = 0; i < N; i++) swap(R[i].x, R[i].y);
      }
      for (int i = 0; i < N; i++) printf("%d %d\n", R[i].x, R[i].y);
    }
  }
}
}  // namespace TYC
int main() {
  TYC::work();
  return 0;
}
