From a663f5b481679d8a352c668825cee92f548f3fcc Mon Sep 17 00:00:00 2001
From: trondeau <trondeau@221aa14e-8319-0410-a670-987f0aec2ac5>
Date: Sun, 10 Jun 2007 18:16:11 +0000
Subject: Merging OFDM features branch r5661:5759 into trunk. OFDM works over
 the air with BPSK and QPSK modulations on subcarriers. Passes make distcheck.

git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@5761 221aa14e-8319-0410-a670-987f0aec2ac5
---
 gnuradio-core/src/lib/general/Makefile.am          |  12 +
 gnuradio-core/src/lib/general/general.i            |   8 +
 gnuradio-core/src/lib/general/gr_delay.cc          |   2 +-
 .../src/lib/general/gr_ofdm_bpsk_mapper.cc         |  73 ++----
 .../src/lib/general/gr_ofdm_bpsk_mapper.h          |  31 +--
 .../src/lib/general/gr_ofdm_bpsk_mapper.i          |  13 +-
 .../src/lib/general/gr_ofdm_correlator.cc          |  38 ++-
 gnuradio-core/src/lib/general/gr_ofdm_correlator.h |  12 +-
 gnuradio-core/src/lib/general/gr_ofdm_correlator.i |   6 +-
 .../src/lib/general/gr_ofdm_frame_sink.cc          |  80 ++++--
 gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h |  40 +--
 gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i |   8 +-
 .../src/lib/general/gr_ofdm_insert_preamble.cc     | 186 ++++++++++++++
 .../src/lib/general/gr_ofdm_insert_preamble.h      | 102 ++++++++
 .../src/lib/general/gr_ofdm_insert_preamble.i      |  35 +++
 .../src/lib/general/gr_ofdm_qam_mapper.cc          | 249 ++++++++++++++++++
 gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.h |  84 ++++++
 gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.i |  46 ++++
 .../src/lib/general/gr_ofdm_qpsk_mapper.cc         | 141 ++++++++++
 .../src/lib/general/gr_ofdm_qpsk_mapper.h          |  76 ++++++
 .../src/lib/general/gr_ofdm_qpsk_mapper.i          |  44 ++++
 gnuradio-core/src/lib/general/gr_ofdm_sampler.cc   |   4 +-
 gnuradio-core/src/lib/general/gr_regenerate_bb.cc  |  74 ++++++
 gnuradio-core/src/lib/general/gr_regenerate_bb.h   |  59 +++++
 gnuradio-core/src/lib/general/gr_regenerate_bb.i   |  31 +++
 gnuradio-core/src/lib/swig/gnuradio.i              |  10 +-
 .../src/python/gnuradio/blksimpl/Makefile.am       |   7 +-
 gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py | 284 +++++++++++++++++++++
 .../src/python/gnuradio/blksimpl/ofdm_pkt.py       | 229 -----------------
 .../src/python/gnuradio/blksimpl/ofdm_receiver.py  |  19 +-
 .../src/python/gnuradio/blksimpl/ofdm_sync.py      | 141 ----------
 .../python/gnuradio/blksimpl/ofdm_sync_fixed.py    |  41 +++
 .../src/python/gnuradio/blksimpl/ofdm_sync_ml.py   | 135 ++++++++++
 .../src/python/gnuradio/blksimpl/ofdm_sync_pn.py   | 135 ++++++++++
 .../src/python/gnuradio/blksimpl/ofdm_sync_pnac.py | 126 +++++++++
 gnuradio-core/src/python/gnuradio/gr/Makefile.am   |   1 +
 .../python/gnuradio/gr/qa_ofdm_insert_preamble.py  | 179 +++++++++++++
 .../src/python/gnuradio/ofdm_packet_utils.py       |  19 +-
 gnuradio-core/src/python/gnuradio/packet_utils.py  |   4 +-
 39 files changed, 2260 insertions(+), 524 deletions(-)
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.cc
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.h
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.i
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.cc
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.h
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.i
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.h
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.i
 create mode 100644 gnuradio-core/src/lib/general/gr_regenerate_bb.cc
 create mode 100644 gnuradio-core/src/lib/general/gr_regenerate_bb.h
 create mode 100644 gnuradio-core/src/lib/general/gr_regenerate_bb.i
 create mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py
 delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/ofdm_pkt.py
 delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync.py
 create mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_fixed.py
 create mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_ml.py
 create mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pn.py
 create mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pnac.py
 create mode 100755 gnuradio-core/src/python/gnuradio/gr/qa_ofdm_insert_preamble.py

(limited to 'gnuradio-core/src')

diff --git a/gnuradio-core/src/lib/general/Makefile.am b/gnuradio-core/src/lib/general/Makefile.am
index d774baa1c5..35aac0a22f 100644
--- a/gnuradio-core/src/lib/general/Makefile.am
+++ b/gnuradio-core/src/lib/general/Makefile.am
@@ -102,7 +102,10 @@ libgeneral_la_SOURCES = 		\
         gr_ofdm_mapper_bcv.cc           \
         gr_ofdm_bpsk_demapper.cc        \
         gr_ofdm_bpsk_mapper.cc          \
+        gr_ofdm_qpsk_mapper.cc          \
+        gr_ofdm_qam_mapper.cc	        \
 	gr_ofdm_frame_sink.cc		\
+	gr_ofdm_insert_preamble.cc	\
         gr_ofdm_sampler.cc              \
 	gr_pa_2x2_phase_combiner.cc	\
 	gr_packet_sink.cc		\
@@ -121,6 +124,7 @@ libgeneral_la_SOURCES = 		\
 	gr_pwr_squelch_ff.cc		\
 	gr_quadrature_demod_cf.cc	\
 	gr_random.cc			\
+	gr_regenerate_bb.cc		\
 	gr_remez.cc			\
 	gr_reverse.cc			\
 	gr_rms_cf.cc			\
@@ -240,8 +244,11 @@ grinclude_HEADERS = 			\
         gr_ofdm_demapper_vcb.h          \
         gr_ofdm_mapper_bcv.h            \
         gr_ofdm_bpsk_mapper.h           \
+        gr_ofdm_qpsk_mapper.h		\
+        gr_ofdm_qam_mapper.h		\
         gr_ofdm_bpsk_demapper.h         \
         gr_ofdm_frame_sink.h		\
+	gr_ofdm_insert_preamble.h	\
 	gr_ofdm_sampler.h               \
 	gr_pa_2x2_phase_combiner.h	\
 	gr_packet_sink.h		\
@@ -260,6 +267,7 @@ grinclude_HEADERS = 			\
 	gr_pwr_squelch_ff.h		\
 	gr_quadrature_demod_cf.h	\
 	gr_random.h			\
+	gr_regenerate_bb.h		\
 	gr_remez.h			\
 	gr_reverse.h			\
 	gr_rms_cf.h			\
@@ -381,7 +389,10 @@ swiginclude_HEADERS =			\
         gr_ofdm_mapper_bcv.i            \
         gr_ofdm_bpsk_demapper.i         \
         gr_ofdm_bpsk_mapper.i           \
+        gr_ofdm_qpsk_mapper.i	        \
+        gr_ofdm_qam_mapper.i	        \
         gr_ofdm_frame_sink.i		\
+	gr_ofdm_insert_preamble.i	\
 	gr_ofdm_sampler.i               \
 	gr_pa_2x2_phase_combiner.i	\
 	gr_packet_sink.i		\
@@ -399,6 +410,7 @@ swiginclude_HEADERS =			\
 	gr_pwr_squelch_cc.i		\
 	gr_pwr_squelch_ff.i		\
 	gr_quadrature_demod_cf.i	\
+	gr_regenerate_bb.i		\
 	gr_remez.i			\
 	gr_rms_cf.i			\
 	gr_rms_ff.i			\
diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i
index 1fdb4239a6..b362d24d05 100644
--- a/gnuradio-core/src/lib/general/general.i
+++ b/gnuradio-core/src/lib/general/general.i
@@ -97,8 +97,12 @@
 #include <gr_ofdm_cyclic_prefixer.h>
 #include <gr_ofdm_bpsk_demapper.h>
 #include <gr_ofdm_bpsk_mapper.h>
+#include <gr_ofdm_qpsk_mapper.h>
+#include <gr_ofdm_qam_mapper.h>
 #include <gr_ofdm_frame_sink.h>
+#include <gr_ofdm_insert_preamble.h>
 #include <gr_ofdm_sampler.h>
+#include <gr_regenerate_bb.h>
 #include <gr_costas_loop_cc.h>
 #include <gr_pa_2x2_phase_combiner.h>
 #include <gr_kludge_copy.h>
@@ -200,8 +204,12 @@
 %include "gr_ofdm_cyclic_prefixer.i"
 %include "gr_ofdm_bpsk_demapper.i"
 %include "gr_ofdm_bpsk_mapper.i"
+%include "gr_ofdm_qpsk_mapper.i"
+%include "gr_ofdm_qam_mapper.i"
 %include "gr_ofdm_frame_sink.i"
+%include "gr_ofdm_insert_preamble.i"
 %include "gr_ofdm_sampler.i"
+%include "gr_regenerate_bb.i"
 %include "gr_costas_loop_cc.i"
 %include "gr_pa_2x2_phase_combiner.i"
 %include "gr_kludge_copy.i"
diff --git a/gnuradio-core/src/lib/general/gr_delay.cc b/gnuradio-core/src/lib/general/gr_delay.cc
index 89ab3ce0e0..73b61a9a0c 100644
--- a/gnuradio-core/src/lib/general/gr_delay.cc
+++ b/gnuradio-core/src/lib/general/gr_delay.cc
@@ -52,7 +52,7 @@ gr_delay::work (int noutput_items,
   const char *iptr;
   char *optr;
 
-  for(int i = 0; i < input_items.size(); i++) {
+  for(size_t i = 0; i < input_items.size(); i++) {
     iptr = (const char *) input_items[i];
     optr = (char *) output_items[i];
 
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
index f0b52c3255..5b4631227c 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
@@ -26,23 +26,18 @@
 
 #include <gr_ofdm_bpsk_mapper.h>
 #include <gr_io_signature.h>
-#include <vector>
+#include <stdexcept>
 
 gr_ofdm_bpsk_mapper_sptr
 gr_make_ofdm_bpsk_mapper (unsigned int msgq_limit, 
-			  unsigned int occupied_carriers, unsigned int fft_length,
-			  const std::vector<gr_complex> &known_symbol1, 
-			  const std::vector<gr_complex> &known_symbol2)
+			  unsigned int occupied_carriers, unsigned int fft_length)
 {
-  return gr_ofdm_bpsk_mapper_sptr (new gr_ofdm_bpsk_mapper (msgq_limit, occupied_carriers, fft_length, 
-							    known_symbol1, known_symbol2));
+  return gr_ofdm_bpsk_mapper_sptr (new gr_ofdm_bpsk_mapper (msgq_limit, occupied_carriers, fft_length));
 }
 
 // Consumes 1 packet and produces as many OFDM symbols of fft_length to hold the full packet
 gr_ofdm_bpsk_mapper::gr_ofdm_bpsk_mapper (unsigned int msgq_limit, 
-					  unsigned int occupied_carriers, unsigned int fft_length,
-					  const std::vector<gr_complex> &known_symbol1, 
-					  const std::vector<gr_complex> &known_symbol2)
+					  unsigned int occupied_carriers, unsigned int fft_length)
   : gr_sync_block ("ofdm_bpsk_mapper",
 		   gr_make_io_signature (0, 0, 0),
 		   gr_make_io_signature2 (1, 2, sizeof(gr_complex)*fft_length, sizeof(char))),
@@ -50,20 +45,18 @@ gr_ofdm_bpsk_mapper::gr_ofdm_bpsk_mapper (unsigned int msgq_limit,
     d_occupied_carriers(occupied_carriers),
     d_fft_length(fft_length),
     d_bit_offset(0),
-    d_header_sent(0),
-    d_known_symbol1(known_symbol1),
-    d_known_symbol2(known_symbol2)
+    d_pending_flag(0)
 {
-  assert(d_occupied_carriers <= d_fft_length);
-  assert(d_occupied_carriers == d_known_symbol1.size());
-  assert(d_occupied_carriers == d_known_symbol2.size());
+  if (!(d_occupied_carriers <= d_fft_length))
+    throw std::invalid_argument("gr_ofdm_bpsk_mapper: occupied carriers must be <= fft_length");
 }
 
 gr_ofdm_bpsk_mapper::~gr_ofdm_bpsk_mapper(void)
 {
 }
 
-float randombit()
+static float
+randombit()
 {
   int r = rand()&1;
   return (float)(-1 + 2*r);
@@ -90,47 +83,25 @@ gr_ofdm_bpsk_mapper::work(int noutput_items,
     d_msg = d_msgq->delete_head();	   // block, waiting for a message
     d_msg_offset = 0;
     d_bit_offset = 0;
-    d_header_sent = 0;
+    d_pending_flag = 1;			   // new packet, write start of packet flag
     
     if((d_msg->length() == 0) && (d_msg->type() == 1)) {
       d_msg.reset();
-      return -1;
+      return -1;		// We're done; no more messages coming.
     }
   }
 
-  if(output_items.size() == 2) {
-    char *sig = (char *)output_items[1];
-    if(d_header_sent == 1) {
-      sig[0] = 1;
-    }
-    else {
-      sig[0] = 0;
-    }
-  }
+  char *out_flag = 0;
+  if(output_items.size() == 2)
+    out_flag = (char *) output_items[1];
   
+
   // Build a single symbol:
+  
 
   // Initialize all bins to 0 to set unused carriers
   memset(out, 0, d_fft_length*sizeof(gr_complex));
   
-  if(d_header_sent == 0) {
-     for(i=0; i < d_occupied_carriers; i++) {
-       out[i+zeros_on_left] = d_known_symbol1[i];
-     }
-    d_header_sent++;
-
-    return 1;
-  }
-  
-  if(d_header_sent == 1) {
-    for(i=0; i < d_occupied_carriers; i++) {
-      out[i+zeros_on_left] = d_known_symbol2[i];
-    }
-    d_header_sent++;
-
-    return 1;
-  }
-
   i = 0;
   while((d_msg_offset < d_msg->length()) && (i < d_occupied_carriers)) {
     unsigned char bit = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
@@ -150,14 +121,16 @@ gr_ofdm_bpsk_mapper::work(int noutput_items,
       i++;
     }
 
-    if (d_msg->type() == 1)	           // type == 1 sets EOF
+    if (d_msg->type() == 1)	        // type == 1 sets EOF
       d_eof = true;
-    d_msg.reset();   // finished packet, free message
- 
+    d_msg.reset();   			// finished packet, free message
     assert(d_bit_offset == 0);
-    return 1;          // produced one symbol
   }
-  
+
+  if (out_flag)
+    out_flag[0] = d_pending_flag;
+  d_pending_flag = 0;
+
   return 1;  // produced symbol
 }
 
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h
index 41b2f5bede..da78ca4753 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h
+++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -27,19 +27,16 @@
 #include <gr_sync_block.h>
 #include <gr_message.h>
 #include <gr_msg_queue.h>
-#include <vector>
 
 class gr_ofdm_bpsk_mapper;
 typedef boost::shared_ptr<gr_ofdm_bpsk_mapper> gr_ofdm_bpsk_mapper_sptr;
 
 gr_ofdm_bpsk_mapper_sptr 
 gr_make_ofdm_bpsk_mapper (unsigned msgq_limit, 
-			  unsigned occupied_carriers, unsigned int fft_length,
-			  const std::vector<gr_complex> &known_symbol1, 
-			  const std::vector<gr_complex> &known_symbol2);
+			  unsigned occupied_carriers, unsigned int fft_length);
 
 /*!
- * \brief take a stream of bytes in and map to a vector of complex
+ * \brief take a message in and map to a vector of complex
  * constellation points suitable for IFFT input to be used in an ofdm
  * modulator.  Simple BPSK version.
  */
@@ -47,28 +44,22 @@ gr_make_ofdm_bpsk_mapper (unsigned msgq_limit,
 class gr_ofdm_bpsk_mapper : public gr_sync_block
 {
   friend gr_ofdm_bpsk_mapper_sptr
-    gr_make_ofdm_bpsk_mapper (unsigned msgq_limit, 
-			      unsigned occupied_carriers, unsigned int fft_length,
-			      const std::vector<gr_complex> &known_symbol1, 
-			      const std::vector<gr_complex> &known_symbol2);
-  
+  gr_make_ofdm_bpsk_mapper (unsigned msgq_limit, 
+			    unsigned occupied_carriers, unsigned int fft_length);
  protected:
   gr_ofdm_bpsk_mapper (unsigned msgq_limit, 
-		       unsigned occupied_carriers, unsigned int fft_length,
-		       const std::vector<gr_complex> &known_symbol1, 
-		       const std::vector<gr_complex> &known_symbol2);
-  
+		       unsigned occupied_carriers, unsigned int fft_length);
+
  private:
   gr_msg_queue_sptr	d_msgq;
   gr_message_sptr	d_msg;
   unsigned		d_msg_offset;
   bool			d_eof;
   
-  unsigned int d_occupied_carriers;
-  unsigned int d_fft_length;
-  unsigned int d_bit_offset;
-  unsigned int d_header_sent;
-  std::vector<gr_complex> d_known_symbol1, d_known_symbol2;
+  unsigned int 		d_occupied_carriers;
+  unsigned int 		d_fft_length;
+  unsigned int 		d_bit_offset;
+  int			d_pending_flag;
 
  public:
   ~gr_ofdm_bpsk_mapper(void);
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i
index d0094062a6..2af37d641e 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i
+++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2006 Free Software Foundation, Inc.
+ * Copyright 2006,2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -20,25 +20,20 @@
  * Boston, MA 02110-1301, USA.
  */
 
-#include <vector>
-
 GR_SWIG_BLOCK_MAGIC(gr,ofdm_bpsk_mapper);
 
 gr_ofdm_bpsk_mapper_sptr 
 gr_make_ofdm_bpsk_mapper (unsigned int msgq_limit,
 			  unsigned int bits_per_symbol, 
-			  unsigned int fft_length,
-			  const std::vector<gr_complex> &known_symbol1, 
-			  const std::vector<gr_complex> &known_symbol2);
+			  unsigned int fft_length);
+
 
 class gr_ofdm_bpsk_mapper : public gr_sync_block
 {
  protected:
   gr_ofdm_bpsk_mapper (unsigned int msgq_limit,
 		       unsigned int bits_per_symbol,
-		       unsigned int fft_length,
-		       const std::vector<gr_complex> &known_symbol1, 
-		       const std::vector<gr_complex> &known_symbol2);
+		       unsigned int fft_length);
 
  public:
   gr_msg_queue_sptr msgq();
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc b/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
index 3973b83749..4eb6626a17 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
@@ -30,28 +30,32 @@
 
 #define VERBOSE 0
 #define M_TWOPI (2*M_PI)
+#define MAX_NUM_SYMBOLS 1000
 
 gr_ofdm_correlator_sptr
 gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length, 
 			 unsigned int cplen,
 			 const std::vector<gr_complex> &known_symbol1, 
-			 const std::vector<gr_complex> &known_symbol2)
+			 const std::vector<gr_complex> &known_symbol2,
+			 unsigned int max_fft_shift_len)
 {
   return gr_ofdm_correlator_sptr (new gr_ofdm_correlator (occupied_carriers, fft_length, cplen,
-							  known_symbol1, known_symbol2));
+							  known_symbol1, known_symbol2,
+							  max_fft_shift_len));
 }
 
 gr_ofdm_correlator::gr_ofdm_correlator (unsigned occupied_carriers, unsigned int fft_length, 
 					unsigned int cplen,
 					const std::vector<gr_complex> &known_symbol1, 
-					const std::vector<gr_complex> &known_symbol2)
+					const std::vector<gr_complex> &known_symbol2,
+					unsigned int max_fft_shift_len)
   : gr_block ("ofdm_correlator",
 	      gr_make_io_signature (1, 1, sizeof(gr_complex)*fft_length),
 	      gr_make_io_signature2 (2, 2, sizeof(gr_complex)*occupied_carriers, sizeof(char))),
     d_occupied_carriers(occupied_carriers),
     d_fft_length(fft_length),
     d_cplen(cplen),
