#include <bits/stdc++.h>
using namespace std;

#define EPS 1e-10
#define equals(a,b) (fabs((a)-(b))<EPS)
#define int long long
const int inf = 1LL << 55;
class Point{
  public:
  double x,y;
  Point(double x=0,double y=0):x(x),y(y){}
  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double a){return Point(a*x,a*y);}
  Point operator / (double a){return Point(x/a,y/a);}

  double norm() { return x*x + y*y; }

  bool operator == (const Point &p) const{
    return fabs(x-p.x)<EPS&&fabs(y-p.y)<EPS;
  }
  bool operator < (const Point &p)const{
    return y+x*EPS<p.y+p.x*EPS;
  }
};

//bool operator<(const Point& a, const Point& b) { return a.y * 1e10 + a.x < b.y * 1e10 + b.x; }

typedef Point V;
typedef vector<Point> Polygon;
struct Segment {
  Point p1, p2;
  Segment(Point p1 = Point(), Point p2 = Point()):p1(p1), p2(p2){}
};
typedef Segment Line;

//内積
double dot(V a,V b){
  return a.x*b.x+a.y*b.y;
}

//外積
double cross(V a,V b){
  return a.x*b.y-a.y*b.x;
}

//直行判定 内積が0
bool isOrthogonal(Point a,Point b){
  return equals(dot(a,b),0.0);
}
bool isOrthogonal(Point a1,Point a2,Point b1,Point b2){
  return isOrthogonal(a1-a2,b1-b2);
}
//平行判定　外積が0
bool isParallel(Point a,Point b){
  return equals(cross(a,b),0.0);
}

bool isParallel(Point a1,Point a2,Point b1,Point b2){
  return isParallel(a1-a2,b1-b2);
}

double norm(Point p){return p.x*p.x+p.y*p.y;}
double abs(Point p){return sqrt(norm(p));}


//直線a1,a2に対する点pの射影
Point project(Point a1,Point a2,Point p){
  Point base = a2-a1;
  double r=dot(p-a1,base)/norm(base);
  return a1+base*r;
}

Point reflect(Point a1,Point a2,Point p){
  return p + (project(a1,a2,p)-p)*2.0;
}

//線分a,bに対するcの位置
int ccw(Point a, Point b, Point c) {
    Point d = b - a;
    Point e = c - a;
    //CCW
    if (cross(d, e) > EPS) { return 1; }
    //CW
    if ((cross(d, e)) < -EPS) { return -1; }
    if (fabs(cross(d, e)) < 1e-10) return -1;
    //ONB
    if (dot(d, e) < -EPS) { return 2; }
    //ONF
    if (dot(d, e) < e.norm()) { return -2; }
    //ONS
    return 0;
}

bool intersect(Point p1,Point p2,Point p3,Point p4){
  return (ccw(p1,p2,p3)*ccw(p1,p2,p4)<=0&&ccw(p3,p4,p1)*ccw(p3,p4,p2)<=0);
}
bool intersect(Segment s1, Segment s2)
{
  return intersect(s1.p1, s1.p2, s2.p1, s2.p2);
}
//2点間の距離
double getDistance(Point a,Point b){
  return sqrt(norm(a-b));
}

//直線と点との距離
double getDistanceLP(Point a1,Point a2,Point b){
  return abs(cross(a2-a1,b-a1))/sqrt(norm(a2-a1));
}
double getDistanceLP(Line l, Point p)
{
  return abs(cross(l.p2 - l.p1, p - l.p1) / abs(l.p2 - l.p1));
}
//線分と点との距離 線分と線分の時は交差していたら0になるのを忘れずに
double getDistanceSP(Point a1,Point a2,Point b){
  if(dot(a2-a1,b-a1)<0.0)return abs(b-a1);
  if(dot(a1-a2,b-a2)<0.0)return abs(b-a2);
  return getDistanceLP(a1,a2,b);
}
double getDistanceSP(Segment s, Point p)
{
  if(dot(s.p2 - s.p1, p - s.p1) < 0.0) return abs(p - s.p1);
  if(dot(s.p1 - s.p2, p - s.p2) < 0.0) return abs(p - s.p2);
  return getDistanceLP(s, p);
}

//線分a1a2とb1b2との交点を求める。
Point getCrossPoint(Point a1,Point a2,Point b1,Point b2){
  Point base=b2-b1;
  double d1=abs(cross(base,a1-b1));
  double d2=abs(cross(base,a2-b1));
  double t=d1/(d1+d2);
  return a1+(a2-a1)*t;
}

//2線分間の距離
double getDistance(Segment s1, Segment s2)
{
  if(intersect(s1, s2)) return 0.0;
  return min(min(getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2)),
         min(getDistanceSP(s2, s1.p1), getDistanceSP(s2, s1.p2)));
}

//点の包含判定 in 2 on 1 out 0
int contain(vector<Point> v,Point p){
  bool in=false;
  for(int i=0;i<v.size();i++){
    Point a=v[i]-p,b=v[(i+1)%v.size()]-p;
    if(abs(cross(a,b))<EPS&&dot(a,b)<EPS)return 1;
    if(a.y>b.y)swap(a,b);
    if(a.y<=0&&0<b.y&&cross(a,b)<0)in=!in;
    if(cross(a,b)==0&&dot(a,b)<=0)return 1;
  }
  return in ?2:0;
}

vector<Point> andrewScan(vector<Point> s){
  vector<Point> u,l;
  if(s.size()<3)return s;
  //x,yを基準にソート
  sort(s.begin(),s.end());
  //xが小さいものから2つuに追加
  u.push_back(s[0]);
  u.push_back(s[1]);
  //xが大きいものから2つlに追加
  l.push_back(s[s.size()-1]);
  l.push_back(s[s.size()-2]);

  //凸　上部
  for(int i=2;i<s.size();i++){
    for(int j=u.size();j>=2;j--){
      if(ccw(u[j-2],u[j-1],s[i])==-1)break;
      u.pop_back();
    }
    u.push_back(s[i]);
  }
  //凸　下部
  for(int i=s.size()-3;i>=0;i--){
    for(int j=l.size();j>=2;j--){
      if(ccw(l[j-2],l[j-1],s[i])==-1)break;
      l.pop_back();
    }
    l.push_back(s[i]);
  }

  //時計回りになるように凸の点の列を生成
  reverse(l.begin(),l.end());
  for(int i=u.size()-2;i>=1;i--)l.push_back(u[i]);

  return l;

}

signed main(){
  int q;
  cin>>q;
  while(q--){
    Point p1,p2,p3,p4;
    cin>>p1.x>>p1.y>>p2.x>>p2.y>>p3.x>>p3.y>>p4.x>>p4.y;
    Segment s1={p1,p2},s2={p3,p4};
    cout<<fixed<<setprecision(10)<<getCrossPoint(p1,p2,p3,p4).x<<" "<<getCrossPoint(p1,p2,p3,p4).y<<endl;
  }
}

Measured memory_bytes: 3268