#ifndef POINT3_H__
#define POINT3_H__

#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>
#include <cmath>
#include <float.h>

/*
If you want to use the methods that project 2x2 or 3x3 matrices
onto the closest 2D/3D rotation, or similarity, or rotation
restricted to a 2D plane in 3D, you need to use a Singular Values Decomposition.
We provide implementation of this, using the GNU Scientific Library.
Uncomment #define __USE_GSL_FOR_MAT33
*/

#define __USE_GSL_FOR_MAT33
#define __USE_OPENGL_METHODS_ON_POINT3

#ifdef __USE_GSL_FOR_MAT33
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_linalg.h>
// you need to add the following libraries to your project : gsl, gslcblas
#endif

#ifdef __USE_OPENGL_METHODS_ON_POINT3
#include <GL/gl.h>
#endif

template< typename T >
class point3
{
public:
    typedef T               type_t;

    point3< T >( T x_ , T y_ , T z_) { v[0] = x_; v[1] = y_; v[2] = z_; }

    template< class point_t > point3< T >( point_t const & p )
    {
        v[0] = (T)(p[0]);
        v[1] = (T)(p[1]);
        v[2] = (T)(p[2]);
    }

    point3< T >(){v[0] = 0; v[1] = 0; v[2] = 0;}

    inline  T x() const {return v[0];}
    inline  T y() const {return v[1];}
    inline  T z() const {return v[2];}

    inline  T operator [] (unsigned int c) const
    {
        return v[c];
    }
    inline  T & operator [] (unsigned int c)
    {
        return v[c];
    }

    static point3<T> Zero() { return point3<T>(0,0,0); }

    void setZero()
    {
        v[0] = 0;
        v[1] = 0;
        v[2] = 0;
    }

    // You cannot template over anything here, but maybe you could template over typename T2 for operator += (const point3< T2 > & other)
    void operator += (const point3< T > & other)
    {
        v[0] += other.x();
        v[1] += other.y();
        v[2] += other.z();
    }
    void operator -= (const point3< T > & other)
    {
        v[0] -= other.x();
        v[1] -= other.y();
        v[2] -= other.z();
    }

    // This is going to create problems if the compiler needs to resolve umbiguous casts, but it's the cleaner way to do it
    void operator *= (int s)
    {
        v[0] *= s;
        v[1] *= s;
        v[2] *= s;
    }
    void operator *= (unsigned int s)
    {
        v[0] *= s;
        v[1] *= s;
        v[2] *= s;
    }
    void operator *= (float s)
    {
        v[0] *= s;
        v[1] *= s;
        v[2] *= s;
    }
    void operator *= (double s)
    {
        v[0] *= s;
        v[1] *= s;
        v[2] *= s;
    }
    void operator /= (int s)
    {
        v[0] /= s;
        v[1] /= s;
        v[2] /= s;
    }
    void operator /= (unsigned int s)
    {
        v[0] /= s;
        v[1] /= s;
        v[2] /= s;
    }
    void operator /= (float s)
    {
        v[0] /= s;
        v[1] /= s;
        v[2] /= s;
    }
    void operator /= (double s)
    {
        v[0] /= s;
        v[1] /= s;
        v[2] /= s;
    }

    point3<T> getOrthogonal() const
    {
        if( v[0] == 0 )
        {
            return point3<T>( 0 , v[2] , -v[1] );
        }
        else if( v[1] == 0 )
        {
            return point3<T>( v[2] , 0 , -v[0] );
        }

        return point3<T>( v[1] , -v[0] , 0 );
    }

    T sqrnorm() const
    {
        return v[0]*v[0]+v[1]*v[1]+v[2]*v[2];
    }
    T norm() const
    {
        return sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
    }

    void normalize()
    {
        T _n = norm();
        v[0] /= _n;
        v[1] /= _n;
        v[2] /= _n;
    }
    void setNorm( T newNorm )
    {
        T _factor = newNorm / norm();
        v[0] *= _factor;
        v[1] *= _factor;
        v[2] *= _factor;
    }

    inline static
    T dot( const point3< T > & p1 , const point3< T > & p2 )
    {
        return p1.x() * p2.x() + p1.y() * p2.y() + p1.z() * p2.z();
    }

    inline static
    point3< T > cross( const point3< T > & p1 , const point3< T > & p2 )
    {
        return point3< T >(
                    p1.y() * p2.z() - p1.z() * p2.y(),
                    p1.z() * p2.x() - p1.x() * p2.z(),
                    p1.x() * p2.y() - p1.y() * p2.x()
                    );
    }

//    inline static point3< T > min ( const point3< T >  & p , const point3< T >  & p2 )
//    {
//        return point3< T >( std::min( p2[0] , p[0] ),
//                            std::min( p2[1] , p[1] ),
//                            std::min( p2[2] , p[2] ) );
//    }

//    inline static point3< T > max ( point3< T > const & p , point3< T > const & p2 )
//    {
//        return point3< T >( std::max( p2[0] , p[0] ),
//                            std::max( p2[1] , p[1] ),
//                            std::max( p2[2] , p[2] ) );
//    }

    template< class point_t1 , class point_t2 >
    inline static point3< T > min ( const point_t1  & p , const point_t2  & p2 )
    {
        return point3< T >( std::min( (T)(p2[0]) , (T)(p[0]) ),
                            std::min( (T)(p2[1]) , (T)(p[1]) ),
                            std::min( (T)(p2[2]) , (T)(p[2]) ) );
    }

    template< class point_t1 , class point_t2 >
    inline static point3< T > max ( const point_t1  & p , const point_t2  & p2 )
    {
        return point3< T >( std::max( (T)(p2[0]) , (T)(p[0]) ),
                            std::max( (T)(p2[1]) , (T)(p[1]) ),
                            std::max( (T)(p2[2]) , (T)(p[2]) ) );
    }

    inline static point3< T > Rand ( point3< T > const & p , point3< T > const & p2 )
    {
        T rx = p[0] + (p2[0] - p[0]) * (float)(rand()) / (float)( RAND_MAX );
        T ry = p[1] + (p2[1] - p[1]) * (float)(rand()) / (float)( RAND_MAX );
        T rz = p[2] + (p2[2] - p[2]) * (float)(rand()) / (float)( RAND_MAX );
        return point3<T>( rx , ry , rz );
    }
    inline static point3< T > Rand ( double randMagnitude )
    {
        T rx = randMagnitude * (2.0*(float)(rand()) / (float)( RAND_MAX ) - 1.0);
        T ry = randMagnitude * (2.0*(float)(rand()) / (float)( RAND_MAX ) - 1.0);
        T rz = randMagnitude * (2.0*(float)(rand()) / (float)( RAND_MAX ) - 1.0);
        return point3<T>( rx , ry , rz );
    }

    //    inline static point3< T > RandOrientation (  )
    //    {
    //        T rx = -1.f + 2.f * (float)(rand()) / (float)( RAND_MAX );
    //        T ry = -1.f + 2.f * (float)(rand()) / (float)( RAND_MAX );
    //        T rz = -1.f + 2.f * (float)(rand()) / (float)( RAND_MAX );
    //        point3<T> orientation( rx , ry , rz );
    //        orientation.normalize();
    //        return orientation;
    //    }

    //    Choose z uniformly distributed in [-1,1].
    //    Choose t uniformly distributed on [0, 2*pi).
    //    Let r = sqrt(1-z^2).
    //    Let x = r * cos(t).
    //    Let y = r * sin(t).
    inline static point3< T > RandOrientation (  )
    {
        T zz = -1.f + 2.f * (float)(rand()) / (float)( RAND_MAX );
        T tt = 2.f * M_PI * (float)(rand()) / (float)( RAND_MAX );
        T rr = sqrt( 1.0 - zz*zz );
        T xx = rr * cos(tt);
        T yy = rr * sin(tt);
        return point3<T>( xx , yy , zz );
    }
    inline static point3< T > RandInBox ( double boxHalfSide = 1.0 )
    {
        T xx = boxHalfSide*(-1.0 + 2.0 * (double)(rand()) / (double)( RAND_MAX ));
        T yy = boxHalfSide*(-1.0 + 2.0 * (double)(rand()) / (double)( RAND_MAX ));
        T zz = boxHalfSide*(-1.0 + 2.0 * (double)(rand()) / (double)( RAND_MAX ));
        return point3<T>( xx , yy , zz );
    }

    point3<T> direction() const {
        T n = norm();
        return *this/n;
    }

    static
    T getAngleAroundAxis( point3<T> const & srcVector , point3<T> const & rotatedVector , point3<T> const & axis ) {
//        double angle = atan2( std::max<double>(-1.0 , std::min<double>( 1.0 , point3<T>::cross(srcVector , rotatedVector).norm() ) ) ,
//                              std::max<double>(-1.0 , std::min<double>( 1.0 , point3<T>::dot(srcVector , rotatedVector) ) )); // aie aie aie aie aie aie aie aie...
        double angle = atan2( point3<T>::cross(srcVector , rotatedVector).norm() , point3<T>::dot(srcVector , rotatedVector) );
        if( point3<T>::dot(point3<T>::cross(srcVector , rotatedVector) , axis) < 0.0 ) angle = -angle;
        return angle;
    }

    bool isnan() const {
        return std::isnan(v[0]) || std::isnan(v[1]) || std::isnan(v[2]);
    }

    inline static void glVertex( point3< T > const & p )
    {
        glVertex3f( p[0],p[1],p[2] );
    }

    inline static void glNormal( point3< T > const & p )
    {
        glNormal3f( p[0],p[1],p[2] );
    }

    void glVertex() const
    {
        glVertex3f( v[0],v[1],v[2] );
    }

    void glNormal() const
    {
        glNormal3f( v[0],v[1],v[2] );
    }

private:
    T v[3];
};

template< typename T > inline
point3< T > operator + (const point3< T > & p1 , const point3< T > & p2 )
{
    return point3< T >( p1.x() + p2.x() , p1.y() + p2.y() , p1.z() + p2.z() );
}
template< typename T > inline
point3< T > operator - (const point3< T > & p1 , const point3< T > & p2 )
{
    return point3< T >( p1.x() - p2.x() , p1.y() - p2.y() , p1.z() - p2.z() );
}

template< typename T > inline
point3< T > operator - (const point3< T > & p2 )
{
    return point3< T >( - p2.x() , - p2.y() , - p2.z() );
}

template< typename T > inline
point3< T > operator * (const point3< T > & p , int s)
{
    return point3< T >( s*p.x() , s*p.y()  , s*p.z() );
}
template< typename T > inline
point3< T > operator * (const point3< T > & p , float s)
{
    return point3< T >( s*p.x() , s*p.y() , s*p.z()  );
}
template< typename T > inline
point3< T > operator * (const point3< T > & p , double s)
{
    return point3< T >( s*p.x() , s*p.y()  , s*p.z() );
}
template< typename T > inline
point3< T > operator * ( int s , const point3< T > & p )
{
    return point3< T >( s*p.x() , s*p.y()  , s*p.z() );
}
template< typename T > inline
point3< T > operator * ( float s , const point3< T > & p )
{
    return point3< T >( s*p.x() , s*p.y() , s*p.z()  );
}
template< typename T > inline
point3< T > operator * ( double s , const point3< T > & p )
{
    return point3< T >( s*p.x() , s*p.y()  , s*p.z() );
}

template< typename T > inline
point3< T > operator / (const point3< T > & p , int s)
{
    return point3< T >( p.x()/s , p.y()/s  , p.z()/s );
}
template< typename T > inline
point3< T > operator / (const point3< T > & p , float s)
{
    return point3< T >( p.x()/s , p.y()/s  , p.z()/s );
}
template< typename T > inline
point3< T > operator / (const point3< T > & p , double s)
{
    return point3< T >( p.x()/s , p.y()/s  , p.z()/s );
}

template< typename T > inline
T operator * (const point3< T > & p1 , const point3< T > & p2)
{
    return p1.x() * p2.x() + p1.y() * p2.y() + p1.z() * p2.z();
}

template< typename T > inline
point3<T> operator % (const point3<T> & p1 , const point3<T> & p2)
{
    return point3<T>::cross(p1,p2);
}

template< typename T > inline std::ostream & operator << (std::ostream & s , point3< T > const & p)
{
    s << p[0] << " \t" << p[1] << " \t" << p[2];
    return s;
}

typedef point3< float >    point3f;
typedef point3< double >   point3d;

inline double myAbs( const point3d & f )
{
    return f.norm();
}
inline float myAbs( const point3f & f )
{
    return f.norm();
}

