// 平面幾何

// 型変換
//   double  -> Point
//   Segment -> Line

////////////////////
// ライブラリ
#include<cmath>
#include<algorithm>
#include<cassert>
////////////////////
// 定数
const double EPS = 1e-9;
////////////////////
// 構造体
struct Point {
  double x, y;
  Point(const double d = 0.0) :x(d), y(d) {}
  Point(const double x, const double y) :x(x), y(y) {}
};
struct Segment {
  Point initial, terminal;
  Segment(const Point& initial = 0, const Point& terminal = 0) :initial(initial), terminal(terminal) {}
};
struct Line {
  Point initial, terminal;
  Line(const Point& initial = 0, const Point& terminal = 0) :initial(initial), terminal(terminal) {}
  Line(const Segment& s) :initial(s.initial), terminal(s.terminal) {}
};
////////////////////
// 実装
// bool operator==(const Point& lhs, const Point& rhs) {return lhs.x == rhs.x && lhs.y == rhs.y;}
// bool operator<(const Point& lhs, const Point& rhs) {return lhs.x != rhs.x ? lhs.x < rhs.x : lhs.y < rhs.y;}
// bool operator>(const Point& lhs, const Point& rhs) {return lhs.x != rhs.x ? lhs.x > rhs.x : lhs.y > rhs.y;}
// bool operator!=(const Point& lhs, const Point& rhs) {return !(lhs == rhs);}
// bool operator<=(const Point& lhs, const Point& rhs) {return !(lhs > rhs);}
// bool operator>=(const Point& lhs, const Point& rhs) {return !(lhs < rhs);}
const Point operator+(const Point& lhs, const Point& rhs) {return Point(lhs.x + rhs.x, lhs.y + rhs.y);}
const Point operator-(const Point& lhs, const Point& rhs) {return Point(lhs.x - rhs.x, lhs.y - rhs.y);}
const Point operator*(const Point& lhs, const Point& rhs) {return Point(lhs.x * rhs.x, lhs.y * rhs.y);}
const Point operator/(const Point& lhs, const Point& rhs) {return Point(lhs.x / rhs.x, lhs.y / rhs.y);}
const Point operator-(const Point& p) {return Point(-p.x, -p.y);}
// 点
double abs(const Point& p) {return std::hypot(p.x, p.y);}
double norm(const Point& p) {return p.x * p.x + p.y * p.y;}
double dot(const Point& a, const Point& b) {return a.x * b.x + a.y * b.y;}
double cross(const Point& a, const Point& b) {return a.x * b.y - a.y * b.x;}
// const Point normalize(const Point& p) {return p / hypot(p.x, p.y);}
// 線
bool parallel(const Line& l1, const Line& l2) {return std::abs(cross(l2.terminal - l2.initial, l1.terminal - l1.initial)) <= EPS;}
bool orthogonal(const Line& l1, const Line& l2) {return std::abs(dot(l2.terminal - l2.initial, l1.terminal - l1.initial)) <= EPS;}
// 点の位置関係
enum POSITION {ONLINE_FRONT = -2, CLOCKWISE, ON_SEGMENT, COUNTER_CLOCKWISE, ONLINE_BACK}; 
POSITION ccw(const Point& a, const Point& b, const Point& p) {
  Point v1 = b - a;
  Point v2 = p - a;
  if(cross(v1, v2) > EPS) return COUNTER_CLOCKWISE;
  if(cross(v1, v2) < -EPS) return CLOCKWISE;
  if(dot(v1, v2) < -EPS) return ONLINE_BACK;
  if(norm(v2) - norm(v1) > EPS) return ONLINE_FRONT;
  return ON_SEGMENT;
}
// 交差判定
bool intersect(const Point& p1, const Point& p2) {return p1.x == p2.x && p1.y == p2.y;}
bool intersect(const Point& p, const Segment& s) {return abs(p - s.initial) + abs(p - s.terminal) - abs(s.initial - s.terminal) <= EPS;}
bool intersect(const Segment& s, const Point& p) {return intersect(p, s);}
bool intersect(const Point& p, const Line& l) {return !parallel(l.terminal - p, l.initial - p);}
bool intersect(const Line& l, const Point& p) {return intersect(p, l);}
bool intersect(const Segment& s1, const Segment& s2) {
  return ccw(s1.initial, s1.terminal, s2.initial) * ccw(s1.initial, s1.terminal, s2.terminal) <= 0
      && ccw(s2.initial, s2.terminal, s1.initial) * ccw(s2.initial, s2.terminal, s1.terminal) <= 0;
}
bool intersect(const Segment& s, const Line& l) {
  auto v1 = l.terminal - l.initial;
  auto v2 = s.initial  - l.initial;
  auto v3 = s.terminal - l.initial;
  return cross(v1, v2) * cross(v1, v3) <= EPS;
}
bool intersect(const Line& l, const Segment& s) {return intersect(s, l);}
bool intersect(const Line& l1, const Line& l2) {return !parallel(l1, l2) || parallel(l1, Line(l1.initial, l2.initial));}  // 非平行または同一直線上
// 点移動
Point projection(const Point& p, const Line& l) {
  auto v = l.initial - l.terminal;
  return l.initial + dot(p - l.initial, v) / norm(v) * v;
}
Point projection(const Line& l, const Point& p) {return projection(p, l);}
Point reflection(const Point& p, const Line& l) {return p + 2 * (projection(p, l) - p);}
Point reflection(const Line& l, const Point& p) {return reflection(p, l);}
// 距離
double distance(const Point& p1, const Point& p2) {
  auto p = p1 - p2;
  return hypot(p.x, p.y);
}
double distance(const Point& p, const Segment& s) {
  auto r = projection(s, p);
  return intersect(r, s) ? distance(p, r) : std::min(distance(p, s.initial), distance(p, s.terminal));
}
double distance(const Segment& s, const Point& p) {return distance(p, s);}
double distance(const Point& p, const Line& l) {return distance(p, projection(p, l));}
double distance(const Line& l, const Point& p) {return distance(p, l);}
double distance(const Segment& s1, const Segment& s2) {
  return intersect(s1, s2) ? 0.0 : std::min({distance(s1, s2.initial),
                                             distance(s1, s2.terminal),
                                             distance(s2, s1.initial),
                                             distance(s2, s1.terminal)});
}
double distance(const Segment& s, const Line& l) {return intersect(s, l) ? 0.0 : std::min(distance(s.initial, l), distance(s.terminal, l));}
double distance(const Line& l,const Segment& s) {return distance(s, l);}
double distance(const Line& l1, const Line& l2) {return intersect(l1, l2) ? 0.0 : distance(l1.initial, l2);}
// 交点
const Point crosspoint(const Line& l1, const Line& l2) {
  double A = cross(l1.terminal - l1.initial, l2.terminal - l2.initial);
  double B = cross(l1.terminal - l1.initial, l1.terminal - l2.initial);
  if(std::abs(A) < EPS && std::abs(B) < EPS) return l2.initial;
  assert(std::abs(A) > EPS);                                // 平行かつ同一直線上にない
  return l2.initial + B / A * (l2.terminal - l2.initial);
}
const Point crosspoint(const Segment& s, const Line& l) {
  Point cp = crosspoint(Line(s), l);
  assert(intersect(s, cp));                                 // 2直線の交点が線分上にない
  return cp;
}
const Point crosspoint(const Line& l, const Segment& s) {return crosspoint(s, l);}
const Point crosspoint(const Segment& s1, const Segment& s2) {
  Point cp = crosspoint(Line(s1), Line(s2));
  assert(intersect(s1, cp) && intersect(s2, cp));           // 2直線の交点が線分上にない
  return cp;
}
// デバッグ用
// #include<bits/stdc++.h>
// using namespace std;
// void print(const Point& p) {cout<<"("<<p.x<<","<<p.y<<")";}
// void print(const Line& l) {print(l.initial); cout<<" - ";print(l.terminal);}
////////////////////////////////////////////////////////////////////////////////
// 多角形
//   辺をメンバ変数に持たないようにすればメモリ節約（1/3くらい？） + シンプルに記述 + edge(void)がO(n)
#include<vector>
#include<algorithm>
#include<utility>
class Polygon {
public:
  void add(const Point& p) {
    if(!vertex_.empty()) {
      if(!edge_.empty()) edge_.pop_back();
      edge_.push_back(Segment(vertex_.back(), p));
      edge_.push_back(Segment(p, vertex_.front()));
    }
    vertex_.push_back(p);
  }
  int size() const {return vertex_.size();}
  Point vertex(const int n) const {return vertex_.at(n);}
  Segment edge(const int n) const {return edge_.at(n);}
  const std::vector<Point>& vertex() const {return vertex_;}
  const std::vector<Segment>& edge() const {return edge_;}
  bool touch(const Point& p) const {
    return std::any_of(edge_.begin(), edge_.end(), [=](const Segment& s) {return ccw(s.initial, s.terminal, p) == ON_SEGMENT;});
  }
  bool include(const Point& p) const {  // intersect()という名前にしたいけどグローバルスコープのintersect()たちが隠蔽されて困った
    bool in = false;                    // p=(x,y)から(INF,y)への半直線と多角形とが交差する回数 mod 2
    for(const auto& e: edge()) {
      if(intersect(p, e)) return true;
      Point a = e.initial  - p;
      Point b = e.terminal - p;
      if(a.y > b.y) std::swap(a, b);
      if(a.y <= EPS && 0.0 < b.y && cross(a, b) < EPS) in = !in;
    }
    return in;
  }
    void clear() {
      vertex_.clear();
      edge_.clear();
    };
private:
  std::vector<Point> vertex_;
  std::vector<Segment> edge_;
};
////////////////////////////////////////////////////////////////////////////////
#include<bits/stdc++.h>
using namespace std;
int main() {
  int n;
//   Polygon polygon;
  for(cin >> n; n > 0; --n) {
    int a, b, c, d, e, f, g, h;
    cin >> a >> b >> c >> d >> e >> f >> g >> h;
    Segment s(Point(a, b), Point(c, d));
    Segment t(Point(e, f), Point(g, h));
    auto cp = crosspoint(s, t);
    cout<<setprecision(10)<<fixed<<cp.x<<" "<<cp.y<<endl;
//     cout << (intersect(s, t) ? 1 : 0) << endl;
//     int x, y;
//     cin >> x >> y;
//     polygon.add(Point(x, y));
  }
//   int q;
//   for(cin >> q; q > 0; --q) {
//     int x, y;
//     cin >> x >> y;
//     Point p(x, y);
//     cout << (polygon.touch(p) ? 1 : (polygon.include(p) ? 2 : 0)) << endl;
//   }
}

Measured memory_bytes: 1248