-    d_freq_shift_len(5),
+    d_freq_shift_len(max_fft_shift_len),
     d_known_symbol1(known_symbol1),
     d_known_symbol2(known_symbol2),
     d_coarse_freq(0),
@@ -62,16 +66,24 @@ gr_ofdm_correlator::gr_ofdm_correlator (unsigned occupied_carriers, unsigned int
 
   std::vector<gr_complex>::iterator i1, i2;
 
-  int i = 0;
+  unsigned int i = 0, j = 0;
   gr_complex one(1.0, 0.0);
   for(i1 = d_known_symbol1.begin(), i2 = d_known_symbol2.begin(); i1 != d_known_symbol1.end(); i1++, i2++) {
     d_diff_corr_factor[i] = one / ((*i1) * conj(*i2));
     i++;
   }
+  
+  d_phase_lut = new gr_complex[(2*d_freq_shift_len+1) * MAX_NUM_SYMBOLS];
+  for(i = 0; i <= 2*d_freq_shift_len; i++) {
+    for(j = 0; j < MAX_NUM_SYMBOLS; j++) {
+      d_phase_lut[j + i*MAX_NUM_SYMBOLS] =  gr_expj(-M_TWOPI*d_cplen/d_fft_length*(i-d_freq_shift_len)*j);
+    }
+  }
 }
 
 gr_ofdm_correlator::~gr_ofdm_correlator(void)
 {
+  delete [] d_phase_lut;
 }
 
 void
@@ -87,7 +99,12 @@ gr_ofdm_correlator::coarse_freq_comp(int freq_delta, int symbol_count)
 {
   //  return gr_complex(cos(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count),
   //	    sin(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count));
-  return gr_expj(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count);
+  //return gr_expj(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count);
+
+  assert(d_freq_shift_len + freq_delta >= 0);
+  assert(symbol_count <= MAX_NUM_SYMBOLS);
+
+  return d_phase_lut[MAX_NUM_SYMBOLS * (d_freq_shift_len + freq_delta) + symbol_count];
 }
 
 bool
@@ -132,14 +149,17 @@ gr_ofdm_correlator::correlate(const gr_complex *previous, const gr_complex *curr
 	d_snr_est = 10*log10(fabs(h_sqrd.real()/h_sqrd.imag()));
       }
 
+#if VERBOSE
       printf("CORR: Found, bin %d\tSNR Est %f dB\tcorr power fraction %f\n", 
              search_delta, d_snr_est, h_sqrd.real()/power);
+#endif
+
       // search_delta,10*log10(h_sqrd.real()/fabs(h_sqrd.imag())),h_sqrd.real()/power);
       break;
     }
     else {
       if(search_delta <= 0)
-	search_delta = (-search_delta) + 1;
+	search_delta = (-search_delta) + 2;
       else
 	search_delta = -search_delta;
     }
@@ -161,10 +181,6 @@ gr_ofdm_correlator::calculate_equalizer(const gr_complex *previous, const gr_com
     d_hestimate[i] = 0.5F * (d_known_symbol1[i] / previous[i+zeros_on_left+d_coarse_freq] +
 			     d_known_symbol2[i] / (coarse_freq_comp(d_coarse_freq,1)*
 						   current[i+zeros_on_left+d_coarse_freq]));
-    
-#if VERBOSE
-    fprintf(stderr, "%f %f ", d_hestimate[i].real(), d_hestimate[i].imag());
-#endif
   }
 #if VERBOSE
   fprintf(stderr, "\n");
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_correlator.h b/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
index 44a6847af3..36aa1f0b69 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
+++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
@@ -34,7 +34,8 @@ gr_ofdm_correlator_sptr
 gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length,
 			 unsigned int cplen,
 			 const std::vector<gr_complex> &known_symbol1, 
-			 const std::vector<gr_complex> &known_symbol2);
+			 const std::vector<gr_complex> &known_symbol2,
+			 unsigned int max_fft_shift_len=4);
 
 /*!
  * \brief take a vector of complex constellation points in from an FFT
@@ -65,18 +66,21 @@ class gr_ofdm_correlator : public gr_block
    *                            start of a frame after known_symbol1 (usually a BPSK PN sequence). 
    *                            Both of these start symbols are differentially correlated to compensate
    *                            for phase changes between symbols. 
+   * \param max_fft_shift_len   Set's the maximum distance you can look between bins for correlation
    */
   friend gr_ofdm_correlator_sptr
   gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length,
 			   unsigned int cplen,
 			   const std::vector<gr_complex> &known_symbol1, 
-			   const std::vector<gr_complex> &known_symbol2);
+			   const std::vector<gr_complex> &known_symbol2,
+			   unsigned int max_fft_shift_len);
   
  protected:
   gr_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length,
 		      unsigned int cplen,
 		      const std::vector<gr_complex> &known_symbol1, 
-		      const std::vector<gr_complex> &known_symbol2);
+		      const std::vector<gr_complex> &known_symbol2,
+		      unsigned int max_fft_shift_len);
   
  private:
   unsigned char slicer(gr_complex x);
@@ -96,6 +100,8 @@ class gr_ofdm_correlator : public gr_block
   unsigned int d_phase_count;           // !< \brief accumulator for coarse freq correction
   float d_snr_est;                      // !< an estimation of the signal to noise ratio
 
+  gr_complex *d_phase_lut;  // !< look-up table for coarse frequency compensation
+
   void forecast(int noutput_items, gr_vector_int &ninput_items_required);
 
  public:
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_correlator.i b/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
index 40f9f83ff8..700faaa097 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
+++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
@@ -29,7 +29,8 @@ gr_make_ofdm_correlator (unsigned int occupied_carriers,
 			 unsigned int fft_length,
 			 unsigned int cplen,
 			 const std::vector<gr_complex> &known_symbol1, 
-			 const std::vector<gr_complex> &known_symbol2);
+			 const std::vector<gr_complex> &known_symbol2,
+			 unsigned int max_fft_shift_len=4);
 
 class gr_ofdm_correlator : public gr_sync_decimator
 {
@@ -38,7 +39,8 @@ class gr_ofdm_correlator : public gr_sync_decimator
 		      unsigned int fft_length,
 		      unsigned int cplen,
 		      const std::vector<gr_complex> &known_symbol1, 
-		      const std::vector<gr_complex> &known_symbol2);
+		      const std::vector<gr_complex> &known_symbol2,
+		      unsigned int max_fft_shift_len);
 
  public:
   float snr() { return d_snr_est; }
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
index acaf1258bd..c04aca3d7a 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
@@ -79,6 +79,14 @@ unsigned char gr_ofdm_frame_sink::bpsk_slicer(gr_complex x)
   return (unsigned char)(x.real() > 0 ? 1 : 0);
 }
 
+unsigned char gr_ofdm_frame_sink::qpsk_slicer(gr_complex x)
+{
+  unsigned char i = (x.real() > 0 ? 1 : 0);
+  unsigned char q = (x.imag() > 0 ? 1 : 0);
+
+  return (q << 1) | i;
+}
+
 unsigned int gr_ofdm_frame_sink::bpsk_demapper(const gr_complex *in,
 					       unsigned char *out)
 {
@@ -101,23 +109,56 @@ unsigned int gr_ofdm_frame_sink::bpsk_demapper(const gr_complex *in,
   return bytes_produced;
 }
 
+unsigned int gr_ofdm_frame_sink::qpsk_demapper(const gr_complex *in,
+					       unsigned char *out)
+{
+  unsigned int i=0, bytes_produced=0;
 
+  while(i < d_occupied_carriers) {
+    
+    while((d_byte_offset < 8) && (i < d_occupied_carriers)) {
+      //fprintf(stderr, "%f+j%f\n", in[i].real(), in[i].imag()); 
+      d_partial_byte |= qpsk_slicer(in[i++]) << (d_byte_offset);
+      d_byte_offset += 2;
+    }
+
+    if(d_byte_offset == 8) {
+      out[bytes_produced++] = d_partial_byte;
+      d_byte_offset = 0;
+      d_partial_byte = 0;
+    }
+  }
+
+  return bytes_produced;
+}
 
 gr_ofdm_frame_sink_sptr
-gr_make_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_carriers)
+gr_make_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_carriers,
+			const std::string &mod)
 {
-  return gr_ofdm_frame_sink_sptr(new gr_ofdm_frame_sink(target_queue, occupied_carriers));
+  return gr_ofdm_frame_sink_sptr(new gr_ofdm_frame_sink(target_queue, occupied_carriers, mod));
 }
 
 
-gr_ofdm_frame_sink::gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_carriers)
+gr_ofdm_frame_sink::gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_carriers,
+				       const std::string &mod)
   : gr_sync_block ("ofdm_frame_sink",
 		   gr_make_io_signature2 (2, 2, sizeof(gr_complex)*occupied_carriers, sizeof(char)),
 		   gr_make_io_signature (0, 0, 0)),
     d_target_queue(target_queue), d_occupied_carriers(occupied_carriers), 
     d_byte_offset(0), d_partial_byte(0)
 {
-  d_bytes_out = new unsigned char[(int)ceil(d_occupied_carriers/8.0)];
+  d_bytes_out = new unsigned char[(int)ceil(d_occupied_carriers/4.0)];
+
+  if(mod == "qpsk") {
+    d_demapper = &gr_ofdm_frame_sink::qpsk_demapper;
+  }
+  else if(mod == "bpsk") {
+    d_demapper = &gr_ofdm_frame_sink::bpsk_demapper;
+  }
+  else {
+    throw std::invalid_argument("Modulation type must be BPSK or QPSK.");  
+  }
 
   enter_search();
 }