namespace StochasticBoundingStruct{

// the 3 canonical axes  +  2000 random orientations on the z-positive hemisphere.
static double dirs[2003][3] =
{
    { 1 , 0 , 0 } ,
    { 0 , 1 , 0 } ,
    { 0 , 0 , 1 } ,
    { -0.385422 , 0.516128 , 0.764893 } ,    { 0.697097 , 0.110109 , 0.708471 } ,    { 0.311979 , 0.691569 , 0.651461 } ,    { -0.832093 , 0.481536 , 0.275217 } ,    { -0.572238 , 0.234887 , 0.78573 } ,    { -0.109098 , -0.971394 , 0.210928 } ,    { -0.902306 , 0.408123 , 0.138848 } ,    { -0.570128 , 0.632602 , 0.524185 } ,    { -0.66706 , -0.32457 , 0.670586 } ,    { 0.221621 , 0.376512 , 0.899513 } ,
    { 0.0314351 , -0.920669 , 0.389077 } ,    { -0.674986 , 0.509768 , 0.533415 } ,    { 0.453828 , 0.177408 , 0.87325 } ,    { 0.752111 , 0.29876 , 0.587429 } ,    { -0.920397 , -0.328854 , 0.21148 } ,    { 0.109396 , -0.64581 , 0.75562 } ,    { -0.971678 , 0.144991 , 0.186598 } ,    { 0.801684 , 0.447118 , 0.396721 } ,    { 0.879867 , -0.353183 , 0.317956 } ,    { -0.0950819 , -0.0321161 , 0.994951 } ,
    { 0.754686 , -0.608428 , 0.245486 } ,    { 0.777216 , -0.270578 , 0.568086 } ,    { -0.7292 , -0.217505 , 0.648814 } ,    { -0.925599 , 0.0634084 , 0.373158 } ,    { -0.0803568 , 0.968324 , 0.236416 } ,    { -0.641205 , 0.333491 , 0.691115 } ,    { 0.879154 , -0.475082 , 0.0372188 } ,    { 0.812369 , 0.459884 , 0.358556 } ,    { -0.751874 , -0.658148 , 0.0390828 } ,    { 0.676722 , -0.679121 , 0.284326 } ,
    { -0.0675079 , 0.746549 , 0.661897 } ,    { 0.637238 , 0.328494 , 0.697151 } ,    { -0.83858 , 0.254731 , 0.481556 } ,    { 0.587564 , -0.428267 , 0.686553 } ,    { -0.55295 , -0.804897 , 0.215376 } ,    { 0.0526419 , -0.425982 , 0.903199 } ,    { -0.0897022 , -0.991671 , 0.0924214 } ,    { -0.619757 , 0.654863 , 0.432499 } ,    { -0.884142 , -0.166764 , 0.436444 } ,    { -0.77648 , 0.56425 , 0.280537 } ,
    { 0.906532 , 0.0809475 , 0.414304 } ,    { 0.287072 , -0.706101 , 0.647311 } ,    { -0.610819 , -0.781133 , 0.129353 } ,    { -0.843402 , 0.493208 , 0.213117 } ,    { -0.854138 , -0.194333 , 0.482373 } ,    { -0.731727 , 0.356389 , 0.581001 } ,    { 0.747388 , -0.285504 , 0.599915 } ,    { 0.11617 , 0.0304004 , 0.992764 } ,    { -0.522105 , -0.826618 , 0.210022 } ,    { 0.109879 , -0.460211 , 0.880984 } ,
    { -0.723265 , 0.5825 , 0.37092 } ,    { 0.636892 , -0.762517 , 0.11374 } ,    { -0.13995 , 0.956635 , 0.255468 } ,    { -0.710729 , 0.454106 , 0.537263 } ,    { 0.772457 , 0.497738 , 0.39442 } ,    { -0.647809 , -0.444059 , 0.618996 } ,    { 0.411236 , 0.455686 , 0.789452 } ,    { 0.950792 , 0.24793 , 0.185808 } ,    { 0.259714 , -0.790225 , 0.555061 } ,    { -0.970326 , -0.225514 , 0.0872409 } ,
    { 0.0145111 , 0.740151 , 0.672285 } ,    { 0.654429 , 0.752727 , 0.0715813 } ,    { 0.76677 , -0.157146 , 0.622389 } ,    { 0.65972 , 0.383442 , 0.646329 } ,    { 0.715623 , 0.649749 , 0.256337 } ,    { -0.90427 , 0.34034 , 0.257809 } ,    { -0.173731 , 0.0844812 , 0.981163 } ,    { -0.517476 , -0.603214 , 0.60692 } ,    { -0.782505 , -0.174024 , 0.59783 } ,    { -0.99534 , -0.0242384 , 0.0933291 } ,
    { -0.598719 , 0.760331 , 0.251856 } ,    { 0.0705489 , 0.594529 , 0.800974 } ,    { -0.205445 , -0.00853607 , 0.978631 } ,    { -0.0940051 , 0.884794 , 0.456401 } ,    { 0.126101 , 0.913963 , 0.385707 } ,    { 0.494095 , 0.623035 , 0.606381 } ,    { -0.0340296 , 0.310029 , 0.950118 } ,    { 0.42724 , 0.710798 , 0.558777 } ,    { 0.849255 , -0.239664 , 0.470454 } ,    { -0.567892 , 0.657388 , 0.495317 } ,
    { -0.383365 , -0.354398 , 0.852897 } ,    { -0.799306 , -0.459051 , 0.387791 } ,    { -0.32595 , -0.268149 , 0.906561 } ,    { 0.012387 , 0.897792 , 0.440245 } ,    { 0.0740104 , -0.699068 , 0.711215 } ,    { 0.110024 , -0.857044 , 0.503358 } ,    { 0.575597 , -0.779886 , 0.245899 } ,    { -0.761359 , -0.648324 , 0.00304508 } ,    { -0.139983 , 0.948432 , 0.284397 } ,    { 0.494213 , 0.835043 , 0.241777 } ,
    { 0.412646 , 0.910886 , 0.00300169 } ,    { -0.778852 , 0.115545 , 0.616473 } ,    { 0.847906 , 0.520515 , 0.100597 } ,    { 0.381559 , 0.880646 , 0.280848 } ,    { -0.75984 , 0.644168 , 0.0876987 } ,    { -0.736586 , -0.669403 , 0.0966486 } ,    { 0.61001 , -0.792276 , 0.0136739 } ,    { -0.864806 , -0.302517 , 0.400742 } ,    { -0.32708 , 0.178495 , 0.927986 } ,    { 0.619961 , 0.50237 , 0.602721 } ,
    { -0.876188 , -0.303311 , 0.374562 } ,    { -0.241242 , 0.606737 , 0.757412 } ,    { 0.716436 , -0.670845 , 0.191536 } ,    { 0.0403957 , -0.533251 , 0.844992 } ,    { 0.229727 , -0.683459 , 0.692899 } ,    { 0.555794 , 0.818392 , 0.146037 } ,    { -0.0926963 , -0.995174 , 0.0321806 } ,    { -0.618159 , 0.273929 , 0.736778 } ,    { 0.105384 , -0.756296 , 0.645687 } ,    { 0.432666 , -0.480367 , 0.76292 } ,
    { 0.365927 , 0.635624 , 0.679764 } ,    { -0.124722 , -0.216931 , 0.968187 } ,    { -0.399871 , -0.915581 , 0.0425861 } ,    { 0.825642 , -0.076549 , 0.558977 } ,    { -0.607219 , -0.0839766 , 0.790084 } ,    { 0.257646 , -0.947904 , 0.187343 } ,    { -0.973859 , 0.170738 , 0.149824 } ,    { -0.601329 , 0.0792537 , 0.795061 } ,    { 0.700292 , 0.110759 , 0.705212 } ,    { 0.87532 , 0.033876 , 0.482355 } ,
    { -0.461323 , -0.816624 , 0.346854 } ,    { 0.351135 , -0.879064 , 0.322415 } ,    { -0.260794 , 0.945855 , 0.193246 } ,    { 0.129913 , 0.863015 , 0.488188 } ,    { 0.644597 , -0.753439 , 0.129708 } ,    { -0.153882 , -0.970458 , 0.185826 } ,    { -0.883671 , -0.464376 , 0.0589968 } ,    { -0.927063 , -0.306326 , 0.216147 } ,    { 0.668522 , 0.570521 , 0.477059 } ,    { -0.666277 , 0.742205 , 0.072155 } ,
    { 0.660494 , 0.701136 , 0.26862 } ,    { -0.185185 , -0.706877 , 0.682665 } ,    { -0.0684437 , 0.976522 , 0.204253 } ,    { 0.750589 , -0.219435 , 0.623269 } ,    { -0.816743 , 0.387197 , 0.427795 } ,    { 0.757362 , 0.648293 , 0.078222 } ,    { -0.427486 , -0.412167 , 0.804596 } ,    { 0.988097 , 0.00670096 , 0.153683 } ,    { 0.277227 , 0.484279 , 0.829831 } ,    { -0.88351 , 0.112915 , 0.454599 } ,
    { 0.14541 , -0.307944 , 0.940227 } ,    { 0.751495 , 0.294184 , 0.590518 } ,    { -0.498719 , -0.346624 , 0.794438 } ,    { 0.529421 , 0.819243 , 0.220353 } ,    { -0.493423 , -0.646572 , 0.581789 } ,    { 0.553122 , -0.831585 , 0.0502359 } ,    { 0.361316 , 0.817773 , 0.447994 } ,    { -0.321953 , 0.309534 , 0.894726 } ,    { 0.0257802 , 0.455535 , 0.889844 } ,    { -0.112102 , -0.935785 , 0.334276 } ,
    { -0.204189 , 0.72398 , 0.658909 } ,    { -0.0830892 , 0.721511 , 0.6874 } ,    { -0.0587021 , 0.55212 , 0.831696 } ,    { 0.409426 , -0.736357 , 0.538654 } ,    { 0.991057 , -0.0210081 , 0.131779 } ,    { 0.901846 , -0.20756 , 0.378935 } ,    { -0.770037 , -0.0741259 , 0.633679 } ,    { 0.0676739 , 0.294555 , 0.953235 } ,    { 0.421282 , 0.469216 , 0.776117 } ,    { -0.287748 , 0.601198 , 0.745495 } ,
    { -0.663875 , 0.496073 , 0.559626 } ,    { -0.696262 , -0.254709 , 0.671075 } ,    { -0.112409 , -0.536003 , 0.836699 } ,    { 0.489847 , 0.0825545 , 0.867891 } ,    { 0.105038 , -0.990931 , 0.0837964 } ,    { 0.604117 , 0.632461 , 0.484805 } ,    { -0.383633 , -0.283532 , 0.878883 } ,    { 0.60152 , -0.0898302 , 0.793791 } ,    { 0.484633 , 0.834026 , 0.263689 } ,    { 0.254487 , -0.746876 , 0.614339 } ,
    { -0.545553 , -0.497684 , 0.674301 } ,    { -0.876818 , 0.112511 , 0.467473 } ,    { -0.237656 , 0.934232 , 0.265952 } ,    { -0.0294367 , -0.921402 , 0.387493 } ,    { -0.486728 , -0.216072 , 0.846409 } ,    { 0.144429 , 0.474964 , 0.868072 } ,    { 0.0454862 , 0.367985 , 0.928718 } ,    { 0.820079 , 0.243908 , 0.517667 } ,    { 0.349893 , 0.930892 , 0.104949 } ,    { -0.430319 , 0.289971 , 0.854835 } ,
    { -0.190132 , 0.344923 , 0.919172 } ,    { 0.989667 , 0.125939 , 0.0685496 } ,    { 0.899366 , -0.415161 , 0.137045 } ,    { 0.0359748 , -0.111595 , 0.993102 } ,    { -0.196376 , 0.559523 , 0.805215 } ,    { -0.0629583 , 0.976987 , 0.203798 } ,    { 0.363838 , -0.396525 , 0.842846 } ,    { 0.804676 , 0.286272 , 0.520139 } ,    { -0.666725 , 0.295121 , 0.684383 } ,    { -0.799799 , -0.446346 , 0.401368 } ,
    { -0.66263 , 0.748947 , 0.00034225 } ,    { -0.802633 , 0.181898 , 0.568061 } ,    { -0.946128 , -0.261158 , 0.191413 } ,    { 0.96312 , 0.268246 , 0.0210805 } ,    { 0.735642 , 0.423428 , 0.528715 } ,    { 0.148642 , 0.414738 , 0.897718 } ,    { -0.559624 , 0.0595275 , 0.826606 } ,    { 0.461185 , -0.680632 , 0.569253 } ,    { 0.132656 , 0.543885 , 0.828608 } ,    { -0.701118 , -0.0516204 , 0.711174 } ,
    { 0.00575105 , 0.248135 , 0.968709 } ,    { -0.82125 , 0.342783 , 0.456122 } ,    { -0.970733 , -0.0725293 , 0.228949 } ,    { -0.139528 , 0.990071 , 0.0170648 } ,    { -0.251948 , 0.961593 , 0.108907 } ,    { 0.666862 , -0.236694 , 0.706591 } ,    { 0.471992 , 0.551411 , 0.687873 } ,    { -0.0109387 , 0.983696 , 0.179504 } ,    { -0.675435 , 0.366979 , 0.63962 } ,    { -0.697104 , 0.407359 , 0.590003 } ,
    { -0.0385627 , -0.999226 , 0.00782239 } ,    { -0.846063 , 0.484601 , 0.222123 } ,    { -0.387058 , 0.743006 , 0.54601 } ,    { 0.537536 , 0.660675 , 0.523989 } ,    { -0.319601 , 0.213093 , 0.92328 } ,    { -0.678914 , -0.239643 , 0.694008 } ,    { -0.848249 , 0.432644 , 0.305439 } ,    { -0.0202819 , 0.187009 , 0.982149 } ,    { -0.483706 , 0.0532724 , 0.873608 } ,    { 0.287804 , -0.262376 , 0.921047 } ,
    { -0.696575 , 0.55611 , 0.453349 } ,    { 0.848109 , -0.403074 , 0.343864 } ,    { -0.0732127 , -0.995498 , 0.0601963 } ,    { 0.190215 , 0.746444 , 0.637683 } ,    { 0.937405 , -0.141473 , 0.318209 } ,    { -0.345088 , -0.567249 , 0.747759 } ,    { -0.0722422 , -0.895066 , 0.440042 } ,    { 0.93285 , -0.322559 , 0.16046 } ,    { -0.543124 , 0.829956 , 0.127234 } ,    { 0.454942 , 0.339249 , 0.82337 } ,
    { -0.0471716 , -0.863152 , 0.502736 } ,    { 0.773356 , -0.551904 , 0.311965 } ,    { -0.568357 , -0.752609 , 0.332491 } ,    { 0.597168 , 0.451598 , 0.662909 } ,    { -0.175125 , -0.648494 , 0.740802 } ,    { -0.196635 , 0.137415 , 0.9708 } ,    { 0.233797 , -0.554866 , 0.798413 } ,    { -0.508417 , -0.547525 , 0.664627 } ,    { -0.441595 , -0.0374702 , 0.896432 } ,    { 0.230679 , 0.919724 , 0.31764 } ,
    { -0.198322 , 0.0413295 , 0.979265 } ,    { -0.166508 , -0.642696 , 0.747808 } ,    { 0.773382 , -0.229258 , 0.591034 } ,    { 0.107766 , -0.943507 , 0.313339 } ,    { -0.025376 , -0.805011 , 0.592717 } ,    { -0.927324 , -0.269352 , 0.259846 } ,    { 0.229413 , 0.0379033 , 0.972591 } ,    { -0.259051 , -0.368793 , 0.892684 } ,    { 0.704154 , 0.61991 , 0.346234 } ,    { -0.283702 , 0.824966 , 0.48882 } ,
    { -0.0529137 , -0.933678 , 0.354182 } ,    { 0.717219 , -0.372836 , 0.588718 } ,    { 0.965919 , 0.234816 , 0.108916 } ,    { 0.356842 , 0.281283 , 0.890811 } ,    { 0.350351 , -0.26904 , 0.897146 } ,    { -0.899917 , -0.237456 , 0.365739 } ,    { 0.248937 , 0.640887 , 0.72615 } ,    { 0.788417 , 0.35633 , 0.501426 } ,    { -0.799418 , 0.525962 , 0.290338 } ,    { -0.69171 , 0.266217 , 0.671316 } ,
    { -0.197335 , -0.691134 , 0.695265 } ,    { -0.64364 , -0.764853 , 0.0269642 } ,    { 0.769969 , -0.345561 , 0.53641 } ,    { 0.672079 , -0.457287 , 0.582408 } ,    { 0.952714 , 0.288473 , 0.0954944 } ,    { 0.625464 , -0.660573 , 0.415257 } ,    { -0.774309 , 0.469365 , 0.424432 } ,    { -0.499203 , 0.762656 , 0.411282 } ,    { -0.250921 , 0.350182 , 0.902447 } ,    { -0.99454 , -0.0165641 , 0.103032 } ,
    { 0.0854172 , -0.867835 , 0.489456 } ,    { 0.318629 , 0.256267 , 0.91258 } ,    { 0.112212 , -0.391527 , 0.913299 } ,    { -0.75129 , -0.559069 , 0.350722 } ,    { 0.800773 , 0.0555304 , 0.596388 } ,    { 0.247943 , -0.323097 , 0.913308 } ,    { -0.885332 , -0.1681 , 0.433509 } ,    { -0.948103 , 0.317639 , 0.0143269 } ,    { -0.0804184 , 0.370244 , 0.925447 } ,    { -0.70576 , -0.0464985 , 0.706923 } ,
    { 0.872552 , 0.3524 , 0.338332 } ,    { 0.713814 , 0.658746 , 0.237746 } ,    { 0.450675 , 0.891214 , 0.0512814 } ,    { 0.889924 , -0.449341 , 0.07828 } ,    { -0.260058 , 0.166545 , 0.951122 } ,    { -0.118895 , 0.982478 , 0.143533 } ,    { -0.922262 , 0.164286 , 0.349917 } ,    { 0.656328 , 0.713224 , 0.24606 } ,    { -0.836753 , -0.285493 , 0.467267 } ,    { 0.829162 , -0.16806 , 0.533147 } ,
    { -0.166073 , 0.97794 , 0.1267 } ,    { -0.143735 , 0.750808 , 0.644692 } ,    { -0.314528 , 0.724548 , 0.613272 } ,    { -0.101917 , 0.833726 , 0.542692 } ,    { 0.852526 , 0.483548 , 0.198446 } ,    { -0.812519 , 0.381986 , 0.44034 } ,    { -0.508506 , -0.812028 , 0.286412 } ,    { 0.735844 , 0.670117 , 0.0973507 } ,    { -0.943289 , -0.0565823 , 0.327114 } ,    { -0.63929 , 0.764108 , 0.0862963 } ,
    { 0.537237 , -0.0976577 , 0.837759 } ,    { 0.559135 , 0.374049 , 0.739902 } ,    { 0.992589 , 0.0438028 , 0.11335 } ,    { 0.209411 , 0.80909 , 0.549108 } ,    { -0.959962 , 0.25374 , 0.1187 } ,    { -0.548551 , -0.532922 , 0.644272 } ,    { 0.881978 , 0.00116461 , 0.471289 } ,    { 0.946514 , 0.257534 , 0.194391 } ,    { 0.629944 , 0.683265 , 0.369214 } ,    { -0.796188 , 0.473462 , 0.37672 } ,
    { -0.758918 , -0.491514 , 0.427149 } ,    { -0.450385 , 0.567411 , 0.689346 } ,    { 0.680931 , -0.539595 , 0.495146 } ,    { 0.846995 , 0.529119 , 0.0513089 } ,    { -0.975036 , -0.107606 , 0.194233 } ,    { -0.190396 , 0.393247 , 0.899503 } ,    { 0.18395 , 0.100827 , 0.977751 } ,    { -0.506283 , 0.229744 , 0.831201 } ,    { 0.622738 , 0.76292 , 0.173639 } ,    { -0.423672 , -0.55456 , 0.716216 } ,
    { -0.415831 , 0.887214 , 0.199838 } ,    { 0.454089 , -0.761655 , 0.462261 } ,    { 0.440816 , 0.822212 , 0.360068 } ,    { -0.432005 , -0.492247 , 0.755688 } ,    { -0.341161 , -0.853571 , 0.393734 } ,    { 0.989515 , 0.104259 , 0.0999494 } ,    { -0.652492 , 0.508443 , 0.561907 } ,    { -0.946259 , -0.201426 , 0.253024 } ,    { 0.471441 , -0.667815 , 0.575992 } ,    { 0.351964 , 0.903516 , 0.2445 } ,
    { -0.614064 , -0.298446 , 0.730654 } ,    { 0.608745 , -0.792963 , 0.0252848 } ,    { -0.857587 , 0.415174 , 0.303604 } ,    { -0.0645872 , -0.90185 , 0.427195 } ,    { -0.891527 , 0.431248 , 0.138579 } ,    { -0.473025 , -0.850385 , 0.230419 } ,    { -0.494065 , -0.713991 , 0.496101 } ,    { 0.910021 , 0.414453 , 0.00954401 } ,    { 0.693493 , -0.630108 , 0.349331 } ,    { -0.631744 , -0.659888 , 0.406752 } ,
    { -0.0208304 , 0.989329 , 0.144199 } ,    { -0.577209 , 0.763234 , 0.290349 } ,    { 0.94863 , 0.111749 , 0.295996 } ,    { 0.896166 , -0.381178 , 0.227134 } ,    { 0.679225 , 0.0370938 , 0.732992 } ,    { -0.110232 , -0.960969 , 0.253747 } ,    { 0.63138 , 0.758498 , 0.161369 } ,    { 0.108181 , 0.97913 , 0.17205 } ,    { 0.689171 , -0.711814 , 0.135518 } ,    { -0.650513 , -0.757294 , 0.0577842 } ,
    { -0.566207 , 0.721501 , 0.398555 } ,    { -0.878926 , -0.278109 , 0.387485 } ,    { 0.374062 , -0.927207 , 0.0191176 } ,    { -0.326607 , 0.553109 , 0.76642 } ,    { -0.337242 , 0.714741 , 0.61271 } ,    { -0.0984992 , 0.992435 , 0.073279 } ,    { -0.405226 , -0.328998 , 0.852967 } ,    { 0.1152 , 0.636763 , 0.762405 } ,    { 0.666029 , 0.0218966 , 0.745604 } ,    { -0.727988 , 0.0288606 , 0.684983 } ,
    { 0.214271 , -0.976378 , 0.0278273 } ,    { 0.739439 , 0.499799 , 0.451033 } ,    { -0.199992 , 0.491167 , 0.847796 } ,    { 0.937008 , -0.0491626 , 0.34583 } ,    { -0.231079 , 0.739663 , 0.63206 } ,    { -0.961836 , 0.092796 , 0.257412 } ,    { 0.872997 , -0.37802 , 0.308183 } ,    { 0.515165 , 0.854473 , 0.0669315 } ,    { -0.510595 , -0.705155 , 0.491985 } ,    { 0.0708553 , -0.0282404 , 0.997087 } ,
    { 0.969787 , -0.236671 , 0.0591562 } ,    { -0.877217 , -0.248522 , 0.410764 } ,    { 0.44491 , -0.884426 , 0.140878 } ,    { 0.285348 , 0.83578 , 0.469094 } ,    { 0.832011 , -0.437441 , 0.34118 } ,    { 0.511226 , -0.769557 , 0.382661 } ,    { 0.70264 , -0.404607 , 0.585312 } ,    { 0.327603 , 0.354364 , 0.875844 } ,    { -0.0837555 , 0.885629 , 0.456778 } ,    { 0.826032 , -0.507201 , 0.245799 } ,
    { 0.00490831 , -0.486619 , 0.873601 } ,    { 0.1997 , 0.95798 , 0.205897 } ,    { -0.706051 , 0.329445 , 0.626863 } ,    { 0.590432 , -0.266318 , 0.761882 } ,    { 0.717202 , -0.677882 , 0.161546 } ,    { 0.633489 , 0.211104 , 0.744397 } ,    { 0.837894 , 0.444187 , 0.317223 } ,    { 0.83489 , -0.516486 , 0.190267 } ,    { -0.627778 , 0.753187 , 0.196479 } ,    { -0.115169 , -0.96892 , 0.218929 } ,
    { 0.28284 , -0.855918 , 0.432904 } ,    { -0.98722 , 0.0565568 , 0.148989 } ,    { -0.897555 , -0.0701648 , 0.435285 } ,    { -0.914489 , 0.322557 , 0.244269 } ,    { 0.025956 , 0.831548 , 0.554847 } ,    { -0.517053 , 0.807739 , 0.283219 } ,    { -0.0341836 , 0.999393 , 0.00672197 } ,    { -0.404717 , -0.907077 , 0.115828 } ,    { -0.8606 , 0.347916 , 0.371917 } ,    { -0.102083 , 0.967455 , 0.231537 } ,
    { 0.929003 , -0.0703717 , 0.36332 } ,    { 0.500379 , 0.785505 , 0.364147 } ,    { -0.422947 , 0.25714 , 0.868904 } ,    { -0.968901 , 0.201867 , 0.143112 } ,    { 0.35149 , 0.759556 , 0.547292 } ,    { -0.746753 , -0.280536 , 0.603042 } ,    { -0.14375 , 0.988946 , 0.0363689 } ,    { 0.310807 , 0.945595 , 0.0961729 } ,    { -0.434021 , -0.792083 , 0.429221 } ,    { 0.883181 , 0.367863 , 0.290979 } ,
    { -0.985239 , -0.0240218 , 0.169491 } ,    { 0.502497 , -0.31057 , 0.806872 } ,    { -0.829904 , 0.205594 , 0.518643 } ,    { -0.924289 , 0.330929 , 0.190202 } ,    { 0.145904 , 0.581424 , 0.800411 } ,    { 0.177825 , 0.888022 , 0.424023 } ,    { 0.901342 , 0.171577 , 0.397673 } ,    { 0.0590222 , -0.65127 , 0.756548 } ,    { -0.440845 , 0.143761 , 0.885996 } ,    { 0.175558 , 0.825363 , 0.536615 } ,
    { -0.873736 , 0.409999 , 0.2617 } ,    { 0.635658 , 0.544049 , 0.547677 } ,    { 0.351396 , -0.723898 , 0.59371 } ,    { 0.924316 , -0.0667023 , 0.375753 } ,    { -0.964625 , 0.263156 , 0.0157086 } ,    { 0.831046 , -0.546641 , 0.102695 } ,    { -0.369409 , 0.107867 , 0.922985 } ,    { -0.140331 , -0.756646 , 0.638588 } ,    { -0.476096 , 0.284012 , 0.832268 } ,    { -0.301348 , 0.6806 , 0.667812 } ,
    { 0.697784 , -0.671069 , 0.250528 } ,    { 0.164754 , -0.327916 , 0.93023 } ,    { 0.49401 , -0.299924 , 0.816088 } ,    { -0.336862 , 0.457324 , 0.82303 } ,    { 0.410453 , -0.869736 , 0.274023 } ,    { 0.990052 , -0.0383465 , 0.135372 } ,    { -0.470803 , 0.726392 , 0.500698 } ,    { -0.590812 , 0.177725 , 0.786991 } ,    { -0.824206 , 0.462408 , 0.326899 } ,    { -0.555217 , -0.823585 , 0.115943 } ,
    { -0.968044 , 0.0403105 , 0.247518 } ,    { 0.254495 , -0.413933 , 0.874009 } ,    { -0.734757 , 0.67036 , 0.103679 } ,    { 0.308956 , -0.35359 , 0.882905 } ,    { -0.144948 , -0.90202 , 0.406632 } ,    { -0.678742 , 0.362395 , 0.638732 } ,    { -0.130536 , -0.593061 , 0.794505 } ,    { -0.859435 , -0.0583625 , 0.507903 } ,    { 0.339207 , -0.577424 , 0.742644 } ,    { -0.689204 , 0.0361204 , 0.723667 } ,
    { -0.859196 , 0.407481 , 0.309422 } ,    { 0.826946 , -0.561533 , 0.0289896 } ,    { -0.703765 , -0.45919 , 0.542088 } ,    { 0.879049 , -0.383726 , 0.282891 } ,    { -0.0641181 , 0.194902 , 0.978725 } ,    { -0.745461 , 0.641735 , 0.180177 } ,    { -0.462702 , -0.663519 , 0.58792 } ,    { 0.0442161 , 0.892324 , 0.449224 } ,    { 0.206327 , -0.975922 , 0.0707459 } ,    { 0.481743 , -0.850075 , 0.212829 } ,
    { -0.0405921 , 0.171217 , 0.984397 } ,    { 0.661784 , 0.551332 , 0.50801 } ,    { -0.101208 , -3.41008e-05 , 0.994865 } ,    { -0.443302 , -0.479532 , 0.757319 } ,    { -0.938423 , 0.0995841 , 0.330826 } ,    { 0.967124 , -0.0651274 , 0.245824 } ,    { -0.764881 , -0.620054 , 0.174614 } ,    { -0.395289 , -0.893927 , 0.211282 } ,    { 0.0167702 , -0.915989 , 0.400853 } ,    { -0.235339 , -0.94271 , 0.23646 } ,
    { 0.257422 , 0.960357 , 0.106994 } ,    { 0.341693 , -0.486462 , 0.804114 } ,    { 0.304235 , -0.620479 , 0.722805 } ,    { -0.784049 , 0.594281 , 0.179153 } ,    { 0.325347 , 0.921654 , 0.21143 } ,    { 0.635366 , 0.549711 , 0.542335 } ,    { 0.256747 , -0.0277946 , 0.966079 } ,    { 0.890315 , -0.080736 , 0.448131 } ,    { 0.146326 , -0.214136 , 0.965782 } ,    { 0.264313 , -0.585602 , 0.766296 } ,
    { -0.0484446 , -0.752193 , 0.657159 } ,    { -0.0505503 , -0.920925 , 0.386447 } ,    { -0.216903 , -0.68413 , 0.696362 } ,    { 0.942936 , 0.297282 , 0.149981 } ,    { -0.959244 , -0.267218 , 0.0919018 } ,    { -0.875923 , -0.0415609 , 0.480657 } ,    { 0.543083 , -0.676881 , 0.496883 } ,    { -0.725927 , -0.623645 , 0.289995 } ,    { -0.722524 , 0.262284 , 0.639661 } ,    { 0.223519 , -0.974505 , 0.019473 } ,
    { 0.0498862 , 0.693363 , 0.718859 } ,    { -0.698671 , -0.68657 , 0.201198 } ,    { 0.640082 , 0.627864 , 0.442812 } ,    { 0.176685 , 0.598277 , 0.781567 } ,    { 0.0520292 , 0.343406 , 0.937745 } ,    { -0.0857454 , 0.279019 , 0.95645 } ,    { -0.172126 , 0.319958 , 0.931665 } ,    { -0.151051 , 0.355083 , 0.922551 } ,    { 0.330673 , -0.0766805 , 0.940625 } ,    { 0.956497 , -0.0980828 , 0.274759 } ,
    { -0.718965 , -0.694907 , 0.0139478 } ,    { -0.0535765 , 0.998412 , 0.0174351 } ,    { 0.159613 , -0.230832 , 0.959813 } ,    { 0.358364 , 0.565284 , 0.742987 } ,    { -0.597215 , 0.552201 , 0.581728 } ,    { 0.410876 , -0.188839 , 0.89192 } ,    { 0.366262 , -0.53632 , 0.760403 } ,    { -0.247317 , 0.383265 , 0.889912 } ,    { -0.512036 , -0.856698 , 0.062346 } ,    { -0.920523 , 0.379943 , 0.0910034 } ,
    { 0.889771 , 0.400246 , 0.219341 } ,    { 0.524738 , -0.666386 , 0.529697 } ,    { -0.091312 , 0.604103 , 0.791657 } ,    { -0.670759 , 0.339034 , 0.65965 } ,    { -0.861253 , -0.180026 , 0.47522 } ,    { -0.0334579 , -0.982823 , 0.181495 } ,    { -0.587137 , 0.423571 , 0.689825 } ,    { -0.0737231 , -0.0836161 , 0.993767 } ,    { 0.613437 , -0.616453 , 0.49364 } ,    { 0.886698 , 0.213963 , 0.409861 } ,
    { -0.0491599 , -0.871278 , 0.488321 } ,    { 0.708581 , -0.702922 , 0.0617624 } ,    { -0.973631 , -0.148964 , 0.17278 } ,    { -0.775082 , -0.280242 , 0.566314 } ,    { 0.0717724 , -0.92349 , 0.376848 } ,    { -0.879966 , -0.474826 , 0.0141669 } ,    { 0.129146 , 0.931239 , 0.340757 } ,    { -0.152334 , -0.979719 , 0.13017 } ,    { 0.0695774 , 0.0540327 , 0.996112 } ,    { 0.0469622 , 0.71449 , 0.698068 } ,
    { 0.640787 , 0.254725 , 0.724229 } ,    { -0.0666535 , 0.240829 , 0.968276 } ,    { -0.99372 , 0.07975 , 0.0784926 } ,    { -0.260678 , -0.954616 , 0.144065 } ,    { -0.116351 , -0.680206 , 0.723728 } ,    { 0.643787 , 0.587309 , 0.490516 } ,    { 0.0826253 , 0.362963 , 0.928133 } ,    { 0.950081 , 0.311718 , 0.0133163 } ,    { -0.217576 , -0.851502 , 0.47708 } ,    { -0.876288 , 0.432957 , 0.211348 } ,
    { -0.812961 , -0.57972 , 0.0549417 } ,    { 0.321818 , -0.946733 , 0.0114336 } ,    { 0.70502 , -0.275905 , 0.653317 } ,    { -0.155319 , 0.288498 , 0.944799 } ,    { 0.432093 , 0.897181 , 0.0914433 } ,    { -0.401382 , -0.90571 , 0.136313 } ,    { -0.831591 , -0.283518 , 0.477571 } ,    { 0.0942993 , 0.287389 , 0.953161 } ,    { -0.822893 , 0.562663 , 0.079098 } ,    { 0.800031 , -0.570472 , 0.185774 } ,
    { -0.384117 , -0.545602 , 0.744831 } ,    { 0.83811 , 0.54416 , 0.0382339 } ,    { -0.960882 , -0.0753728 , 0.266505 } ,    { 0.756507 , 0.588998 , 0.284216 } ,    { 0.0124783 , 0.895301 , 0.445287 } ,    { 0.337014 , 0.939288 , 0.0645022 } ,    { -0.924676 , -0.224872 , 0.307255 } ,    { 0.04805 , 0.0914872 , 0.994646 } ,    { 0.285888 , 0.0451397 , 0.957199 } ,    { 0.0798163 , 0.012293 , 0.996734 } ,
    { 0.729009 , 0.341868 , 0.593019 } ,    { -0.758849 , 0.287968 , 0.584143 } ,    { -0.261892 , -0.600109 , 0.755832 } ,    { 0.367793 , 0.592909 , 0.71637 } ,    { -0.937877 , -0.297763 , 0.178113 } ,    { 0.10114 , 0.475453 , 0.873908 } ,    { -0.796084 , -0.451848 , 0.402597 } ,    { 0.716422 , 0.32644 , 0.616585 } ,    { -0.934631 , 0.301083 , 0.189244 } ,    { 0.310528 , -0.690455 , 0.653333 } ,
    { -0.2529 , -0.882574 , 0.396365 } ,    { 0.960773 , 0.276218 , 0.024876 } ,    { -0.871701 , -0.0535292 , 0.487105 } ,    { 0.143654 , 0.812608 , 0.564829 } ,    { 0.191739 , 0.978991 , 0.0693697 } ,    { 0.0639794 , 0.859537 , 0.507053 } ,    { -0.782763 , 0.230607 , 0.578016 } ,    { 0.790834 , -0.4943 , 0.360902 } ,    { 0.421349 , -0.863296 , 0.277821 } ,    { 0.136527 , 0.9799 , 0.14545 } ,
    { 0.635472 , 0.72788 , 0.257614 } ,    { 0.410846 , 0.201244 , 0.889217 } ,    { -0.0150485 , 0.825548 , 0.564132 } ,    { -0.266225 , 0.642084 , 0.718925 } ,    { 0.31442 , -0.740959 , 0.593397 } ,    { -0.547492 , 0.390031 , 0.740357 } ,    { 0.173042 , 0.215324 , 0.961089 } ,    { 0.0368923 , -0.450376 , 0.892076 } ,    { -0.370864 , -0.614899 , 0.695959 } ,    { 0.387121 , 0.921551 , 0.0296797 } ,
    { 0.111938 , 0.965695 , 0.234315 } ,    { -0.466181 , -0.871839 , 0.150239 } ,    { -0.61396 , -0.478287 , 0.627929 } ,    { -0.250251 , 0.491555 , 0.834115 } ,    { -0.289533 , -0.4299 , 0.855194 } ,    { 0.135113 , -0.426848 , 0.894173 } ,    { -0.90874 , 0.0141507 , 0.417123 } ,    { 0.96462 , 0.0568716 , 0.257437 } ,    { -0.863151 , -0.0642172 , 0.500845 } ,    { -0.89521 , 0.267884 , 0.356143 } ,
    { -0.72415 , 0.226519 , 0.65138 } ,    { 0.396117 , -0.581723 , 0.710415 } ,    { -0.184708 , 0.553687 , 0.811981 } ,    { 0.0243526 , 0.976022 , 0.216307 } ,    { 0.306722 , 0.203732 , 0.929739 } ,    { -0.288601 , 0.409477 , 0.86547 } ,    { -0.47563 , 0.592801 , 0.649895 } ,    { 0.996856 , 0.0688997 , 0.0391247 } ,    { 0.797468 , 0.598793 , 0.0741063 } ,    { -0.572313 , 0.470174 , 0.671858 } ,
    { -0.670323 , 0.562801 , 0.483656 } ,    { -0.880931 , -0.28385 , 0.378668 } ,    { 0.589255 , 0.235943 , 0.772729 } ,    { 0.307613 , 0.356918 , 0.882034 } ,    { -0.725146 , 0.673184 , 0.144869 } ,    { -0.788785 , 0.587409 , 0.181022 } ,    { -0.703554 , 0.249713 , 0.665323 } ,    { -0.768632 , 0.381528 , 0.51346 } ,    { -0.513182 , 0.693207 , 0.506071 } ,    { -0.179554 , -0.734344 , 0.654599 } ,
    { 0.36032 , 0.281075 , 0.889475 } ,    { 0.122492 , -0.985298 , 0.119092 } ,    { -0.876589 , -0.475532 , 0.0738979 } ,    { 0.739728 , -0.371086 , 0.561336 } ,    { -0.692662 , -0.623126 , 0.363226 } ,    { -0.864465 , 0.343617 , 0.366917 } ,    { 0.99926 , 0.0369065 , 0.0108788 } ,    { 0.777513 , -0.62851 , 0.0212089 } ,    { 0.475434 , 0.14914 , 0.867018 } ,    { 0.214186 , 0.255377 , 0.942818 } ,
    { -0.375702 , -0.348838 , 0.85858 } ,    { -0.0283414 , 0.376705 , 0.9259 } ,    { 0.0932436 , -0.483508 , 0.870359 } ,    { -0.350559 , 0.857202 , 0.377244 } ,    { -0.435486 , 0.517593 , 0.736511 } ,    { 0.88575 , 0.461752 , 0.0472374 } ,    { 0.31069 , 0.178938 , 0.933517 } ,    { -0.652534 , 0.308015 , 0.692334 } ,    { 0.515375 , 0.527399 , 0.675454 } ,    { -0.532645 , 0.79569 , 0.288386 } ,
    { 0.402348 , 0.758161 , 0.513136 } ,    { -0.0058395 , -0.823462 , 0.567342 } ,    { -0.134937 , 0.924519 , 0.356449 } ,    { 0.023085 , 0.694989 , 0.71865 } ,    { 0.372095 , 0.669505 , 0.64289 } ,    { -0.00449124 , 0.972534 , 0.232718 } ,    { -0.717585 , 0.390447 , 0.576735 } ,    { 0.603677 , -0.796825 , 0.025373 } ,    { 0.275775 , 0.873112 , 0.402023 } ,    { -0.368822 , 0.644203 , 0.670055 } ,
    { 0.182373 , 0.448971 , 0.874737 } ,    { 0.564772 , 0.105493 , 0.818476 } ,    { 0.0285027 , -0.838917 , 0.543512 } ,    { -0.912261 , 0.401398 , 0.0816022 } ,    { -0.38601 , 0.891923 , 0.235519 } ,    { -0.585327 , -0.590293 , 0.555829 } ,    { 0.925767 , 0.377247 , 0.0252901 } ,    { -0.489721 , -0.834995 , 0.250912 } ,    { -0.739595 , -0.0709388 , 0.669304 } ,    { -0.317976 , -0.474894 , 0.820589 } ,
    { -0.253331 , 0.894251 , 0.36897 } ,    { 0.968228 , -0.166774 , 0.186337 } ,    { 0.790145 , -0.437507 , 0.429254 } ,    { 0.808875 , -0.473997 , 0.347919 } ,    { 0.650813 , -0.0367879 , 0.758346 } ,    { -0.350867 , -0.789728 , 0.503211 } ,    { -0.420957 , -0.642014 , 0.640791 } ,    { -0.780709 , 0.24631 , 0.574304 } ,    { -0.265123 , -0.4973 , 0.826076 } ,    { -0.178817 , 0.611494 , 0.770779 } ,
    { 0.518012 , 0.854981 , 0.0258942 } ,    { 0.532669 , -0.0863995 , 0.841902 } ,    { 0.235454 , -0.801135 , 0.550222 } ,    { -0.64595 , -0.253597 , 0.720026 } ,    { 0.744696 , 0.243425 , 0.621427 } ,    { -0.90181 , 0.0272154 , 0.431275 } ,    { -0.682509 , -0.661142 , 0.311565 } ,    { 0.327961 , 0.127102 , 0.936102 } ,    { 0.109708 , -0.385826 , 0.916025 } ,    { -0.520135 , -0.852558 , 0.0510342 } ,
    { -0.139319 , -0.8096 , 0.570209 } ,    { -0.928265 , 0.209275 , 0.307455 } ,    { -0.604482 , -0.235475 , 0.761021 } ,    { 0.149857 , -0.533936 , 0.832139 } ,    { -0.267889 , 0.799469 , 0.537666 } ,    { 0.112862 , 0.557683 , 0.822346 } ,    { -0.995632 , -0.0612462 , 0.070475 } ,    { -0.341586 , -0.857261 , 0.385256 } ,    { -0.456918 , 0.79972 , 0.389454 } ,    { 0.646747 , 0.577347 , 0.498385 } ,
    { -0.627449 , 0.140955 , 0.765794 } ,    { 0.139713 , 0.9649 , 0.222369 } ,    { -0.865115 , -0.470204 , 0.174599 } ,    { 0.621598 , 0.656019 , 0.428083 } ,    { 0.0436108 , -0.663782 , 0.746654 } ,    { -0.441615 , -0.680943 , 0.584202 } ,    { -0.644906 , -0.763534 , 0.0333617 } ,    { -0.635579 , 0.7317 , 0.24628 } ,    { -0.890948 , -0.224046 , 0.394988 } ,    { -0.656366 , 0.315634 , 0.685243 } ,
    { -0.022597 , -0.947599 , 0.318663 } ,    { 0.326225 , -0.898488 , 0.293762 } ,    { 0.465407 , -0.73839 , 0.488033 } ,    { 0.926797 , 0.375434 , 0.00983512 } ,    { -0.0271515 , -0.754488 , 0.655752 } ,    { 0.87974 , 0.316855 , 0.354485 } ,    { -0.217193 , 0.882002 , 0.41821 } ,    { 0.258732 , -0.862089 , 0.43573 } ,    { -0.616627 , -0.28119 , 0.735326 } ,    { -0.0296808 , -0.523704 , 0.851383 } ,
    { 0.188799 , 0.920192 , 0.34293 } ,    { -0.371185 , 0.906508 , 0.201159 } ,    { 0.694803 , 0.0991563 , 0.712332 } ,    { 0.718251 , 0.251776 , 0.648633 } ,    { -0.494704 , 0.860236 , 0.123541 } ,    { -0.817417 , 0.57496 , 0.035358 } ,    { 0.67949 , 0.716352 , 0.158535 } ,    { 0.464199 , -0.7821 , 0.415739 } ,    { -0.290753 , -0.954749 , 0.062578 } ,    { 0.619657 , 0.757088 , 0.206986 } ,
    { -0.889549 , -0.444481 , 0.105546 } ,    { 0.510778 , 0.76529 , 0.391711 } ,    { -0.952082 , 0.13251 , 0.275646 } ,    { -0.125766 , -0.987546 , 0.0945262 } ,    { -0.719099 , 0.688768 , 0.0921677 } ,    { 0.23742 , -0.238559 , 0.941659 } ,    { 0.404413 , -0.429302 , 0.807558 } ,    { 0.886641 , -0.273456 , 0.372946 } ,    { -0.632746 , 0.744094 , 0.214378 } ,    { 0.959487 , -0.281494 , 0.012094 } ,
    { -0.790622 , 0.0578863 , 0.609563 } ,    { 0.107287 , -0.691835 , 0.714041 } ,    { 0.591391 , 0.255433 , 0.76486 } ,    { -0.835731 , -0.503374 , 0.219474 } ,    { 0.843769 , 0.0331206 , 0.535684 } ,    { -0.182435 , -0.817835 , 0.545768 } ,    { -0.480253 , 0.252462 , 0.840012 } ,    { 0.903267 , -0.343452 , 0.257197 } ,    { 0.26834 , -0.533771 , 0.801924 } ,    { -0.887466 , 0.30668 , 0.344022 } ,
    { 0.501243 , 0.628402 , 0.594867 } ,    { 0.281916 , -0.890679 , 0.356671 } ,    { -0.227028 , -0.0116182 , 0.973819 } ,    { 0.720141 , -0.483467 , 0.497651 } ,    { 0.0304788 , -0.671267 , 0.740589 } ,    { -0.880069 , -0.384213 , 0.279034 } ,    { 0.176621 , 0.852964 , 0.491179 } ,    { 0.478491 , -0.555562 , 0.679998 } ,    { -0.784423 , 0.256313 , 0.564787 } ,    { 0.945726 , 0.308833 , 0.101119 } ,
    { 0.443525 , 0.891927 , 0.0880395 } ,    { -0.826056 , -0.189961 , 0.530609 } ,    { 0.640161 , 0.742004 , 0.199056 } ,    { -0.292418 , -0.000900415 , 0.95629 } ,    { -0.227712 , -0.314066 , 0.921688 } ,    { 0.230814 , 0.381538 , 0.895072 } ,    { 0.10955 , -0.903657 , 0.414007 } ,    { 0.344167 , -0.93586 , 0.0756037 } ,    { 0.204243 , 0.871764 , 0.445324 } ,    { 0.543181 , 0.724706 , 0.423977 } ,
    { -0.896551 , -0.439018 , 0.0588118 } ,    { -0.172723 , -0.80064 , 0.573709 } ,    { -0.857375 , -0.297432 , 0.42005 } ,    { -0.485622 , -0.237407 , 0.841314 } ,    { -0.983674 , -0.179867 , 0.00576198 } ,    { 0.937264 , -0.24781 , 0.245209 } ,    { 0.615678 , -0.523109 , 0.589319 } ,    { -0.337943 , 0.94111 , 0.0103292 } ,    { -0.984429 , 0.168749 , 0.0492296 } ,    { 0.917277 , -0.0840402 , 0.389283 } ,
    { 0.0119516 , -0.657079 , 0.753727 } ,    { -0.825143 , 0.480094 , 0.297739 } ,    { 0.765471 , 0.641951 , 0.0441902 } ,    { 0.273785 , -0.852945 , 0.444439 } ,    { -0.696798 , 0.305656 , 0.648881 } ,    { -0.125027 , 0.429996 , 0.894132 } ,    { 0.534656 , 0.844964 , 0.0133595 } ,    { 0.288889 , -0.9571 , 0.0224361 } ,    { 0.690251 , 0.441469 , 0.573287 } ,    { -0.142068 , -0.659623 , 0.738047 } ,
    { 0.647491 , -0.0340915 , 0.76131 } ,    { -0.423592 , 0.835423 , 0.350197 } ,    { 0.31386 , 0.57035 , 0.759074 } ,    { 0.553468 , -0.380465 , 0.740892 } ,    { -0.879258 , 0.38106 , 0.285829 } ,    { 0.0631023 , -0.623564 , 0.779221 } ,    { -0.899819 , -0.221898 , 0.375615 } ,    { -0.192444 , -0.747621 , 0.635632 } ,    { 0.787205 , -0.539306 , 0.299096 } ,    { 0.189777 , -0.0312954 , 0.981328 } ,
    { -0.911185 , 0.256043 , 0.322776 } ,    { 0.475066 , -0.696289 , 0.538046 } ,    { 0.121238 , -0.630365 , 0.766773 } ,    { -0.461772 , 0.84034 , 0.283893 } ,    { -0.669244 , -0.0462034 , 0.741605 } ,    { -0.419062 , 0.0259755 , 0.907586 } ,    { 0.0182572 , 0.100165 , 0.994803 } ,    { -0.685607 , 0.626734 , 0.370334 } ,    { -0.585048 , 0.213178 , 0.78248 } ,    { 0.883313 , 0.192522 , 0.427426 } ,
    { 0.292522 , 0.5822 , 0.7586 } ,    { 0.836406 , 0.375172 , 0.399589 } ,    { -0.897896 , 0.0997581 , 0.428755 } ,    { -0.546317 , 0.628172 , 0.55402 } ,    { -0.22051 , 0.948743 , 0.226413 } ,    { -0.113446 , -0.728276 , 0.675828 } ,    { -0.684211 , -0.544196 , 0.485496 } ,    { 0.627953 , -0.765299 , 0.141395 } ,    { 0.147156 , 0.6154 , 0.774357 } ,    { -0.0392734 , 0.782557 , 0.621338 } ,
    { 0.0811623 , 0.89073 , 0.447229 } ,    { -0.129275 , -0.858497 , 0.496256 } ,    { 0.375029 , 0.156616 , 0.913687 } ,    { 0.564267 , -0.796646 , 0.216696 } ,    { 0.788661 , -0.614653 , 0.0146966 } ,    { 0.735627 , -0.635123 , 0.235524 } ,    { 0.210895 , 0.46664 , 0.858936 } ,    { 0.0913936 , -0.409962 , 0.907512 } ,    { 0.0894591 , 0.736648 , 0.670333 } ,    { 0.674728 , 0.226884 , 0.702329 } ,
    { 0.995953 , -0.0831084 , 0.0342247 } ,    { 0.0554167 , -0.893348 , 0.445935 } ,    { 0.565981 , -0.802843 , 0.187374 } ,    { 0.643419 , -0.077731 , 0.761558 } ,    { 0.171322 , -0.444482 , 0.879252 } ,    { -0.180729 , 0.833385 , 0.522308 } ,    { 0.99277 , -0.081435 , 0.0881799 } ,    { -0.999775 , -0.00586502 , 0.0204021 } ,    { -0.32026 , -0.295296 , 0.90013 } ,    { 0.892234 , 0.33576 , 0.301966 } ,
    { 0.0268055 , 0.226541 , 0.973633 } ,    { 0.39791 , 0.23101 , 0.887864 } ,    { -0.78838 , 0.590479 , 0.172603 } ,    { -0.595026 , -0.320008 , 0.737251 } ,    { 0.960625 , 0.105818 , 0.256908 } ,    { -0.410565 , -0.533205 , 0.739682 } ,    { 0.10811 , -0.0713151 , 0.991578 } ,    { 0.801966 , 0.566634 , 0.189147 } ,    { 0.861203 , 0.134448 , 0.490157 } ,    { 0.214876 , -0.494032 , 0.842473 } ,
    { -0.30729 , 0.679326 , 0.6664 } ,    { 0.428951 , -0.416782 , 0.801432 } ,    { 0.711123 , 0.584425 , 0.390833 } ,    { -0.39931 , 0.518015 , 0.756447 } ,    { 0.12683 , 0.880861 , 0.456067 } ,    { -0.0312822 , -0.566302 , 0.823604 } ,    { 0.245943 , -0.314068 , 0.916991 } ,    { -0.527879 , 0.546825 , 0.649866 } ,    { -0.299337 , -0.808398 , 0.506843 } ,    { -0.319023 , 0.292586 , 0.901453 } ,
    { 0.791997 , 0.441161 , 0.42204 } ,    { -0.216398 , -0.974761 , 0.0548838 } ,    { -0.912094 , 0.409286 , 0.0238452 } ,    { 0.040788 , 0.926636 , 0.373741 } ,    { 0.775227 , -0.625943 , 0.0849673 } ,    { 0.118577 , -0.453348 , 0.883411 } ,    { 0.498131 , 0.759144 , 0.419005 } ,    { 0.938171 , 0.0832501 , 0.336012 } ,    { -0.809991 , -0.242125 , 0.534126 } ,    { 0.964395 , -0.0297215 , 0.262791 } ,
    { -0.158969 , 0.82194 , 0.54694 } ,    { 0.0960675 , 0.844186 , 0.527372 } ,    { -0.635711 , -0.257476 , 0.72772 } ,    { -0.469659 , 0.390722 , 0.791679 } ,    { 0.809745 , 0.290877 , 0.509612 } ,    { 0.868977 , -0.189509 , 0.457127 } ,    { -0.207109 , 0.653039 , 0.728455 } ,    { 0.548485 , 0.540617 , 0.637885 } ,    { -0.885509 , 0.0323574 , 0.463494 } ,    { -0.358976 , -0.89455 , 0.266302 } ,
    { -0.566431 , 0.287968 , 0.77216 } ,    { 0.824356 , 0.564653 , 0.0400408 } ,    { 0.589737 , 0.790468 , 0.165443 } ,    { -0.572403 , 0.790092 , 0.219337 } ,    { 0.912905 , -0.125406 , 0.38843 } ,    { -0.709163 , 0.145999 , 0.689762 } ,    { -0.764295 , -0.427679 , 0.482642 } ,    { 0.631152 , -0.490723 , 0.600697 } ,    { 0.231863 , -0.659431 , 0.715116 } ,    { -0.720647 , 0.542863 , 0.43124 } ,
    { 0.900848 , 0.329557 , 0.282603 } ,    { 0.961192 , -0.0334031 , 0.273851 } ,    { 0.920292 , 0.261933 , 0.29061 } ,    { -0.553017 , -0.333854 , 0.763357 } ,    { 0.382263 , -0.0357214 , 0.923363 } ,    { -0.794788 , 0.408755 , 0.448589 } ,    { 0.020409 , -0.571098 , 0.820628 } ,    { -0.998245 , 0.04371 , 0.0399619 } ,    { 0.404887 , 0.429262 , 0.807342 } ,    { -0.594547 , -0.420013 , 0.68564 } ,
    { 0.236755 , 0.573626 , 0.784156 } ,    { 0.331111 , -0.36804 , 0.868857 } ,    { -0.0805159 , 0.839224 , 0.537793 } ,    { 0.723547 , -0.450686 , 0.522841 } ,    { 0.949695 , 0.281099 , 0.138069 } ,    { 0.707099 , -0.345121 , 0.617173 } ,    { 0.46272 , 0.862894 , 0.203234 } ,    { -0.950839 , 0.267763 , 0.155591 } ,    { -0.872986 , -0.227222 , 0.431585 } ,    { -0.0104505 , 0.404471 , 0.914491 } ,
    { 0.131964 , -0.287628 , 0.948607 } ,    { 0.859609 , -0.365525 , 0.35702 } ,    { -0.166648 , -0.496809 , 0.851709 } ,    { -0.98028 , 0.137528 , 0.141908 } ,    { 0.128612 , -0.930223 , 0.34372 } ,    { -0.909775 , 0.386505 , 0.151405 } ,    { -0.248672 , -0.305539 , 0.919134 } ,    { -0.107382 , -0.7887 , 0.605327 } ,    { -0.535705 , -0.228169 , 0.812994 } ,    { -0.948791 , 0.147028 , 0.279604 } ,
    { -0.924705 , 0.31084 , 0.219769 } ,    { -0.235016 , -0.952542 , 0.193471 } ,    { 0.443258 , -0.86364 , 0.240099 } ,    { 0.383857 , -0.641298 , 0.664373 } ,    { -0.236259 , -0.933998 , 0.26801 } ,    { 0.444762 , -0.360047 , 0.820093 } ,    { 0.115552 , -0.991603 , 0.0580566 } ,    { 0.748312 , 0.566817 , 0.344596 } ,    { 0.015153 , -0.357193 , 0.933908 } ,    { -0.275867 , 0.947449 , 0.16198 } ,
    { -0.184476 , -0.277756 , 0.942773 } ,    { 0.884273 , -0.0657883 , 0.462313 } ,    { -0.784972 , -0.169362 , 0.595932 } ,    { -0.254361 , -0.864616 , 0.433289 } ,    { 0.368547 , -0.466315 , 0.804192 } ,    { 0.201407 , 0.741499 , 0.640011 } ,    { -0.686645 , -0.396007 , 0.60967 } ,    { -0.485221 , 0.247677 , 0.83858 } ,    { -0.83959 , -0.511631 , 0.182544 } ,    { 0.132017 , -0.843006 , 0.521453 } ,
    { -0.540667 , 0.737518 , 0.404656 } ,    { -0.345251 , 0.660064 , 0.667171 } ,    { -0.970531 , 0.0358942 , 0.238286 } ,    { 0.84874 , 0.509872 , 0.140252 } ,    { -0.865002 , -0.0591363 , 0.498272 } ,    { -0.119174 , 0.636059 , 0.762382 } ,    { 0.568444 , 0.484557 , 0.664888 } ,    { -0.864781 , 0.190324 , 0.464682 } ,    { -0.703115 , 0.0695712 , 0.707664 } ,    { 0.0350197 , 0.939784 , 0.339971 } ,
    { -0.557077 , 0.766957 , 0.318501 } ,    { 0.261154 , 0.339243 , 0.903721 } ,    { -0.683623 , 0.717517 , 0.133522 } ,    { 0.540768 , -0.829281 , 0.140938 } ,    { -0.195335 , 0.349077 , 0.916509 } ,    { -0.0362013 , 0.971711 , 0.23338 } ,    { -0.159317 , 0.754854 , 0.63625 } ,    { -0.173502 , 0.522586 , 0.834746 } ,    { 0.892493 , 0.0702457 , 0.445557 } ,    { 0.959052 , 0.17102 , 0.22577 } ,
    { -0.114643 , 0.992307 , 0.0467293 } ,    { -0.285994 , -0.734729 , 0.615127 } ,    { 0.577309 , 0.295169 , 0.761308 } ,    { 0.936335 , 0.159308 , 0.312886 } ,    { 0.218608 , -0.419689 , 0.880949 } ,    { 0.71999 , -0.521206 , 0.458212 } ,    { -0.129866 , -0.751191 , 0.647184 } ,    { -0.768672 , -0.633033 , 0.0917187 } ,    { -0.434375 , -0.389444 , 0.812189 } ,    { -0.942332 , -0.320385 , 0.0967726 } ,
    { -0.904291 , -0.413814 , 0.104953 } ,    { 0.634652 , 0.670741 , 0.383827 } ,    { -0.550148 , 0.450983 , 0.702817 } ,    { -0.684074 , -0.716013 , 0.139166 } ,    { 0.243451 , -0.538892 , 0.806429 } ,    { -0.850345 , 0.422698 , 0.313431 } ,    { 0.546199 , -0.124691 , 0.828323 } ,    { -0.629809 , 0.13459 , 0.765 } ,    { 0.149402 , -0.985615 , 0.0790023 } ,    { -0.13244 , -0.0949911 , 0.986629 } ,
    { 0.0535806 , -0.598595 , 0.799258 } ,    { -0.00884962 , 0.0520983 , 0.998603 } ,    { 0.959685 , 0.279865 , 0.0260745 } ,    { -0.554417 , -0.308743 , 0.772852 } ,    { -0.497229 , 0.805263 , 0.322978 } ,    { 0.74654 , 0.60983 , 0.266056 } ,    { -0.91583 , 0.355203 , 0.187313 } ,    { -0.0427974 , 0.877957 , 0.476823 } ,    { -0.459749 , -0.82189 , 0.336344 } ,    { -0.0913867 , -0.969542 , 0.227236 } ,
    { 0.223523 , 0.0620523 , 0.972721 } ,    { 0.850603 , 0.414715 , 0.323243 } ,    { 0.181937 , -0.983199 , 0.0147532 } ,    { -0.369108 , -0.111975 , 0.922616 } ,    { 0.974313 , 0.19862 , 0.106129 } ,    { -0.54537 , -0.78576 , 0.291808 } ,    { 0.558758 , 0.722271 , 0.407571 } ,    { 0.105457 , -0.498539 , 0.860429 } ,    { -0.319243 , 0.717351 , 0.619267 } ,    { -0.574676 , 0.771889 , 0.271909 } ,
    { -0.723076 , 0.0132976 , 0.69064 } ,    { -0.359659 , -0.145081 , 0.921736 } ,    { -0.150904 , -0.457376 , 0.876376 } ,    { -0.0966361 , 0.764323 , 0.637551 } ,    { 0.188163 , 0.650063 , 0.736215 } ,    { 0.610233 , -0.792158 , 0.0101179 } ,    { -0.431935 , -0.748285 , 0.503489 } ,    { 0.0184455 , -0.521036 , 0.853335 } ,    { 0.442132 , -0.09778 , 0.891605 } ,    { -0.796191 , 0.00566982 , 0.605019 } ,
    { -0.0971762 , 0.0326487 , 0.994732 } ,    { 0.194327 , -0.691854 , 0.695396 } ,    { -0.506032 , -0.288706 , 0.812761 } ,    { 0.112829 , -0.52032 , 0.846485 } ,    { -0.561061 , 0.218873 , 0.798314 } ,    { -0.646408 , -0.227399 , 0.728318 } ,    { -0.814636 , -0.566508 , 0.124248 } ,    { -0.692783 , 0.683579 , 0.22972 } ,    { -0.736898 , 0.326412 , 0.591976 } ,    { -0.491501 , -0.820408 , 0.292161 } ,
    { 0.559106 , 0.781246 , 0.277587 } ,    { 0.758038 , -0.651153 , 0.037128 } ,    { 0.876661 , -0.314177 , 0.364359 } ,    { -0.0819339 , 0.954911 , 0.285361 } ,    { 0.926114 , -0.332171 , 0.178818 } ,    { -0.712707 , 0.465238 , 0.524978 } ,    { 0.530396 , -0.314615 , 0.787208 } ,    { 0.91222 , -0.0733874 , 0.403074 } ,    { 0.0183266 , -0.101998 , 0.994616 } ,    { -0.707567 , 0.538488 , 0.457581 } ,
    { 0.690153 , -0.456141 , 0.561805 } ,    { -0.239829 , -0.362485 , 0.900604 } ,    { -0.917324 , -0.39807 , 0.00751901 } ,    { 0.109925 , -0.34015 , 0.933924 } ,    { -0.0298575 , -0.0625489 , 0.997595 } ,    { -0.242316 , -0.284043 , 0.927687 } ,    { -0.74623 , 0.0828246 , 0.660516 } ,    { 0.596785 , 0.800887 , 0.0492789 } ,    { 0.257241 , 0.449808 , 0.855278 } ,    { 0.51813 , -0.836872 , 0.176598 } ,
    { 0.44676 , 0.865893 , 0.22502 } ,    { -0.869742 , -0.0334299 , 0.492373 } ,    { 0.538992 , -0.183692 , 0.822037 } ,    { -0.856514 , -0.515951 , 0.013324 } ,    { -0.0763536 , 0.83301 , 0.547963 } ,    { -0.245044 , 0.0880203 , 0.965508 } ,    { -0.688333 , 0.307905 , 0.656804 } ,    { 0.273693 , 0.540148 , 0.795822 } ,    { -0.660709 , -0.750633 , 0.00356448 } ,    { -0.311555 , 0.00584329 , 0.95021 } ,
    { 0.721288 , -0.291106 , 0.628491 } ,    { 0.420054 , 0.538056 , 0.730788 } ,    { 0.533103 , 0.831301 , 0.157289 } ,    { -0.47249 , 0.659043 , 0.585163 } ,    { 0.21454 , 0.726218 , 0.653131 } ,    { -0.860136 , 0.346343 , 0.374449 } ,    { 0.886343 , -0.394107 , 0.243055 } ,    { -0.445732 , 0.0924414 , 0.890381 } ,    { -0.599578 , 0.243827 , 0.76227 } ,    { 0.777262 , 0.619928 , 0.107486 } ,
    { 0.783514 , 0.182892 , 0.593849 } ,    { -0.701789 , 0.704673 , 0.104537 } ,    { 0.564367 , 0.823275 , 0.0608941 } ,    { -0.427109 , 0.0876926 , 0.899938 } ,    { 0.805202 , 0.128238 , 0.578969 } ,    { 0.793046 , 0.605076 , 0.0704278 } ,    { -0.301915 , -0.217598 , 0.928169 } ,    { 0.649656 , -0.569562 , 0.503533 } ,    { -0.847132 , -0.222137 , 0.482724 } ,    { 0.75969 , 0.450592 , 0.46887 } ,
    { 0.758158 , -0.406567 , 0.509805 } ,    { -0.712589 , -0.6999 , 0.0485588 } ,    { -0.691146 , 0.134232 , 0.710141 } ,    { 0.0498011 , 0.573127 , 0.817952 } ,    { -0.354963 , -0.456237 , 0.815996 } ,    { 0.556967 , 0.467127 , 0.686717 } ,    { 0.61065 , -0.469827 , 0.637471 } ,    { 0.583386 , 0.811695 , 0.0285054 } ,    { 0.424861 , 0.097152 , 0.90003 } ,    { 0.517801 , -0.821967 , 0.237176 } ,
    { 0.859447 , 0.496496 , 0.121829 } ,    { 0.981295 , 0.155418 , 0.113601 } ,    { -0.334844 , -0.868484 , 0.365533 } ,    { 0.532831 , -0.205543 , 0.820879 } ,    { -0.543327 , -0.699313 , 0.464496 } ,    { -0.318614 , 0.0456605 , 0.946784 } ,    { 0.473164 , 0.156662 , 0.866933 } ,    { 0.862984 , -0.463166 , 0.201832 } ,    { 0.100763 , 0.26385 , 0.959286 } ,    { 0.854356 , -0.412869 , 0.315618 } ,
    { 0.945142 , 0.00693212 , 0.326585 } ,    { 0.386745 , 0.0438578 , 0.921143 } ,    { -0.600858 , -0.0958466 , 0.793589 } ,    { -0.707635 , 0.245865 , 0.662422 } ,    { -0.111343 , 0.465358 , 0.878092 } ,    { -0.591055 , -0.568244 , 0.572497 } ,    { 0.0864004 , 0.665364 , 0.741503 } ,    { 0.6683 , 0.233595 , 0.706264 } ,    { 0.505228 , 0.190213 , 0.841762 } ,    { 0.571738 , 0.820374 , 0.0101559 } ,
    { -0.906242 , -0.123347 , 0.404365 } ,    { 0.11326 , -0.958685 , 0.260949 } ,    { -0.0604709 , -0.514816 , 0.855165 } ,    { 0.772015 , 0.509025 , 0.38064 } ,    { -0.307696 , 0.434151 , 0.846662 } ,    { 0.0181294 , -0.287057 , 0.957742 } ,    { 0.664347 , 0.265729 , 0.698592 } ,    { -0.0204153 , -0.830918 , 0.55602 } ,    { 0.930659 , -0.323222 , 0.171466 } ,    { -0.557713 , -0.734957 , 0.385739 } ,
    { -0.875948 , 0.115593 , 0.468353 } ,    { 0.700654 , 0.542972 , 0.462888 } ,    { -0.783512 , 0.460553 , 0.417132 } ,    { 0.501783 , 0.530637 , 0.683109 } ,    { 0.569689 , 0.820049 , 0.0545357 } ,    { -0.409251 , -0.802135 , 0.434848 } ,    { -0.64917 , 0.394729 , 0.650205 } ,    { 0.00778237 , 0.461202 , 0.887261 } ,    { 0.468419 , 0.524305 , 0.711117 } ,    { -0.862866 , -0.391378 , 0.319822 } ,
    { -0.170686 , 0.203139 , 0.964158 } ,    { -0.459377 , 0.818765 , 0.344379 } ,    { -0.777294 , -0.609375 , 0.156449 } ,    { 0.986826 , 0.046591 , 0.154931 } ,    { 0.0568999 , -0.442906 , 0.894761 } ,    { 0.217973 , -0.925949 , 0.308392 } ,    { 0.766562 , -0.404321 , 0.498906 } ,    { 0.942505 , -0.254539 , 0.216553 } ,    { 0.899558 , 0.29334 , 0.323647 } ,    { -0.210998 , 0.524159 , 0.825068 } ,
    { 0.55139 , -0.586861 , 0.592927 } ,    { -0.170757 , 0.163543 , 0.971646 } ,    { -0.813929 , 0.386426 , 0.433815 } ,    { -0.869255 , 0.425612 , 0.251497 } ,    { 0.969163 , -0.211287 , 0.126807 } ,    { 0.959401 , 0.281889 , 0.00938708 } ,    { -0.416048 , 0.84099 , 0.34589 } ,    { 0.00712107 , 0.969172 , 0.246284 } ,    { 0.492841 , -0.145458 , 0.857875 } ,    { 0.852823 , -0.0992688 , 0.512679 } ,
    { 0.706273 , -0.44489 , 0.550682 } ,    { 0.832631 , -0.136643 , 0.536706 } ,    { -0.504781 , -0.796256 , 0.333426 } ,    { 0.469291 , 0.872548 , 0.135738 } ,    { -0.900427 , -0.111435 , 0.420491 } ,    { -0.856288 , 0.515293 , 0.0352561 } ,    { -0.614207 , 0.124402 , 0.779278 } ,    { -0.42444 , -0.804458 , 0.415569 } ,    { -0.851647 , 0.482486 , 0.204704 } ,    { 0.950498 , -0.237363 , 0.200532 } ,
    { 0.528799 , 0.362158 , 0.767602 } ,    { 0.243454 , 0.969824 , 0.0130686 } ,    { 0.406356 , -0.365612 , 0.837379 } ,    { 0.226455 , -0.321667 , 0.919374 } ,    { -0.15622 , -0.720685 , 0.675432 } ,    { 0.695627 , 0.287496 , 0.658368 } ,    { 0.543948 , 0.382485 , 0.746877 } ,    { 0.363125 , -0.0936031 , 0.927027 } ,    { -0.840445 , 0.167902 , 0.515229 } ,    { 0.661756 , -0.135483 , 0.737376 } ,
    { -0.163077 , -0.141392 , 0.976429 } ,    { -0.699217 , 0.674582 , 0.236716 } ,    { 0.252451 , 0.486792 , 0.836243 } ,    { 0.434678 , -0.056226 , 0.898829 } ,    { -0.573527 , -0.798337 , 0.183643 } ,    { 0.981289 , -0.151489 , 0.118843 } ,    { 0.822516 , -0.283848 , 0.492847 } ,    { -0.471747 , -0.798973 , 0.372958 } ,    { -0.455556 , -0.596267 , 0.66101 } ,    { -0.49136 , -0.870584 , 0.0254794 } ,
    { 0.524847 , -0.80534 , 0.275616 } ,    { -0.885086 , 0.0626489 , 0.461191 } ,    { 0.0510943 , -0.474219 , 0.878923 } ,    { -0.144161 , -0.417424 , 0.897204 } ,    { -0.744092 , -0.408544 , 0.528601 } ,    { -0.121111 , -0.732297 , 0.670129 } ,    { -0.882796 , -0.265992 , 0.387195 } ,    { -0.0963813 , 0.596956 , 0.796464 } ,    { -0.47735 , -0.677872 , 0.55913 } ,    { -0.332361 , 0.80588 , 0.489993 } ,
    { -0.266612 , -0.749123 , 0.606409 } ,    { 0.861879 , 0.277817 , 0.424243 } ,    { 0.945999 , -0.15375 , 0.285389 } ,    { 0.809668 , -0.137645 , 0.570518 } ,    { -0.136864 , -0.960815 , 0.241046 } ,    { -0.692803 , 0.0755387 , 0.717159 } ,    { -0.352608 , 0.366084 , 0.861191 } ,    { -0.996822 , -0.055587 , 0.0570632 } ,    { -0.841918 , 0.462365 , 0.278196 } ,    { 0.643523 , -0.64516 , 0.411883 } ,
    { -0.688555 , 0.725185 , 3.18289e-05 } ,    { -0.207068 , -0.55946 , 0.802576 } ,    { -0.301945 , -0.938922 , 0.165091 } ,    { -0.224272 , -0.263893 , 0.938117 } ,    { -0.155068 , -0.943039 , 0.294333 } ,    { -0.553902 , -0.82659 , 0.0997092 } ,    { -0.0408728 , -0.542151 , 0.839287 } ,    { -0.842457 , -0.347952 , 0.411333 } ,    { 0.794438 , -0.434102 , 0.424763 } ,    { 0.184269 , -0.321159 , 0.928925 } ,
    { 0.423175 , 0.856411 , 0.295776 } ,    { 0.189682 , 0.909965 , 0.368761 } ,    { -0.0996739 , 0.41996 , 0.902052 } ,    { -0.338336 , -0.82519 , 0.452317 } ,    { 0.737888 , -0.335404 , 0.585684 } ,    { -0.26393 , -0.956311 , 0.125739 } ,    { 0.484736 , 0.780871 , 0.394045 } ,    { -0.110472 , -0.587773 , 0.801448 } ,    { 0.471423 , -0.503393 , 0.724124 } ,    { -0.209815 , -0.935781 , 0.283358 } ,
    { -0.209464 , 0.54431 , 0.812312 } ,    { -0.962643 , -0.0817722 , 0.258132 } ,    { 0.882556 , 0.460922 , 0.0929811 } ,    { -0.0550703 , 0.986899 , 0.15165 } ,    { -0.0835697 , -0.0703485 , 0.994016 } ,    { -0.603002 , -0.776336 , 0.183552 } ,    { 0.682559 , -0.448998 , 0.576641 } ,    { -0.501199 , 0.820263 , 0.275624 } ,    { 0.782924 , 0.485524 , 0.388967 } ,    { 0.813987 , -0.578664 , 0.050732 } ,
    { 0.849505 , 0.525994 , 0.0408934 } ,    { 0.434482 , -0.874008 , 0.217567 } ,    { -0.864691 , -0.0517164 , 0.499635 } ,    { -0.759991 , -0.643988 , 0.0877117 } ,    { -0.792815 , 0.559607 , 0.24142 } ,    { -0.746124 , 0.127161 , 0.653551 } ,    { 0.292639 , 0.858417 , 0.421287 } ,    { 0.0447946 , -0.998638 , 0.0267586 } ,    { -0.824524 , -0.341199 , 0.45138 } ,    { -0.133476 , 0.990535 , 0.0320121 } ,
    { 0.730719 , 0.587548 , 0.347616 } ,    { -0.53852 , 0.130618 , 0.832428 } ,    { 0.0434046 , -0.240637 , 0.969644 } ,    { 0.22969 , 0.886745 , 0.401155 } ,    { -0.43643 , 0.859363 , 0.266503 } ,    { 0.740113 , -0.63457 , 0.222606 } ,    { 0.105307 , 0.553674 , 0.826048 } ,    { -0.472218 , -0.774318 , 0.421239 } ,    { -0.0249753 , 0.887988 , 0.459188 } ,    { -0.691847 , -0.564221 , 0.450557 } ,
    { -0.584066 , -0.4328 , 0.686696 } ,    { 0.66296 , -0.730463 , 0.164035 } ,    { -0.831966 , -0.382833 , 0.401587 } ,    { 0.59096 , 0.294203 , 0.75114 } ,    { 0.428824 , 0.521261 , 0.737832 } ,    { 0.244826 , -0.681481 , 0.689669 } ,    { 0.0602117 , -0.865982 , 0.496437 } ,    { -0.074388 , 0.881674 , 0.465959 } ,    { 0.35589 , 0.157854 , 0.9211 } ,    { 0.830083 , -0.55503 , 0.0538844 } ,
    { -0.842118 , -0.493472 , 0.217537 } ,    { 0.304456 , -0.858232 , 0.413212 } ,    { -0.920053 , -0.0232065 , 0.391106 } ,    { 0.348633 , 0.0757269 , 0.934195 } ,    { -0.0449895 , -0.874451 , 0.483023 } ,    { 0.602829 , -0.355792 , 0.714149 } ,    { 0.148893 , 0.937887 , 0.313369 } ,    { 0.562852 , 0.702754 , 0.435126 } ,    { -0.674787 , 0.447105 , 0.587162 } ,    { -0.732583 , 0.375215 , 0.567923 } ,
    { -0.393894 , -0.158459 , 0.905394 } ,    { 0.250643 , -0.852287 , 0.459114 } ,    { 0.764981 , -0.0164537 , 0.643843 } ,    { 0.639553 , -0.759662 , 0.117836 } ,    { 0.972071 , 0.197968 , 0.126041 } ,    { -0.849059 , 0.251008 , 0.464859 } ,    { 0.594783 , 0.239671 , 0.767327 } ,    { 0.769387 , -0.418055 , 0.482985 } ,    { 0.151384 , 0.979895 , 0.129956 } ,    { -0.443564 , 0.891677 , 0.0903503 } ,
    { 0.815509 , 0.575066 , 0.0651521 } ,    { -0.317493 , 0.791135 , 0.522785 } ,    { 0.926851 , 0.123273 , 0.354614 } ,    { -0.741533 , -0.664372 , 0.0934764 } ,    { -0.251187 , -0.452187 , 0.855822 } ,    { -0.3915 , 0.0614674 , 0.918123 } ,    { 0.114004 , -0.880388 , 0.460347 } ,    { -0.796083 , -0.270298 , 0.541471 } ,    { -0.405657 , 0.741708 , 0.534145 } ,    { 0.474989 , -0.862806 , 0.173067 } ,
    { 0.403477 , 0.872136 , 0.276742 } ,    { 0.893571 , -0.124509 , 0.43131 } ,    { 0.825728 , 0.227861 , 0.515997 } ,    { 0.211412 , -0.565068 , 0.797498 } ,    { -0.511077 , 0.67121 , 0.536915 } ,    { 0.0855244 , 0.961572 , 0.260893 } ,    { 0.292745 , -0.315479 , 0.902648 } ,    { 0.0633871 , -0.416861 , 0.906758 } ,    { 0.975544 , -0.000717178 , 0.219803 } ,    { 0.404331 , -0.887903 , 0.219419 } ,
    { 0.68091 , -0.314012 , 0.661633 } ,    { -0.734426 , 0.538139 , 0.413552 } ,    { -0.738635 , -0.313919 , 0.596551 } ,    { -0.976209 , 0.193878 , 0.0970962 } ,    { -0.645793 , 0.733266 , 0.212774 } ,    { -0.0301506 , 0.915047 , 0.402219 } ,    { -0.862666 , -0.497353 , 0.0919106 } ,    { -0.199795 , 0.821809 , 0.533585 } ,    { -0.448485 , -0.489511 , 0.747824 } ,    { 0.77406 , -0.60397 , 0.189873 } ,
    { -0.153995 , -0.987648 , 0.0289389 } ,    { 0.621224 , -0.260276 , 0.739146 } ,    { -0.258797 , -0.524497 , 0.811127 } ,    { -0.902438 , 0.0879666 , 0.421743 } ,    { 0.752637 , 0.555264 , 0.353863 } ,    { 0.452108 , -0.655336 , 0.605089 } ,    { 0.822625 , 0.564881 , 0.0647826 } ,    { -0.0868027 , -0.866856 , 0.490943 } ,    { -0.239846 , -0.69234 , 0.680544 } ,    { -0.863098 , -0.30061 , 0.405827 } ,
    { -0.481706 , -0.00545994 , 0.876316 } ,    { 0.719895 , 0.578956 , 0.382833 } ,    { -0.951653 , -0.255792 , 0.170079 } ,    { 0.236509 , 0.948997 , 0.208492 } ,    { 0.936078 , -0.0548174 , 0.347495 } ,    { 0.52746 , 0.822872 , 0.211346 } ,    { 0.0717982 , 0.819992 , 0.567854 } ,    { -0.364176 , 0.911268 , 0.192266 } ,    { -0.197447 , 0.527493 , 0.826296 } ,    { -0.681442 , -0.432934 , 0.590089 } ,
    { 0.803915 , 0.565674 , 0.183667 } ,    { -0.923448 , 0.361882 , 0.127611 } ,    { 0.383898 , 0.838495 , 0.386715 } ,    { 0.565343 , -0.747224 , 0.349347 } ,    { 0.697002 , -0.674704 , 0.242821 } ,    { 0.914327 , -0.359142 , 0.187146 } ,    { 0.211641 , 0.947112 , 0.241218 } ,    { -0.417842 , 0.094971 , 0.903542 } ,    { 0.820175 , -0.301215 , 0.486398 } ,    { 0.848589 , -0.395747 , 0.351115 } ,
    { 0.193297 , -0.972402 , 0.130653 } ,    { 0.333962 , 0.464222 , 0.820346 } ,    { 0.102207 , 0.240151 , 0.96534 } ,    { 0.349727 , -0.163287 , 0.922512 } ,    { 0.00661616 , -0.167036 , 0.985929 } ,    { -0.812484 , 0.581532 , 0.0411156 } ,    { -0.921259 , 0.256687 , 0.29222 } ,    { -0.90706 , -0.277474 , 0.316624 } ,    { -0.68703 , -0.0708787 , 0.723164 } ,    { -0.595693 , -0.0639003 , 0.800666 } ,
    { 0.341178 , -0.915756 , 0.212103 } ,    { 0.0589931 , -0.399396 , 0.914878 } ,    { -0.291679 , -0.0103922 , 0.95646 } ,    { -0.157075 , 0.865558 , 0.475539 } ,    { 0.850995 , -0.515429 , 0.100698 } ,    { -0.607823 , 0.54047 , 0.581759 } ,    { -0.278863 , 0.877967 , 0.389114 } ,    { -0.236604 , -0.969071 , 0.070142 } ,    { -0.243777 , 0.00562681 , 0.969815 } ,    { 0.949357 , -0.132852 , 0.284731 } ,
    { -0.4521 , -0.742182 , 0.494745 } ,    { 0.760964 , 0.601973 , 0.241996 } ,    { 0.118874 , 0.638186 , 0.76065 } ,    { -0.0483665 , 0.950308 , 0.30753 } ,    { -0.830093 , -0.29355 , 0.474104 } ,    { 0.567781 , 0.612293 , 0.550202 } ,    { -0.0757834 , -0.688028 , 0.721716 } ,    { 0.435407 , -0.395548 , 0.80868 } ,    { -0.551408 , -0.684818 , 0.476416 } ,    { -0.279902 , -0.680083 , 0.677601 } ,
    { 0.313959 , -0.332989 , 0.889128 } ,    { 2.24853e-05 , 0.517584 , 0.855632 } ,    { -0.735254 , -0.587193 , 0.338535 } ,    { 0.564715 , 0.821757 , 0.0762397 } ,    { -0.483314 , -0.37124 , 0.792836 } ,    { -0.596923 , 0.757587 , 0.264093 } ,    { -0.882831 , -0.0613865 , 0.465663 } ,    { -0.287069 , 0.247234 , 0.925455 } ,    { -0.659155 , -0.592201 , 0.463478 } ,    { -0.938723 , 0.186471 , 0.289874 } ,
    { 0.659334 , -0.362266 , 0.658819 } ,    { 0.960813 , 0.192366 , 0.199583 } ,    { 0.718919 , 0.0186663 , 0.694844 } ,    { 0.433633 , -0.355138 , 0.828155 } ,    { -0.629111 , -0.321928 , 0.707518 } ,    { -0.160962 , -0.513745 , 0.842708 } ,    { -0.580095 , -0.807249 , 0.108806 } ,    { 0.321983 , 0.283379 , 0.90334 } ,    { -0.733212 , 0.442685 , 0.516169 } ,    { 0.544053 , -0.6438 , 0.538078 } ,
    { -0.812493 , 0.581884 , 0.0355911 } ,    { -0.179919 , 0.805763 , 0.564247 } ,    { -0.415771 , -0.89233 , 0.175731 } ,    { -0.4666 , -0.592827 , 0.656384 } ,    { 0.32751 , -0.734624 , 0.594193 } ,    { 0.954271 , -0.196452 , 0.22533 } ,    { -0.198705 , -0.826671 , 0.526433 } ,    { -0.0451304 , 0.0376411 , 0.998272 } ,    { 0.770595 , -0.467485 , 0.433176 } ,    { -0.584706 , 0.681747 , 0.439704 } ,
    { -0.134732 , 0.1654 , 0.97698 } ,    { 0.449769 , -0.197704 , 0.870989 } ,    { 0.994655 , 0.10144 , 0.0192468 } ,    { -0.1105 , 0.989042 , 0.0979023 } ,    { 0.410207 , -0.901097 , 0.140549 } ,    { -0.635069 , 0.217338 , 0.74125 } ,    { -0.515723 , 0.736242 , 0.438152 } ,    { 0.601121 , 0.649966 , 0.464971 } ,    { 0.823297 , -0.56487 , 0.0557101 } ,    { 0.405221 , -0.795894 , 0.449831 } ,
    { 0.682978 , -0.581471 , 0.442078 } ,    { -0.878181 , 0.238333 , 0.414724 } ,    { 0.155825 , -0.57998 , 0.799588 } ,    { -0.387968 , 0.869522 , 0.305633 } ,    { 0.562482 , 0.579209 , 0.590026 } ,    { 0.324512 , 0.875006 , 0.359245 } ,    { -0.00862921 , -0.233782 , 0.972251 } ,    { -0.966562 , 0.0258241 , 0.255128 } ,    { 0.380356 , 0.764394 , 0.520607 } ,    { 0.312731 , 0.790292 , 0.526914 } ,
    { -0.781685 , 0.623577 , 0.010989 } ,    { -0.156254 , -0.670899 , 0.724899 } ,    { -0.584927 , 0.622601 , 0.519834 } ,    { -0.106913 , 0.94457 , 0.310416 } ,    { -0.609895 , -0.571841 , 0.548659 } ,    { 0.580308 , -0.0168921 , 0.814222 } ,    { -0.752211 , 0.658746 , 0.015252 } ,    { 0.775703 , 0.624115 , 0.0936187 } ,    { 0.291027 , -0.888572 , 0.354603 } ,    { -0.730294 , 0.666293 , 0.150749 } ,
    { -0.784708 , -0.602766 , 0.144588 } ,    { 0.453553 , -0.272745 , 0.848469 } ,    { -0.207342 , -0.686692 , 0.696752 } ,    { -0.444957 , -0.361925 , 0.81916 } ,    { -0.302347 , -0.575724 , 0.759689 } ,    { -0.56473 , 0.56936 , 0.597418 } ,    { 0.912843 , -0.386474 , 0.131737 } ,    { 0.33899 , -0.924206 , 0.175864 } ,    { 0.72083 , -0.324246 , 0.612591 } ,    { -0.864807 , -0.479865 , 0.147779 } ,
    { -0.496619 , -0.86157 , 0.105201 } ,    { -0.492481 , -0.195799 , 0.848013 } ,    { 0.437821 , 0.0811959 , 0.895388 } ,    { -0.120346 , -0.9341 , 0.336117 } ,    { -0.785149 , -0.517049 , 0.340883 } ,    { 0.0444725 , -0.973622 , 0.223792 } ,    { 0.303627 , 0.735126 , 0.606135 } ,    { -0.722871 , -0.211534 , 0.657808 } ,    { -0.853222 , -0.473794 , 0.218018 } ,    { -0.124196 , 0.943253 , 0.307976 } ,
    { -0.823915 , 0.252352 , 0.507427 } ,    { -0.405158 , 0.866909 , 0.290372 } ,    { -0.103231 , -0.969547 , 0.222086 } ,    { -0.223474 , -0.623826 , 0.748933 } ,    { 0.232434 , 0.706631 , 0.668316 } ,    { -0.164286 , -0.817665 , 0.551755 } ,    { -0.575475 , 0.7728 , 0.267597 } ,    { -0.723802 , 0.406797 , 0.557339 } ,    { 0.917389 , -0.319073 , 0.237889 } ,    { 0.174018 , 0.688786 , 0.70377 } ,
    { 0.0626636 , -0.994917 , 0.0788244 } ,    { 0.0855177 , 0.994263 , 0.0642416 } ,    { 0.638844 , 0.762185 , 0.104655 } ,    { 0.436851 , -0.701318 , 0.563306 } ,    { -0.825885 , 0.353449 , 0.439303 } ,    { 0.615803 , -0.10403 , 0.781002 } ,    { 0.018539 , -0.629627 , 0.776677 } ,    { -0.138301 , 0.7985 , 0.585893 } ,    { 0.191359 , -0.107593 , 0.975605 } ,    { -0.568249 , -0.821023 , 0.0549051 } ,
    { 0.00961648 , 0.971752 , 0.235806 } ,    { 0.664657 , -0.0666023 , 0.744174 } ,    { 0.350822 , 0.487721 , 0.799407 } ,    { 0.974123 , -0.114662 , 0.194775 } ,    { 0.563353 , 0.185896 , 0.805032 } ,    { 0.513834 , 0.597022 , 0.616067 } ,    { 0.496715 , 0.781022 , 0.378523 } ,    { -0.0510972 , 0.96598 , 0.253518 } ,    { -0.515082 , -0.756834 , 0.402358 } ,    { 0.974372 , 0.113602 , 0.194148 } ,
    { -0.265032 , -0.947086 , 0.18107 } ,    { 0.991071 , -0.132336 , 0.0163258 } ,    { 0.216165 , -0.973277 , 0.0774841 } ,    { -0.815172 , 0.270196 , 0.512337 } ,    { -0.107314 , -0.797668 , 0.593472 } ,    { 0.423182 , -0.882453 , 0.20541 } ,    { 0.98645 , -0.157561 , 0.0457181 } ,    { -0.700073 , -0.370316 , 0.610544 } ,    { -0.173318 , -0.639612 , 0.748904 } ,    { -0.0793354 , -0.463722 , 0.882421 } ,
    { -0.00406452 , 0.85584 , 0.517224 } ,    { 0.629261 , 0.292979 , 0.719857 } ,    { 0.0602318 , 0.567448 , 0.821203 } ,    { 0.190457 , 0.730763 , 0.655523 } ,    { 0.867935 , -0.443363 , 0.223873 } ,    { -0.831375 , 0.112474 , 0.54421 } ,    { 0.12773 , 0.663512 , 0.737182 } ,    { 0.832204 , 0.547906 , 0.0850565 } ,    { -0.0303688 , -0.13061 , 0.990969 } ,    { -0.104853 , -0.385942 , 0.916545 } ,
    { 0.611616 , 0.78271 , 0.115288 } ,    { -0.293326 , 0.162466 , 0.942107 } ,    { -0.327169 , 0.559464 , 0.761552 } ,    { -0.0328401 , -0.999442 , 0.00613129 } ,    { 0.377281 , 0.137771 , 0.915794 } ,    { -0.312639 , 0.947687 , 0.0643909 } ,    { -0.370741 , 0.697734 , 0.612959 } ,    { -0.138099 , -0.658128 , 0.740132 } ,    { -0.31957 , -0.939701 , 0.121805 } ,    { 0.495298 , -0.164497 , 0.853007 } ,
    { -0.370833 , -0.541251 , 0.754672 } ,    { -0.0132647 , 0.518246 , 0.855129 } ,    { -0.497727 , 0.438604 , 0.748261 } ,    { 0.52099 , -0.49765 , 0.693479 } ,    { 0.749306 , -0.632133 , 0.197353 } ,    { -0.543409 , -0.143288 , 0.827149 } ,    { 0.74694 , 0.661628 , 0.065799 } ,    { -0.224673 , -0.318076 , 0.921059 } ,    { -0.42204 , 0.11556 , 0.899182 } ,    { 0.607361 , -0.031725 , 0.793792 } ,
    { 0.15056 , -0.171425 , 0.973625 } ,    { 0.343841 , -0.734684 , 0.584819 } ,    { -0.482372 , -0.786889 , 0.384868 } ,    { -0.0209057 , 0.997076 , 0.0734965 } ,    { 0.934695 , -0.219737 , 0.279393 } ,    { 0.798837 , -0.0858186 , 0.595395 } ,    { 0.665918 , 0.707946 , 0.2353 } ,    { -0.879308 , 0.0454528 , 0.47408 } ,    { -0.864235 , -0.502205 , 0.0298067 } ,    { -0.730156 , -0.63223 , 0.259147 } ,
    { 0.96199 , -0.267385 , 0.055506 } ,    { -0.722692 , -0.0233776 , 0.690775 } ,    { 0.74166 , 0.655038 , 0.144449 } ,    { -0.940341 , -0.129706 , 0.314541 } ,    { -0.932651 , -0.330267 , 0.145212 } ,    { -0.85788 , -0.513139 , 0.027019 } ,    { -0.187942 , 0.512718 , 0.837734 } ,    { 0.751474 , 0.632089 , 0.189079 } ,    { 0.327079 , -0.124277 , 0.93679 } ,    { -0.324712 , 0.602263 , 0.729275 } ,
    { -0.89638 , -0.400939 , 0.189079 } ,    { 0.773728 , 0.113148 , 0.623332 } ,    { 0.758225 , 0.239564 , 0.606386 } ,    { -0.238161 , -0.970769 , 0.0297819 } ,    { -0.509495 , 0.447379 , 0.735028 } ,    { -0.600854 , -0.464456 , 0.65058 } ,    { -0.941317 , 0.119501 , 0.315661 } ,    { 0.837802 , -0.499794 , 0.219759 } ,    { 0.0630814 , -0.583151 , 0.809911 } ,    { 0.490595 , 0.861997 , 0.127582 } ,
    { 0.728256 , -0.23805 , 0.642632 } ,    { 0.0536279 , 0.868311 , 0.493112 } ,    { 0.472535 , 0.733389 , 0.488725 } ,    { -0.155106 , -0.942186 , 0.297033 } ,    { 0.2069 , 0.957234 , 0.202227 } ,    { 0.993575 , 0.0410637 , 0.105461 } ,    { 0.593256 , -0.678083 , 0.433879 } ,    { 0.33672 , -0.0428219 , 0.940631 } ,    { -0.541417 , -0.155732 , 0.826205 } ,    { -0.755016 , -0.222382 , 0.616844 } ,
    { -0.984565 , -0.104744 , 0.140214 } ,    { 0.131784 , -0.944588 , 0.300642 } ,    { -0.00726727 , 0.113233 , 0.993542 } ,    { 0.777702 , 0.50608 , 0.372911 } ,    { 0.716332 , 0.695612 , 0.0547003 } ,    { -0.496634 , 0.695747 , 0.518932 } ,    { -0.516538 , -0.0419909 , 0.855234 } ,    { 0.267919 , -0.502034 , 0.822302 } ,    { -0.873879 , 0.343882 , 0.343629 } ,    { -0.142782 , 0.984264 , 0.104106 } ,
    { 0.751267 , 0.581108 , 0.312907 } ,    { -0.83347 , 0.332941 , 0.440996 } ,    { 0.362676 , -0.929875 , 0.0616398 } ,    { 0.729046 , -0.665203 , 0.161236 } ,    { -0.541786 , -0.453737 , 0.707524 } ,    { 0.207692 , -0.967499 , 0.144258 } ,    { 0.852421 , 0.45609 , 0.255657 } ,    { 0.3252 , 0.323567 , 0.888566 } ,    { 0.0465218 , 0.945181 , 0.323215 } ,    { 0.599306 , -0.673417 , 0.43283 } ,
    { -0.675957 , 0.10323 , 0.729675 } ,    { -0.757789 , 0.315448 , 0.571182 } ,    { 0.328336 , -0.944295 , 0.0224192 } ,    { -0.470258 , -0.747269 , 0.469518 } ,    { 0.358344 , -0.796395 , 0.487181 } ,    { 0.801997 , -0.582347 , 0.132935 } ,    { -0.123399 , -0.521705 , 0.844154 } ,    { 0.734514 , -0.597932 , 0.320884 } ,    { -0.0165508 , 0.294336 , 0.955559 } ,    { 0.595549 , -0.588239 , 0.54708 } ,
    { -0.290221 , -0.920906 , 0.2602 } ,    { -0.732465 , 0.0104548 , 0.680725 } ,    { -0.193855 , -0.876425 , 0.440794 } ,    { -0.715119 , -0.654789 , 0.244656 } ,    { -0.213418 , 0.34224 , 0.915055 } ,    { -0.438943 , 0.897926 , 0.0325235 } ,    { -0.248759 , -0.736321 , 0.629246 } ,    { -0.28148 , 0.806989 , 0.51917 } ,    { -0.0740029 , -0.0116379 , 0.99719 } ,    { 0.031358 , 0.996914 , 0.0719631 } ,
    { 0.583317 , -0.437675 , 0.684239 } ,    { -0.0627384 , 0.701481 , 0.709921 } ,    { -0.970672 , 0.0942335 , 0.22117 } ,    { 0.486683 , 0.536928 , 0.689092 } ,    { -0.774407 , 0.370406 , 0.512925 } ,    { -0.75645 , -0.653815 , 0.0175772 } ,    { 0.33028 , 0.586952 , 0.739191 } ,    { -0.82322 , 0.522376 , 0.222332 } ,    { 0.0663577 , 0.637531 , 0.767562 } ,    { -0.179087 , 0.277134 , 0.943994 } ,
    { -0.986817 , -0.0729325 , 0.144473 } ,    { -0.716036 , 0.616553 , 0.327345 } ,    { 0.721595 , -0.377678 , 0.580223 } ,    { 0.222693 , 0.897548 , 0.380546 } ,    { -0.562701 , -0.820114 , 0.103833 } ,    { -0.102195 , 0.395927 , 0.912578 } ,    { -0.356546 , -0.263619 , 0.896315 } ,    { 0.237185 , 0.386657 , 0.891201 } ,    { 0.24587 , 0.953947 , 0.171851 } ,    { -0.436801 , 0.800929 , 0.409533 } ,
    { -0.230261 , 0.652115 , 0.722306 } ,    { 0.119877 , -0.986199 , 0.114199 } ,    { -0.941419 , -0.332706 , 0.055103 } ,    { -0.577843 , 0.733186 , 0.358518 } ,    { 0.240175 , 0.872807 , 0.42488 } ,    { -0.506784 , 0.614195 , 0.604925 } ,    { -0.53207 , 0.633297 , 0.561993 } ,    { 0.777503 , -0.372499 , 0.506688 } ,    { -0.832392 , 0.348292 , 0.431065 } ,    { -0.105028 , -0.954129 , 0.28037 } ,
    { 0.473252 , 0.32807 , 0.817559 } ,    { -0.185644 , -0.233409 , 0.954493 } ,    { 0.812604 , 0.427985 , 0.395604 } ,    { -0.166509 , 0.773935 , 0.610982 } ,    { -0.729512 , -0.535114 , 0.425988 } ,    { 0.566121 , -0.284641 , 0.773619 } ,    { -0.551042 , -0.202664 , 0.809494 } ,    { -0.659971 , 0.642009 , 0.390209 } ,    { -0.68697 , 0.692484 , 0.220314 } ,    { 0.707914 , -0.530009 , 0.46685 } ,
    { -0.496873 , 0.230152 , 0.836748 } ,    { -0.268104 , 0.814167 , 0.515027 } ,    { 0.811227 , 0.0212555 , 0.584344 } ,    { 0.787385 , 0.411466 , 0.459043 } ,    { -0.321708 , 0.343851 , 0.882196 } ,    { 0.769731 , 0.15849 , 0.618382 } ,    { 0.178024 , -0.314657 , 0.932362 } ,    { 0.391347 , 0.652181 , 0.649236 } ,    { 0.570794 , -0.068929 , 0.818195 } ,    { 0.147905 , 0.419935 , 0.895421 } ,
    { -0.507906 , -0.204427 , 0.836804 } ,    { 0.96623 , -0.0831043 , 0.243913 } ,    { -0.397646 , 0.887203 , 0.233983 } ,    { -0.137656 , -0.952138 , 0.272919 } ,    { 0.757596 , 0.528653 , 0.38285 } ,    { -0.0954204 , 0.65421 , 0.750269 } ,    { -0.243561 , 0.221963 , 0.944145 } ,    { -0.222766 , 0.472634 , 0.852638 } ,    { 0.208103 , -0.599179 , 0.773096 } ,    { 0.285275 , -0.537596 , 0.793479 } ,
    { 0.206763 , 0.727527 , 0.654182 } ,    { 0.445453 , 0.532234 , 0.71993 } ,    { 0.972636 , 0.219638 , 0.0757494 } ,    { -0.751614 , 0.260124 , 0.606145 } ,    { -0.00124297 , 0.25264 , 0.96756 } ,    { 0.782836 , 0.552527 , 0.286151 } ,    { -0.0737421 , 0.778444 , 0.623367 } ,    { 0.500432 , -0.240594 , 0.831674 } ,    { -0.933654 , 0.318329 , 0.164186 } ,    { -0.139899 , 0.939843 , 0.311647 } ,
    { 0.190866 , -0.977542 , 0.0893371 } ,    { 0.378343 , 0.185631 , 0.906862 } ,    { 0.688094 , 0.6482 , 0.326136 } ,    { 0.929623 , 0.299573 , 0.214609 } ,    { -0.13041 , 0.515505 , 0.846905 } ,    { -0.797084 , -0.551723 , 0.245476 } ,    { 0.0108906 , 0.135406 , 0.99073 } ,    { 0.830121 , 0.175938 , 0.529098 } ,    { -0.864605 , -0.213465 , 0.454852 } ,    { -0.0672245 , 0.270309 , 0.960424 } ,
    { -0.58289 , -0.570478 , 0.578614 } ,    { 0.784361 , 0.577365 , 0.226776 } ,    { -0.619356 , 0.115026 , 0.776639 } ,    { 0.33348 , -0.0627198 , 0.940669 } ,    { -0.215802 , -0.502925 , 0.836957 } ,    { -0.849624 , 0.200328 , 0.487861 } ,    { -0.251153 , 0.965581 , 0.0676435 } ,    { -0.255449 , -0.269456 , 0.928514 } ,    { -0.513534 , 0.247834 , 0.821499 } ,    { 0.47132 , -0.806159 , 0.357723 } ,
    { 0.844685 , 0.310858 , 0.435747 } ,    { -0.116386 , -0.49489 , 0.861126 } ,    { -0.458526 , -0.786726 , 0.4133 } ,    { 0.789031 , 0.346897 , 0.507043 } ,    { -0.11773 , -0.798091 , 0.590924 } ,    { 0.704243 , -0.0272486 , 0.709436 } ,    { 0.0388859 , 0.713127 , 0.699955 } ,    { -0.0721327 , -0.979194 , 0.189671 } ,    { -0.642333 , -0.638321 , 0.42421 } ,    { 0.554205 , 0.594521 , 0.582582 } ,
    { -0.884327 , 0.271205 , 0.380019 } ,    { -0.0954127 , 0.575044 , 0.812539 } ,    { 0.600266 , 0.634992 , 0.486279 } ,    { -0.332349 , -0.481767 , 0.81083 } ,    { -0.857238 , -0.501724 , 0.115823 } ,    { 0.161256 , -0.986625 , 0.0238186 } ,    { -0.837109 , 0.469468 , 0.2808 } ,    { 0.190593 , -0.08426 , 0.978046 } ,    { 0.0896565 , 0.981472 , 0.169336 } ,    { -0.243856 , 0.969811 , 0.000651658 } ,
    { 0.608139 , -0.790221 , 0.0756161 } ,    { -0.313878 , 0.762239 , 0.566103 } ,    { -0.706502 , 0.681325 , 0.191445 } ,    { 0.155597 , -0.409229 , 0.899067 } ,    { 0.00562531 , -0.0974633 , 0.995223 } ,    { -0.183663 , 0.444356 , 0.876821 } ,    { -0.800582 , -0.16391 , 0.576369 } ,    { -0.545575 , 0.158672 , 0.822904 } ,    { -0.735663 , 0.0279183 , 0.676772 } ,    { -0.185746 , -0.958181 , 0.217687 } ,
    { 0.810085 , 0.565046 , 0.156479 } ,    { 0.026751 , 0.134 , 0.99062 } ,    { 0.994675 , -0.0982306 , 0.0311762 } ,    { -0.580838 , -0.423434 , 0.69522 } ,    { 0.478114 , 0.676341 , 0.56033 } ,    { -0.259766 , -0.570787 , 0.778925 } ,    { 0.0749413 , 0.141569 , 0.987088 } ,    { -0.121672 , -0.0909701 , 0.988393 } ,    { -0.420426 , -0.12118 , 0.899198 } ,    { 0.541151 , 0.186377 , 0.820012 } ,
    { -0.533231 , 0.749499 , 0.392322 } ,    { 0.9583 , 0.0945623 , 0.269663 } ,    { -0.621383 , 0.185976 , 0.761115 } ,    { -0.963431 , -0.261429 , 0.058782 } ,    { -0.873138 , -0.476109 , 0.104641 } ,    { 0.840816 , 0.138154 , 0.523394 } ,    { -0.0335506 , 0.761559 , 0.647226 } ,    { 0.306516 , 0.803148 , 0.510883 } ,    { -0.698534 , 0.52827 , 0.482681 } ,    { 0.787397 , -0.195984 , 0.584462 } ,
    { 0.179678 , 0.392628 , 0.901975 } ,    { 0.900507 , 0.327201 , 0.286404 } ,    { 0.621691 , 0.726965 , 0.291585 } ,    { -0.78358 , 0.535344 , 0.315294 } ,    { -0.848468 , -0.384079 , 0.364123 } ,    { -0.992456 , 0.088155 , 0.0852048 } ,    { -0.434063 , 0.885106 , 0.167861 } ,    { -0.288791 , 0.957387 , 0.0031085 } ,    { -0.880672 , 0.155623 , 0.447436 } ,    { 0.154178 , 0.933962 , 0.322403 } ,
    { -0.357179 , -0.261208 , 0.896768 } ,    { 0.119334 , 0.857903 , 0.499761 } ,    { 0.698693 , -0.0244223 , 0.715005 } ,    { -0.441325 , -0.315764 , 0.839956 } ,    { 0.229606 , 0.948733 , 0.217225 } ,    { -0.923969 , 0.363142 , 0.120036 } ,    { -0.283117 , -0.935317 , 0.212195 } ,    { 0.0118727 , 0.999895 , 0.00826287 } ,    { 0.41711 , 0.601612 , 0.681236 } ,    { 0.71214 , 0.102171 , 0.694563 } ,
    { -0.690616 , -0.572178 , 0.442337 } ,    { 0.650604 , 0.759223 , 0.0171586 } ,    { -0.988887 , -0.0630486 , 0.134636 } ,    { 0.252747 , 0.958448 , 0.132271 } ,    { 0.037429 , -0.261071 , 0.964594 } ,    { -0.96855 , -0.20956 , 0.134148 } ,    { 0.272732 , 0.607148 , 0.746317 } ,    { 0.106588 , 0.87287 , 0.476169 } ,    { -0.316947 , -0.694883 , 0.645509 } ,    { 0.854004 , 0.39294 , 0.340993 } ,
    { 0.473003 , -0.393703 , 0.788204 } ,    { 0.0447569 , -0.183854 , 0.981934 } ,    { 0.579864 , 0.0178638 , 0.814517 } ,    { -0.340918 , 0.15172 , 0.927769 } ,    { 0.355611 , 0.879293 , 0.316834 } ,    { 0.724368 , -0.683784 , 0.0879228 } ,    { 0.781844 , -0.176735 , 0.5979 } ,    { 0.115086 , 0.992786 , 0.0336468 } ,    { 0.298818 , -0.0956656 , 0.949503 } ,    { 0.455644 , -0.126041 , 0.881193 } ,
    { -0.626736 , 0.638481 , 0.446702 } ,    { -0.155539 , -0.107875 , 0.981922 } ,    { -0.0179569 , 0.993472 , 0.112658 } ,    { 0.0966711 , 0.933367 , 0.345659 } ,    { 0.548622 , 0.825829 , 0.130461 } ,    { 0.436741 , -0.807942 , 0.395585 } ,    { -0.373755 , 0.922915 , 0.0923917 } ,    { -0.624754 , -0.745011 , 0.233754 } ,    { -0.443516 , -0.635225 , 0.632284 } ,    { -0.976876 , 0.157497 , 0.144593 } ,
    { 0.718273 , 0.129246 , 0.683652 } ,    { -0.447313 , -0.546111 , 0.70829 } ,    { -0.115265 , 0.121258 , 0.985906 } ,    { 0.653578 , -0.134474 , 0.744817 } ,    { -0.360251 , 0.861971 , 0.356687 } ,    { 0.506625 , 0.147214 , 0.849505 } ,    { -0.672345 , 0.393565 , 0.626944 } ,    { -0.0430316 , -0.958144 , 0.283035 } ,    { -0.734334 , 0.146366 , 0.66282 } ,    { 0.795545 , 0.604059 , 0.0471372 } ,
    { 0.173257 , -0.952428 , 0.250725 } ,    { 0.237852 , 0.442866 , 0.864463 } ,    { 0.545003 , 0.173713 , 0.820241 } ,    { 0.651095 , -0.436402 , 0.620991 } ,    { 0.595012 , -0.539429 , 0.595799 } ,    { -0.934308 , -0.264621 , 0.238839 } ,    { -0.0943004 , -0.979548 , 0.177746 } ,    { -0.765547 , 0.526761 , 0.369406 } ,    { -0.915146 , -0.343254 , 0.211387 } ,    { -0.867598 , 0.426047 , 0.256432 } ,
    { 0.278356 , -0.924683 , 0.259767 } ,    { -0.307344 , -0.114252 , 0.944715 } ,    { 0.617251 , 0.536472 , 0.575499 } ,    { 0.671095 , -0.623564 , 0.400997 } ,    { 0.159994 , -0.973209 , 0.165125 } ,    { 0.0651679 , 0.240737 , 0.9684 } ,    { 0.860117 , -0.498284 , 0.109144 } ,    { 0.597477 , 0.764803 , 0.241034 } ,    { -0.367376 , -0.927516 , 0.0689201 } ,    { -0.492165 , -0.864629 , 0.100945 } ,
    { 0.897961 , -0.415313 , 0.14554 } ,    { 0.901433 , -0.0915184 , 0.423134 } ,    { 0.591306 , -0.451155 , 0.668443 } ,    { -0.131085 , 0.965722 , 0.224047 } ,    { 0.025843 , -0.42085 , 0.906762 } ,    { -0.408819 , 0.821429 , 0.397644 } ,    { 0.219085 , 0.405605 , 0.887404 } ,    { -0.0755332 , 0.645184 , 0.760285 } ,    { -0.386255 , -0.816088 , 0.429892 } ,    { 0.642788 , -0.705376 , 0.298777 } ,
    { -0.275235 , -0.306668 , 0.911153 } ,    { 0.527452 , 0.0336785 , 0.848917 } ,    { -0.955519 , 0.277444 , 0.100041 } ,    { -0.719592 , -0.0705782 , 0.690801 } ,    { -0.266584 , -0.919146 , 0.290006 } ,    { 0.187122 , 0.911447 , 0.366401 } ,    { -0.759446 , 0.590865 , 0.272251 } ,    { -0.257097 , 0.760196 , 0.59666 } ,    { -0.687519 , -0.434174 , 0.582074 } ,    { -0.0346846 , -0.988565 , 0.146752 } ,
    { 0.132568 , -0.944306 , 0.301185 } ,    { 0.417439 , -0.280995 , 0.864168 } ,    { 0.437841 , -0.148193 , 0.886755 } ,    { 0.126634 , 0.928712 , 0.348507 } ,    { 0.29796 , -0.597324 , 0.744596 } ,    { -0.510463 , -0.294482 , 0.807904 } ,    { 0.191401 , 0.356546 , 0.914462 } ,    { -0.981368 , -0.0447431 , 0.186854 } ,    { -0.0119937 , -0.967332 , 0.253229 } ,    { -0.135266 , 0.989758 , 0.0456232 } ,
    { -0.271675 , -0.957807 , 0.0938017 } ,    { -0.846737 , -0.531588 , 0.0212198 } ,    { -0.354496 , -0.913075 , 0.20156 } ,    { -0.484497 , 0.391581 , 0.782258 } ,    { 0.876431 , -0.19877 , 0.438587 } ,    { 0.469293 , 0.500465 , 0.72753 } ,    { 0.250256 , 0.844546 , 0.473406 } ,    { 0.158083 , 0.336385 , 0.928361 } ,    { 0.178352 , 0.695957 , 0.695582 } ,    { -0.107728 , 0.566451 , 0.817024 } ,
    { -0.360842 , -0.0103419 , 0.93257 } ,    { -0.960282 , 0.0546871 , 0.273621 } ,    { -0.733765 , 0.205119 , 0.6477 } ,    { -0.325486 , 0.94554 , 0.00360537 } ,    { 0.904468 , 0.120091 , 0.409287 } ,    { -0.287448 , -0.439055 , 0.851237 } ,    { 0.771452 , 0.326791 , 0.545958 } ,    { -0.405028 , 0.761479 , 0.506065 } ,    { -0.563529 , -0.664834 , 0.490337 } ,    { 0.80742 , 0.183347 , 0.560764 } ,
    { -0.604001 , 0.770114 , 0.205202 } ,    { 0.395659 , -0.629524 , 0.668696 } ,    { 0.298042 , 0.946979 , 0.120008 } ,    { 0.0648546 , 0.268012 , 0.96123 } ,    { 0.510623 , -0.248574 , 0.823089 } ,    { 0.166434 , -0.0596135 , 0.984249 } ,    { -0.308412 , 0.395986 , 0.864914 } ,    { 0.379318 , 0.308248 , 0.872411 } ,    { 0.848971 , -0.371171 , 0.376138 } ,    { 0.565334 , 0.0590879 , 0.822743 } ,
    { -0.992028 , 0.0890424 , 0.0891767 } ,    { 0.312534 , 0.691408 , 0.651366 } ,    { -0.875838 , 0.472331 , 0.0990485 } ,    { 0.334856 , -0.942047 , 0.0204675 } ,    { -0.125364 , -0.984977 , 0.118761 } ,    { -0.497613 , -0.806129 , 0.320213 } ,    { 0.559516 , 0.0195039 , 0.82859 } ,    { -0.609379 , -0.792875 , 0.00257254 } ,    { -0.902595 , -0.117893 , 0.414034 } ,    { 0.704823 , 0.649985 , 0.284155 } ,
    { 0.584904 , -0.804553 , 0.102864 } ,    { -0.727364 , 0.674276 , 0.127642 } ,    { -0.911761 , -0.000150243 , 0.410722 } ,    { -0.99389 , -0.108412 , 0.0207353 } ,    { -0.40234 , 0.288458 , 0.868858 } ,    { 0.278518 , -0.23088 , 0.932267 } ,    { -0.252979 , -0.940588 , 0.226487 } ,    { -0.476927 , 0.201844 , 0.855453 } ,    { -0.838985 , -0.478599 , 0.258936 } ,    { 0.328574 , 0.81266 , 0.481273 } ,
    { -0.810767 , -0.449245 , 0.375282 } ,    { 0.765292 , -0.57037 , 0.298339 } ,    { 0.589559 , -0.789167 , 0.172151 } ,    { 0.10944 , -0.394271 , 0.912454 } ,    { 0.788405 , -0.560077 , 0.254424 } ,    { 0.246038 , -0.511497 , 0.823308 } ,    { -0.853767 , 0.132614 , 0.503484 } ,    { 0.774539 , -0.213967 , 0.595237 } ,    { -0.110172 , -0.28889 , 0.951002 } ,    { -0.842985 , 0.535495 , 0.0512097 } ,
    { 0.580131 , 0.0301411 , 0.813965 } ,    { 0.908925 , -0.116136 , 0.400459 } ,    { -0.625472 , 0.649147 , 0.43289 } ,    { 0.558774 , -0.812148 , 0.167891 } ,    { 0.230474 , 0.347007 , 0.909103 } ,    { -0.105795 , 0.991955 , 0.0695239 } ,    { -0.640253 , 0.560236 , 0.525558 } ,    { 0.419539 , -0.845648 , 0.329948 } ,    { -0.225489 , -0.850371 , 0.475419 } ,    { -0.492912 , -0.410376 , 0.767222 } ,
    { -0.617174 , -0.109886 , 0.779116 } ,    { 0.326556 , -0.383888 , 0.863708 } ,    { 0.664892 , 0.746907 , 0.00703597 } ,    { 0.924311 , -0.12256 , 0.361425 } ,    { 0.205385 , -0.729426 , 0.652498 } ,    { -0.852246 , 0.473653 , 0.222102 } ,    { 0.344869 , 0.850976 , 0.396112 } ,    { -0.972872 , -0.112911 , 0.201919 } ,    { -0.190017 , 0.438384 , 0.878472 } ,    { -0.958015 , -0.0924744 , 0.271396 } ,
    { 0.266771 , -0.196227 , 0.943572 } ,    { -0.229298 , -0.870471 , 0.435549 } ,    { 0.777292 , -0.267766 , 0.569314 } ,    { 0.350124 , 0.0495305 , 0.935393 } ,    { 0.56476 , 0.764048 , 0.311893 } ,    { 0.0990969 , -0.958941 , 0.265729 } ,    { 0.700681 , 0.301741 , 0.646528 } ,    { -0.410066 , -0.875055 , 0.257146 } ,    { 0.868634 , -0.295203 , 0.397907 } ,    { 0.722704 , 0.115409 , 0.681454 } ,
    { -0.83569 , -0.261247 , 0.483086 } ,    { -0.956946 , -0.26818 , 0.111061 } ,    { -0.471397 , 0.707804 , 0.526117 } ,    { 0.142281 , -0.460376 , 0.876248 } ,    { -0.848155 , 0.424277 , 0.31721 } ,    { 0.633217 , 0.677636 , 0.373958 } ,    { 0.774101 , 0.527833 , 0.349515 } ,    { 0.566104 , 0.46772 , 0.678796 } ,    { 0.689802 , -0.719004 , 0.0848926 } ,    { 0.307254 , 0.914121 , 0.264532 } ,
    { 0.0268339 , -0.281412 , 0.959212 } ,    { 0.120226 , 0.348506 , 0.929564 } ,    { -0.62591 , -0.415976 , 0.659698 } ,    { -0.64528 , -0.118069 , 0.754768 } ,    { 0.97028 , 0.227512 , 0.082431 } ,    { 0.0923899 , -0.442515 , 0.891989 } ,    { -0.985441 , 0.00944439 , 0.169757 } ,    { -0.40892 , 0.843814 , 0.347509 } ,    { 0.723835 , -0.613341 , 0.316031 } ,    { -0.648807 , -0.00240352 , 0.760949 } ,
    { -0.708918 , 0.31984 , 0.6286 } ,    { 0.6173 , 0.741834 , 0.261961 } ,    { 0.32308 , -0.0608347 , 0.944414 } ,    { 0.782464 , 0.369637 , 0.501117 } ,    { -0.698584 , 0.642048 , 0.31584 } ,    { -0.547649 , 0.641426 , 0.537265 } ,    { 0.0736367 , 0.704049 , 0.706324 } ,    { 0.982237 , -0.144916 , 0.119208 } ,    { 0.865498 , -0.361769 , 0.346462 } ,    { 0.675221 , -0.737534 , 0.0109788 } ,
    { 0.929646 , 0.364663 , 0.0527114 } ,    { -0.667761 , -0.257242 , 0.698514 } ,    { 0.462495 , -0.0673398 , 0.884061 } ,    { -0.525039 , 0.381695 , 0.760686 } ,    { 0.683212 , -0.000564444 , 0.73022 } ,    { 0.420557 , 0.885192 , 0.198913 } ,    { -0.971449 , -0.194974 , 0.13517 } ,    { -0.746171 , 0.190546 , 0.637904 } ,    { 0.909071 , 0.416623 , 0.00380576 } ,    { -0.191327 , 0.285436 , 0.939106 } ,
    { 0.132169 , -0.414928 , 0.900203 } ,    { -0.663947 , -0.463146 , 0.587086 } ,    { 0.100529 , -0.992809 , 0.0649869 } ,    { -0.331074 , 0.403996 , 0.852747 } ,    { 0.707163 , 0.383667 , 0.593903 } ,    { -0.395927 , -0.79792 , 0.454495 } ,    { -0.497763 , 0.479399 , 0.722778 } ,    { 0.290656 , 0.833195 , 0.470431 } ,    { 0.715641 , 0.635401 , 0.290042 } ,    { 0.183316 , 0.963909 , 0.193069 } ,
    { 0.972824 , -0.0178622 , 0.230854 } ,    { 0.574369 , 0.178051 , 0.798998 } ,    { 0.0656519 , 0.326844 , 0.942795 } ,    { -0.98156 , -0.190474 , 0.0160997 } ,    { -0.795229 , -0.196193 , 0.57369 } ,    { 0.0793034 , 0.964727 , 0.251024 } ,    { 0.826061 , 0.460539 , 0.324848 } ,    { 0.50979 , -0.542397 , 0.667772 } ,    { -0.79576 , 0.522625 , 0.305988 } ,    { -0.845024 , -0.274884 , 0.458664 } ,
    { 0.962671 , -0.26935 , 0.0267422 } ,    { 0.591278 , 0.593062 , 0.546505 } ,    { -0.916858 , 0.223392 , 0.33086 } ,    { -0.28375 , -0.710783 , 0.64364 } ,    { -0.860743 , 0.484853 , 0.155043 } ,    { 0.201168 , 0.536951 , 0.819277 } ,    { -0.357849 , 0.918334 , 0.169135 } ,    { 0.802802 , -0.294537 , 0.518418 } ,    { -0.00727225 , -0.99845 , 0.0551767 } ,    { -0.124085 , 0.289568 , 0.94908 } ,
    { 0.527489 , -0.735428 , 0.425325 } ,    { 0.312386 , 0.312047 , 0.897241 } ,    { 0.383408 , -0.336884 , 0.859946 } ,    { 0.168695 , -0.985617 , 0.0100337 } ,    { 0.130254 , 0.800098 , 0.585557 } ,    { -0.138974 , 0.743561 , 0.654067 } ,    { 0.879539 , 0.309063 , 0.36179 } ,    { 0.584633 , 0.0569884 , 0.809294 } ,    { 0.0366785 , 0.246249 , 0.968512 } ,    { -0.759899 , -0.50441 , 0.410029 }
};

// just define how many of them you want to keep:
static unsigned int nDirs = 33;

class NDirectionalBS{
    unsigned int ndirs;
    std::vector< std::pair< double , double > > bounds;

