description: You have an axis-aligned rectangle room with width W and height H, so the lower left corner is in point (0, 0) and the upper right corner is in (W, H).
  
  There is a rectangular table standing in this room. The sides of the table are parallel to the walls, the lower left corner is in (x_1, y_1), and the upper right corner in (x_2, y_2).
  
  You want to place another rectangular table in this room with width w and height h with the width of the table parallel to the width of the room.
  
  The problem is that sometimes there is not enough space to place the second table without intersecting with the first one (there are no problems with tables touching, though).
  
  You can't rotate any of the tables, but you can move the first table inside the room. 
  
  <image> Example of how you may move the first table.
  
  What is the minimum distance you should move the first table to free enough space for the second one?
  
  Input
  
  The first line contains the single integer t (1 ≤ t ≤ 5000) — the number of the test cases.
  
  The first line of each test case contains two integers W and H (1 ≤ W, H ≤ 10^8) — the width and the height of the room.
  
  The second line contains four integers x_1, y_1, x_2 and y_2 (0 ≤ x_1 < x_2 ≤ W; 0 ≤ y_1 < y_2 ≤ H) — the coordinates of the corners of the first table.
  
  The third line contains two integers w and h (1 ≤ w ≤ W; 1 ≤ h ≤ H) — the width and the height of the second table.
  
  Output
  
  For each test case, print the minimum distance you should move the first table, or -1 if there is no way to free enough space for the second table.
  
  Your answer will be considered correct if its absolute or relative error doesn't exceed 10^{-6}.
  
  Example
  
  Input
  
  
  5
  8 5
  2 1 7 4
  4 2
  5 4
  2 2 5 4
  3 3
  1 8
  0 3 1 6
  1 5
  8 1
  3 0 6 1
  5 1
  8 10
  4 5 7 8
  8 5
  
  
  Output
  
  
  1.000000000
  -1
  2.000000000
  2.000000000
  0.000000000
  
  Note
  
  The configuration of the first test case is shown in the picture. But the movement of the first table is not optimal. One of the optimal movement, for example, is to move the table by (0, -1), so the lower left corner will move from (2, 1) to (2, 0). Then you can place the second table at (0, 3)-(4, 5).
  
  In the second test case, there is no way to fit both tables in the room without intersecting.
  
  In the third test case, you can move the first table by (0, 2), so the lower left corner will move from (0, 3) to (0, 5).
