#include "target.h"
#include <emmintrin.h>
#include <iostream>
#include <iomanip>
#include <string.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
#include "cpucycles.h"

long long innerloopcycles;

class uint32x4 {
  __m128i x;
public:
  inline uint32x4() { }
  inline uint32x4(unsigned int u) { x = _mm_set_epi32(u,u,u,u); }
  inline uint32x4(__m128i u) { x = u; }
  inline uint32x4(const uint32x4 &a) { x = a.x; }
  unsigned int uint0() const { return _mm_cvtsi128_si32(x); }
  unsigned int uint1() const { return _mm_cvtsi128_si32(_mm_shuffle_epi32(x,0x39)); }
  unsigned int uint2() const { return _mm_cvtsi128_si32(_mm_shuffle_epi32(x,0x4e)); }
  unsigned int uint3() const { return _mm_cvtsi128_si32(_mm_shuffle_epi32(x,0x93)); }
  friend inline uint32x4 operator+(uint32x4 a,uint32x4 b) { return _mm_add_epi32(a.x,b.x); }
  friend inline uint32x4 operator|(uint32x4 a,uint32x4 b) { return _mm_or_si128(a.x,b.x); }
  friend inline uint32x4 operator&(uint32x4 a,uint32x4 b) { return _mm_and_si128(a.x,b.x); }
  friend inline uint32x4 operator^(uint32x4 a,uint32x4 b) { return _mm_xor_si128(a.x,b.x); }
  friend inline uint32x4 operator>>(uint32x4 a,int b) { return _mm_srli_epi32(a.x,b); }
  friend inline uint32x4 andnot(uint32x4 a,uint32x4 b) { return _mm_andnot_si128(b.x,a.x); }
  friend inline uint32x4 rotate1(uint32x4 a) {
    return _mm_xor_si128(_mm_slli_epi32(a.x,1),_mm_srli_epi32(a.x,31)); }
  friend inline uint32x4 rotate5(uint32x4 a) {
    return _mm_xor_si128(_mm_slli_epi32(a.x,5),_mm_srli_epi32(a.x,27)); }
  friend inline uint32x4 rotate30(uint32x4 a) {
    return _mm_xor_si128(_mm_slli_epi32(a.x,30),_mm_srli_epi32(a.x,2)); }
  friend ostream& operator<<(ostream& o,const uint32x4& u) {
    unsigned int r = u.uint0();
    o << hex << setw(2) << setfill('0') << ((r >> 24) & 255);
    o << hex << setw(2) << setfill('0') << ((r >> 16) & 255);
    o << hex << setw(2) << setfill('0') << ((r >> 8) & 255);
    o << hex << setw(2) << setfill('0') << (r & 255);
    return o;
  }
} ;