    double minInterval , maxInterval;
    bool intervalsUpToDate;

    void updateIntervals()
    {
        minInterval = FLT_MAX;
        maxInterval = 0.0;
        for( unsigned int i = 0 ; i < ndirs ; ++i )
        {
            double interval = maxValue(i) - minValue(i);
            minInterval = std::min( minInterval , interval );
            maxInterval = std::max( maxInterval , interval );
        }
        intervalsUpToDate = true;
    }

public:
    NDirectionalBS()
    {
        ndirs = nDirs;
        bounds.resize(ndirs);
        for( unsigned int i = 0 ; i < ndirs ; ++i )
            bounds[i] = std::pair< double , double >( FLT_MAX , -FLT_MAX );

        intervalsUpToDate = true;
        minInterval = 0.0;
        maxInterval = 0.0;
    }
    NDirectionalBS( unsigned int n )
    {
        assert( n < nDirs );
        ndirs = n;
        bounds.resize(ndirs);
        for( unsigned int i = 0 ; i < ndirs ; ++i )
            bounds[i] = std::pair< double , double >( FLT_MAX , -FLT_MAX );

        intervalsUpToDate = true;
        minInterval = 0.0;
        maxInterval = 0.0;
    }

    void operator = ( const NDirectionalBS & rightSide )
    {
        ndirs = rightSide.ndirs;
        bounds = rightSide.bounds;
        minInterval = rightSide.minInterval;
        maxInterval = rightSide.maxInterval;
        intervalsUpToDate = rightSide.intervalsUpToDate;
    }