@@ -134,15 +175,15 @@ gr_ofdm_frame_sink::work (int noutput_items,
 {
   const gr_complex *in = (const gr_complex *) input_items[0];
   const char *sig = (const char *) input_items[1];
-  int count_tones=0, count_items=0;
   unsigned int j = 0;
   unsigned int bytes=0;
   
   if (VERBOSE)
     fprintf(stderr,">>> Entering state machine\n");
   
-  bytes = bpsk_demapper(&in[0], d_bytes_out);
-  
+  //bytes = bpsk_demapper(&in[0], d_bytes_out);
+  bytes = (this->*d_demapper)(&in[0], d_bytes_out);  
+
   switch(d_state) {
       
   case STATE_SYNC_SEARCH:    // Look for flag indicating beginning of pkt
@@ -155,12 +196,13 @@ gr_ofdm_frame_sink::work (int noutput_items,
     break;
 
   case STATE_HAVE_SYNC:
-    if(sig[0])
-      printf("ERROR -- Found SYNC in HAVE_SYNC\n");
-    if (VERBOSE)
+    if (VERBOSE) {
+      if(sig[0])
+	printf("ERROR -- Found SYNC in HAVE_SYNC\n");
       fprintf(stderr,"Header Search bitcnt=%d, header=0x%08x\n",
 	      d_headerbytelen_cnt, d_header);
-    
+    }
+
     j = 0;
     while(j < bytes) {
       d_header = (d_header << 8) | (d_bytes_out[j] & 0xFF);
@@ -174,10 +216,9 @@ gr_ofdm_frame_sink::work (int noutput_items,
 	// we have a full header, check to see if it has been received properly
 	if (header_ok()){
 	  enter_have_header();
-	  printf("\nPacket Length: %d\n", d_packetlen);
-	  //for(int k=0; k < d_packetlen; k++)
-	  //  printf("%02x", d_packet[k]);
-	  //printf("\n");
+	  
+	  if (VERBOSE)
+	    printf("\nPacket Length: %d\n", d_packetlen);
 	  
 	  while((j < bytes) && (d_packetlen_cnt < d_packetlen)) {
 	    d_packet[d_packetlen_cnt++] = d_bytes_out[j++];
@@ -201,10 +242,11 @@ gr_ofdm_frame_sink::work (int noutput_items,
     break;
       
   case STATE_HAVE_HEADER:
-    if(sig[0])
-      printf("ERROR -- Found SYNC in HAVE_HEADER at %d, length of %d\n", d_packetlen_cnt, d_packetlen);
-    if (VERBOSE)
-	fprintf(stderr,"Packet Build\n");
+    if (VERBOSE) {
+      if(sig[0])
+	printf("ERROR -- Found SYNC in HAVE_HEADER at %d, length of %d\n", d_packetlen_cnt, d_packetlen);
+      fprintf(stderr,"Packet Build\n");
+    }
     
     j = 0;
     while(j < bytes) {
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
index d77c76741e..8f38abb04b 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
+++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2005,2006 Free Software Foundation, Inc.
+ * Copyright 2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -30,30 +30,22 @@ class gr_ofdm_frame_sink;
 typedef boost::shared_ptr<gr_ofdm_frame_sink> gr_ofdm_frame_sink_sptr;
 
 gr_ofdm_frame_sink_sptr 
-gr_make_ofdm_frame_sink (gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
+gr_make_ofdm_frame_sink (gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
+			 const std::string &mod);
 
 /*!
- * \brief Given a stream of bits and access_code flags, assemble packets.
- * \ingroup sink
- *
- * input: stream of bytes from gr_correlate_access_code_bb
- * output: none.  Pushes assembled packet into target queue
- *
- * The framer expects a fixed length header of 2 16-bit shorts
- * containing the payload length, followed by the payload.  If the 
- * 2 16-bit shorts are not identical, this packet is ignored.  Better
- * algs are welcome.
- *
- * The input data consists of bytes that have two bits used.
- * Bit 0, the LSB, contains the data bit.
- * Bit 1 if set, indicates that the corresponding bit is the
- * the first bit of the packet.  That is, this bit is the first
- * one after the access code.
+ * \brief Takes an OFDM symbol in, demaps it into bits of 0's and 1's, packs
+ * them into packets, and sends to to a message queue sink.
+
+ * NOTE: The mod input parameter simply chooses a pre-defined demapper/slicer. Eventually,
+ * we want to be able to pass in a reference to an object to do the demapping and slicing
+ * for a given modulation type.
  */
 class gr_ofdm_frame_sink : public gr_sync_block
 {
   friend gr_ofdm_frame_sink_sptr 
-  gr_make_ofdm_frame_sink (gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
+  gr_make_ofdm_frame_sink (gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
+			   const std::string &mod);
 
  private:
   enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER};
@@ -78,7 +70,8 @@ class gr_ofdm_frame_sink : public gr_sync_block
   int		     d_packetlen_cnt;		// how many so far
 
  protected:
-  gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
+  gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
+		     const std::string &mod);
 
   void enter_search();
   void enter_have_sync();
@@ -94,6 +87,13 @@ class gr_ofdm_frame_sink : public gr_sync_block
   unsigned int bpsk_demapper(const gr_complex *in,
 			     unsigned char *out);  
 
+  unsigned char qpsk_slicer(gr_complex x);
+  unsigned int qpsk_demapper(const gr_complex *in,
+			     unsigned char *out);
+
+  // pointer to mod-specific demapper
+  unsigned int (gr_ofdm_frame_sink::*d_demapper)(const gr_complex *in, unsigned char *out);
+
  public:
   ~gr_ofdm_frame_sink();
 
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
index b05c8b795c..32a0ec9fdf 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
+++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2006 Free Software Foundation, Inc.
+ * Copyright 2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -23,12 +23,14 @@
 GR_SWIG_BLOCK_MAGIC(gr,ofdm_frame_sink);
 
 gr_ofdm_frame_sink_sptr 
-gr_make_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
+gr_make_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
+			const std::string &mod);
 
 class gr_ofdm_frame_sink : public gr_sync_block
 {
  protected:
-  gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
+  gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
+		     const std::string &mod);
 
  public:
   ~gr_ofdm_frame_sink();
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.cc b/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.cc
new file mode 100644
index 0000000000..41b23fcd55
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.cc
@@ -0,0 +1,186 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_ofdm_insert_preamble.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+gr_ofdm_insert_preamble_sptr
+gr_make_ofdm_insert_preamble(int fft_length,
+			     const std::vector<std::vector<gr_complex> > &preamble)
+{
+  return gr_ofdm_insert_preamble_sptr(new gr_ofdm_insert_preamble(fft_length,
+								  preamble));
+}
+
+gr_ofdm_insert_preamble::gr_ofdm_insert_preamble
+       (int fft_length,
+	const std::vector<std::vector<gr_complex> > &preamble)
+  : gr_block("ofdm_insert_preamble",
+	     gr_make_io_signature2(2, 2,
+				   sizeof(gr_complex)*fft_length,
+				   sizeof(char)),
+	     gr_make_io_signature2(1, 2,
+				   sizeof(gr_complex)*fft_length,
+				   sizeof(char))),
+    d_fft_length(fft_length),
+    d_preamble(preamble),
+    d_state(ST_IDLE),
+    d_nsymbols_output(0),
+    d_pending_flag(0)
+{
+  // sanity check preamble symbols
+  for (size_t i = 0; i < d_preamble.size(); i++){
+    if (d_preamble[i].size() != (size_t) d_fft_length)
+      throw std::invalid_argument("gr_ofdm_insert_preamble: invalid length for preamble symbol");
+  }
+
+  enter_idle();
+}
+
+
+gr_ofdm_insert_preamble::~gr_ofdm_insert_preamble()
+{
+}
+
+int
+gr_ofdm_insert_preamble::general_work (int noutput_items,
+				       gr_vector_int &ninput_items_v,
+				       gr_vector_const_void_star &input_items,
+				       gr_vector_void_star &output_items)
+{
+  int ninput_items = std::min(ninput_items_v[0], ninput_items_v[1]);
+  const gr_complex *in_sym = (const gr_complex *) input_items[0];
+  const unsigned char *in_flag = (const unsigned char *) input_items[1];
+
+  gr_complex *out_sym = (gr_complex *) output_items[0];
+  unsigned char *out_flag = 0;
+  if (output_items.size() == 2)
+    out_flag = (unsigned char *) output_items[1];
+
+
+  int no = 0;	// number items output
+  int ni = 0;	// number items read from input
+
+
+#define write_out_flag() 			\
+  do { if (out_flag) 				\
+          out_flag[no] = d_pending_flag; 	\
+       d_pending_flag = 0; 			\
+  } while(0)
+
+
+  while (no < noutput_items && ni < ninput_items){
+    switch(d_state){
+    case ST_IDLE:
+      if (in_flag[ni] & 0x1)	// this is first symbol of new payload
+	enter_preamble();
+      else
+	ni++;			// eat one input symbol
+      break;
+      
+    case ST_PREAMBLE:
+      assert(in_flag[ni] & 0x1);
+      if (d_nsymbols_output >= (int) d_preamble.size()){
+	// we've output all the preamble
+	enter_first_payload();
+      }
+      else {
+	memcpy(&out_sym[no * d_fft_length],
+	       &d_preamble[d_nsymbols_output][0],
+	       d_fft_length*sizeof(gr_complex));
+
+	write_out_flag();
+	no++;
+	d_nsymbols_output++;
+      }
+      break;
+      
+    case ST_FIRST_PAYLOAD:
+      // copy first payload symbol from input to output
+      memcpy(&out_sym[no * d_fft_length],
+	     &in_sym[ni * d_fft_length],
+	     d_fft_length * sizeof(gr_complex));
+
+      write_out_flag();
+      no++;
+      ni++;
+      enter_payload();
+      break;
+      
+    case ST_PAYLOAD:
+      if (in_flag[ni] & 0x1){	// this is first symbol of a new payload
+	enter_preamble();
+	break;
+      }
+
+      // copy a symbol from input to output
+      memcpy(&out_sym[no * d_fft_length],
+	     &in_sym[ni * d_fft_length],
+	     d_fft_length * sizeof(gr_complex));
+
+      write_out_flag();
+      no++;
+      ni++;
+      break;
+
+    default:
+      std::cerr << "gr_ofdm_insert_preamble: (can't happen) invalid state, resetting\n";
+      enter_idle();
+    }
+  }
+
+  consume_each(ni);
+  return no;
+}
+
+void
+gr_ofdm_insert_preamble::enter_idle()
+{
+  d_state = ST_IDLE;
+  d_nsymbols_output = 0;
+  d_pending_flag = 0;
+}
+
+void
+gr_ofdm_insert_preamble::enter_preamble()
+{
+  d_state = ST_PREAMBLE;
+  d_nsymbols_output = 0;
+  d_pending_flag = 1;
+}
+
+void
+gr_ofdm_insert_preamble::enter_first_payload()
+{
+  d_state = ST_FIRST_PAYLOAD;
+}
+
+void
+gr_ofdm_insert_preamble::enter_payload()
+{
+  d_state = ST_PAYLOAD;
+}
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.h b/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.h
new file mode 100644
index 0000000000..48622b06d9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.h
@@ -0,0 +1,102 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_GR_OFDM_INSERT_PREAMBLE_H
+#define INCLUDED_GR_OFDM_INSERT_PREAMBLE_H
+
+#include <gr_block.h>
+#include <vector>
+
+class gr_ofdm_insert_preamble;
+typedef boost::shared_ptr<gr_ofdm_insert_preamble> gr_ofdm_insert_preamble_sptr;
+
+gr_ofdm_insert_preamble_sptr
+gr_make_ofdm_insert_preamble(int fft_length,
+			     const std::vector<std::vector<gr_complex> > &preamble);
+
+/*!
+ * \brief insert "pre-modulated" preamble symbols before each payload.
+ *
+ * <pre>
+ * input 1: stream of vectors of gr_complex [fft_length]
+ *          These are the modulated symbols of the payload.
+ *
+ * input 2: stream of char.  The LSB indicates whether the corresponding
+ *          symbol on input 1 is the first symbol of the payload or not.
+ *          It's a 1 if the corresponding symbol is the first symbol,
+ *          otherwise 0.
+ *
+ * N.B., this implies that there must be at least 1 symbol in the payload.
+ *
+ *
+ * output 1: stream of vectors of gr_complex [fft_length]
+ *           These include the preamble symbols and the payload symbols.
+ *
+ * output 2: stream of char.  The LSB indicates whether the corresponding
+ *           symbol on input 1 is the first symbol of a packet (i.e., the
+ *           first symbol of the preamble.)   It's a 1 if the corresponding
+ *           symbol is the first symbol, otherwise 0.
+ * </pre>
+ *
+ * \param fft_length length of each symbol in samples.
+ * \param preamble   vector of symbols that represent the pre-modulated preamble.
+ */
+
+class gr_ofdm_insert_preamble : public gr_block
+{
+  friend gr_ofdm_insert_preamble_sptr
+  gr_make_ofdm_insert_preamble(int fft_length,
+			       const std::vector<std::vector<gr_complex> > &preamble);
+
+protected:
+  gr_ofdm_insert_preamble(int fft_length,
+			  const std::vector<std::vector<gr_complex> > &preamble);
+
+private:
+  enum state_t {
+    ST_IDLE,
+    ST_PREAMBLE,
+    ST_FIRST_PAYLOAD,
+    ST_PAYLOAD
+  };
+
+  int						d_fft_length;
+  const std::vector<std::vector<gr_complex> > 	d_preamble;
+  state_t					d_state;
+  int						d_nsymbols_output;
+  int						d_pending_flag;
+
+  void enter_idle();
+  void enter_preamble();
+  void enter_first_payload();
+  void enter_payload();
+  
+
+public:
+  ~gr_ofdm_insert_preamble();
+
+  int general_work (int noutput_items,
+		    gr_vector_int &ninput_items,
+		    gr_vector_const_void_star &input_items,
+		    gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_OFDM_INSERT_PREAMBLE_H */
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.i b/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.i
new file mode 100644
index 0000000000..183e91b0e3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.i
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,ofdm_insert_preamble);
+
+gr_ofdm_insert_preamble_sptr
+gr_make_ofdm_insert_preamble(int fft_length,
+			     const std::vector<std::vector<gr_complex> > &preamble);
+
+
+class gr_ofdm_insert_preamble : public gr_block
+{
+ protected:
+  gr_ofdm_insert_preamble(int fft_length,
+			  const std::vector<std::vector<gr_complex> > &preamble);
+};
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.cc b/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.cc
new file mode 100644
index 0000000000..8e774fe766
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.cc
@@ -0,0 +1,249 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_ofdm_qam_mapper.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+gr_ofdm_qam_mapper_sptr
+gr_make_ofdm_qam_mapper (unsigned int msgq_limit, 
+			 unsigned int occupied_carriers, unsigned int fft_length,
+			 int m)
+{
+  return gr_ofdm_qam_mapper_sptr (new gr_ofdm_qam_mapper (msgq_limit, occupied_carriers, fft_length, m));
+}
+
+// Consumes 1 packet and produces as many OFDM symbols of fft_length to hold the full packet
+gr_ofdm_qam_mapper::gr_ofdm_qam_mapper (unsigned int msgq_limit, 
+					unsigned int occupied_carriers, unsigned int fft_length,
+					int m)
+  : gr_sync_block ("ofdm_qam_mapper",
+		   gr_make_io_signature (0, 0, 0),
+		   gr_make_io_signature2 (1, 2, sizeof(gr_complex)*fft_length, sizeof(char))),
+    d_msgq(gr_make_msg_queue(msgq_limit)), d_msg_offset(0), d_eof(false),
+    d_occupied_carriers(occupied_carriers),
+    d_fft_length(fft_length),
+    d_bit_offset(0),
+    d_pending_flag(0),
+    d_mod_order(m)
+{
+  if (!(d_occupied_carriers <= d_fft_length))
+    throw std::invalid_argument("gr_ofdm_qam_mapper: occupied carriers must be <= fft_length");
+
+  bool ok = false;
+  if(m == 2) {
+    ok = true;
+  }
+  if(m == 4) {
+    ok = true;
+  }
+  if(m == 16) {
+    ok = true;
+  }
+  if(m == 64) {
+    ok = true;
+  }
+  if(m == 256) {
+    ok = true;
+  }
+  
+  if(!ok)
+    throw std::invalid_argument("Order M must be [2, 4, 16, 64, 256]");  
+
+  make_constellation();
+}
+
+gr_ofdm_qam_mapper::~gr_ofdm_qam_mapper(void)
+{
+}
+
+void gr_ofdm_qam_mapper::make_constellation()
+{
+  int i = 0, j = 0, ii = 0, jj = 0;
+  // number of bits/symbol (log2(M))
+  int k = (int)(log10(d_mod_order) / log10(2.0));
+
+  int a, b;
+  float re, im;
+  float coeff = 1;
+  std::vector<int> bits_i, bits_q;
+
+  int rr = 0;
+  int ss = 0;
+  int ll = bits_i.size();
+
+  for(i=0; i < d_mod_order; i++) {
+    a = (i & (0x01 << (k-1))) >> (k-1);
+    b = (i & (0x01 << (k-2))) >> (k-2);
+    for(j=2; j < k; j+=2) {
+      bits_i.push_back( (i & (0x01 << (k-j-1))) >> (k-j-1));
+      bits_q.push_back( (i & (0x01 << (k-(j+1)-1))) >> (k-(j+1)-1));
+    }
+    
+    ss = 0;
+    ll = bits_i.size();
+    for(ii = 0; ii < ll; ii++) {
+      rr = 0;
+      for(jj = 0; jj < (ll-ii); jj++) {
+	rr = abs(bits_i[jj] - rr);
+      }
+      ss += rr * pow(2.0, ii+1.0);
+    }
+    re = (2.0*a-1.0)*(ss+1.0);
+    
+    ss = 0;
+    ll = bits_q.size();
+    for(ii = 0; ii < ll; ii++) {
+      rr = 0;
+      for(jj = 0; jj < (ll-ii); jj++) {
+	rr = abs(bits_q[jj] - rr);
+      }
+      ss += rr*pow(2.0, ii+1.0);
+    }
+    im = (2.0*b-1.0)*(ss+1.0);
+      
+    a = std::max(re, im);
+    if(a > coeff) {
+      coeff = a;
+    }
+    d_constellation_map.push_back(gr_complex(re, im));
+  }
+  
+  d_constellation_map[0] = gr_complex(-3, -3);
+  d_constellation_map[1] = gr_complex(-3, -1);
+  d_constellation_map[2] = gr_complex(-3, 1);
+  d_constellation_map[3] = gr_complex(-3, 3);
+  d_constellation_map[4] = gr_complex(-1, -3);
+  d_constellation_map[5] = gr_complex(-1, -1);
+  d_constellation_map[6] = gr_complex(-1, 1);
+  d_constellation_map[7] = gr_complex(-1, 3);
+  d_constellation_map[8] = gr_complex(1, -3);
+  d_constellation_map[9] = gr_complex(1, -1);
+  d_constellation_map[10] = gr_complex(1, 1);
+  d_constellation_map[11] = gr_complex(1, 3);
+  d_constellation_map[12] = gr_complex(3, -3);
+  d_constellation_map[13] = gr_complex(3, -1);
+  d_constellation_map[14] = gr_complex(3, 1);
+  d_constellation_map[15] = gr_complex(3, 3);
+
+  coeff = sqrt(31.0)/2.0;
+  for(i = 0; i < d_constellation_map.size(); i++) {
+    d_constellation_map[i] /= coeff;
+    printf("const[%d]: %f + j%f\n", i, d_constellation_map[i].real(), d_constellation_map[i].imag());
+  }
+}
+
+static float
+randombit()
+{
+  int r = rand()&1;
+  return (float)(-1 + 2*r);
+}
+
+int
+gr_ofdm_qam_mapper::work(int noutput_items,
+			  gr_vector_const_void_star &input_items,
+			  gr_vector_void_star &output_items)
+{
+  gr_complex *out = (gr_complex *)output_items[0];
+  
+  unsigned int i=0;
+  unsigned int unoccupied_carriers = d_fft_length - d_occupied_carriers;
+  unsigned int zeros_on_left = (unsigned)ceil(unoccupied_carriers/2.0);
+
+  //printf("OFDM QAM Mapper:  ninput_items: %d   noutput_items: %d\n", ninput_items[0], noutput_items);
+
+  if(d_eof) {
+    return -1;
+  }
+  
+  if(!d_msg) {
+    d_msg = d_msgq->delete_head();	   // block, waiting for a message
+    d_msg_offset = 0;
+    d_bit_offset = 0;
+    d_pending_flag = 1;			   // new packet, write start of packet flag
+    
+    if((d_msg->length() == 0) && (d_msg->type() == 1)) {
+      d_msg.reset();
+      return -1;		// We're done; no more messages coming.
+    }
+  }
+
+  char *out_flag = 0;
+  if(output_items.size() == 2)
+    out_flag = (char *) output_items[1];
+  
+
+  // Build a single symbol:
+  
+
+  // Initialize all bins to 0 to set unused carriers
+  memset(out, 0, d_fft_length*sizeof(gr_complex));
+  
+  i = 0;
+  while((d_msg_offset < d_msg->length()) && (i < d_occupied_carriers)) {
+    unsigned char bit0 = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
+    d_bit_offset++;
+    
+    unsigned char bit1 = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
+    d_bit_offset++;
+    
+    unsigned char bit2 = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
+    d_bit_offset++;
+    
+    unsigned char bit3 = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
+    d_bit_offset++;
+
+    unsigned char bit = (bit0 << 3) | (bit1 << 2) | (bit2 << 1) | (bit3 << 0);
+    
+    out[i + zeros_on_left] = d_constellation_map[bit];
+    i++;
+    if(d_bit_offset == 8) {
+      d_bit_offset = 0;
+      d_msg_offset++;
+    }
+  }
+
+  // Ran out of data to put in symbol
+  if (d_msg_offset == d_msg->length()) {
+    while(i < d_occupied_carriers) {   // finish filling out the symbol
+      out[i + zeros_on_left] = d_constellation_map[rand() & 0x0F];
+      i++;
+    }
+
+    if (d_msg->type() == 1)	        // type == 1 sets EOF
+      d_eof = true;
+    d_msg.reset();   			// finished packet, free message
+    assert(d_bit_offset == 0);
+  }
+
+  if (out_flag)
+    out_flag[0] = d_pending_flag;
+  d_pending_flag = 0;
+
+  return 1;  // produced symbol
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.h b/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.h
new file mode 100644
index 0000000000..2b2a8e39f4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.h
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_OFDM_QAM_MAPPER_H
+#define INCLUDED_GR_OFDM_QAM_MAPPER_H
+
+
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+
+class gr_ofdm_qam_mapper;
+typedef boost::shared_ptr<gr_ofdm_qam_mapper> gr_ofdm_qam_mapper_sptr;
+
+gr_ofdm_qam_mapper_sptr 
+gr_make_ofdm_qam_mapper (unsigned msgq_limit, 
+			 unsigned occupied_carriers, unsigned int fft_length,
+			 int m=4);
+
+/*!
+ * \brief take a message in and map to a vector of complex
+ * constellation points suitable for IFFT input to be used in an ofdm
+ * modulator.  Simple QAM version.
+ */
+
+class gr_ofdm_qam_mapper : public gr_sync_block
+{
+  friend gr_ofdm_qam_mapper_sptr
+  gr_make_ofdm_qam_mapper (unsigned msgq_limit, 
+			   unsigned occupied_carriers, unsigned int fft_length,
+			   int m);
+ protected:
+  gr_ofdm_qam_mapper (unsigned msgq_limit, 
+		      unsigned occupied_carriers, unsigned int fft_length,
+		      int m);
+
+ private:
+  gr_msg_queue_sptr	d_msgq;
+  gr_message_sptr	d_msg;
+  unsigned		d_msg_offset;
+  bool			d_eof;
+  
+  unsigned int 		d_occupied_carriers;
+  unsigned int 		d_fft_length;
+  unsigned int 		d_bit_offset;
+  int			d_pending_flag;
+
+  int                     d_mod_order;
+  std::vector<gr_complex> d_constellation_map;
+
+  void make_constellation();
+
+ public:
+  ~gr_ofdm_qam_mapper(void);
+
+  gr_msg_queue_sptr	msgq() const { return d_msgq; }
+
+  int work(int noutput_items,
+	   gr_vector_const_void_star &input_items,
+	   gr_vector_void_star &output_items);
+
+};
+
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.i b/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.i
new file mode 100644
index 0000000000..84fd0851c4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.i
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,ofdm_qam_mapper);
+
+gr_ofdm_qam_mapper_sptr 
+gr_make_ofdm_qam_mapper (unsigned int msgq_limit,
+			 unsigned int bits_per_symbol, 
+			 unsigned int fft_length,
+			 int m=16);
+
+
+class gr_ofdm_qam_mapper : public gr_sync_block
+{
+ protected:
+  gr_ofdm_qam_mapper (unsigned int msgq_limit,
+		      unsigned int bits_per_symbol,
+		      unsigned int fft_length,
+		      int m);
+  
+ public:
+  gr_msg_queue_sptr msgq();
+  
+  int work(int noutput_items,
+	   gr_vector_const_void_star &input_items,
+	   gr_vector_void_star &output_items);
+};
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc b/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc
new file mode 100644
index 0000000000..cad14c706a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc
@@ -0,0 +1,141 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_ofdm_qpsk_mapper.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+gr_ofdm_qpsk_mapper_sptr
+gr_make_ofdm_qpsk_mapper (unsigned int msgq_limit, 
+			  unsigned int occupied_carriers, unsigned int fft_length)
+{
+  return gr_ofdm_qpsk_mapper_sptr (new gr_ofdm_qpsk_mapper (msgq_limit, occupied_carriers, fft_length));
+}
+
+// Consumes 1 packet and produces as many OFDM symbols of fft_length to hold the full packet
+gr_ofdm_qpsk_mapper::gr_ofdm_qpsk_mapper (unsigned int msgq_limit, 
+					  unsigned int occupied_carriers, unsigned int fft_length)
+  : gr_sync_block ("ofdm_qpsk_mapper",
+		   gr_make_io_signature (0, 0, 0),
+		   gr_make_io_signature2 (1, 2, sizeof(gr_complex)*fft_length, sizeof(char))),
+    d_msgq(gr_make_msg_queue(msgq_limit)), d_msg_offset(0), d_eof(false),
+    d_occupied_carriers(occupied_carriers),
+    d_fft_length(fft_length),
+    d_bit_offset(0),
+    d_pending_flag(0)
+{
+  if (!(d_occupied_carriers <= d_fft_length))
+    throw std::invalid_argument("gr_ofdm_qpsk_mapper: occupied carriers must be <= fft_length");
+}
+
+gr_ofdm_qpsk_mapper::~gr_ofdm_qpsk_mapper(void)
+{
+}
+
+static gr_complex
+randombit()
+{
+  int r1 = rand()&1;
+  int r2 = rand()&1;
+  return gr_complex((0.707)*(-1 + 2*r1),(0.707)*(-1 + 2*r2));
+}
+
+int
+gr_ofdm_qpsk_mapper::work(int noutput_items,
+			  gr_vector_const_void_star &input_items,
+			  gr_vector_void_star &output_items)
+{
+  gr_complex *out = (gr_complex *)output_items[0];
+  
+  unsigned int i=0;
+  unsigned int unoccupied_carriers = d_fft_length - d_occupied_carriers;
+  unsigned int zeros_on_left = (unsigned)ceil(unoccupied_carriers/2.0);
+
+  //printf("OFDM QPSK Mapper:  ninput_items: %d   noutput_items: %d\n", ninput_items[0], noutput_items);
+
+  if(d_eof) {
+    return -1;
+  }
+  
+  if(!d_msg) {
+    d_msg = d_msgq->delete_head();	   // block, waiting for a message
+    d_msg_offset = 0;
+    d_bit_offset = 0;
+    d_pending_flag = 1;			   // new packet, write start of packet flag
+    
+    if((d_msg->length() == 0) && (d_msg->type() == 1)) {
+      d_msg.reset();
+      return -1;		// We're done; no more messages coming.
+    }
+  }
+
+  char *out_flag = 0;
+  if(output_items.size() == 2)
+    out_flag = (char *) output_items[1];
+  
+
+  // Build a single symbol:
+  
+
+  // Initialize all bins to 0 to set unused carriers
+  memset(out, 0, d_fft_length*sizeof(gr_complex));
+  
+  i = 0;
+  while((d_msg_offset < d_msg->length()) && (i < d_occupied_carriers)) {
+    unsigned char bit0 = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
+    d_bit_offset++;
+    
+    unsigned char bit1 = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
+    d_bit_offset++;
+    
+    out[i + zeros_on_left] = gr_complex((0.707)*(-1+2*(bit0)), (0.707)*(-1+2*(bit1)) );
+    i++;
+    if(d_bit_offset == 8) {
+      d_bit_offset = 0;
+      d_msg_offset++;
+    }
+  }
+
+  // Ran out of data to put in symbol
+  if (d_msg_offset == d_msg->length()) {
+    while(i < d_occupied_carriers) {   // finish filling out the symbol
+      out[i + zeros_on_left] = randombit();
+      i++;
+    }
+
+    if (d_msg->type() == 1)	        // type == 1 sets EOF
+      d_eof = true;
+    d_msg.reset();   			// finished packet, free message
+    assert(d_bit_offset == 0);
+  }
+
+  if (out_flag)
+    out_flag[0] = d_pending_flag;
+  d_pending_flag = 0;
+
+  return 1;  // produced symbol
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.h b/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.h
new file mode 100644
index 0000000000..93bd8f9878
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_OFDM_QPSK_MAPPER_H
+#define INCLUDED_GR_OFDM_QPSK_MAPPER_H
+
+
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+
+class gr_ofdm_qpsk_mapper;
+typedef boost::shared_ptr<gr_ofdm_qpsk_mapper> gr_ofdm_qpsk_mapper_sptr;
+
+gr_ofdm_qpsk_mapper_sptr 
+gr_make_ofdm_qpsk_mapper (unsigned msgq_limit, 
+			  unsigned occupied_carriers, unsigned int fft_length);
+
+/*!
+ * \brief take a message in and map to a vector of complex
+ * constellation points suitable for IFFT input to be used in an ofdm
+ * modulator.  Simple QPSK version.
+ */
+
+class gr_ofdm_qpsk_mapper : public gr_sync_block
+{
+  friend gr_ofdm_qpsk_mapper_sptr
+  gr_make_ofdm_qpsk_mapper (unsigned msgq_limit, 
+			    unsigned occupied_carriers, unsigned int fft_length);
+ protected:
+  gr_ofdm_qpsk_mapper (unsigned msgq_limit, 
+		       unsigned occupied_carriers, unsigned int fft_length);
+
+ private:
+  gr_msg_queue_sptr	d_msgq;
+  gr_message_sptr	d_msg;
+  unsigned		d_msg_offset;
+  bool			d_eof;
+  
+  unsigned int 		d_occupied_carriers;
+  unsigned int 		d_fft_length;
+  unsigned int 		d_bit_offset;
+  int			d_pending_flag;
+
+ public:
+  ~gr_ofdm_qpsk_mapper(void);
+
+  gr_msg_queue_sptr	msgq() const { return d_msgq; }
+
+  int work(int noutput_items,
+	   gr_vector_const_void_star &input_items,
+	   gr_vector_void_star &output_items);
+
+};
+
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.i b/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.i
new file mode 100644
index 0000000000..5f19f08f3a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.i
@@ -0,0 +1,44 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,ofdm_qpsk_mapper);
+
+gr_ofdm_qpsk_mapper_sptr 
+gr_make_ofdm_qpsk_mapper (unsigned int msgq_limit,
+			  unsigned int bits_per_symbol, 
+			  unsigned int fft_length);
+
+
+class gr_ofdm_qpsk_mapper : public gr_sync_block
+{
+ protected:
+  gr_ofdm_qpsk_mapper (unsigned int msgq_limit,
+		       unsigned int bits_per_symbol,
+		       unsigned int fft_length);
+
+ public:
+  gr_msg_queue_sptr msgq();
+
+  int work(int noutput_items,
+	   gr_vector_const_void_star &input_items,
+	   gr_vector_void_star &output_items);
+};
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc b/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
index 5f5a91fd23..1ca738a291 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
@@ -67,7 +67,7 @@ gr_ofdm_sampler::general_work (int noutput_items,
 
   int found=0;
 
-  unsigned int i=d_fft_length-1;
+  int i=d_fft_length-1;
 
   while(!found && i<std::min(ninput_items[0],ninput_items[1]) )
     if(trigger[i])
@@ -77,7 +77,7 @@ gr_ofdm_sampler::general_work (int noutput_items,
 
   if(found) {
     assert(i-d_fft_length+1 >= 0);
-    for(unsigned int j=i-d_fft_length+1;j<=i;j++)
+    for(int j=i-d_fft_length+1;j<=i;j++)
       *optr++ = iptr[j];
     consume_each(i-d_fft_length+2);
     //printf("OFDM Sampler found:  ninput_items: %d/%d   noutput_items: %d  consumed: %d   found: %d\n", 
diff --git a/gnuradio-core/src/lib/general/gr_regenerate_bb.cc b/gnuradio-core/src/lib/general/gr_regenerate_bb.cc
new file mode 100644
index 0000000000..6b0535e189
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_regenerate_bb.cc
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_regenerate_bb.h>
+#include <gr_io_signature.h>
+
+gr_regenerate_bb_sptr
+gr_make_regenerate_bb (int period, unsigned int max_regen)
+{
+  return gr_regenerate_bb_sptr (new gr_regenerate_bb (period, max_regen));
+}
+
+gr_regenerate_bb::gr_regenerate_bb (int period, unsigned int max_regen)
+  : gr_sync_block ("regenerate_bb",
+		   gr_make_io_signature (1, 1, sizeof (char)),
+		   gr_make_io_signature (1, 1, sizeof (char))),
+    d_period(period),
+    d_max_regen(max_regen),
+    d_regen_count(0)
+{
+}
+
+int
+gr_regenerate_bb::work (int noutput_items,
+			gr_vector_const_void_star &input_items,
+			gr_vector_void_star &output_items)
+{
+  const char *iptr = (const char *) input_items[0];
+  char *optr = (char *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+    optr[i] = 0;
+    
+    if(iptr[i] == 1) {
+      d_countdown = d_period;
+      optr[i] = 1;
+      d_regen_count = 0;
+    }
+
+    if(d_regen_count <= d_max_regen) {
+      d_countdown--;
+      
+      if(d_countdown == 0) {
+	optr[i] = 1;
+	d_countdown = d_period;
+	d_regen_count++;
+      }
+    }
+  }
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_regenerate_bb.h b/gnuradio-core/src/lib/general/gr_regenerate_bb.h
new file mode 100644
index 0000000000..446e658ae4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_regenerate_bb.h
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_REGENERATE_BB_H
+#define INCLUDED_GR_REGENERATE_BB_H
+
+#include <gr_sync_block.h>
+
+class gr_regenerate_bb;
+typedef boost::shared_ptr<gr_regenerate_bb> gr_regenerate_bb_sptr;
+
+gr_regenerate_bb_sptr gr_make_regenerate_bb (int period, unsigned int max_regen=500);
+
+/*!
+ * \brief Detect the peak of a signal
+ * \ingroup block
+ *
+ * If a peak is detected, this block outputs a 1 repeated every period samples 
+ * until reset by detection of another 1 on the input
+ */
+class gr_regenerate_bb : public gr_sync_block
+{
+  friend gr_regenerate_bb_sptr gr_make_regenerate_bb (int period, unsigned int max_regen);
+
+  gr_regenerate_bb (int period, unsigned int max_regen);
+
+ private:
+  int d_period;
+  int d_countdown;
+  unsigned int d_max_regen;
+  unsigned int d_regen_count;
+
+ public:
+
+  int work (int noutput_items,
+	    gr_vector_const_void_star &input_items,
+	    gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_regenerate_bb.i b/gnuradio-core/src/lib/general/gr_regenerate_bb.i
new file mode 100644
index 0000000000..6afd84d8de
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_regenerate_bb.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,regenerate_bb)
+
+gr_regenerate_bb_sptr gr_make_regenerate_bb (int period, unsigned int max_regen=500);
+
+class gr_regenerate_bb : public gr_sync_block
+{
+ private:
+  gr_regenerate_bb (int period, unsigned int max_regen);
+};
diff --git a/gnuradio-core/src/lib/swig/gnuradio.i b/gnuradio-core/src/lib/swig/gnuradio.i
index 706ba8a666..a3e04223de 100644
--- a/gnuradio-core/src/lib/swig/gnuradio.i
+++ b/gnuradio-core/src/lib/swig/gnuradio.i
@@ -59,7 +59,15 @@ namespace std {
   %template()	  vector<int>;
   %template()	  vector<float>;
   %template()	  vector<double>;
-  %template() 	  vector<std::complex<float> >;
+
+  %template() 	  vector< std::complex<float> >;
+  %template()     vector< std::vector< unsigned char > >;
+  %template()     vector< std::vector< char > >;
+  %template()     vector< std::vector< short > >;
+  %template()     vector< std::vector< int > >;
+  %template()     vector< std::vector< float > >;
+  %template()     vector< std::vector< double > >;
+  %template()     vector< std::vector< std::complex<float> > >;
 };
 
 ////////////////////////////////////////////////////////////////////////
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am b/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am
index b8c8001101..71598354c1 100644
--- a/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am
+++ b/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am
@@ -40,9 +40,12 @@ grblkspython_PYTHON =		\
 	cpm.py			\
 	nbfm_rx.py		\
 	nbfm_tx.py		\
-	ofdm_pkt.py		\
+	ofdm.py			\
 	ofdm_receiver.py	\
-	ofdm_sync.py		\
+	ofdm_sync_fixed.py	\
+	ofdm_sync_ml.py		\
+	ofdm_sync_pnac.py	\
+	ofdm_sync_pn.py		\
 	pkt.py			\
 	psk.py			\
 	qam.py			\
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py
new file mode 100644
index 0000000000..74a674cb5e
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py
@@ -0,0 +1,284 @@
+
+#
+# Copyright 2006,2007 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+import math
+from numpy import fft
+from gnuradio import gr, ofdm_packet_utils
+import gnuradio.gr.gr_threading as _threading
+
+from gnuradio.blksimpl.ofdm_receiver import ofdm_receiver
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                   mod/demod with packets as i/o
+# /////////////////////////////////////////////////////////////////////////////
+
+class ofdm_mod(gr.hier_block):
+    """
+    Modulates an OFDM stream. Based on the options fft_length, occupied_tones, and
+    cp_length, this block creates OFDM symbols using a specified modulation option.
+    
+    Send packets by calling send_pkt
+    """
+    def __init__(self, fg, options, msgq_limit=2, pad_for_usrp=True):
+        """
+	Hierarchical block for sending packets
+
+        Packets to be sent are enqueued by calling send_pkt.
+        The output is the complex modulated signal at baseband.
+
+	@param fg: flow graph
+	@type fg: flow graph
+        @param options: pass modulation options from higher layers (fft length, occupied tones, etc.)
+        @param msgq_limit: maximum number of messages in message queue
+        @type msgq_limit: int
+        @param pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples
+        """
+
+        self._pad_for_usrp = pad_for_usrp
+        self._modulation = options.modulation
+        self._fft_length = options.fft_length
+        self._occupied_tones = options.occupied_tones
+        self._cp_length = options.cp_length
+
+        win = [] #[1 for i in range(self._fft_length)]
+
+        # Use freq domain to get doubled-up known symbol for correlation in time domain
+        zeros_on_left = int(math.ceil((self._fft_length - self._occupied_tones)/2.0))
+        ksfreq = known_symbols_4512_3[0:self._occupied_tones]
+        for i in range(len(ksfreq)):
+            if((zeros_on_left + i) & 1):
+                ksfreq[i] = 0
+
+        # hard-coded known symbols
+        preambles = (ksfreq,
+                     known_symbols_4512_1[0:self._occupied_tones],
+                     known_symbols_4512_2[0:self._occupied_tones])
+        
+        padded_preambles = list()
+        for pre in preambles:
+            padded = self._fft_length*[0,]
+            padded[zeros_on_left : zeros_on_left + self._occupied_tones] = pre
+            padded_preambles.append(padded)
+            
+        symbol_length = options.fft_length + options.cp_length
+
+        # The next step will all us to pass a constellation into a generic mapper function instead
+        # of using these hard-coded versions
+        if self._modulation == "bpsk":
+            self._pkt_input = gr.ofdm_bpsk_mapper(msgq_limit, options.occupied_tones, options.fft_length)
+        elif self._modulation == "qpsk":
+            self._pkt_input = gr.ofdm_qpsk_mapper(msgq_limit, options.occupied_tones, options.fft_length)
+        else:
+            print "Modulation type not supported (must be \"bpsk\" or \"qpsk\""
+        
+        self.preambles = gr.ofdm_insert_preamble(self._fft_length, padded_preambles)
+        self.ifft = gr.fft_vcc(self._fft_length, False, win, True)
+        self.cp_adder = gr.ofdm_cyclic_prefixer(self._fft_length, symbol_length)
+        self.scale = gr.multiply_const_cc(1.0 / math.sqrt(self._fft_length))
+        
+        fg.connect((self._pkt_input, 0), (self.preambles, 0))
+        fg.connect((self._pkt_input, 1), (self.preambles, 1))
+        fg.connect(self.preambles, self.ifft, self.cp_adder, self.scale)
+        
+        if options.verbose:
+            self._print_verbage()
+
+        if options.log:
+            fg.connect(self._pkt_input, gr.file_sink(gr.sizeof_gr_complex*options.fft_length, "ofdm_mapper_c.dat"))
+
+        gr.hier_block.__init__(self, fg, None, self.scale)
+
+    def send_pkt(self, payload='', eof=False):
+        """
+        Send the payload.
+
+        @param payload: data to send
+        @type payload: string
+        """
+        if eof:
+            msg = gr.message(1) # tell self._pkt_input we're not sending any more packets
+        else:
+            # print "original_payload =", string_to_hex_list(payload)
+            pkt = ofdm_packet_utils.make_packet(payload, 1, 1, self._pad_for_usrp)
+
+            #print "pkt =", string_to_hex_list(pkt)
+            msg = gr.message_from_string(pkt)
+        self._pkt_input.msgq().insert_tail(msg)
+
+    def add_options(normal, expert):
+        """
+        Adds OFDM-specific options to the Options Parser
+        """
+        normal.add_option("-m", "--modulation", type="string", default="bpsk",
+                          help="set modulation type (bpsk or qpsk) [default=%default]")
+        expert.add_option("", "--fft-length", type="intx", default=512,
+                          help="set the number of FFT bins [default=%default]")
+        expert.add_option("", "--occupied-tones", type="intx", default=200,
+                          help="set the number of occupied FFT bins [default=%default]")
+        expert.add_option("", "--cp-length", type="intx", default=128,
+                          help="set the number of bits in the cyclic prefix [default=%default]")
+    # Make a static method to call before instantiation
+    add_options = staticmethod(add_options)
+
+    def _print_verbage(self):
+        """
+        Prints information about the OFDM modulator
+        """
+        print "\nOFDM Modulator:"
+        print "Modulation Type: %s"    % (self._modulation)
+        print "FFT length:      %3d"   % (self._fft_length)
+        print "Occupied Tones:  %3d"   % (self._occupied_tones)
+        print "CP length:       %3d"   % (self._cp_length)
+
+
+class ofdm_demod(gr.hier_block):
+    """
+    Demodulates a received OFDM stream. Based on the options fft_length, occupied_tones, and
+    cp_length, this block performs synchronization, FFT, and demodulation of incoming OFDM
+    symbols and passes packets up the a higher layer.
+
+    The input is complex baseband.  When packets are demodulated, they are passed to the
+    app via the callback.
+    """
+
+    def __init__(self, fg, options, callback=None):
+        """
+	Hierarchical block for demodulating and deframing packets.
+
+	The input is the complex modulated signal at baseband.
+        Demodulated packets are sent to the handler.
+
+	@param fg: flow graph
+	@type fg: flow graph
+        @param options: pass modulation options from higher layers (fft length, occupied tones, etc.)
+        @param callback:  function of two args: ok, payload
+        @type callback: ok: bool; payload: string
+	"""
+        self._rcvd_pktq = gr.msg_queue()          # holds packets from the PHY
+
+        self._modulation = options.modulation
+        self._fft_length = options.fft_length
+        self._occupied_tones = options.occupied_tones
+        self._cp_length = options.cp_length
+        self._snr = options.snr
+
+
+        # Use freq domain to get doubled-up known symbol for correlation in time domain
+        ksfreq = known_symbols_4512_3[0:self._occupied_tones]
+        for i in range(len(ksfreq)):
+            if(i&1):
+                ksfreq[i] = 0        
+
+        zeros_on_left = int(math.ceil((self._fft_length - self._occupied_tones)/2.0))
+        zeros_on_right = self._fft_length - self._occupied_tones - zeros_on_left
+        ks0 = zeros_on_left*[0.0,]
+        ks0.extend(ksfreq)
+        ks0.extend(zeros_on_right*[0.0,])
+        
+        ks0time = fft.ifft(ks0)
+        # ADD SCALING FACTOR
+        ks0time = ks0time.tolist()
+
+        # hard-coded known symbols
+        preambles = (ks0time,
+                     known_symbols_4512_1[0:self._occupied_tones],
+                     known_symbols_4512_2[0:self._occupied_tones])
+        
+        symbol_length = self._fft_length + self._cp_length
+        self.ofdm_recv = ofdm_receiver(fg, self._fft_length, self._cp_length,
+                                       self._occupied_tones, self._snr, preambles,
+                                       options.log)
+        self.ofdm_demod = gr.ofdm_frame_sink(self._rcvd_pktq,
+                                             self._occupied_tones,
+                                             self._modulation)
+        
+        fg.connect((self.ofdm_recv, 0), (self.ofdm_demod, 0))
+        fg.connect((self.ofdm_recv, 1), (self.ofdm_demod, 1))
+
+        if options.verbose:
+            self._print_verbage()
+            
+        gr.hier_block.__init__(self, fg, self.ofdm_recv, None)
+        self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback)
+
+
+    def add_options(normal, expert):
+        """
+        Adds OFDM-specific options to the Options Parser
+        """
+        normal.add_option("-m", "--modulation", type="string", default="bpsk",
+                          help="set modulation type (bpsk or qpsk) [default=%default]")
+        expert.add_option("", "--fft-length", type="intx", default=512,
+                          help="set the number of FFT bins [default=%default]")
+        expert.add_option("", "--occupied-tones", type="intx", default=200,
+                          help="set the number of occupied FFT bins [default=%default]")
+        expert.add_option("", "--cp-length", type="intx", default=128,
+                          help="set the number of bits in the cyclic prefix [default=%default]")
+    # Make a static method to call before instantiation
+    add_options = staticmethod(add_options)
+
+    def _print_verbage(self):
+        """
+        Prints information about the OFDM demodulator
+        """
+        print "\nOFDM Demodulator:"
+        print "Modulation Type: %s"    % (self._modulation)
+        print "FFT length:      %3d"   % (self._fft_length)
+        print "Occupied Tones:  %3d"   % (self._occupied_tones)
+        print "CP length:       %3d"   % (self._cp_length)
+
+
+
+class _queue_watcher_thread(_threading.Thread):
+    def __init__(self, rcvd_pktq, callback):
+        _threading.Thread.__init__(self)
+        self.setDaemon(1)
+        self.rcvd_pktq = rcvd_pktq
+        self.callback = callback
+        self.keep_running = True
+        self.start()
+
+
+    def run(self):
+        while self.keep_running:
+            msg = self.rcvd_pktq.delete_head()
+            ok, payload = ofdm_packet_utils.unmake_packet(msg.to_string())
+            if self.callback:
+                self.callback(ok, payload)
+
+# Generating known symbols with:
+# i = [2*random.randint(0,1)-1 for i in range(4512)]
+
+known_symbols_200_1 = [1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0]
+        
+known_symbols_200_2 = [-1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0]
+
+
+known_symbols_4512_1 = [-1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1]
+
+known_symbols_4512_2 = [1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1]
+
+
+known_symbols_4512_impulse = 4512*[1,]
+
+known_symbols_4512_3 = [-1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1]
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_pkt.py b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_pkt.py
deleted file mode 100644
index 9a98b374b0..0000000000
--- a/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_pkt.py
+++ /dev/null
@@ -1,229 +0,0 @@
-
-#
-# Copyright 2005,2006,2007 Free Software Foundation, Inc.
-# 
-# This file is part of GNU Radio
-# 
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-# 
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING.  If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-# 
-
-import math
-from math import pi
-from gnuradio import gr, ofdm_packet_utils
-import gnuradio.gr.gr_threading as _threading
-
-from gnuradio.blksimpl.ofdm_receiver import ofdm_receiver
-
-
-# /////////////////////////////////////////////////////////////////////////////
-#                   mod/demod with packets as i/o
-# /////////////////////////////////////////////////////////////////////////////
-
-class mod_ofdm_pkts(gr.hier_block):
-    """
-    Wrap an arbitrary digital modulator in our packet handling framework.
-
-    Send packets by calling send_pkt
-    """
-    def __init__(self, fg, options, msgq_limit=2, pad_for_usrp=True):
-        """
-	Hierarchical block for sending packets
-
-        Packets to be sent are enqueued by calling send_pkt.
-        The output is the complex modulated signal at baseband.
-
-	@param fg: flow graph
-	@type fg: flow graph
-        @param msgq_limit: maximum number of messages in message queue
-        @type msgq_limit: int
-        @param pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples
-
-        See modulators for remaining parameters
-        """
-        self._pad_for_usrp = pad_for_usrp
-
-        win = [] #[1 for i in range(self._fft_length)]
-
-        # hard-coded known symbol
-        ks1 = known_symbols_4512_1[0:options.occupied_tones]
-        #ks1 = known_symbols_4512_impulse[0:options.occupied_tones]
-        ks2 = known_symbols_4512_2[0:options.occupied_tones]
-                
-        symbol_length = options.fft_length + options.cp_length
-
-        # accepts messages from the outside world
-        self._pkt_input = gr.ofdm_bpsk_mapper(msgq_limit, options.occupied_tones, options.fft_length, ks1, ks2)
-        self.ifft = gr.fft_vcc(options.fft_length, False, win, True)
-        self.cp_adder = gr.ofdm_cyclic_prefixer(options.fft_length, symbol_length)
-        self.scale = gr.multiply_const_cc(1.0 / math.sqrt(options.fft_length))
-
-        fg.connect(self._pkt_input, self.ifft, self.cp_adder, self.scale)
-
-        if options.verbose:
-            self._print_verbage()
-
-        if 1:
-            fg.connect(self._pkt_input, gr.file_sink(gr.sizeof_gr_complex*options.fft_length, "ofdm_mapper_c.dat"))
-
-        gr.hier_block.__init__(self, fg, None, self.scale)
-
-    def send_pkt(self, payload='', eof=False):
-        """
-        Send the payload.
-
-        @param payload: data to send
-        @type payload: string
-        """
-        if eof:
-            msg = gr.message(1) # tell self._pkt_input we're not sending any more packets
-        else:
-            # print "original_payload =", string_to_hex_list(payload)
-            pkt = ofdm_packet_utils.make_packet(payload,
-                                                self.samples_per_symbol(),
-                                                self.bits_per_symbol(),
-                                                self._pad_for_usrp)
-            #print "pkt =", string_to_hex_list(pkt)
-            msg = gr.message_from_string(pkt)
-        self._pkt_input.msgq().insert_tail(msg)
-
-    def samples_per_symbol(self):
-        return 2
-
-    def bits_per_symbol(self=None):   # staticmethod that's also callable on an instance
-        return 1
-    bits_per_symbol = staticmethod(bits_per_symbol)      # make it a static method.  RTFM
-
-    def add_options(normal, expert):
-        """
-        Adds OFDM-specific options to the Options Parser
-        """
-        expert.add_option("", "--fft-length", type="intx", default=512,
-                          help="set the number of FFT bins [default=%default]")
-        expert.add_option("", "--occupied-tones", type="intx", default=200,
-                          help="set the number of occupied FFT bins [default=%default]")
-        expert.add_option("", "--cp-length", type="intx", default=128,
-                          help="set the number of bits in the cyclic prefix [default=%default]")
-    # Make a static method to call before instantiation
-    add_options = staticmethod(add_options)
-
-    def _print_verbage(self):
-        """
-        Prints information about the OFDM modulator
-        """
-        print "\nOFDM Modulator:"
-        print "FFT length:      %3d"   % (self._fft_length)
-        print "Occupied Tones:  %3d"   % (self._occupied_tones)
-        print "CP length:       %3d"   % (self._cp_length)
-
-
-class demod_ofdm_pkts(gr.hier_block):
-    """
-    Wrap an arbitrary digital demodulator in our packet handling framework.
-
-    The input is complex baseband.  When packets are demodulated, they are passed to the
-    app via the callback.
-    """
-
-    def __init__(self, fg, options, callback=None):
-        """
-	Hierarchical block for demodulating and deframing packets.
-
-	The input is the complex modulated signal at baseband.
-        Demodulated packets are sent to the handler.
-
-	@param fg: flow graph
-	@type fg: flow graph
-        @param demodulator: instance of demodulator class (gr_block or hier_block)
-        @type demodulator: complex baseband in
-        @param callback:  function of two args: ok, payload
-        @type callback: ok: bool; payload: string
-	"""
-        self._rcvd_pktq = gr.msg_queue()          # holds packets from the PHY
-
-        ks1 = known_symbols_4512_1[0:options.occupied_tones]
-        #ks1 = known_symbols_4512_impulse[0:options.occupied_tones]
-        ks2 = known_symbols_4512_2[0:options.occupied_tones]
-        
-        symbol_length = options.fft_length + options.cp_length
-        self.ofdm_recv = ofdm_receiver(fg, options.fft_length, options.cp_length,
-                                       options.occupied_tones, options.snr, ks1, ks2)
-        self.ofdm_demod = gr.ofdm_frame_sink(self._rcvd_pktq,
-                                             options.occupied_tones)
-        
-        fg.connect((self.ofdm_recv, 0), (self.ofdm_demod, 0))
-        fg.connect((self.ofdm_recv, 1), (self.ofdm_demod, 1))
-
-        gr.hier_block.__init__(self, fg, self.ofdm_recv, None)
-        self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback)
-
-
-    def bits_per_symbol(self=None):   # staticmethod that's also callable on an instance
-        return 1
-    bits_per_symbol = staticmethod(bits_per_symbol)      # make it a static method.  RTFM
-
-    def add_options(normal, expert):
-        """
-        Adds OFDM-specific options to the Options Parser
-        """
-        expert.add_option("", "--fft-length", type="intx", default=512,
-                          help="set the number of FFT bins [default=%default]")
-        expert.add_option("", "--occupied-tones", type="intx", default=200,
-                          help="set the number of occupied FFT bins [default=%default]")
-        expert.add_option("", "--cp-length", type="intx", default=128,
-                          help="set the number of bits in the cyclic prefix [default=%default]")
-    # Make a static method to call before instantiation
-    add_options = staticmethod(add_options)
-
-    def _print_verbage(self):
-        """
-        Prints information about the OFDM demodulator
-        """
-        print "\nOFDM Demodulator:"
-        print "FFT length:      %3d"   % (self._fft_length)
-        print "Occupied Tones:  %3d"   % (self._occupied_tones)
-        print "CP length:       %3d"   % (self._cp_length)
-
-
-
-class _queue_watcher_thread(_threading.Thread):
-    def __init__(self, rcvd_pktq, callback):
-        _threading.Thread.__init__(self)
-        self.setDaemon(1)
-        self.rcvd_pktq = rcvd_pktq
-        self.callback = callback
-        self.keep_running = True
-        self.start()
-
-
-    def run(self):
-        while self.keep_running:
-            msg = self.rcvd_pktq.delete_head()
-            ok, payload = ofdm_packet_utils.unmake_packet(msg.to_string())
-            if self.callback:
-                self.callback(ok, payload)
-
-known_symbols_200_1 = [1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0]
-        
-known_symbols_200_2 = [-1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0]
-
-
-
-known_symbols_4512_1 = [-1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1]
-
-known_symbols_4512_2 = [1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1]
-
-
-known_symbols_4512_impulse = 4512*[1,]
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_receiver.py b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_receiver.py
index e2f5932836..22ec41f1d9 100644
--- a/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_receiver.py
+++ b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_receiver.py
@@ -22,10 +22,12 @@
 
 import math
 from gnuradio import gr
-from gnuradio.blksimpl.ofdm_sync import ofdm_sync
+from gnuradio.blksimpl.ofdm_sync_ml import ofdm_sync_ml
+from gnuradio.blksimpl.ofdm_sync_pn import ofdm_sync_pn
+from gnuradio.blksimpl.ofdm_sync_pnac import ofdm_sync_pnac
 
 class ofdm_receiver(gr.hier_block):
-    def __init__(self, fg, fft_length, cp_length, occupied_tones, snr, ks1, ks2):
+    def __init__(self, fg, fft_length, cp_length, occupied_tones, snr, ks, logging=False):
         self.fg = fg
 
         bw = (float(occupied_tones) / float(fft_length)) / 2.0
@@ -39,14 +41,21 @@ class ofdm_receiver(gr.hier_block):
         
         win = [1 for i in range(fft_length)]
 
-        self.ofdm_sync = ofdm_sync(fg, fft_length, cp_length, snr)
+        SYNC = "pn"
+        if SYNC == "ml":
+            self.ofdm_sync = ofdm_sync_ml(fg, fft_length, cp_length, snr, logging)
+        elif SYNC == "pn":
+            self.ofdm_sync = ofdm_sync_pn(fg, fft_length, cp_length, logging)
+        elif SYNC == "pnac":
+            self.ofdm_sync = ofdm_sync_pnac(fg, fft_length, cp_length, ks[0])
+
         self.fft_demod = gr.fft_vcc(fft_length, True, win, True)
         self.ofdm_corr  = gr.ofdm_correlator(occupied_tones, fft_length,
-                                             cp_length, ks1, ks2)
+                                             cp_length, ks[1], ks[2])
 
         self.fg.connect(self.chan_filt, self.ofdm_sync, self.fft_demod, self.ofdm_corr)
         
-        if 1:
+        if logging:
             self.fg.connect(self.chan_filt, gr.file_sink(gr.sizeof_gr_complex, "chan_filt_c.dat"))
             self.fg.connect(self.fft_demod, gr.file_sink(gr.sizeof_gr_complex*fft_length, "fft_out_c.dat"))
             self.fg.connect(self.ofdm_corr, gr.file_sink(gr.sizeof_gr_complex*occupied_tones, "ofdm_corr_out_c.dat"))
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync.py b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync.py
deleted file mode 100644
index 271be93def..0000000000
--- a/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync.py
+++ /dev/null
@@ -1,141 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2007 Free Software Foundation, Inc.
-# 
-# This file is part of GNU Radio
-# 
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-# 
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING.  If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-# 
-
-import math
-from gnuradio import gr
-
-class ofdm_sync(gr.hier_block):
-    def __init__(self, fg, fft_length, cp_length, snr):
-        self.fg = fg
-
-        self.input = gr.add_const_cc(0)
-
-        SNR = 10.0**(snr/10.0)
-        rho = SNR / (SNR + 1.0)
-        symbol_length = fft_length + cp_length
-
-        # ML Sync
-
-        # Energy Detection from ML Sync
-
-        # Create a delay line
-        self.delay = gr.delay(gr.sizeof_gr_complex, fft_length)
-        self.fg.connect(self.input, self.delay)
-
-        # magnitude squared blocks
-        self.magsqrd1 = gr.complex_to_mag_squared()
-        self.magsqrd2 = gr.complex_to_mag_squared()
-        self.adder = gr.add_ff()
-
-        moving_sum_taps = [rho/2 for i in range(cp_length)]
-        self.moving_sum_filter = gr.fir_filter_fff(1,moving_sum_taps)
-        
-        self.fg.connect(self.input,self.magsqrd1)
-        self.fg.connect(self.delay,self.magsqrd2)
-        self.fg.connect(self.magsqrd1,(self.adder,0))
-        self.fg.connect(self.magsqrd2,(self.adder,1))
-        self.fg.connect(self.adder,self.moving_sum_filter)
-        
-
-        # Correlation from ML Sync
-        self.conjg = gr.conjugate_cc();
-        self.mixer = gr.multiply_cc();
-
-        movingsum2_taps = [1.0 for i in range(cp_length)]
-        self.movingsum2 = gr.fir_filter_ccf(1,movingsum2_taps)
-        
-        # Correlator data handler
-        self.c2mag = gr.complex_to_mag()
-        self.angle = gr.complex_to_arg()
-        self.fg.connect(self.input,(self.mixer,1))
-        self.fg.connect(self.delay,self.conjg,(self.mixer,0))
-        self.fg.connect(self.mixer,self.movingsum2,self.c2mag)
-        self.fg.connect(self.movingsum2,self.angle)
-
-        # ML Sync output arg, need to find maximum point of this
-        self.diff = gr.sub_ff()
-        self.fg.connect(self.c2mag,(self.diff,0))
-        self.fg.connect(self.moving_sum_filter,(self.diff,1))
-
-        #ML measurements input to sampler block and detect
-        nco_sensitivity = 1.0/fft_length
-        self.f2c = gr.float_to_complex()
-        self.sampler = gr.ofdm_sampler(fft_length,symbol_length)
-        self.pk_detect = gr.peak_detector_fb(0.2, 0.25, 30, 0.0005)
-        self.sample_and_hold = gr.sample_and_hold_ff()
-        self.nco = gr.frequency_modulator_fc(nco_sensitivity)
-        self.inv = gr.multiply_const_ff(-1)
-        self.sigmix = gr.multiply_cc()
-
-        # Mix the signal with an NCO controlled by the sync loop
-        self.fg.connect(self.input, (self.sigmix,0))
-        self.fg.connect(self.nco, (self.sigmix,1))
-        self.fg.connect(self.sigmix, (self.sampler,0))
-
-        # use the sync loop values to set the sampler and the NCO
-        #     self.diff = theta
-        #     self.angle = epsilon
-                          
-        self.fg.connect(self.diff, self.pk_detect)
-        use_dpll = 1
-
-        fixed_timing = 0
-        if fixed_timing:
-            # Use a fixed trigger point instead of sync block
-            peak_null = gr.null_sink(gr.sizeof_char)
-            data = 640*[0,]
-            data[639] = 1
-            peak_trigger = gr.vector_source_b(data, True)
-
-            self.fg.connect(self.pk_detect, peak_null)
-            self.fg.connect(peak_trigger, (self.sampler,1))
-            self.fg.connect(peak_trigger, (self.sample_and_hold,1))
-        else:
-            self.dpll = gr.dpll_bb(float(symbol_length),0.01)
-            if use_dpll:
-                self.fg.connect(self.pk_detect, self.dpll)
-                self.fg.connect(self.dpll, (self.sampler,1))
-                self.fg.connect(self.dpll, (self.sample_and_hold,1))
-            else:
-                self.fg.connect(self.pk_detect, (self.sampler,1))
-                self.fg.connect(self.pk_detect, (self.sample_and_hold,1))
-            
-        self.fg.connect(self.angle, (self.sample_and_hold,0))
-        self.fg.connect(self.sample_and_hold, self.inv, self.nco)
-
-        if 1:
-            self.fg.connect(self.diff, gr.file_sink(gr.sizeof_float, "theta_f.dat"))
-            self.fg.connect(self.angle, gr.file_sink(gr.sizeof_float, "epsilon_f.dat"))
-            if fixed_timing:
-                self.fg.connect(peak_trigger, gr.file_sink(gr.sizeof_char, "peaks_b.dat"))
-            else:
-                self.fg.connect(self.pk_detect, gr.file_sink(gr.sizeof_char, "peaks_b.dat"))
-                if use_dpll:
-                    self.fg.connect(self.dpll, gr.file_sink(gr.sizeof_char, "dpll_b.dat"))
-
-            self.fg.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex, "sigmix_c.dat"))
-            self.fg.connect(self.sampler, gr.file_sink(gr.sizeof_gr_complex*fft_length, "sampler_c.dat"))
-            self.fg.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, "sample_and_hold_f.dat"))
-            self.fg.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex, "nco_c.dat"))
-            self.fg.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, "input_c.dat"))
-
-        gr.hier_block.__init__(self, fg, self.input, self.sampler)
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_fixed.py b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_fixed.py
new file mode 100644
index 0000000000..bd5f4b8707
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_fixed.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+#
+# Copyright 2007 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+import math
+from gnuradio import gr
+
+class ofdm_sync_fixed(gr.hier_block):
+    def __init__(self, fg, fft_length, cp_length, snr):
+        self.fg = fg
+
+        # Use a fixed trigger point instead of sync block
+        data = (fft_length+cp_len)*[0,]
+        data[(fft_length+cp_len)-1] = 1
+        peak_trigger = gr.vector_source_b(data, True)
+        
+        self.fg.connect(peak_trigger, (self.sampler,1))
+
+        if 1:
+            self.fg.connect(self.sampler, gr.file_sink(gr.sizeof_gr_complex*fft_length,
+                                                       "ofdm_sync_fixed-sampler_c.dat"))
+        
+        gr.hier_block.__init__(self, fg, (self.sampler,0), self.sampler)
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_ml.py b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_ml.py
new file mode 100644
index 0000000000..6944cb81c5
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_ml.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python
+#
+# Copyright 2007 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+import math
+from gnuradio import gr
+
+class ofdm_sync_ml(gr.hier_block):
+    def __init__(self, fg, fft_length, cp_length, snr, logging):
+        ''' Maximum Likelihood OFDM synchronizer:
+        J. van de Beek, M. Sandell, and P. O. Borjesson, "ML Estimation
+        of Time and Frequency Offset in OFDM Systems," IEEE Trans.
+        Signal Processing, vol. 45, no. 7, pp. 1800-1805, 1997.
+        '''
+
+        self.fg = fg
+
+        # FIXME: when converting to hier_block2's, the output signature
+        # should be the output of the divider (the normalized peaks) and
+        # the angle value out of the sample and hold block
+
+        self.input = gr.add_const_cc(0)
+
+        SNR = 10.0**(snr/10.0)
+        rho = SNR / (SNR + 1.0)
+        symbol_length = fft_length + cp_length
+
+        # ML Sync
+
+        # Energy Detection from ML Sync
+
+        # Create a delay line
+        self.delay = gr.delay(gr.sizeof_gr_complex, fft_length)
+        self.fg.connect(self.input, self.delay)
+
+        # magnitude squared blocks
+        self.magsqrd1 = gr.complex_to_mag_squared()
+        self.magsqrd2 = gr.complex_to_mag_squared()
+        self.adder = gr.add_ff()
+
+        moving_sum_taps = [rho/2 for i in range(cp_length)]
+        self.moving_sum_filter = gr.fir_filter_fff(1,moving_sum_taps)
+        
+        self.fg.connect(self.input,self.magsqrd1)
+        self.fg.connect(self.delay,self.magsqrd2)
+        self.fg.connect(self.magsqrd1,(self.adder,0))
+        self.fg.connect(self.magsqrd2,(self.adder,1))
+        self.fg.connect(self.adder,self.moving_sum_filter)
+        
+
+        # Correlation from ML Sync
+        self.conjg = gr.conjugate_cc();
+        self.mixer = gr.multiply_cc();
+
+        movingsum2_taps = [1.0 for i in range(cp_length)]
+        self.movingsum2 = gr.fir_filter_ccf(1,movingsum2_taps)
+        
+        # Correlator data handler
+        self.c2mag = gr.complex_to_mag()
+        self.angle = gr.complex_to_arg()
+        self.fg.connect(self.input,(self.mixer,1))
+        self.fg.connect(self.delay,self.conjg,(self.mixer,0))
+        self.fg.connect(self.mixer,self.movingsum2,self.c2mag)
+        self.fg.connect(self.movingsum2,self.angle)
+
+        # ML Sync output arg, need to find maximum point of this
+        self.diff = gr.sub_ff()
+        self.fg.connect(self.c2mag,(self.diff,0))
+        self.fg.connect(self.moving_sum_filter,(self.diff,1))
+
+        #ML measurements input to sampler block and detect
+        nco_sensitivity = -1.0/fft_length
+        self.f2c = gr.float_to_complex()
+        self.sampler = gr.ofdm_sampler(fft_length,symbol_length)
+        self.pk_detect = gr.peak_detector_fb(0.2, 0.25, 30, 0.0005)
+        self.sample_and_hold = gr.sample_and_hold_ff()
+        self.nco = gr.frequency_modulator_fc(nco_sensitivity)
+        self.sigmix = gr.multiply_cc()
+
+        # Mix the signal with an NCO controlled by the sync loop
+        self.fg.connect(self.input, (self.sigmix,0))
+        self.fg.connect(self.nco, (self.sigmix,1))
+        self.fg.connect(self.sigmix, (self.sampler,0))
+
+        # use the sync loop values to set the sampler and the NCO
+        #     self.diff = theta
+        #     self.angle = epsilon
+                          
+        self.fg.connect(self.diff, self.pk_detect)
+
+        use_dpll = 1
+        if use_dpll:
+            self.dpll = gr.dpll_bb(float(symbol_length),0.01)
+            self.fg.connect(self.pk_detect, self.dpll)
+            self.fg.connect(self.dpll, (self.sampler,1))
+            self.fg.connect(self.dpll, (self.sample_and_hold,1))
+        else:
+            self.fg.connect(self.pk_detect, (self.sampler,1))
+            self.fg.connect(self.pk_detect, (self.sample_and_hold,1))
+            
+        self.fg.connect(self.angle, (self.sample_and_hold,0))
+        self.fg.connect(self.sample_and_hold, self.nco)
+
+        if logging:
+            self.fg.connect(self.diff, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-theta_f.dat"))
+            self.fg.connect(self.angle, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-epsilon_f.dat"))
+            self.fg.connect(self.pk_detect, gr.file_sink(gr.sizeof_char, "ofdm_sync_ml-peaks_b.dat"))
+            if use_dpll:
+                self.fg.connect(self.dpll, gr.file_sink(gr.sizeof_char, "ofdm_sync_ml-dpll_b.dat"))
+
+            self.fg.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_ml-sigmix_c.dat"))
+            self.fg.connect(self.sampler, gr.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_sync_ml-sampler_c.dat"))
+            self.fg.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-sample_and_hold_f.dat"))
+            self.fg.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_ml-nco_c.dat"))
+            self.fg.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_ml-input_c.dat"))
+
+        gr.hier_block.__init__(self, fg, self.input, self.sampler)
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pn.py b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pn.py
new file mode 100644
index 0000000000..a49ff84f9c
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pn.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python
+#
+# Copyright 2007 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+import math
+from numpy import fft
+from gnuradio import gr
+
+class ofdm_sync_pn(gr.hier_block):
+    def __init__(self, fg, fft_length, cp_length, logging=False):
+        ''' OFDM synchronization using PN Correlation:
+        T. M. Schmidl and D. C. Cox, "Robust Frequency and Timing
+        Synchonization for OFDM," IEEE Trans. Communications, vol. 45,
+        no. 12, 1997.
+        '''
+        
+        self.fg = fg
+
+        # FIXME: when converting to hier_block2's, the output signature
+        # should be the output of the divider (the normalized peaks) and
+        # the angle value out of the sample and hold block
+            
+        self.input = gr.add_const_cc(0)
+
+        symbol_length = fft_length + cp_length
+
+        # PN Sync
+
+        # Create a delay line
+        self.delay = gr.delay(gr.sizeof_gr_complex, fft_length/2)
+
+        # Correlation from ML Sync
+        self.conjg = gr.conjugate_cc();
+        self.corr = gr.multiply_cc();
+
+        # Create a moving sum filter for the corr output
+        if 1:
+            moving_sum_taps = [1.0 for i in range(fft_length//2)]
+            self.moving_sum_filter = gr.fir_filter_ccf(1,moving_sum_taps)
+        else:
+            moving_sum_taps = [complex(1.0,0.0) for i in range(fft_length//2)]
+            self.moving_sum_filter = gr.fft_filter_ccc(1,moving_sum_taps)
+
+        # Create a moving sum filter for the input
+        self.inputmag2 = gr.complex_to_mag_squared()
+        movingsum2_taps = [1.0 for i in range(fft_length//2)]
+
+        if 1:
+            self.inputmovingsum = gr.fir_filter_fff(1,movingsum2_taps)
+        else:
+            self.inputmovingsum = gr.fft_filter_fff(1,movingsum2_taps)
+
+        self.square = gr.multiply_ff()
+        self.normalize = gr.divide_ff()
+     
+        # Get magnitude (peaks) and angle (phase/freq error)
+        self.c2mag = gr.complex_to_mag_squared()
+        self.angle = gr.complex_to_arg()
+
+        self.sample_and_hold = gr.sample_and_hold_ff()
+
+        # Mix the signal with an NCO controlled by the sync loop
+        nco_sensitivity = -2.0/fft_length
+        self.nco = gr.frequency_modulator_fc(nco_sensitivity)
+        self.sigmix = gr.multiply_cc()
+
+        #ML measurements input to sampler block and detect
+        self.sub1 = gr.add_const_ff(-1)
+        self.pk_detect = gr.peak_detector_fb(0.2, 0.25, 30, 0.0005)
+        self.regen = gr.regenerate_bb(symbol_length)
+
+        self.sampler = gr.ofdm_sampler(fft_length,symbol_length)
+        
+        self.fg.connect(self.input, self.delay)
+        self.fg.connect(self.input, (self.corr,0))
+        self.fg.connect(self.delay, self.conjg)
+        self.fg.connect(self.conjg, (self.corr,1))
+        self.fg.connect(self.corr, self.moving_sum_filter)
+        self.fg.connect(self.moving_sum_filter, self.c2mag)
+        self.fg.connect(self.moving_sum_filter, self.angle)
+        self.fg.connect(self.angle, (self.sample_and_hold,0))
+        self.fg.connect(self.sample_and_hold, self.nco)
+
+        self.fg.connect(self.input, (self.sigmix,0))
+        self.fg.connect(self.nco, (self.sigmix,1))
+        self.fg.connect(self.sigmix, (self.sampler,0))
+
+        self.fg.connect(self.input, self.inputmag2, self.inputmovingsum)
+        self.fg.connect(self.inputmovingsum, (self.square,0))
+        self.fg.connect(self.inputmovingsum, (self.square,1))
+        self.fg.connect(self.square, (self.normalize,1))
+        self.fg.connect(self.c2mag, (self.normalize,0))
+
+        # Create a moving sum filter for the corr output
+        matched_filter_taps = [1.0/cp_length for i in range(cp_length)]
+        self.matched_filter = gr.fir_filter_fff(1,matched_filter_taps)
+        self.fg.connect(self.normalize, self.matched_filter)
+        
+        self.fg.connect(self.matched_filter, self.sub1, self.pk_detect)
+        self.fg.connect(self.pk_detect, self.regen)
+        self.fg.connect(self.regen, (self.sampler,1))
+        self.fg.connect(self.pk_detect, (self.sample_and_hold,1))
+
+
+        if logging:
+            self.fg.connect(self.matched_filter, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-mf_f.dat"))
+            self.fg.connect(self.normalize, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-theta_f.dat"))
+            self.fg.connect(self.angle, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-epsilon_f.dat"))
+            self.fg.connect(self.pk_detect, gr.file_sink(gr.sizeof_char, "ofdm_sync_pn-peaks_b.dat"))
+            self.fg.connect(self.regen, gr.file_sink(gr.sizeof_char, "ofdm_sync_pn-regen_b.dat"))
+            self.fg.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_pn-sigmix_c.dat"))
+            self.fg.connect(self.sampler, gr.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_sync_pn-sampler_c.dat"))
+            self.fg.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-sample_and_hold_f.dat"))
+            self.fg.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_pn-nco_c.dat"))
+            self.fg.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_pn-input_c.dat"))
+
+        gr.hier_block.__init__(self, fg, self.input, self.sampler)
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pnac.py b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pnac.py
new file mode 100644
index 0000000000..833cee57dd
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pnac.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+#
+# Copyright 2007 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+import math
+from numpy import fft
+from gnuradio import gr
+
+class ofdm_sync_pnac(gr.hier_block):
+    def __init__(self, fg, fft_length, cp_length, ks):
+        self.fg = fg
+
+        # FIXME: when converting to hier_block2's, the output signature
+        # should be the output of the divider (the normalized peaks) and
+        # the angle value out of the sample and hold block
+            
+        self.input = gr.add_const_cc(0)
+
+        symbol_length = fft_length + cp_length
+
+        # PN Sync
+
+        # autocorrelate with the known symbol
+        ks = ks[0:fft_length//2]
+        ks.reverse()
+        self.crosscorr_filter = gr.fir_filter_ccc(1, ks)
+        self.fg.connect(self.crosscorr_filter, gr.file_sink(gr.sizeof_gr_complex, "crosscorr.dat"))
+        
+        # Create a delay line
+        self.delay = gr.delay(gr.sizeof_gr_complex, fft_length/2)
+
+        # Correlation from ML Sync
+        self.conjg = gr.conjugate_cc();
+        self.corr = gr.multiply_cc();
+
+        # Create a moving sum filter for the corr output
+        moving_sum_taps = [1.0 for i in range(fft_length//2)]
+        self.moving_sum_filter = gr.fir_filter_ccf(1,moving_sum_taps)
+
+        # Create a moving sum filter for the input
+        self.inputmag2 = gr.complex_to_mag_squared()
+        movingsum2_taps = [1.0 for i in range(fft_length/2)]
+        self.inputmovingsum = gr.fir_filter_fff(1,movingsum2_taps)
+        self.square = gr.multiply_ff()
+        self.normalize = gr.divide_ff()
+     
+        # Get magnitude (peaks) and angle (phase/freq error)
+        self.c2mag = gr.complex_to_mag_squared()
+        self.angle = gr.complex_to_arg()
+
+        self.sample_and_hold = gr.sample_and_hold_ff()
+
+        # Mix the signal with an NCO controlled by the sync loop
+        nco_sensitivity = -1.0/fft_length
+        self.nco = gr.frequency_modulator_fc(nco_sensitivity)
+        self.sigmix = gr.multiply_cc()
+
+        #ML measurements input to sampler block and detect
+        self.sub1 = gr.add_const_ff(-1)
+        self.pk_detect = gr.peak_detector_fb(0.2, 0.25, 30, 0.0005)
+
+        self.sampler = gr.ofdm_sampler(fft_length,symbol_length)
+        
+        self.fg.connect(self.input, self.crosscorr_filter)
+        self.fg.connect(self.crosscorr_filter, self.delay)
+        self.fg.connect(self.crosscorr_filter, (self.corr,0))
+        self.fg.connect(self.delay, self.conjg)
+        self.fg.connect(self.conjg, (self.corr,1))
+        self.fg.connect(self.corr, self.moving_sum_filter)
+        self.fg.connect(self.moving_sum_filter, self.c2mag)
+        self.fg.connect(self.moving_sum_filter, self.angle)
+        self.fg.connect(self.angle, (self.sample_and_hold,0))
+        self.fg.connect(self.sample_and_hold, self.nco)
+
+        self.fg.connect(self.input, (self.sigmix,0))
+        self.fg.connect(self.nco, (self.sigmix,1))
+        self.fg.connect(self.sigmix, (self.sampler,0))
+
+        self.fg.connect(self.input, self.inputmag2, self.inputmovingsum)
+        self.fg.connect(self.inputmovingsum, (self.square,0))
+        self.fg.connect(self.inputmovingsum, (self.square,1))
+        self.fg.connect(self.square, (self.normalize,1))
+        self.fg.connect(self.c2mag, (self.normalize,0))
+        self.fg.connect(self.normalize, self.sub1, self.pk_detect)
+
+        self.fg.connect(self.pk_detect, (self.sampler,1))
+        self.fg.connect(self.pk_detect, (self.sample_and_hold,1))
+            
+
+        if 1:
+            self.fg.connect(self.normalize, gr.file_sink(gr.sizeof_float,
+                                                         "ofdm_sync_pnac-theta_f.dat"))
+            self.fg.connect(self.angle, gr.file_sink(gr.sizeof_float,
+                                                     "ofdm_sync_pnac-epsilon_f.dat"))
+            self.fg.connect(self.pk_detect, gr.file_sink(gr.sizeof_char,
+                                                         "ofdm_sync_pnac-peaks_b.dat"))
+            self.fg.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex,
+                                                      "ofdm_sync_pnac-sigmix_c.dat"))
+            self.fg.connect(self.sampler, gr.file_sink(gr.sizeof_gr_complex*fft_length,
+                                                       "ofdm_sync_pnac-sampler_c.dat"))
+            self.fg.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float,
+                                                               "ofdm_sync_pnac-sample_and_hold_f.dat"))
+            self.fg.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex,
+                                                   "ofdm_sync_pnac-nco_c.dat"))
+            self.fg.connect(self.input, gr.file_sink(gr.sizeof_gr_complex,
+                                                     "ofdm_sync_pnac-input_c.dat"))
+
+        gr.hier_block.__init__(self, fg, self.input, self.sampler)
diff --git a/gnuradio-core/src/python/gnuradio/gr/Makefile.am b/gnuradio-core/src/python/gnuradio/gr/Makefile.am
index dc0e4a8a3d..92b3b66638 100644
--- a/gnuradio-core/src/python/gnuradio/gr/Makefile.am
+++ b/gnuradio-core/src/python/gnuradio/gr/Makefile.am
@@ -80,6 +80,7 @@ noinst_PYTHON = 			\
 	qa_mute.py			\
 	qa_nlog10.py			\
 	qa_noise.py			\
+	qa_ofdm_insert_preamble.py	\
 	qa_packed_to_unpacked.py	\
 	qa_pipe_fittings.py		\
 	qa_pll_carriertracking.py	\
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_ofdm_insert_preamble.py b/gnuradio-core/src/python/gnuradio/gr/qa_ofdm_insert_preamble.py
new file mode 100755
index 0000000000..58edb8298b
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_ofdm_insert_preamble.py
@@ -0,0 +1,179 @@
+#!/usr/bin/env python
+#
+# Copyright 2007 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr, gr_unittest
+from pprint import pprint
+
+class testing (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def helper(self, v0, v1, fft_length, preamble):
+        fg = self.fg
+        src0 = gr.vector_source_c(v0)
+        src1 = gr.vector_source_b(v1)
+        
+        s2v = gr.stream_to_vector(gr.sizeof_gr_complex, fft_length)
+
+        # print "len(v) = %d" % (len(v))
+
+        op = gr.ofdm_insert_preamble(fft_length, preamble)
+
+        v2s = gr.vector_to_stream(gr.sizeof_gr_complex, fft_length)
+        dst0 = gr.vector_sink_c()
+        dst1 = gr.vector_sink_b()
+
+        fg.connect(src0, s2v, (op, 0))
+        fg.connect(src1, (op, 1))
+        fg.connect((op, 0), v2s, dst0)
+        fg.connect((op, 1), dst1)
+
+        fg.run()
+        r0 = dst0.data()
+        r0v = []
+        for i in range(len(r0)//fft_length):
+            r0v.append(r0[i*fft_length:(i+1)*fft_length])
+            
+        r1 = dst1.data()
+        self.assertEqual(len(r0v), len(r1))
+        return (r1, r0v)
+        
+    def check_match(self, actual, expected_list):
+        lst = []
+        map(lambda x: lst.append(x), expected_list)
+        self.assertEqual(actual, lst)
+
+
+    # ----------------------------------------------------------------
+
+    def test_000(self):
+        # no preamble, 1 symbol payloads
+
+        preamble = ()
+        fft_length = 8
+        npayloads = 8
+        v = []
+        p = []
+        for i in range(npayloads):
+            t = fft_length*[(i + i*1j)]
+            p.append(tuple(t))
+            v += t
+
+        p = tuple(p)
+            
+        r = self.helper(v, npayloads*[1], fft_length, preamble)
+        # pprint(r)
+
+        self.assertEqual(r[0], tuple(npayloads*[1]))
+        self.check_match(r[1], (p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]))
+            
+
+    def test_001(self):
+        # 1 symbol preamble, 1 symbol payloads
+        preamble = ((100, 101, 102, 103, 104, 105, 106, 107),)
+        p0 = preamble[0]
+        fft_length = 8
+        npayloads = 8
+        v = []
+        p = []
+        for i in range(npayloads):
+            t = fft_length*[(i + i*1j)]
+            p.append(tuple(t))
+            v += t
+
+        
+        r = self.helper(v, npayloads*[1], fft_length, preamble)
+
+        self.assertEqual(r[0], tuple(npayloads*[1, 0]))
+        self.check_match(r[1], (p0, p[0],
+                                p0, p[1],
+                                p0, p[2],
+                                p0, p[3],
+                                p0, p[4],
+                                p0, p[5],
+                                p0, p[6],
+                                p0, p[7]))
+
+    def test_002(self):
+        # 2 symbol preamble, 1 symbol payloads
+        preamble = ((100, 101, 102, 103, 104, 105, 106, 107),
+                    (200, 201, 202, 203, 204, 205, 206, 207))
+        p0 = preamble[0]
+        p1 = preamble[1]
+
+        fft_length = 8
+        npayloads = 8
+        v = []
+        p = []
+        for i in range(npayloads):
+            t = fft_length*[(i + i*1j)]
+            p.append(tuple(t))
+            v += t
+        
+        r = self.helper(v, npayloads*[1], fft_length, preamble)
+
+        self.assertEqual(r[0], tuple(npayloads*[1, 0, 0]))
+        self.check_match(r[1], (p0, p1, p[0],
+                                p0, p1, p[1],
+                                p0, p1, p[2],
+                                p0, p1, p[3],
+                                p0, p1, p[4],
+                                p0, p1, p[5],
+                                p0, p1, p[6],
+                                p0, p1, p[7]))
+
+
+    def xtest_003_preamble(self):
+        # 2 symbol preamble, 2 symbol payloads
+        preamble = ((100, 101, 102, 103, 104, 105, 106, 107),
+                    (200, 201, 202, 203, 204, 205, 206, 207))
+        p0 = preamble[0]
+        p1 = preamble[1]
+
+        fft_length = 8
+        npayloads = 8
+        v = []
+        p = []
+        for i in range(npayloads * 2):
+            t = fft_length*[(i + i*1j)]
+            p.append(tuple(t))
+            v += t
+        
+        r = self.helper(v, npayloads*[1, 0], fft_length, preamble)
+
+        self.assertEqual(r[0], tuple(npayloads*[1, 0, 0, 0]))
+        self.check_match(r[1], (p0, p1, p[0],  p[1],
+                                p0, p1, p[2],  p[3],
+                                p0, p1, p[4],  p[5],
+                                p0, p1, p[6],  p[7],
+                                p0, p1, p[8],  p[9],
+                                p0, p1, p[10], p[11],
+                                p0, p1, p[12], p[13],
+                                p0, p1, p[14], p[15]))
+
+
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gnuradio-core/src/python/gnuradio/ofdm_packet_utils.py b/gnuradio-core/src/python/gnuradio/ofdm_packet_utils.py
index 006ca6de28..463284d616 100644
--- a/gnuradio-core/src/python/gnuradio/ofdm_packet_utils.py
+++ b/gnuradio-core/src/python/gnuradio/ofdm_packet_utils.py
@@ -96,7 +96,7 @@ def make_header(payload_len, whitener_offset=0):
     return struct.pack('!HH', val, val)
 
 def make_packet(payload, samples_per_symbol, bits_per_symbol,
-                pad_for_usrp=True, whitener_offset=0, dowhiten=1):
+                pad_for_usrp=True, whitener_offset=0, whitening=True):
     """
     Build a packet, given access code, payload, and whitener offset
 
@@ -106,10 +106,13 @@ def make_packet(payload, samples_per_symbol, bits_per_symbol,
     @param bits_per_symbol:       (needed for padding calculation)
     @type bits_per_symbol:        int
     @param whitener_offset        offset into whitener string to use [0-16)
+    @param whitening:             Turn whitener on or off
+    @type whitening:              bool
     
     Packet will have access code at the beginning, followed by length, payload
     and finally CRC-32.
     """
+
     if not whitener_offset >=0 and whitener_offset < 16:
         raise ValueError, "whitener_offset must be between 0 and 15, inclusive (%i)" % (whitener_offset,)
 
@@ -129,7 +132,7 @@ def make_packet(payload, samples_per_symbol, bits_per_symbol,
         usrp_packing = _npadding_bytes(packet_length, samples_per_symbol, bits_per_symbol) * '\x55'
         pkt_dt = pkt_dt + usrp_packing
 
-    if(dowhiten):
+    if(whitening):
         pkt = pkt_hd + whiten(pkt_dt, whitener_offset)
     else:
         pkt = pkt_hd + pkt_dt
@@ -147,8 +150,10 @@ def _npadding_bytes(pkt_byte_len, samples_per_symbol, bits_per_symbol):
     is a multiple of 128 samples.
 
     @param ptk_byte_len: len in bytes of packet, not including padding.
-    @param samples_per_symbol: samples per bit (1 bit / symbolwith GMSK)
+    @param samples_per_symbol: samples per bit (1 bit / symbolwidth GMSK)
     @type samples_per_symbol: int
+    @param bits_per_symbol: bits per symbol (log2(modulation order))
+    @type bits_per_symbol: int
 
     @returns number of bytes of padding to append.
     """
@@ -160,13 +165,17 @@ def _npadding_bytes(pkt_byte_len, samples_per_symbol, bits_per_symbol):
     return byte_modulus - r
     
 
-def unmake_packet(whitened_payload_with_crc, whitener_offset=0, dodewhiten=1):
+def unmake_packet(whitened_payload_with_crc, whitener_offset=0, dewhitening=1):
     """
     Return (ok, payload)
 
     @param whitened_payload_with_crc: string
+    @param whitener_offset        offset into whitener string to use [0-16)
+    @param dewhitening:           Turn whitener on or off
+    @type  dewhitening:           bool
     """
-    if dodewhiten:
+
+    if dewhitening:
         payload_with_crc = dewhiten(whitened_payload_with_crc, whitener_offset)
     else:
         payload_with_crc = whitened_payload_with_crc
diff --git a/gnuradio-core/src/python/gnuradio/packet_utils.py b/gnuradio-core/src/python/gnuradio/packet_utils.py
index e4de621337..dad050c8d3 100644
--- a/gnuradio-core/src/python/gnuradio/packet_utils.py
+++ b/gnuradio-core/src/python/gnuradio/packet_utils.py
@@ -157,8 +157,10 @@ def _npadding_bytes(pkt_byte_len, samples_per_symbol, bits_per_symbol):
     is a multiple of 128 samples.
 
     @param ptk_byte_len: len in bytes of packet, not including padding.
-    @param samples_per_symbol: samples per bit (1 bit / symbolwith GMSK)
+    @param samples_per_symbol: samples per bit (1 bit / symbolwidth GMSK)
     @type samples_per_symbol: int
+    @param bits_per_symbol: bits per symbol (log2(modulation order))
+    @type bits_per_symbol: int
 
     @returns number of bytes of padding to append.
     """
-- 
cgit v1.2.3