class hash {
  uint32x4 state[5];
public:
  hash() { }
  hash(const hash &x) {
    state[0] = x.state[0];
    state[1] = x.state[1];
    state[2] = x.state[2];
    state[3] = x.state[3];
    state[4] = x.state[4];
  }
  void init()
  {
    state[0] = 0x67452301;
    state[1] = 0xefcdab89;
    state[2] = 0x98badcfe;
    state[3] = 0x10325476;
    state[4] = 0xc3d2e1f0;
  }
  uint32x4 hammingdistance(hash b) {
    uint32x4 x0 = state[0] ^ b.state[0];
    uint32x4 x1 = state[1] ^ b.state[1];
    uint32x4 x2 = state[2] ^ b.state[2];
    uint32x4 x3 = state[3] ^ b.state[3];
    uint32x4 x4 = state[4] ^ b.state[4];
    uint32x4 mask;
    // 32 1-bit chunks
    mask = 0x55555555;
    x0 = (x0 & mask) + ((x0 >> 1) & mask);
    x1 = (x1 & mask) + ((x1 >> 1) & mask);
    x2 = (x2 & mask) + ((x2 >> 1) & mask);
    x3 = (x3 & mask) + ((x3 >> 1) & mask);
    x4 = (x4 & mask) + ((x4 >> 1) & mask);
    // 16 2-bit chunks: 012,012,012,012,012,012,012,012,012,012,012,012,012,012,012,012
    mask = 0x33333333;
    x0 = (x0 & mask) + ((x0 >> 2) & mask);
    x1 = (x1 & mask) + ((x1 >> 2) & mask);
    x2 = (x2 & mask) + ((x2 >> 2) & mask);
    x3 = (x3 & mask) + ((x3 >> 2) & mask);
    x4 = (x4 & mask) + ((x4 >> 2) & mask);
    // 8 4-bit chunks: 01234,01234,01234,01234,01234,01234,01234,01234
    mask = 0x0f0f0f0f;
    x0 = (x0 & mask) + ((x0 >> 4) & mask);
    x1 = (x1 & mask) + ((x1 >> 4) & mask);
    x2 = (x2 & mask) + ((x2 >> 4) & mask);
    x3 = (x3 & mask) + ((x3 >> 4) & mask);
    x4 = (x4 & mask) + ((x4 >> 4) & mask);
    // 4 8-bit chunks: 012345678,012345678,012345678,012345678
    mask = 0x00ff00ff;
    x0 = (x0 & mask) + ((x0 >> 8) & mask);
    x1 = (x1 & mask) + ((x1 >> 8) & mask);
    x2 = (x2 & mask) + ((x2 >> 8) & mask);
    x3 = (x3 & mask) + ((x3 >> 8) & mask);
    x4 = (x4 & mask) + ((x4 >> 8) & mask);
    mask = 0x0000ffff;
    x0 = (x0 & mask) + ((x0 >> 16) & mask);
    x1 = (x1 & mask) + ((x1 >> 16) & mask);
    x2 = (x2 & mask) + ((x2 >> 16) & mask);
    x3 = (x3 & mask) + ((x3 >> 16) & mask);
    x4 = (x4 & mask) + ((x4 >> 16) & mask);
    return x0 + x1 + x2 + x3 + x4;
  }
  friend ostream& operator<<(ostream& o,const hash& h) {
    o << h.state[0];
    o << h.state[1];
    o << h.state[2];
    o << h.state[3];
    o << h.state[4];
    return o;
  }
  void update(const uint32x4 *in,unsigned long long inblocks) {
    uint32x4 a = state[0];
    uint32x4 b = state[1];
    uint32x4 c = state[2];
    uint32x4 d = state[3];
    uint32x4 e = state[4];
    uint32x4 delta;
    uint32x4 f;
    uint32x4 x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15;
    int i;
  
    while (inblocks > 0) {
      delta = 0x5a827999;
      x0 = in[0];
      f = (c & b) | andnot(d,b);
      e = rotate5(a) + f + e + delta + x0;
      b = rotate30(b);
      x1 = in[1];
      f = (b & a) | andnot(c,a);
      d = rotate5(e) + f + d + delta + x1;
      a = rotate30(a);
      x2 = in[2];
      f = (a & e) | andnot(b,e);
      c = rotate5(d) + f + c + delta + x2;
      e = rotate30(e);
      x3 = in[3];
      f = (e & d) | andnot(a,d);
      b = rotate5(c) + f + b + delta + x3;
      d = rotate30(d);
      x4 = in[4];
      f = (d & c) | andnot(e,c);
      a = rotate5(b) + f + a + delta + x4;
      c = rotate30(c);
      x5 = in[5];
      f = (c & b) | andnot(d,b);
      e = rotate5(a) + f + e + delta + x5;
      b = rotate30(b);
      x6 = in[6];
      f = (b & a) | andnot(c,a);
      d = rotate5(e) + f + d + delta + x6;
      a = rotate30(a);
      x7 = in[7];
      f = (a & e) | andnot(b,e);
      c = rotate5(d) + f + c + delta + x7;
      e = rotate30(e);
      x8 = in[8];
      f = (e & d) | andnot(a,d);
      b = rotate5(c) + f + b + delta + x8;
      d = rotate30(d);
      x9 = in[9];
      f = (d & c) | andnot(e,c);
      a = rotate5(b) + f + a + delta + x9;
      c = rotate30(c);
      x10 = in[10];
      f = (c & b) | andnot(d,b);
      e = rotate5(a) + f + e + delta + x10;
      b = rotate30(b);
      x11 = in[11];
      f = (b & a) | andnot(c,a);
      d = rotate5(e) + f + d + delta + x11;
      a = rotate30(a);
      x12 = in[12];
      f = (a & e) | andnot(b,e);
      c = rotate5(d) + f + c + delta + x12;
      e = rotate30(e);
      x13 = in[13];
      f = (e & d) | andnot(a,d);
      b = rotate5(c) + f + b + delta + x13;
      d = rotate30(d);
      x14 = in[14];
      f = (d & c) | andnot(e,c);
      a = rotate5(b) + f + a + delta + x14;
      c = rotate30(c);
      x15 = in[15];
      f = (c & b) | andnot(d,b);
      e = rotate5(a) + f + e + delta + x15;
      b = rotate30(b);
      x0 = rotate1(x13 ^ x8 ^ x2 ^ x0);
      f = (b & a) | andnot(c,a);
      d = rotate5(e) + f + d + delta + x0;
      a = rotate30(a);
      x1 = rotate1(x14 ^ x9 ^ x3 ^ x1);
      f = (a & e) | andnot(b,e);
      c = rotate5(d) + f + c + delta + x1;
      e = rotate30(e);
      x2 = rotate1(x15 ^ x10 ^ x4 ^ x2);
      f = (e & d) | andnot(a,d);
      b = rotate5(c) + f + b + delta + x2;
      d = rotate30(d);
      x3 = rotate1(x0 ^ x11 ^ x5 ^ x3);
      f = (d & c) | andnot(e,c);
      a = rotate5(b) + f + a + delta + x3;
      c = rotate30(c);
      delta = 0x6ed9eba1;
      x4 = rotate1(x1 ^ x12 ^ x6 ^ x4);
      f = b ^ c ^ d;
      e = rotate5(a) + f + e + delta + x4;
      b = rotate30(b);
      x5 = rotate1(x2 ^ x13 ^ x7 ^ x5);
      f = a ^ b ^ c;
      d = rotate5(e) + f + d + delta + x5;
      a = rotate30(a);
      x6 = rotate1(x3 ^ x14 ^ x8 ^ x6);
      f = e ^ a ^ b;
      c = rotate5(d) + f + c + delta + x6;
      e = rotate30(e);
      x7 = rotate1(x4 ^ x15 ^ x9 ^ x7);
      f = d ^ e ^ a;
      b = rotate5(c) + f + b + delta + x7;
      d = rotate30(d);
      x8 = rotate1(x5 ^ x0 ^ x10 ^ x8);
      f = c ^ d ^ e;
      a = rotate5(b) + f + a + delta + x8;
      c = rotate30(c);
      x9 = rotate1(x6 ^ x1 ^ x11 ^ x9);
      f = b ^ c ^ d;
      e = rotate5(a) + f + e + delta + x9;
      b = rotate30(b);
      x10 = rotate1(x7 ^ x2 ^ x12 ^ x10);
      f = a ^ b ^ c;
      d = rotate5(e) + f + d + delta + x10;
      a = rotate30(a);
      x11 = rotate1(x8 ^ x3 ^ x13 ^ x11);
      f = e ^ a ^ b;
      c = rotate5(d) + f + c + delta + x11;
      e = rotate30(e);
      x12 = rotate1(x9 ^ x4 ^ x14 ^ x12);
      f = d ^ e ^ a;
      b = rotate5(c) + f + b + delta + x12;
      d = rotate30(d);
      x13 = rotate1(x10 ^ x5 ^ x15 ^ x13);
      f = c ^ d ^ e;
      a = rotate5(b) + f + a + delta + x13;
      c = rotate30(c);
      x14 = rotate1(x11 ^ x6 ^ x0 ^ x14);
      f = b ^ c ^ d;
      e = rotate5(a) + f + e + delta + x14;
      b = rotate30(b);
      x15 = rotate1(x12 ^ x7 ^ x1 ^ x15);
      f = a ^ b ^ c;
      d = rotate5(e) + f + d + delta + x15;
      a = rotate30(a);
      x0 = rotate1(x13 ^ x8 ^ x2 ^ x0);
      f = e ^ a ^ b;
      c = rotate5(d) + f + c + delta + x0;
      e = rotate30(e);
      x1 = rotate1(x14 ^ x9 ^ x3 ^ x1);
      f = d ^ e ^ a;
      b = rotate5(c) + f + b + delta + x1;
      d = rotate30(d);
      x2 = rotate1(x15 ^ x10 ^ x4 ^ x2);
      f = c ^ d ^ e;
      a = rotate5(b) + f + a + delta + x2;
      c = rotate30(c);
      x3 = rotate1(x0 ^ x11 ^ x5 ^ x3);
      f = b ^ c ^ d;
      e = rotate5(a) + f + e + delta + x3;
      b = rotate30(b);
      x4 = rotate1(x1 ^ x12 ^ x6 ^ x4);
      f = a ^ b ^ c;
      d = rotate5(e) + f + d + delta + x4;
      a = rotate30(a);
      x5 = rotate1(x2 ^ x13 ^ x7 ^ x5);
      f = e ^ a ^ b;
      c = rotate5(d) + f + c + delta + x5;
      e = rotate30(e);
      x6 = rotate1(x3 ^ x14 ^ x8 ^ x6);
      f = d ^ e ^ a;
      b = rotate5(c) + f + b + delta + x6;
      d = rotate30(d);
      x7 = rotate1(x4 ^ x15 ^ x9 ^ x7);
      f = c ^ d ^ e;
      a = rotate5(b) + f + a + delta + x7;
      c = rotate30(c);
      delta = 0x8f1bbcdc;
      x8 = rotate1(x5 ^ x0 ^ x10 ^ x8);
      f = (b & c) | (b & d) | (c & d);
      e = rotate5(a) + f + e + delta + x8;
      b = rotate30(b);
      x9 = rotate1(x6 ^ x1 ^ x11 ^ x9);
      f = (a & b) | (a & c) | (b & c);
      d = rotate5(e) + f + d + delta + x9;
      a = rotate30(a);
      x10 = rotate1(x7 ^ x2 ^ x12 ^ x10);
      f = (e & a) | (e & b) | (a & b);
      c = rotate5(d) + f + c + delta + x10;
      e = rotate30(e);
      x11 = rotate1(x8 ^ x3 ^ x13 ^ x11);
      f = (d & e) | (d & a) | (e & a);
      b = rotate5(c) + f + b + delta + x11;
      d = rotate30(d);
      x12 = rotate1(x9 ^ x4 ^ x14 ^ x12);
      f = (c & d) | (c & e) | (d & e);
      a = rotate5(b) + f + a + delta + x12;
      c = rotate30(c);
      x13 = rotate1(x10 ^ x5 ^ x15 ^ x13);
      f = (b & c) | (b & d) | (c & d);
      e = rotate5(a) + f + e + delta + x13;
      b = rotate30(b);
      x14 = rotate1(x11 ^ x6 ^ x0 ^ x14);
      f = (a & b) | (a & c) | (b & c);
      d = rotate5(e) + f + d + delta + x14;
      a = rotate30(a);
      x15 = rotate1(x12 ^ x7 ^ x1 ^ x15);
      f = (e & a) | (e & b) | (a & b);
      c = rotate5(d) + f + c + delta + x15;
      e = rotate30(e);
      x0 = rotate1(x13 ^ x8 ^ x2 ^ x0);
      f = (d & e) | (d & a) | (e & a);
      b = rotate5(c) + f + b + delta + x0;
      d = rotate30(d);
      x1 = rotate1(x14 ^ x9 ^ x3 ^ x1);
      f = (c & d) | (c & e) | (d & e);
      a = rotate5(b) + f + a + delta + x1;
      c = rotate30(c);
      x2 = rotate1(x15 ^ x10 ^ x4 ^ x2);
      f = (b & c) | (b & d) | (c & d);
      e = rotate5(a) + f + e + delta + x2;
      b = rotate30(b);
      x3 = rotate1(x0 ^ x11 ^ x5 ^ x3);
      f = (a & b) | (a & c) | (b & c);
      d = rotate5(e) + f + d + delta + x3;
      a = rotate30(a);
      x4 = rotate1(x1 ^ x12 ^ x6 ^ x4);
      f = (e & a) | (e & b) | (a & b);
      c = rotate5(d) + f + c + delta + x4;
      e = rotate30(e);
      x5 = rotate1(x2 ^ x13 ^ x7 ^ x5);
      f = (d & e) | (d & a) | (e & a);
      b = rotate5(c) + f + b + delta + x5;
      d = rotate30(d);
      x6 = rotate1(x3 ^ x14 ^ x8 ^ x6);
      f = (c & d) | (c & e) | (d & e);
      a = rotate5(b) + f + a + delta + x6;
      c = rotate30(c);
      x7 = rotate1(x4 ^ x15 ^ x9 ^ x7);
      f = (b & c) | (b & d) | (c & d);
      e = rotate5(a) + f + e + delta + x7;
      b = rotate30(b);
      x8 = rotate1(x5 ^ x0 ^ x10 ^ x8);
      f = (a & b) | (a & c) | (b & c);
      d = rotate5(e) + f + d + delta + x8;
      a = rotate30(a);
      x9 = rotate1(x6 ^ x1 ^ x11 ^ x9);
      f = (e & a) | (e & b) | (a & b);
      c = rotate5(d) + f + c + delta + x9;
      e = rotate30(e);
      x10 = rotate1(x7 ^ x2 ^ x12 ^ x10);
      f = (d & e) | (d & a) | (e & a);
      b = rotate5(c) + f + b + delta + x10;
      d = rotate30(d);
      x11 = rotate1(x8 ^ x3 ^ x13 ^ x11);
      f = (c & d) | (c & e) | (d & e);
      a = rotate5(b) + f + a + delta + x11;
      c = rotate30(c);
      delta = 0xca62c1d6;
      x12 = rotate1(x9 ^ x4 ^ x14 ^ x12);
      f = b ^ c ^ d;
      e = rotate5(a) + f + e + delta + x12;
      b = rotate30(b);
      x13 = rotate1(x10 ^ x5 ^ x15 ^ x13);
      f = a ^ b ^ c;
      d = rotate5(e) + f + d + delta + x13;
      a = rotate30(a);
      x14 = rotate1(x11 ^ x6 ^ x0 ^ x14);
      f = e ^ a ^ b;
      c = rotate5(d) + f + c + delta + x14;
      e = rotate30(e);
      x15 = rotate1(x12 ^ x7 ^ x1 ^ x15);
      f = d ^ e ^ a;
      b = rotate5(c) + f + b + delta + x15;
      d = rotate30(d);
      x0 = rotate1(x13 ^ x8 ^ x2 ^ x0);
      f = c ^ d ^ e;
      a = rotate5(b) + f + a + delta + x0;
      c = rotate30(c);
      x1 = rotate1(x14 ^ x9 ^ x3 ^ x1);
      f = b ^ c ^ d;
      e = rotate5(a) + f + e + delta + x1;
      b = rotate30(b);
      x2 = rotate1(x15 ^ x10 ^ x4 ^ x2);
      f = a ^ b ^ c;
      d = rotate5(e) + f + d + delta + x2;
      a = rotate30(a);
      x3 = rotate1(x0 ^ x11 ^ x5 ^ x3);
      f = e ^ a ^ b;
      c = rotate5(d) + f + c + delta + x3;
      e = rotate30(e);
      x4 = rotate1(x1 ^ x12 ^ x6 ^ x4);
      f = d ^ e ^ a;
      b = rotate5(c) + f + b + delta + x4;
      d = rotate30(d);
      x5 = rotate1(x2 ^ x13 ^ x7 ^ x5);
      f = c ^ d ^ e;
      a = rotate5(b) + f + a + delta + x5;
      c = rotate30(c);
      x6 = rotate1(x3 ^ x14 ^ x8 ^ x6);
      f = b ^ c ^ d;
      e = rotate5(a) + f + e + delta + x6;
      b = rotate30(b);
      x7 = rotate1(x4 ^ x15 ^ x9 ^ x7);
      f = a ^ b ^ c;
      d = rotate5(e) + f + d + delta + x7;
      a = rotate30(a);
      x8 = rotate1(x5 ^ x0 ^ x10 ^ x8);
      f = e ^ a ^ b;
      c = rotate5(d) + f + c + delta + x8;
      e = rotate30(e);
      x9 = rotate1(x6 ^ x1 ^ x11 ^ x9);
      f = d ^ e ^ a;
      b = rotate5(c) + f + b + delta + x9;
      d = rotate30(d);
      x10 = rotate1(x7 ^ x2 ^ x12 ^ x10);
      f = c ^ d ^ e;
      a = rotate5(b) + f + a + delta + x10;
      c = rotate30(c);
      x11 = rotate1(x8 ^ x3 ^ x13 ^ x11);
      f = b ^ c ^ d;
      e = rotate5(a) + f + e + delta + x11;
      b = rotate30(b);
      x12 = rotate1(x9 ^ x4 ^ x14 ^ x12);
      f = a ^ b ^ c;
      d = rotate5(e) + f + d + delta + x12;
      a = rotate30(a);
      x13 = rotate1(x10 ^ x5 ^ x15 ^ x13);
      f = e ^ a ^ b;
      c = rotate5(d) + f + c + delta + x13;
      e = rotate30(e);
      x14 = rotate1(x11 ^ x6 ^ x0 ^ x14);
      f = d ^ e ^ a;
      b = rotate5(c) + f + b + delta + x14;
      d = rotate30(d);
      x15 = rotate1(x12 ^ x7 ^ x1 ^ x15);
      f = c ^ d ^ e;
      a = rotate5(b) + f + a + delta + x15;
      c = rotate30(c);
  
      a = a + state[0];
      b = b + state[1];
      c = c + state[2];
      d = d + state[3];
      e = e + state[4];
      state[0] = a;
      state[1] = b;
      state[2] = c;
      state[3] = d;
      state[4] = e;
  
      --inblocks;
      in += 16; 
    }
  }
} ;
const char ALPHABET[64] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/_";