    void set( const point3d & p )
    {
        for( unsigned int i = 0 ; i < ndirs ; ++i )
        {
            double dirPos = dirs[i][0]*p[0]  +  dirs[i][1]*p[1]  +  dirs[i][2]*p[2];
            bounds[i].first = dirPos;
            bounds[i].second = dirPos;
        }
        intervalsUpToDate = true;
        minInterval = 0.0;
        maxInterval = 0.0;
    }

    void add( const point3d & p )
    {
        for( unsigned int i = 0 ; i < ndirs ; ++i )
        {
            double dirPos = dirs[i][0]*p[0]  +  dirs[i][1]*p[1]  +  dirs[i][2]*p[2];
            bounds[i].first = std::min< double >( dirPos , bounds[i].first );
            bounds[i].second = std::max< double >( dirPos , bounds[i].second );
        }
        intervalsUpToDate = false;
    }

    void add( const NDirectionalBS & bs )
    {
        for( unsigned int i = 0 ; i < ndirs ; ++i )
        {
            bounds[i].first = std::min< double >( bounds[i].first , bs.minValue(i) );
            bounds[i].second = std::max< double >( bounds[i].second , bs.maxValue(i) );
        }
        intervalsUpToDate = false;
    }

    double minValue( unsigned int i ) const {
        return bounds[i].first;
    }
    double maxValue( unsigned int i ) const {
        return bounds[i].second;
    }