solution: import java.io.*;
  import java.util.*;
  import java.math.*;
  
  public final class Main {
      BufferedReader br;
      StringTokenizer stk;
      PrintWriter pw;
      
      String problemName = "";
      String inputFile, outputFile;
      public static void main(String[] args) throws Exception {
          new Main().run();
      }
      
      boolean tests = true;
      
      long mod = 1000_000_000 + 7;
      StringBuilder res = new StringBuilder(1000005);
      
      void preprocess() throws Exception {
          
      }
      
      void run() throws Exception {
          if(!problemName.isEmpty()) {
              inputFile = problemName + ".in";
              outputFile = problemName + ".out";
          }
          try {
              stk = null;
              
              if(inputFile == null)
                  br = new BufferedReader(new InputStreamReader(System.in));
              else
                  br = new BufferedReader(new FileReader(inputFile));
              
              if(outputFile == null)
                  pw = new PrintWriter(System.out);
              else
                  pw = new PrintWriter(new FileWriter(outputFile));
          } catch(Exception ex) {
              ex.printStackTrace();
          }
          
          int t = tests ? ni() : 1;
          preprocess();
          for(int i = 1; i <= t; i++) {
              go(i);
          }
          
          // outputting your solution
          if(outputFile == null)
              System.out.println(res.length() == 0 ? "" : res);
          else
              pw.print(res.length() == 0 ? "" : res);
              
          if(outputFile != null) {
              pw.flush();
          }
      }
      
      void go(int T) throws Exception {
          long W = nl(), H = nl();
          long x1 = ni(), y1 = ni(), x2 = ni(), y2 = ni();
          long w = ni(), h = ni();
  
          if(ok(W, H, x1, y1, x2, y2, w, h)) {
              res.append(0.0d).append("\n");
          } else if(w + (x2 - x1) > W && h + (y2 - y1) > H) {
              res.append("-1\n");
          } else {
              long maxPushUp = H - y2, maxPushDown = y1;
              long maxPushLeft = x1, maxPushRight = W - x2;
  
              long min = Long.MAX_VALUE, low, high;
  
              // vertical
              low = 1; high = maxPushUp;
              while(high - low > 4) {
                  long mid = (high + low) / 2;
                  if(ok(W, H, x1, y1 + mid, x2, y2 + mid, w, h)) {
                      high = mid;
                  } else {
                      low  = mid;
                  }
              }
              for(long i = low; i <= high; i++) {
                  if(ok(W, H, x1, y1 + i, x2, y2 + i, w, h)) {
                      min = Math.min(min, i);
                      break;
                  }
              }
  
              low = 1; high = maxPushDown;
              while(high - low > 4) {
                  long mid = (high + low) / 2;
                  if(ok(W, H, x1, y1 - mid, x2, y2 - mid, w, h)) {
                      high = mid;
                  } else {
                      low  = mid;
                  }
              }
              for(long i = low; i <= high; i++) {
                  if(ok(W, H, x1, y1 - i, x2, y2 - i, w, h)) {
                      min = Math.min(min, i);
                      break;
                  }
              }
  
              // horizontal
              low = 1; high = maxPushLeft;
              while(high - low > 4) {
                  long mid = (high + low) / 2;
                  if(ok(W, H, x1 - mid, y1, x2 - mid, y2, w, h)) {
                      high = mid;
                  } else {
                      low  = mid;
                  }
              }
              for(long i = low; i <= high; i++) {
                  if(ok(W, H, x1 - i, y1, x2 - i, y2, w, h)) {
                      min = Math.min(min, i);
                      break;
                  }
              }
  
              low = 1; high = maxPushRight;
              while(high - low > 4) {
                  long mid = (high + low) / 2;
                  if(ok(W, H, x1 + mid, y1, x2 + mid, y2, w, h)) {
                      high = mid;
                  } else {
                      low  = mid;
                  }
              }
              for(long i = low; i <= high; i++) {
                  if(ok(W, H, x1 + i, y1, x2 + i, y2, w, h)) {
                      min = Math.min(min, i);
                      break;
                  }
              }
  
              // ans
              res.append((double) min).append("\n");
          }
      }
  
      boolean ok(long W, long H, long x1, long y1, long x2, long y2, long w, long h) {
          return (h <= y1 || w <= x1 || w <= (W - x2) || h <= (H - y2));
      }
      
      class Node {
          HashSet<Integer> adj;
          public Node() {
              adj = new HashSet<>();
          }
      }
      
      class SegmentTree {
          long[] tree;
          int L, M, FILLER;
          public SegmentTree(long[] a) {
              L = a.length;
              if(Integer.bitCount(L) == 1) {
                  L <<= 1;
              } else {
                  L = Integer.highestOneBit(L) << 2;
              }
              
              M = L >> 1;
              
              FILLER = 0;
              
              tree = new long[L];
              if(FILLER != 0) {
                  Arrays.fill(tree, FILLER);
              }
              for(int i = 0, j = M; i < a.length; i++, j++) {
                  tree[j] = a[i];
              }
              for(int i = M - 1; i > 0; i--) {
                  tree[i] = merge(tree[2 * i], tree[2 * i + 1]);
              }
          }
          
          void update(int idx, long value) {
              idx += M;
              tree[idx] = value;
              idx >>= 1;
              while(idx > 0) {
                  tree[idx] = merge(tree[2 * idx], tree[2 * idx + 1]);
                  idx >>= 1;
              }
          }
          
          long query(int l, int r) {
              return propogate(l + M, r + M, M, L - 1, 1);
          }
          
          long propogate(int ql, int qr, int cl, int cr, int index) {
              if(cl >= ql && cr <= qr) {
                  return tree[index];
              } else if(cl > qr || ql > cr) {
                  return FILLER;
              } else {
                  int mid = (cl + cr) / 2;
                  return merge(propogate(ql, qr, cl, mid, 2 * index), propogate(ql, qr, mid + 1, cr, 2 * index + 1));
              }
          }
          
          long merge(long a, long b) {
              return a + b;
          }
      }
      
      class DJSet {
          Node[] graph;
          public DJSet(int n) {
              graph = new Node[n];
              for(int i = 0; i < n; i++) {
                  graph[i] = new Node();
              }
          }
          
          boolean belongsToOneSet(int u, int v) {
              int x = root(u);
              int y = root(v);
              return x == y && x != -1;
          }
          
          int root(int x) {
              if(graph[x].parent == -1)
                  return x;
              return root(graph[x].parent);
          }
          
          boolean union(int u, int v) {
              int x = root(u);
              int y = root(v);
              if(x == y)
                  return false;
              if(graph[x].members > graph[y].members) {
                  graph[x].members += graph[y].members;
                  graph[y].parent = x;
              } else {
                  graph[y].members += graph[x].members;
                  graph[x].parent = y;
              }
              return true;
          }
          
          class Node {
              int members, parent;
              public Node() {
                  this.parent = -1;
                  this.members = 1;
              }
          }
      }
      
      // RollingHash works in nlogn time
      // can be improved
      class RollingHash {
          int N;
          long hash[], pows[], invs[], mod, prime;
          public RollingHash(long prime, long mod, int[] a) {
              int n = a.length;
              
              this.N = n;
              this.mod = mod;
              hash = new long[n];
              pows = new long[n];
              invs = new long[n];
              this.prime = prime;
              
              build(a);
          }
          
          void build(int[] a) {
              pows[0] = invs[0] = 1;
              for(int i = 0; i < N; i++) {
                  if(i > 0) {
                      pows[i] = (pows[i - 1] * prime) % mod;
                      invs[i] = modInverse(pows[i], mod);
                  }
                  hash[i] = (a[i] * pows[i]) % mod;
                  if(i > 0) {
                      hash[i] = (hash[i] + hash[i - 1]) % mod;
                  }
              }
          }
          
          long getHash(int l, int r) {
              return ((getSum(l, r, hash) % mod) * invs[l]) % mod;
          }
          
          long modInverse(long x, long m) {
              return modPow(x, m - 2, m);
          }
  
          long modPow(long x, long pow, long m) {
              if(pow == 0) return 1;
              if(pow == 1) return x;
              long tem = modPow(x, pow / 2, m);
              if(pow % 2 == 0)
                  return ((tem * tem) % m);
              return (((tem * tem) % m) * x) % m;
          }
  
          long getSum(int l, int r, long[] a) {
              long sum = (l == 0) ? a[r] : a[r] - a[l - 1];
              if(sum < 0) sum += mod;
              return sum;
          }
          
          void print() {
              System.out.println(Arrays.toString(hash));
          }
      }
      
      //Reader & Writer
      String nt() throws Exception {
          if (stk == null || !stk.hasMoreTokens())
              stk = new StringTokenizer(br.readLine(), " ");
          return stk.nextToken();
      }
  
      char[] nc() throws Exception {
          return nt().toCharArray();
      }
  
      int ni() throws Exception {
          return Integer.parseInt(nt());
      }
  
      long nl() throws Exception {
          return Long.parseLong(nt());
      }
      
      double nd() throws Exception {
          return Double.parseDouble(nt());
      }
      
      //Some Misc methods
      int get(int l, int r, int[] a) {
          return l == 0 ? a[r] : a[r] - a[l - 1];
      }
      
      void shuffle(int[] a) {
          Random r = new Random();
          for(int i = 0; i < a.length; i++) {
              int idx = r.nextInt(a.length);
              int temp = a[i];
              a[i] = a[idx];
              a[idx] = temp;
          }
      }
      
      void reverse(long[] a) {
          for(int i = 0, j = a.length - 1; i < j; i++, j--) {
              long temp = a[i];
              a[i] = a[j];
              a[j] = temp;
          }
      }
      
      boolean isPrime(long n) {
          for(long i = 2; i * i <= n; i++) {
              if(n % i == 0) return false;
          }
          return true;
      }
      
      long max(long... a) {
          long max = a[0];
          for(int i = 1; i < a.length; i++)
              max = Math.max(max, a[i]);
          return max;
      }
      
      long min(long... a) {
          long min = a[0];
          for(int i = 1; i < a.length; i++)
              min = Math.min(min, a[i]);
          return min;
      }
      
      void tr(Object... o) {
          System.out.println(Arrays.deepToString(o));
      }
  }