#define ALPHABETUSED 32
// has to be a multiple of 4 for vectorization

#define WORDS (64 + 16 * ((sizeof s + sizeof target) / 64))
unsigned int words[WORDS];
uint32x4 wordsx4[WORDS];

int main()
{
  int i;
  int c0;
  int c1;
  int c2;
  int c3;
  int c4;
  int pos;
  long long startcycles = cpucycles();
  long long hashes = 1;
  
  long long targetlen = 0;
  while (target[targetlen]) ++targetlen;
  long long targetblocks = (targetlen + 72) / 64;

  for (i = 0;i < WORDS;++i) words[i] = 0;
  for (i = 0;i < targetlen;++i) ((unsigned char *) words)[i ^ 3] = target[i];
  ((unsigned char *) words)[targetlen ^ 3] = 0x80;
  words[targetblocks * 16 - 1] = targetlen * 8;
  for (i = 0;i < WORDS;++i) wordsx4[i] = words[i];

  hash targethash;
  targethash.init();
  targethash.update(wordsx4,targetblocks);

  cout << 0 << " " << targethash << " " << target << "\n";

  unsigned char flip[sizeof s];

  long long slen = 0;
  while (s[slen]) ++slen;
  if (slen < 5) return 100;
  long long sblocks = (slen + 72) / 64;
  long long sblockspre = (slen - 5) / 64;

#ifndef NONRANDOM
  srandom(cpucycles()); // XXX: randomize better
#endif
  for (i = 0;i < slen;++i) {
    flip[i] = 0;
    if (random() & 1) if (s[i] != ' ') s[i] ^= 32;
  }

  for (i = 0;i < sizeof words;++i) ((unsigned char *) words)[i] = 0;
  ((unsigned char *) words)[slen ^ 3] = 0x80;
  words[sblocks * 16 - 1] = slen * 8;
  for (i = 0;i < slen - 5;++i) ((unsigned char *) words)[i ^ 3] = s[i];

  for (;;) {
    for (i = 0;i < WORDS;++i) wordsx4[i] = words[i];

    hash shashpre;
    shashpre.init();
    shashpre.update(wordsx4,sblockspre);

    for (c0 = 0;c0 < ALPHABETUSED;++c0) {
      int pos = (slen - 5) ^ 3;
      ((unsigned char *) (wordsx4 + pos / 4))[3 & pos] = ALPHABET[c0];
      ((unsigned char *) (wordsx4 + pos / 4))[4 + (3 & pos)] = ALPHABET[c0];
      ((unsigned char *) (wordsx4 + pos / 4))[8 + (3 & pos)] = ALPHABET[c0];
      ((unsigned char *) (wordsx4 + pos / 4))[12 + (3 & pos)] = ALPHABET[c0];
      cout << "cycles/hash " << dec
        << (cpucycles() - startcycles) / hashes << " "
        << (innerloopcycles) / hashes << " "
        << s << "\n";
      for (c1 = 0;c1 < ALPHABETUSED;++c1) {
        pos = (slen - 4) ^ 3;
        ((unsigned char *) (wordsx4 + pos / 4))[3 & pos] = ALPHABET[c1];
        ((unsigned char *) (wordsx4 + pos / 4))[4 + (3 & pos)] = ALPHABET[c1];
        ((unsigned char *) (wordsx4 + pos / 4))[8 + (3 & pos)] = ALPHABET[c1];
        ((unsigned char *) (wordsx4 + pos / 4))[12 + (3 & pos)] = ALPHABET[c1];
        for (c2 = 0;c2 < ALPHABETUSED;++c2) {
          pos = (slen - 3) ^ 3;
          ((unsigned char *) (wordsx4 + pos / 4))[3 & pos] = ALPHABET[c2];
          ((unsigned char *) (wordsx4 + pos / 4))[4 + (3 & pos)] = ALPHABET[c2];
          ((unsigned char *) (wordsx4 + pos / 4))[8 + (3 & pos)] = ALPHABET[c2];
          ((unsigned char *) (wordsx4 + pos / 4))[12 + (3 & pos)] = ALPHABET[c2];
          for (c3 = 0;c3 < ALPHABETUSED;++c3) {
            pos = (slen - 2) ^ 3;
            ((unsigned char *) (wordsx4 + pos / 4))[3 & pos] = ALPHABET[c3];
            ((unsigned char *) (wordsx4 + pos / 4))[4 + (3 & pos)] = ALPHABET[c3];
            ((unsigned char *) (wordsx4 + pos / 4))[8 + (3 & pos)] = ALPHABET[c3];
            ((unsigned char *) (wordsx4 + pos / 4))[12 + (3 & pos)] = ALPHABET[c3];
            innerloopcycles -= cpucycles();
            for (c4 = 0;c4 + 4 <= ALPHABETUSED;c4 += 4) {
              pos = (slen - 1) ^ 3;
              ((unsigned char *) (wordsx4 + pos / 4))[3 & pos] = ALPHABET[c4];
              ((unsigned char *) (wordsx4 + pos / 4))[4 + (3 & pos)] = ALPHABET[c4 + 1];
              ((unsigned char *) (wordsx4 + pos / 4))[8 + (3 & pos)] = ALPHABET[c4 + 2];
              ((unsigned char *) (wordsx4 + pos / 4))[12 + (3 & pos)] = ALPHABET[c4 + 3];

              hash shash(shashpre);
              shash.update(wordsx4 + sblockspre * 16,sblocks - sblockspre);
              uint32x4 d = shash.hammingdistance(targethash);

              if (d.uint0() < 49) {
		pos = (slen - 1) ^ 3;
                ((unsigned char *) (wordsx4 + pos / 4))[3 & pos] = ALPHABET[c4];
                hash shash(shashpre);
                shash.update(wordsx4 + sblockspre * 16,sblocks - sblockspre);
                for (i = 0;i < slen;++i) {
		  pos = i ^ 3;
		  s[i] = ((unsigned char *) (wordsx4 + pos / 4))[3 & pos];
		}
                cout << dec << d.uint0() << " " << shash << " " << s << "\n" << flush;
              }
	      if (d.uint1() < 49) {
		pos = (slen - 1) ^ 3;
                ((unsigned char *) (wordsx4 + pos / 4))[3 & pos] = ALPHABET[c4 + 1];
                hash shash(shashpre);
                shash.update(wordsx4 + sblockspre * 16,sblocks - sblockspre);
                for (i = 0;i < slen;++i) {
		  pos = i ^ 3;
		  s[i] = ((unsigned char *) (wordsx4 + pos / 4))[3 & pos];
		}
                cout << dec << d.uint1() << " " << shash << " " << s << "\n" << flush;
              }
	      if (d.uint2() < 49) {
		pos = (slen - 1) ^ 3;
                ((unsigned char *) (wordsx4 + pos / 4))[3 & pos] = ALPHABET[c4 + 2];
                hash shash(shashpre);
                shash.update(wordsx4 + sblockspre * 16,sblocks - sblockspre);
                for (i = 0;i < slen;++i) {
		  pos = i ^ 3;
		  s[i] = ((unsigned char *) (wordsx4 + pos / 4))[3 & pos];
		}
                cout << dec << d.uint2() << " " << shash << " " << s << "\n" << flush;
              }
	      if (d.uint3() < 49) {
		pos = (slen - 1) ^ 3;
                ((unsigned char *) (wordsx4 + pos / 4))[3 & pos] = ALPHABET[c4 + 3];
                hash shash(shashpre);
                shash.update(wordsx4 + sblockspre * 16,sblocks - sblockspre);
                for (i = 0;i < slen;++i) {
		  pos = i ^ 3;
		  s[i] = ((unsigned char *) (wordsx4 + pos / 4))[3 & pos];
		}
                cout << dec << d.uint3() << " " << shash << " " << s << "\n" << flush;
              }
            }
            innerloopcycles += cpucycles();
            hashes += c4;
          }
        }
      }
    }

    for (i = 0;i < slen - 5;++i) if (s[i] != ' ') {
      ((unsigned char *) words)[i ^ 3] ^= 32;
      flip[i] ^= 32;
      if (flip[i]) break;
    }

    if (i == slen - 5) return 0;
  }
}