    double getMinInterval()
    {
        if( !intervalsUpToDate )
            updateIntervals();

        return minInterval;
    }
    double getMaxInterval()
    {
        if( !intervalsUpToDate )
            updateIntervals();

        return maxInterval;
    }

    inline
    double radius()
    {
        return getMinInterval() * 0.75;
        //        return getMinInterval() * 0.55;
        //        return getMinInterval() * 0.66;
        //        return getMinInterval() * 0.55;
        //        return getMinInterval() * 1.0;
    }
};
}

template< typename T >
class BBOX
{
public:
    point3<T> bb,BB;

    BBOX() { clear(); }

    void clear()
    {
        bb[0] = FLT_MAX;
        BB[0] = -FLT_MAX;
    }
    bool isCleared() const { return bb[0] <= BB[0]; }

    template< class point_t >
    void set( const point_t & p )
    {
        bb = point3<T>(p[0],p[1],p[2]);
        BB = point3<T>(p[0],p[1],p[2]);
    }

    template< class point_t >
    void set( const point_t & pbb, const point_t & pBB )
    {
        bb = point3<T>(pbb[0],pbb[1],pbb[2]);
        BB = point3<T>(pBB[0],pBB[1],pBB[2]);
    }

    template< class point_t >
    void add( const point_t & p )
    {
        bb = point3<T>::min( bb,p );
        BB = point3<T>::max( BB,p );
    }

