Problem: Peter had a cube with non-zero length of a side. He put the cube into three-dimensional space in such a way that its vertices lay at integer points (it is possible that the cube's sides are not parallel to the coordinate axes). Then he took a piece of paper and wrote down eight lines, each containing three integers — coordinates of cube's vertex (a single line contains coordinates of a single vertex, each vertex is written exactly once), put the paper on the table and left. While Peter was away, his little brother Nick decided to play with the numbers on the paper. In one operation Nick could swap some numbers inside a single line (Nick didn't swap numbers from distinct lines). Nick could have performed any number of such operations.

When Peter returned and found out about Nick's mischief, he started recollecting the original coordinates. Help Peter restore the original position of the points or else state that this is impossible and the numbers were initially recorded incorrectly.

Input

Each of the eight lines contains three space-separated integers — the numbers written on the piece of paper after Nick's mischief. All numbers do not exceed 106 in their absolute value.

Output

If there is a way to restore the cube, then print in the first line "YES". In each of the next eight lines print three integers — the restored coordinates of the points. The numbers in the i-th output line must be a permutation of the numbers in i-th input line. The numbers should represent the vertices of a cube with non-zero length of a side. If there are multiple possible ways, print any of them.

If there is no valid way, print "NO" (without the quotes) in the first line. Do not print anything else.

Examples

Input

0 0 0
0 0 1
0 0 1
0 0 1
0 1 1
0 1 1
0 1 1
1 1 1


Output

YES
0 0 0
0 0 1
0 1 0
1 0 0
0 1 1
1 0 1
1 1 0
1 1 1


Input

0 0 0
0 0 0
0 0 0
0 0 0
1 1 1
1 1 1
1 1 1
1 1 1


Output

NO

Solution (in JAVA):

Solution:
import java.awt.image.AreaAveragingScaleFilter;
import java.util.*;
import java.io.*;
import java.text.*;

public class CF_464B{
    //SOLUTION BEGIN
    //Into the Hardware Mode
    void pre() throws Exception{}
    void solve(int TC) throws Exception{
        int N = 8;
        int[][] P = new int[N][];
        for(int i = 0; i< N; i++){
            P[i] = new int[]{ni(), ni(), ni()};
            Arrays.sort(P[i]);
        }
        int[][] ord = new int[N][];
        if(good(P, 0)){
            pn("YES");
            for(int i = 0; i< N; i++)pn(P[i][0], P[i][1], P[i][2]);
        }else pn("NO");
    }
    boolean valid(int[][] P){
        int N = P.length;
        long[] ar = new long[(N*N-N)/2];
        for(int i = 0, sz = 0; i< N; i++)
            for(int j = i+1; j< N; j++, sz++){
                ar[sz] = (P[i][0]-P[j][0])*(long)(P[i][0]-P[j][0])+(P[i][1]-P[j][1])*(long)(P[i][1]-P[j][1])+(P[i][2]-P[j][2])*(long)(P[i][2]-P[j][2]);
            }
        Arrays.sort(ar);
        boolean good = ar[0] > 0;
        for(int i = 0; i< 12 && good; i++)good &= ar[i] == ar[0];
        for(int i = 12; i< 24 && good; i++)good &= ar[i] == ar[0]*2;
        for(int i = 24; i< 28 && good; i++)good &= ar[i] == ar[0]*3;
        return good;
    }
    boolean good(int[][] P, int ind){
        if(ind == P.length)return valid(P);
        if(ind == 0)return good(P, ind+1);
        do{
            if(good(P, ind+1))return true;
        }while(nextPerm(P[ind]));
        int mn = Math.min(P[ind][0], Math.min(P[ind][1], P[ind][2]));
        int mx = Math.max(P[ind][0], Math.max(P[ind][1], P[ind][2]));
        P[ind][1] = P[ind][0]+P[ind][1]+P[ind][2]-mn-mx;
        P[ind][0] = mn;
        P[ind][2] = mx;
        return false;
    }
    boolean nextPerm(int[] p){
        for(int i = p.length-2; i >= 0; i--){
            if(p[i] < p[i+1]){
                int ind = i+1;
                for(int j = i+1; j< p.length; j++){
                    if(p[j] > p[i] && p[j] < p[ind])ind = j;
                }
                int tmp = p[i];
                p[i] = p[ind];
                p[ind] = tmp;
                Arrays.sort(p, i+1, p.length);
                return true;
            }
        }
        return false;
    }
    //SOLUTION END
    void hold(boolean b)throws Exception{if(!b)throw new Exception("Hold right there, Sparky!");}
    void exit(boolean b){if(!b)System.exit(0);}
    static void dbg(Object... o){System.err.println(Arrays.deepToString(o));}
    final long IINF = (long)1e17;
    final int INF = (int)1e9+2;
    DecimalFormat df = new DecimalFormat("0.00000000000");
    double PI = 3.141592653589793238462643383279502884197169399, eps = 1e-8;
    static boolean multipleTC = false, memory = true, fileIO = false;
    FastReader in;PrintWriter out;
    void run() throws Exception{
        long ct = System.currentTimeMillis();
        if (fileIO) {
            in = new FastReader("");
            out = new PrintWriter("");
        } else {
            in = new FastReader();
            out = new PrintWriter(System.out);
        }
        //Solution Credits: Taranpreet Singh
        int T = multipleTC? ni():1;
        pre();
        for (int t = 1; t <= T; t++) solve(t);
        out.flush();
        out.close();
        System.err.println(System.currentTimeMillis() - ct);
    }
    public static void main(String[] args) throws Exception{
        if(memory)new Thread(null, new Runnable() {public void run(){try{new CF_464B().run();}catch(Exception e){e.printStackTrace();}}}, "1", 1 << 28).start();
        else new CF_464B().run();
    }
    int[][] make(int n, int e, int[] from, int[] to, boolean f){
        int[][] g = new int[n][];int[]cnt = new int[n];
        for(int i = 0; i< e; i++){
            cnt[from[i]]++;
            if(f)cnt[to[i]]++;
        }
        for(int i = 0; i< n; i++)g[i] = new int[cnt[i]];
        for(int i = 0; i< e; i++){
            g[from[i]][--cnt[from[i]]] = to[i];
            if(f)g[to[i]][--cnt[to[i]]] = from[i];
        }
        return g;
    }
    int[][][] makeS(int n, int e, int[] from, int[] to, boolean f){
        int[][][] g = new int[n][][];int[]cnt = new int[n];
        for(int i = 0; i< e; i++){
            cnt[from[i]]++;
            if(f)cnt[to[i]]++;
        }
        for(int i = 0; i< n; i++)g[i] = new int[cnt[i]][];
        for(int i = 0; i< e; i++){
            g[from[i]][--cnt[from[i]]] = new int[]{to[i], i, 0};
            if(f)g[to[i]][--cnt[to[i]]] = new int[]{from[i], i, 1};
        }
        return g;
    }
    int find(int[] set, int u){return set[u] = (set[u] == u?u:find(set, set[u]));}
    int digit(long s){int ans = 0;while(s>0){s/=10;ans++;}return ans;}
    long gcd(long a, long b){return (b==0)?a:gcd(b,a%b);}
    int gcd(int a, int b){return (b==0)?a:gcd(b,a%b);}
    int bit(long n){return (n==0)?0:(1+bit(n&(n-1)));}
    void p(Object... o){for(Object oo:o)out.print(oo+" ");}
    void pn(Object... o){for(Object oo:o)out.print(oo+" ");out.println();}
    void pni(Object... o){for(Object oo:o)out.print(oo+" ");out.println();out.flush();}
    String n()throws Exception{return in.next();}
    String nln()throws Exception{return in.nextLine();}
    int ni()throws Exception{return Integer.parseInt(in.next());}
    long nl()throws Exception{return Long.parseLong(in.next());}
    double nd()throws Exception{return Double.parseDouble(in.next());}

    class FastReader{
        BufferedReader br;
        StringTokenizer st;
        public FastReader(){
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public FastReader(String s) throws Exception{
            br = new BufferedReader(new FileReader(s));
        }

        String next() throws Exception{
            while (st == null || !st.hasMoreElements()){
                try{
                    st = new StringTokenizer(br.readLine());
                }catch (IOException  e){
                    throw new Exception(e.toString());
                }
            }
            return st.nextToken();
        }

        String nextLine() throws Exception{
            String str;
            try{
                str = br.readLine();
            }catch (IOException e){
                throw new Exception(e.toString());
            }
            return str;
        }
    }
}