#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
using namespace std;

typedef long long LL;
double sqr(double x) { return x*x; }

struct VEC {
	LL x,y,z;

	bool operator==(const VEC a) const { return x==a.x&&y==a.y&&z==a.z; }
	bool operator!=(VEC a) const { return !(*this==a); }
	bool operator<(VEC a) const { return x!=a.x? x<a.x : (y!=a.y?y<a.y:z<a.z); }

	double sqrlen() const { return sqr(x)+sqr(y)+sqr(z); }
	double length() const { return sqrt(sqrlen()); }
};
VEC operator+(VEC a,VEC b) { return (VEC){a.x+b.x,a.y+b.y,a.z+b.z}; }
VEC operator-(VEC a,VEC b) { return (VEC){a.x-b.x,a.y-b.y,a.z-b.z}; }
VEC operator*(VEC a,VEC b) { return (VEC){a.y*b.z-a.z*b.y, a.z*b.x-a.x*b.z, a.x*b.y-a.y*b.x}; }

//判点是否在三角形内，包括边界
bool dotInplaneIn(VEC p,VEC a,VEC b,VEC c) {  //用area写
	return fabs(((a-b)*(a-c)).length() - ((p-a)*(p-b)).length() - ((p-b)*(p-c)).length() - ((p-c)*(p-a)).length()) < 1e-4;
}


int n;
VEC a[2001][4];
VEC A,B; int src,dst;

map<VEC,VEC> pre; VEC final;
bool yes(LL h) {
	map<VEC,vector<int> > xm;  //unordered_map不行的...
	vector<VEC> face[n+1];
	queue<VEC> q;
	set<VEC> xs;  //unordered_set??
	pre.clear(); final=(VEC){-1ll,-1ll,-1ll};
	for (int i=1;i<=n;i++) {
		for (int j=0;j<3;j++) {
			if (a[i][j].z-h<=0) face[i].pb(a[i][j]),xm[a[i][j]].pb(i);
			if (a[i][j+1].z<=h) face[i].pb(a[i][j+1]),xm[a[i][j+1]].pb(i);
		}
		if (i==src)
			for (int z=0;z<face[i].size();z++) {
				q.push(face[i][z]);
				xs.insert(face[i][z]);
			}
	}
	VEC u;
	while (q.size()) {
		u=q.front(); q.pop();
		if (dotInplaneIn(u,a[dst][0],a[dst][1],a[dst][2])) {
			final=u;
			return 1;
		}
		for (int &i:xm[u]) {
			for (VEC &v:face[i]) {
				if (xs.find(v)!=xs.end()) continue;
				q.push(v); xs.insert(v); pre[v]=u;
			}
		}
	}
	return 0;
}
int main() {
	freopen("hiking.in","r",stdin);
	freopen("hiking.out","w",stdout);

	for (;~scanf("%d",&n);) {
		LL mx=0;
		for (int i=1;i<=n;i++) {
			for (int j=0;j<3;j++) {
				scanf("%I64d%I64d%I64d",&a[i][j].x,&a[i][j].y,&a[i][j].z);
				mx=max(mx,a[i][j].z);
			}
			a[i][3]=a[i][0];
		}
		scanf("%I64d%I64d%I64d",&A.x,&A.y,&A.z);
		scanf("%I64d%I64d%I64d",&B.x,&B.y,&B.z);

		src=dst=-1;
		for (int i=1;i<=n;i++) {
			if (dotInplaneIn(A,a[i][0],a[i][1],a[i][2])) src=i;
			if (dotInplaneIn(B,a[i][0],a[i][1],a[i][2])) dst=i;
		}
		assert(src!=-1); assert(dst!=-1);

		LL l=max(A.z,B.z),r=mx+1,mid;
		while (l<=r) {
			mid=(l+r)/2;
			if (yes(mid)) r=mid-1;
			else l=mid+1;
		}
		yes(l);  //

		vector<VEC> ans;
		if (final!=B) ans.pb(B);
		ans.pb(final);
		while (pre.find(final)!=pre.end()) ans.pb(final=pre[final]);
		if (*ans.rbegin()!=A) ans.pb(A);

		assert(ans.size()<=5*n);
		printf("%d\n",(int)ans.size());
		for (int i=ans.size()-1;~i;i--)
			printf("%I64d %I64d %I64d\n",ans[i].x,ans[i].y,ans[i].z);
	}
	return 0;
}