    void add( const BBOX<T> & b )
    {
        bb = point3<T>::min( bb,b.bb );
        BB = point3<T>::max( BB,b.BB );
    }

    T squareDiagonal() const
    {
        return (BB - bb).sqrnorm();
    }
    inline
    T diagonal() const
    {
        return sqrt( (BB - bb).sqrnorm() );
    }
    inline
    T radius() const
    {
        return diagonal() / 2.0;
    }
    inline
    T squareRadius() const
    {
        return squareDiagonal() / 4.0;
    }

    inline
    char getLargestExtent() const
    {
        if(  BB[0] - bb[0]  >  BB[1] - bb[1]  )
        {
            if( BB[0] - bb[0] > BB[2] - bb[2] )
                return 0;
            return 2;
        }
        else
        {
            if( BB[1] - bb[1] > BB[2] - bb[2] )
                return 1;
            return 2;
        }
    }
    inline
    T getExtentValue(char i) const
    {
        return BB[i] - bb[i];
    }
    inline
    T getLargestExtentValue() const
    {
        return getExtentValue( getLargestExtent() );
    }

    template< class point_t >
    inline
    T getPseudoExtentInDirection( point_t const & dir ) const {
        return getExtentValue(0) * fabs(dir[0])
                +getExtentValue(1) * fabs(dir[1])
                +getExtentValue(2) * fabs(dir[2]);
    }

    inline
    void splitAlongAxis( char axis , T value , BBOX<T> & bbox1 , BBOX<T> & bbox2 )
    {
        // for safety:
        value = std::max<T>( std::min<T>( value , BB[axis] ) , bb[axis] );
        point3<T> BB1 = BB;
        BB1[axis] = value;
        point3<T> bb2 = bb;
        bb2[axis] = value;
        bbox1.set( bb , BB1 );
        bbox2.set( bb2 , BB );
    }
};

typedef BBOX< float >    BBOXf;
typedef BBOX< double >   BBOXd;

template< typename T >
class mat33
{
public:
    typedef T                       type_t;

    ////////////         CONSTRUCTORS          //////////////
    mat33<T>()
    {
        vals[0] = 0;
        vals[1] = 0;
        vals[2] = 0;
        vals[3] = 0;
        vals[4] = 0;
        vals[5] = 0;
        vals[6] = 0;
        vals[7] = 0;
        vals[8] = 0;
    }
    mat33<T>( T v1 , T v2 , T v3 , T v4 , T v5 , T v6 , T v7 , T v8 , T v9)
    {
        vals[0] = v1;
        vals[1] = v2;
        vals[2] = v3;
        vals[3] = v4;
        vals[4] = v5;
        vals[5] = v6;
        vals[6] = v7;
        vals[7] = v8;
        vals[8] = v9;
    }
    template< typename T2 > mat33<T>( const std::vector< T2 > & cc )
    {
        for(int i = 0 ; i < 9 ; ++i )
            vals[i]=cc[i];
    }
    template< typename T2 > mat33<T>( const mat33< T2 > & m )
    {
        for(int i = 0 ; i < 9 ; ++i )
            vals[i] = (T)(m(i));
    }

    bool isnan() const {
        return std::isnan(vals[0]) || std::isnan(vals[1]) || std::isnan(vals[2])
                 || std::isnan(vals[3]) || std::isnan(vals[4]) || std::isnan(vals[5])
                 || std::isnan(vals[6]) || std::isnan(vals[7]) || std::isnan(vals[8]);
    }

    /////////////         SET         ///////////////
    inline
    void setIdentity()
    {
        vals[0] = 1;
        vals[1] = 0;
        vals[2] = 0;
        vals[3] = 0;
        vals[4] = 1;
        vals[5] = 0;
        vals[6] = 0;
        vals[7] = 0;
        vals[8] = 1;
    }
    inline
    void setZero()
    {
        vals[0] = 0;
        vals[1] = 0;
        vals[2] = 0;
        vals[3] = 0;
        vals[4] = 0;
        vals[5] = 0;
        vals[6] = 0;
        vals[7] = 0;
        vals[8] = 0;
    }

    template< typename T2 >
    void operator = (const mat33<T2> & m)
    {
        for( unsigned int c = 0 ; c < 9 ; ++c )
            vals[c] = (T)(m(c));
    }

    template< typename T2 >
    inline void set( const mat33<T2> & other )
    {
        for(unsigned int i = 0 ; i < 9; ++i)
            vals[ i ] = (T)(other(i));
    }

    void operator += (const mat33<T> & m)
    {
        for( unsigned int c = 0 ; c < 9 ; ++c )
            vals[c] += m(c);
    }
    void operator -= (const mat33<T> & m)
    {
        for( unsigned int c = 0 ; c < 9 ; ++c )
            vals[c] -= m(c);
    }
    void operator /= (double s)
    {
        for( unsigned int c = 0 ; c < 9 ; ++c )
            vals[c] /= s;
    }

    ////////        ACCESS TO COORDINATES      /////////
    T operator () (unsigned int i , unsigned int j) const
    { return vals[3*i + j]; }
    T & operator () (unsigned int i , unsigned int j)
    { return vals[3*i + j]; }
    T operator () (unsigned int v) const
    { return vals[v]; }
    T & operator () (unsigned int v)
    { return vals[v]; }

    T & getCoord(unsigned int i , unsigned int j)
    { return vals[3*i+j]; }
    T getCoord(unsigned int i , unsigned int j) const
    { return vals[3*i+j]; }
    T & getCoord(unsigned int i)
    { return vals[i]; }
    T getCoord(unsigned int i) const
    { return vals[i]; }

    ////////        ACCESS TO ROWS / COLUMNS      /////////
    point3<T> getRow( unsigned int i ) const
    {
        return point3<T>( vals[3*i] , vals[3*i+1] , vals[3*i+2] );
    }
    void setRow( unsigned int i , const point3<T> & p)
    {
        vals[3*i]   = p[0];
        vals[3*i+1] = p[1];
        vals[3*i+2] = p[2];
    }
    void setRows( const point3<T> & r1 , const point3<T> & r2 , const point3<T> & r3 )
    {
        vals[3*0]   = r1[0];
        vals[3*0+1] = r1[1];
        vals[3*0+2] = r1[2];
        vals[3*1]   = r2[0];
        vals[3*1+1] = r2[1];
        vals[3*1+2] = r2[2];
        vals[3*2]   = r3[0];
        vals[3*2+1] = r3[1];
        vals[3*2+2] = r3[2];
    }
    point3<T> getCol(unsigned int j) const
    {
        return point3<T>( vals[j] , vals[3+j] , vals[6+j] );
    }
    void setCol(unsigned int j , const point3<T> & p)
    {
        vals[j]   = p[0];
        vals[3+j] = p[1];
        vals[6+j] = p[2];
    }
    void setCols(const point3<T> & c1 , const point3<T> & c2 , const point3<T> & c3)
    {
        vals[0]   = c1[0];
        vals[3+0] = c1[1];
        vals[6+0] = c1[2];
        vals[1]   = c2[0];
        vals[3+1] = c2[1];
        vals[6+1] = c2[2];
        vals[2]   = c3[0];
        vals[3+2] = c3[1];
        vals[6+2] = c3[2];
    }

    ////////        BASICS       /////////
    inline T sqrnorm()
    {
        return vals[0]*vals[0] + vals[1]*vals[1] + vals[2]*vals[2]
                + vals[3]*vals[3] + vals[4]*vals[4] + vals[5]*vals[5]
                + vals[6]*vals[6] +  vals[7]*vals[7] + vals[8]*vals[8];
    }

    inline T norm()
    { return sqrt( sqrnorm() ); }

    inline T determinant() const
    {
        return vals[0] * ( vals[4] * vals[8] - vals[7] * vals[5] )
                - vals[1] * ( vals[3] * vals[8] - vals[6] * vals[5] )
                + vals[2] * ( vals[3] * vals[7] - vals[6] * vals[4] );
    }
    template< class point_t >
    inline T determinant_with_col0( point_t const & c ) const
    {
        return c[0] * ( vals[4] * vals[8] - vals[7] * vals[5] )
                - vals[1] * ( c[1] * vals[8] - c[2] * vals[5] )
                + vals[2] * ( c[1] * vals[7] - c[2] * vals[4] );
    }
    template< class point_t >
    inline T determinant_with_col1( point_t const & c ) const
    {
        return vals[0] * ( c[1] * vals[8] - c[2] * vals[5] )
                - c[0] * ( vals[3] * vals[8] - vals[6] * vals[5] )
                + vals[2] * ( vals[3] * c[2] - vals[6] * c[1] );
    }
    template< class point_t >
    inline T determinant_with_col2( point_t const & c ) const
    {
        return vals[0] * ( vals[4] * c[2] - vals[7] * c[1] )
                - vals[1] * ( vals[3] * c[2] - vals[6] * c[1] )
                + c[0] * ( vals[3] * vals[7] - vals[6] * vals[4] );
    }

    void RSD( mat33<T> & R , mat33<T> & S ) const {
        mat33<T> U , Vt; T x,y,z;
        SVD(U,x,y,z,Vt);
        R = U * Vt;
        S = Vt.getTranspose() * mat33<T>::Diag(x,y,z)*Vt;
    }

    static
    mat33<T> pseudoInverse( mat33<T> const & m , bool & isRealInverse , double defaultValueForInverseSingularValue = 0.0 )
    {
        T det = m.determinant();
        if( fabs(det) != 0.0 )
        {
            isRealInverse = true;
            return mat33<T>( m(1,1)*m(2,2) - m(2,1)*m(1,2) , m(0,2)*m(2,1) - m(0,1)*m(2,2) , m(0,1)*m(1,2) - m(0,2)*m(1,1) ,
                             m(1,2)*m(2,0) - m(1,0)*m(2,2) , m(0,0)*m(2,2) - m(0,2)*m(2,0) , m(0,2)*m(1,0) - m(0,0)*m(1,2) ,
                             m(1,0)*m(2,1) - m(1,1)*m(2,0) , m(0,1)*m(2,0) - m(0,0)*m(2,1) , m(0,0)*m(1,1) - m(0,1)*m(1,0) ) / det ;
        }

        // otherwise:
        isRealInverse = false;
        mat33<T> U ; T sx ; T sy ; T sz ; mat33<T> Vt;
        m.SVD(U,sx,sy,sz,Vt);
        T sxInv = sx == 0.0 ? 1.0 / sx : defaultValueForInverseSingularValue;
        T syInv = sy == 0.0 ? 1.0 / sy : defaultValueForInverseSingularValue;
        T szInv = sz == 0.0 ? 1.0 / sz : defaultValueForInverseSingularValue;
        return Vt.getTranspose() * mat33<T>::diag(sxInv , syInv , szInv) * U.getTranspose();
    }

//    template< class point_t >
//    point_t solveLinearSystem(point_t const & rhs , bool & isPseudoInverse) const {
//        double det = determinant();
//        double epsilonPrecision = 0.000001;
//        if(  fabs(det) < epsilonPrecision  ) {
//            isPseudoInverse = true;
//            mat33<T> U , Vt; double x,y,z;
//            SVD(U,x,y,z,Vt);
//            double xInv = fabs(x) < epsilonPrecision ? 0.0 : 1.0/x;
//            double yInv = fabs(y) < epsilonPrecision ? 0.0 : 1.0/y;
//            double zInv = fabs(z) < epsilonPrecision ? 0.0 : 1.0/z;
//            return Vt.getTranspose() * mat33<T>::diag(xInv,yInv,zInv) * U.getTranspose() * rhs;
//        }
//        isPseudoInverse = false;
//        return point_t(
//                    determinant_with_col0(rhs) / det,
//                    determinant_with_col1(rhs) / det,
//                    determinant_with_col2(rhs) / det
//                    );
//    }

    inline T trace() const
    { return vals[0] + vals[4] + vals[8]; }

    ////////        TRANSPOSE       /////////
    inline
    void transpose()
    {
        T xy = vals[1] , xz = vals[2] , yz = vals[5];
        vals[1] = vals[3];
        vals[3] = xy;
        vals[2] = vals[6];
        vals[6] = xz;
        vals[5] = vals[7];
        vals[7] = yz;
    }
    mat33<T> getTranspose() const
    {
        return mat33<T>(vals[0],vals[3],vals[6],vals[1],vals[4],vals[7],vals[2],vals[5],vals[8]);
    }

    ////////        HARMONICITY (not needed usually)       /////////
    void coutHessianHarmonicity()
    {
        std::cout << "xx + yy + zz = " << (getCoord(0,0) + getCoord(1,1) + getCoord(2,2)) << std::endl <<
                     "xy - yx : " << getCoord(0,1) - getCoord(1,0) << std::endl <<
                     "yz - zy : " << getCoord(1,2) - getCoord(2,1) << std::endl <<
                     "xz - zx : " << getCoord(0,2) - getCoord(2,0) << std::endl;
    }
    void enforceHessianHarmonicity()
    {
        vals[8] = -vals[0] - vals[4];
        vals[3] = vals[1];
        vals[5] = vals[7];
        vals[2] = vals[6];
    }
    inline
    T harmonicityError()
    {
        return std::abs( vals[8] + vals[0] + vals[4] ) + std::abs( vals[3] - vals[1] ) + std::abs( vals[5] - vals[7] ) + std::abs( vals[2] - vals[6] );
    }

    ////////        VECTOR PRODUCTS       /////////
    void setVectorProduct( const point3<T> & v1 , const point3<T> & v2 )
    {
        for( int i = 0 ; i < 3 ; ++i )
            for( int j = 0 ; j < 3 ; ++j )
                vals[ 3*i+j ] = v1[i]*v2[j];
    }

    void addVectorProduct( const point3<T> & v1 , const point3<T> & v2 )
    {
        for( int i = 0 ; i < 3 ; ++i )
            for( int j = 0 ; j < 3 ; ++j )
                vals[ 3*i+j ] += v1[i]*v2[j];
    }

    ////////////         ROTATION <-> AXIS/ANGLE         /////////////
    void getAxisAndAngleFromRotationMatrix( point3<T> & axis , T & angle ) const
    {
        angle = acos( (trace() - 1) / 2 );
        axis[0] = vals[7] - vals[5];
        axis[1] = vals[2] - vals[6];
        axis[2] = vals[3] - vals[1];
        axis.normalize();
    }

    inline static
    mat33<T> getRotationMatrixFromAxisAndAngle( const point3<T> & axis , T angle )
    {
        mat33<T> w = vectorial(axis);
        return Identity() + std::sin(angle) * w + ((T)(1.0) - std::cos(angle)) * w * w;
    }

    inline static
    mat33<T> getRotationMatrixMappingUnitsVec1ToVec2( const point3<T> & vec1 , const point3<T> & vec2 )
    {
        point3<T> axis = point3<T>::cross( vec1,vec2 );
        T nn = axis.norm();
        if( nn <= 0.0000001 )
            return mat33<T>::Identity();
        T angle = std::asin( nn );
        axis /= nn;
        return getRotationMatrixFromAxisAndAngle(axis,angle);
    }

    ////////////////////            STATIC STANDARD MATRICES          ////////////////////////////
    inline static mat33<T> Identity()
    {  return mat33<T>(1,0,0  ,  0,1,0  ,  0,0,1);  }

    inline static mat33<T> Zero()
    {  return mat33<T>(0,0,0  ,  0,0,0  ,  0,0,0);  }

    template< typename T2 >
    inline static mat33<T> diag( T2 x , T2 y ,T2 z )
    {  return mat33<T>(x,0,0  ,  0,y,0  ,  0,0,z);  }

    inline static mat33<T> Rand()
    {
        return mat33<T>( -1.0 + 2.0* (float)(rand()) / (float)( RAND_MAX ),
                         -1.0 + 2.0* (float)(rand()) / (float)( RAND_MAX ),
                         -1.0 + 2.0* (float)(rand()) / (float)( RAND_MAX ),
                         -1.0 + 2.0* (float)(rand()) / (float)( RAND_MAX ),
                         -1.0 + 2.0* (float)(rand()) / (float)( RAND_MAX ),
                         -1.0 + 2.0* (float)(rand()) / (float)( RAND_MAX ),
                         -1.0 + 2.0* (float)(rand()) / (float)( RAND_MAX ),
                         -1.0 + 2.0* (float)(rand()) / (float)( RAND_MAX ),
                         -1.0 + 2.0* (float)(rand()) / (float)( RAND_MAX ));
    }

    template< class point_t >
    inline static mat33<T> getFromCols(const point_t & c1 , const point_t & c2 , const point_t & c3)
    {
        // 0 1 2
        // 3 4 5
        // 6 7 8
        return mat33<T>( c1[0] , c2[0] , c3[0] ,
                         c1[1] , c2[1] , c3[1] ,
                         c1[2] , c2[2] , c3[2] );
    }
    template< class point_t >
    inline static mat33<T> getFromRows(const point_t & r1 , const point_t & r2 , const point_t & r3)
    {
        // 0 1 2
        // 3 4 5
        // 6 7 8
        return mat33<T>( r1[0] , r1[1] , r1[2] ,
                         r2[0] , r2[1] , r2[2] ,
                         r3[0] , r3[1] , r3[2] );
    }

    inline static mat33<T> Rand( double min_value , double max_value )
    {
        return mat33<T>( min_value + (max_value - min_value) * ( (float)(rand()) / (float)( RAND_MAX ) ),
                         min_value + (max_value - min_value) * ( (float)(rand()) / (float)( RAND_MAX ) ),
                         min_value + (max_value - min_value) * ( (float)(rand()) / (float)( RAND_MAX ) ),
                         min_value + (max_value - min_value) * ( (float)(rand()) / (float)( RAND_MAX ) ),
                         min_value + (max_value - min_value) * ( (float)(rand()) / (float)( RAND_MAX ) ),
                         min_value + (max_value - min_value) * ( (float)(rand()) / (float)( RAND_MAX ) ),
                         min_value + (max_value - min_value) * ( (float)(rand()) / (float)( RAND_MAX ) ),
                         min_value + (max_value - min_value) * ( (float)(rand()) / (float)( RAND_MAX ) ),
                         min_value + (max_value - min_value) * ( (float)(rand()) / (float)( RAND_MAX ) ));
    }
    inline static mat33<T> Rand( double randMagnitude )
    {
        T mabs = fabs(randMagnitude);
        return mat33<T>::Rand(-mabs,mabs);
    }

    inline static mat33<T> RandRotation()
    {
        point3<T> axis(-1.0 + 2.0* (float)(rand()) / (float)( RAND_MAX )  ,
                       -1.0 + 2.0* (float)(rand()) / (float)( RAND_MAX )  ,
                       -1.0 + 2.0* (float)(rand()) / (float)( RAND_MAX )  );
        axis.normalize();
        T angle = 2.0 * M_PI * ((float)(rand()) / (float)( RAND_MAX )   - 0.5 );

        return mat33<T>::getRotationMatrixFromAxisAndAngle( axis , angle );
    }

    inline static mat33<T> RandRotation( T maxAngle )
    {
        point3<T> axis(-1.0 + 2.0* (float)(rand()) / (float)( RAND_MAX )  ,
                       -1.0 + 2.0* (float)(rand()) / (float)( RAND_MAX )  ,
                       -1.0 + 2.0* (float)(rand()) / (float)( RAND_MAX )  );
        axis.normalize();
        T angle =  maxAngle * ((float)(rand()) / (float)( RAND_MAX )   - 0.5 );

        return mat33<T>::getRotationMatrixFromAxisAndAngle( axis , angle );
    }

    inline static mat33<T> createRandomRotation( point3<T> twistAxis , double maxTwist , double maxRotation )
    {
        twistAxis.normalize();
        point3<T> u = twistAxis.getOrthogonal();
        u.normalize();
        const point3<T> & v = point3<T>::cross(u,twistAxis);

        double uv_axis_angle = 2.0*M_PI * (double)(rand()) / (double)(RAND_MAX);
        const point3<T> & uv = cos(uv_axis_angle)*u + sin(uv_axis_angle)*v;

        double rotation_angle = maxRotation * ( ( 2.0 *(double)(rand()) / (double)(RAND_MAX) ) - 1.0 );
        double twist_angle = maxTwist * ( ( 2.0 *(double)(rand()) / (double)(RAND_MAX) ) - 1.0 );

        return mat33<T>::getRotationMatrixFromAxisAndAngle(uv , rotation_angle) * mat33<T>::getRotationMatrixFromAxisAndAngle(twistAxis , twist_angle);
    }

    // method defined as a standard Linear System Jacobian initialization (either Identity() or RandRotation())
    inline static
    mat33<T> LSJacobianInit()
    { return mat33<T>::Identity(); }

    void SVD( mat33<T> & U , T & sx , T & sy , T & sz , mat33<T> & Vt ) const
    {
#ifdef __USE_GSL_FOR_MAT33
        gsl_matrix * u = gsl_matrix_alloc(3,3);
        for(unsigned int i = 0 ; i < 3; ++i)
            for(unsigned int j = 0 ; j < 3; ++j)
                gsl_matrix_set( u , i , j , this->getCoord(i,j) );

        gsl_matrix * v = gsl_matrix_alloc(3,3);
        gsl_vector * s = gsl_vector_alloc(3);
        gsl_vector * work = gsl_vector_alloc(3);

        gsl_linalg_SV_decomp (u,
                              v,
                              s,
                              work);

        sx = s->data[0];
        sy = s->data[1];
        sz = s->data[2];
        for(unsigned int i = 0 ; i < 3; ++i)
        {
            for(unsigned int j = 0 ; j < 3; ++j)
            {
                U(i,j) = gsl_matrix_get( u , i , j );
                Vt(i,j) = gsl_matrix_get( v , j , i );
            }
        }

        gsl_matrix_free(u);
        gsl_matrix_free(v);
        gsl_vector_free(s);
        gsl_vector_free(work);
#else
        assert( 0   &&   "You need to use a Linear Algebra Library in order to use mat33<T>::SVD !" );
#endif

        // a transformation T is given as R.B.S.Bt, R = rotation , B = local basis (rotation matrix), S = scales in the basis B
        // it can be obtained from the svd decomposition of T = U Sigma Vt :
        // B = V
        // S = Sigma
        // R = U.Vt
    }

    ///////////////////      Projections onto Rotations :     ////////////////////
    mat33<T> getRotationalPart() const
    {
        mat33<T> U,Vt;
        T sx,sy,sz;
        SVD(U,sx,sy,sz,Vt);
        const mat33<T> & res = U*Vt;
        if( res.determinant() < 0 )
        {
            U(2) = -U(2);
            U(5) = -U(5);
            U(8) = -U(8);
            return U*Vt;
        }
        // else
        return res;
    }

    void setRotation()
    {
        mat33<T> U,Vt;
        T sx,sy,sz;
        SVD(U,sx,sy,sz,Vt);
        const mat33<T> & res = U*Vt;
        if( res.determinant() < 0 )
        {
            U(2) = -U(2);
            U(5) = -U(5);
            U(8) = -U(8);
            set(U*Vt);
            return;
        }
        // else
        set(res);
    }

    void setRotation( double weight )
    {
        mat33<T> U,Vt;
        T sx,sy,sz;
        SVD(U,sx,sy,sz,Vt);
        mat33<T> S( weight + (1-weight)*sx ,0,0,0,weight + (1-weight)*sy ,0,0,0, weight + (1-weight)*sz );
        const mat33<T> & res = U*S*Vt;
        if( res.determinant() < 0 )
        {
            S(8) = -S(8);
            set(U*S*Vt);
            return;
        }
        // else
        set(res);
    }

    void setSimilarity()
    {
        mat33<T> U,Vt;
        T sx,sy,sz;
        SVD(U,sx,sy,sz,Vt);
        mat33<T> S((sx+sy+sz)/3,0,0,0,(sx+sy+sz)/3,0,0,0,(sx+sy+sz)/3);
        const mat33<T> & res = U*S*Vt;
        if( res.determinant() < 0 )
        {
            S(8) = -S(8);
            set(U* S * Vt);
            return;
        }
        // else
        set(res);
    }

    // TO CHECK WHAT'S BEST
    // what is the L2 projection on the set of matrices of the form R . B2 . diag[1 1 x] . B2^T ?
    // is U . V^T . B2 . diag[1 1 x] . B2^T enough ?
    void setRotationOnTangentPlane( const mat33<T> & B2 )
    {   // B2 is assumed to be an orthogonal matrix with B2(2) = normal of the tangent plane
        // SVD :
        mat33<T> U,Vt;
        T sx,sy,sz;
        SVD(U,sx,sy,sz,Vt);

        if( (U*Vt).determinant() < 0 ){ U(2) = -U(2); U(5) = -U(5); U(8) = -U(8); }

        const point3<T> & VtB2_col2 = ( Vt * B2 ).getCol(2);
        T lambda = sx * VtB2_col2[0] * VtB2_col2[0]  +  sy * VtB2_col2[1] * VtB2_col2[1]  +  sz * VtB2_col2[2] * VtB2_col2[2];

        // if( (U*Vt).determinant() < 0 ){ lambda = -lambda; }

        mat33<T> NewScales = mat33<T>::Identity();
        NewScales(2,2) = lambda;

        set( U * Vt * B2 * transposeProduct01( NewScales , B2 ) );
    }

    void setRotationOnTangentPlane( const point3<T> & p_normal )
    {   // p_normal is assumed to be normalized
        // construction of B2 : 3x3 matrix that represents an orthogonal basis where B2(2) = p_normal
        point3<T> b1 = p_normal.getOrthogonal();
        b1.normalize();
        const point3<T> & b2 = point3<T>::cross( p_normal , b1 );

        mat33<T> B2;
        B2.setCol( 0 , b1 );
        B2.setCol( 1 , b2 );
        B2.setCol( 2 , p_normal );

        setRotationOnTangentPlane(B2);
    }

    //////////           Stupid products          /////////////
    // get the result of m1^T * m2:
    static
    mat33<T> transposeProduct10( const mat33<T> & m1 , const mat33<T> & m2 )
    {
        return mat33<T>(
                    m1(0)*m2(0) + m1(3)*m2(3) + m1(6)*m2(6) ,
                    m1(0)*m2(1) + m1(3)*m2(4) + m1(6)*m2(7) ,
                    m1(0)*m2(2) + m1(3)*m2(5) + m1(6)*m2(8) ,
                    m1(1)*m2(0) + m1(4)*m2(3) + m1(7)*m2(6) ,
                    m1(1)*m2(1) + m1(4)*m2(4) + m1(7)*m2(7) ,
                    m1(1)*m2(2) + m1(4)*m2(5) + m1(7)*m2(8) ,
                    m1(2)*m2(0) + m1(5)*m2(3) + m1(8)*m2(6) ,
                    m1(2)*m2(1) + m1(5)*m2(4) + m1(8)*m2(7) ,
                    m1(2)*m2(2) + m1(5)*m2(5) + m1(8)*m2(8)
                    );
    }
    // get the result of m1 * m2^T:
    static
    mat33<T> transposeProduct01( const mat33<T> & m1 , const mat33<T> & m2 )
    {
        return mat33<T>(
                    m1(0)*m2(0) + m1(1)*m2(1) + m1(2)*m2(2) ,
                    m1(0)*m2(3) + m1(1)*m2(4) + m1(2)*m2(5) ,
                    m1(0)*m2(6) + m1(1)*m2(7) + m1(2)*m2(8) ,
                    m1(3)*m2(0) + m1(4)*m2(1) + m1(5)*m2(2) ,
                    m1(3)*m2(3) + m1(4)*m2(4) + m1(5)*m2(5) ,
                    m1(3)*m2(6) + m1(4)*m2(7) + m1(5)*m2(8) ,
                    m1(6)*m2(0) + m1(7)*m2(1) + m1(8)*m2(2) ,
                    m1(6)*m2(3) + m1(7)*m2(4) + m1(8)*m2(5) ,
                    m1(6)*m2(6) + m1(7)*m2(7) + m1(8)*m2(8)
                    );
    }

    // get the result of m^T * m:
    mat33<T> selfTransposeProduct10(  ) const
    {
        return mat33<T>(
                    vals[0]*vals[0] + vals[3]*vals[3] + vals[6]*vals[6] ,
                    vals[0]*vals[1] + vals[3]*vals[4] + vals[6]*vals[7] ,
                    vals[0]*vals[2] + vals[3]*vals[5] + vals[6]*vals[8] ,
                    vals[1]*vals[0] + vals[4]*vals[3] + vals[7]*vals[6] ,
                    vals[1]*vals[1] + vals[4]*vals[4] + vals[7]*vals[7] ,
                    vals[1]*vals[2] + vals[4]*vals[5] + vals[7]*vals[8] ,
                    vals[2]*vals[0] + vals[5]*vals[3] + vals[8]*vals[6] ,
                    vals[2]*vals[1] + vals[5]*vals[4] + vals[8]*vals[7] ,
                    vals[2]*vals[2] + vals[5]*vals[5] + vals[8]*vals[8]
                    );
    }
    // get the result of m * m^T:
    mat33<T> selfTransposeProduct01(  ) const
    {
        return mat33<T>(
                    vals[0]*vals[0] + vals[1]*vals[1] + vals[2]*vals[2] ,
                    vals[0]*vals[3] + vals[1]*vals[4] + vals[2]*vals[5] ,
                    vals[0]*vals[6] + vals[1]*vals[7] + vals[2]*vals[8] ,
                    vals[3]*vals[0] + vals[4]*vals[1] + vals[5]*vals[2] ,
                    vals[3]*vals[3] + vals[4]*vals[4] + vals[5]*vals[5] ,
                    vals[3]*vals[6] + vals[4]*vals[7] + vals[5]*vals[8] ,
                    vals[6]*vals[0] + vals[7]*vals[1] + vals[8]*vals[2] ,
                    vals[6]*vals[3] + vals[7]*vals[4] + vals[8]*vals[5] ,
                    vals[6]*vals[6] + vals[7]*vals[7] + vals[8]*vals[8]
                    );
    }

    template< class point_t >
    inline static
    mat33<T> tensor( const point_t & p1 , const point_t & p2 )
    {
        return mat33<T>(
                    p1.x()*p2.x() , p1.x()*p2.y() , p1.x()*p2.z(),
                    p1.y()*p2.x() , p1.y()*p2.y() , p1.y()*p2.z(),
                    p1.z()*p2.x() , p1.z()*p2.y() , p1.z()*p2.z());
    }

    template< class point_t >
    inline static
    mat33<T> vectorial( const point_t & p )
    {
        return mat33<T>(
                    0       , -p.z()    , p.y()     ,
                    p.z()   , 0         , - p.x()   ,
                    - p.y() , p.x()     , 0
                    );
    }

    mat33<T> logOfRotation() const {
        point3<T> axis; double angle;
        this->getAxisAndAngleFromRotationMatrix(axis,angle);
        return angle * vectorial( axis );
    }

    mat33<T> logToRotation() const {
        point3<T> axis( - (this->operator()(1,2)) , (this->operator()(0,2)) , - (this->operator()(0,1)) ); double angle = axis.norm(); axis.normalize();
        return getRotationMatrixFromAxisAndAngle(axis , angle);
    }

    mat33<T> operator - () const
    {
        return mat33<T>( - vals[0],- vals[1],- vals[2],- vals[3],- vals[4],- vals[5],- vals[6],- vals[7],- vals[8] );
    }

private:
    T vals[9];
    // will be noted as :
    // 0 1 2
    // 3 4 5
    // 6 7 8
};

typedef mat33< float >  mat33f;
typedef mat33< double > mat33d;

template< typename T >
mat33<T> operator + (const mat33<T> & m1 , const mat33<T> & m2)
{
    return mat33<T>( m1(0)+m2(0) , m1(1)+m2(1) , m1(2)+m2(2) , m1(3)+m2(3) , m1(4)+m2(4) , m1(5)+m2(5) , m1(6)+m2(6) , m1(7)+m2(7) , m1(8)+m2(8) );
}
template< typename T >
mat33<T> operator - (const mat33<T> & m1 , const mat33<T> & m2)
{
    return mat33<T>( m1(0)-m2(0) , m1(1)-m2(1) , m1(2)-m2(2) , m1(3)-m2(3) , m1(4)-m2(4) , m1(5)-m2(5) , m1(6)-m2(6) , m1(7)-m2(7) , m1(8)-m2(8) );
}

template< typename T >
mat33<T> operator * (int s , const mat33<T> & m)
{
    return mat33<T>( m(0)*s , m(1)*s , m(2)*s , m(3)*s , m(4)*s , m(5)*s , m(6)*s , m(7)*s , m(8)*s );
}
template< typename T >
mat33<T> operator * (float s , const mat33<T> & m)
{
    return mat33<T>( m(0)*s , m(1)*s , m(2)*s , m(3)*s , m(4)*s , m(5)*s , m(6)*s , m(7)*s , m(8)*s );
}
template< typename T >
mat33<T> operator * (double s , const mat33<T> & m)
{
    return mat33<T>( m(0)*s , m(1)*s , m(2)*s , m(3)*s , m(4)*s , m(5)*s , m(6)*s , m(7)*s , m(8)*s );
}

template< typename T >
mat33<T> operator * (const mat33<T> & m , int s)
{
    return mat33<T>( m(0)*s , m(1)*s , m(2)*s , m(3)*s , m(4)*s , m(5)*s , m(6)*s , m(7)*s , m(8)*s );
}
template< typename T >
mat33<T> operator * (const mat33<T> & m , float s)
{
    return mat33<T>( m(0)*s , m(1)*s , m(2)*s , m(3)*s , m(4)*s , m(5)*s , m(6)*s , m(7)*s , m(8)*s );
}
template< typename T >
mat33<T> operator * (const mat33<T> & m , double s)
{
    return mat33<T>( m(0)*s , m(1)*s , m(2)*s , m(3)*s , m(4)*s , m(5)*s , m(6)*s , m(7)*s , m(8)*s );
}

template< typename T >
mat33<T> operator / (const mat33<T> & m , int s)
{
    return mat33<T>( m(0)/s , m(1)/s , m(2)/s , m(3)/s , m(4)/s , m(5)/s , m(6)/s , m(7)/s , m(8)/s );
}
template< typename T >
mat33<T> operator / (const mat33<T> & m , float s)
{
    return mat33<T>( m(0)/s , m(1)/s , m(2)/s , m(3)/s , m(4)/s , m(5)/s , m(6)/s , m(7)/s , m(8)/s );
}
template< typename T >
mat33<T> operator / (const mat33<T> & m , double s)
{
    return mat33<T>( m(0)/s , m(1)/s , m(2)/s , m(3)/s , m(4)/s , m(5)/s , m(6)/s , m(7)/s , m(8)/s );
}

template< typename T >
point3<T> operator * (const mat33<T> & m , const point3<T> & p) // computes m.p
{
    return point3<T>(
                m(0)*p[0] + m(1)*p[1] + m(2)*p[2],
                m(3)*p[0] + m(4)*p[1] + m(5)*p[2],
                m(6)*p[0] + m(7)*p[1] + m(8)*p[2]);
}
template< typename T >
point3<T> operator * (const point3<T> & p , const mat33<T> & m) // computes p^t . m = (m^t . p)^t
{
    return point3<T>(
                m(0)*p[0] + m(3)*p[1] + m(6)*p[2],
                m(1)*p[0] + m(4)*p[1] + m(7)*p[2],
                m(2)*p[0] + m(5)*p[1] + m(8)*p[2]);
}

template< typename T >
mat33<T> operator * (const mat33<T> & m1 , const mat33<T> & m2)
{
    return mat33<T>(
                m1(0)*m2(0) + m1(1)*m2(3) + m1(2)*m2(6) ,
                m1(0)*m2(1) + m1(1)*m2(4) + m1(2)*m2(7) ,
                m1(0)*m2(2) + m1(1)*m2(5) + m1(2)*m2(8) ,
                m1(3)*m2(0) + m1(4)*m2(3) + m1(5)*m2(6) ,
                m1(3)*m2(1) + m1(4)*m2(4) + m1(5)*m2(7) ,
                m1(3)*m2(2) + m1(4)*m2(5) + m1(5)*m2(8) ,
                m1(6)*m2(0) + m1(7)*m2(3) + m1(8)*m2(6) ,
                m1(6)*m2(1) + m1(7)*m2(4) + m1(8)*m2(7) ,
                m1(6)*m2(2) + m1(7)*m2(5) + m1(8)*m2(8)
                );
}

template< typename T > inline std::ostream & operator << (std::ostream & s , mat33< T > const & m)
{
    s << m(0) << " \t" << m(1) << " \t" << m(2) << std::endl << m(3) << " \t" << m(4) << " \t" << m(5) << std::endl << m(6) << " \t" << m(7) << " \t" << m(8) << std::endl;
    return s;
}

#ifdef __USE_GSL_FOR_MAT33

template< typename T >
class mat33staticsvd : public mat33< T >
{
private:
    gsl_matrix * u;
    gsl_matrix * v;
    gsl_vector * s;
    gsl_vector * work;

    bool svd_allocated;

    void allocate_svd()
    {
        if(svd_allocated) return;
        u = gsl_matrix_alloc(3,3);
        v = gsl_matrix_alloc(3,3);
        s = gsl_vector_alloc(3);
        work = gsl_vector_alloc(3);
        svd_allocated = true;
    }
    void free_svd()
    {
        if(!svd_allocated) return;
        gsl_matrix_free(u);
        gsl_matrix_free(v);
        gsl_vector_free(s);
        gsl_vector_free(work);
        svd_allocated = false;
    }

public:
    mat33staticsvd<T>() :
        mat33< T >() ,
        svd_allocated(false)
    {
    }
    mat33staticsvd<T>( T v1 , T v2 , T v3 , T v4 , T v5 , T v6 , T v7 , T v8 , T v9) :
        mat33< T >( v1 , v2 , v3 , v4 , v5 , v6 , v7 , v8 , v9) ,
        svd_allocated(false)
    {
    }
    template< typename T2 > mat33staticsvd<T>( const std::vector< T2 > & cc ) :
        mat33< T >(cc) ,
        svd_allocated(false)
    {
    }
    template< typename T2 > mat33staticsvd<T>( const mat33< T2 > & m ) :
        mat33< T >(m) ,
        svd_allocated(false)
    {
    }
    ~mat33staticsvd<T>()
    {
        free_svd();
    }

    void SVD( mat33<T> & U , T & sx , T & sy , T & sz , mat33<T> & Vt ) const
    {
        allocate_svd();

        for(unsigned int i = 0 ; i < 3; ++i)
            for(unsigned int j = 0 ; j < 3; ++j)
                gsl_matrix_set( u , i , j , this->getCoord(i,j) );

        gsl_linalg_SV_decomp (u,
                              v,
                              s,
                              work);

        sx = s->data[0];
        sy = s->data[1];
        sz = s->data[2];
        for(unsigned int i = 0 ; i < 3; ++i)
        {
            for(unsigned int j = 0 ; j < 3; ++j)
            {
                U(i,j) = gsl_matrix_get( u , i , j );
                Vt(i,j) = gsl_matrix_get( v , j , i );
            }
        }
    }
};
#endif

#endif