diff --git a/mm.c b/mm.c
index 20f2d3bffc0ae6e1eb1f3e6998e36cd8d7647d72..7eb6cc32fb3c71a9610831d8f826a729533ba94f 100644
--- a/mm.c
+++ b/mm.c
@@ -52,39 +52,51 @@ team_t team = {
 #define WSIZE       4       /* word size (bytes) */  
 #define DSIZE       8       /* doubleword size (bytes) */
 #define CHUNKSIZE  (1<<12)  /* initial heap size (bytes) */
-#define OVERHEAD    4       /* overhead of header (bytes) */
+#define OVERHEAD    8       /* overhead of headers (bytes) */
 
-#define MAX(x, y) ((x) > (y)? (x) : (y))  
+#define MAX(x, y)		((x) > (y)? (x) : (y))  
 
 /* Pack a size and allocated bit into a word */
-#define PACK(size, alloc)  ((size) | (alloc))
+#define PACK(size, alloc)	((size) | (alloc))
 
 /* Read and write a word at address p */
-#define GET(p)       (*(size_t *)(p))
-#define PUT(p, val)  (*(size_t *)(p) = (val))  
+#define GET(p)			(*(size_t *)(p))
+#define PUT(p, val)		(*(size_t *)(p) = (val))  
 
 /* Read the size and allocated fields from address p */
-#define GET_SIZE(p)  (GET(p) & ~0x7)
-#define GET_ALLOC(p) (GET(p) & 0x1)
+#define GET_SIZE(p)		(GET(p) & ~0x7)
+#define GET_ALLOC(p)	(GET(p) & 0x1)
 
-/* Given block ptr bp, compute address of its header*/
-#define HDRP(bp)       ((char *)(bp) - WSIZE)  
+/* Given block ptr bp, compute address of its header and footer*/
+#define HDRP(bp)		((char *)(bp) - WSIZE)
+#define FTRP(bp)		((char *)(bp) + GET_SIZE(HDRP(bp)) - DSIZE)
 
-/* Given block ptr bp, compute address of next block */
-#define NEXT_BLKP(bp)  ((char *)(bp) + GET_SIZE(((char*)(bp) - WSIZE)))
+/* Given block ptr bp, compute address of next and prev blocks */
+#define NEXT_BLKP(bp)	((char *)(bp) + GET_SIZE((char *)(bp) - WSIZE))
+#define PREV_BLKP(bp)	((char *)(bp) - GET_SIZE((char *)(bp) - DSIZE))
 
 /* $end mallocmacros */
 
 
 /* Global variables */
 static char *heap_listp;  /* pointer to first block */  
+// static char *free_listp;  /* pointer to free list */
+
+// typedef struct Node
+// {
+// 	char * prev;
+// 	char * next;
+// }Node;
+
+
+
 
 /* function prototypes for internal helper routines */
 static void *extend_heap(size_t words);
 static void place(void *bp, size_t asize);
 static void *find_fit(size_t asize);
 static void printblock(void *bp);
-static void mm_coalesce(void *bp);
+static int mm_coalesce(void *bp);
 static void mm_memcpy(void * dest, void * src);
 
 /* 
@@ -161,22 +173,26 @@ void *mm_malloc(size_t size)
 /* 
  * mm_free - Free a block 
  * 
- * Given the alloced bit is set, get header and increment by 1
- * since that essentially sets the bit to 1 or free, else print
- * error to stderr.
+ * Given the alloced bit is set, tries to coalesce which
+ * frees be default, else OR's header and footer with 1,
+ * else print error to stderr.
  */
 /* $begin mmfree */
 void mm_free(void *bp)
 {
 	if(bp == NULL){
 		fprintf(stderr, "Error: memory not alloced or corrupted");
+		return;
 	}
 
 	if(!GET_ALLOC(HDRP(bp))){
-		*HDRP(bp) |= 1;
-		mm_coalesce(bp);
+		if(mm_coalesce(bp)){
+			*HDRP(bp) |= 1;
+			*FTRP(bp) |= 1;
+		}
 	} else {
 		fprintf(stderr, "Error: memory not alloced or corrupted");
+		return;
 	}
 	mm_checkheap(0);
 		
@@ -190,34 +206,32 @@ void mm_free(void *bp)
  * Given a block pointer that has been freed, find empty
  * blocks near it to be combined into a large free chunk.
  * 
+ * Returns 0 on success, 1 on failure
+ * 
  */
-static void mm_coalesce(void *bp)
+static int mm_coalesce(void *bp)
 {	
-	//find previous block
-	char * prev;
-	for (prev = heap_listp; GET_SIZE(prev-WSIZE) > 0; prev = NEXT_BLKP(prev)) {
-		if (NEXT_BLKP(prev) == bp) {
-	    	break;
-		}
-    }
-
 	size_t nextBlock = GET_ALLOC(HDRP(NEXT_BLKP(bp)));
-	size_t prevBlock = GET_ALLOC(HDRP(prev));
+	size_t prevBlock = GET_ALLOC(HDRP(PREV_BLKP(bp)));
 	size_t size = GET_SIZE(HDRP(bp));
 
 	if(prevBlock && nextBlock){
-		size += GET_SIZE(HDRP(prev)) + GET_SIZE(HDRP(NEXT_BLKP(bp)));
-		PUT(HDRP(prev), PACK(size, 1));
-		return;
+		size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(HDRP(NEXT_BLKP(bp)));
+		PUT(HDRP(PREV_BLKP(bp)), PACK(size, 1));
+		PUT(FTRP(PREV_BLKP(bp)), PACK(size, 1));
+		return 0;
 	} else if(prevBlock && !nextBlock){
-		size += GET_SIZE(HDRP(prev));
-		PUT(HDRP(prev), PACK(size, 1));
-		return;
+		size += GET_SIZE(HDRP(PREV_BLKP(bp)));
+		PUT(HDRP(PREV_BLKP(bp)), PACK(size, 1));
+		PUT(FTRP(PREV_BLKP(bp)), PACK(size, 1));
+		return 0;
 	} else if(!prevBlock && nextBlock){
 		size += GET_SIZE(HDRP(NEXT_BLKP(bp)));
 		PUT(HDRP(bp), PACK(size, 1));
-		return;
+		PUT(FTRP(bp), PACK(size, 1));
+		return 0;
 	}
+	return 1;
 }
 
 /*
@@ -274,11 +288,14 @@ void *mm_realloc(void *ptr, size_t size)
 			if(size < oldSize) {
 				if ((oldSize - size) >= DSIZE) {
 					PUT(HDRP(ptr), PACK(size, 0));
+					PUT(FTRP(ptr), PACK(size, 0));
 					PUT(HDRP(NEXT_BLKP(ptr)), PACK(oldSize-size, 1));
+					PUT(FTRP(NEXT_BLKP(ptr)), PACK(oldSize-size, 1));
 					mm_coalesce(NEXT_BLKP(ptr));
 				}
 				else { 
 					PUT(HDRP(ptr), PACK(oldSize, 0));
+					PUT(FTRP(ptr), PACK(oldSize, 0));
 				}
 				return ptr;
 			}
@@ -289,11 +306,14 @@ void *mm_realloc(void *ptr, size_t size)
 				if(GET_ALLOC(HDRP(NEXT_BLKP(ptr))) && nextSize >= size){
 					if ((nextSize - size) >= DSIZE) {
 						PUT(HDRP(ptr), PACK(size, 0));
+						PUT(FTRP(ptr), PACK(size, 0));
 						PUT(HDRP(NEXT_BLKP(ptr)), PACK(nextSize-size, 1));
+						PUT(FTRP(NEXT_BLKP(ptr)), PACK(nextSize-size, 1));
 						mm_coalesce(NEXT_BLKP(ptr));
 					}
 					else { 
 						PUT(HDRP(ptr), PACK(nextSize, 0));
+						PUT(FTRP(ptr), PACK(nextSize, 0));
 					}
 					
 					return ptr;
@@ -390,11 +410,14 @@ static void place(void *bp, size_t asize)
 
 	if ((csize - asize) >= (DSIZE)) {
 		PUT(HDRP(bp), PACK(asize, 0));
+		PUT(FTRP(bp), PACK(asize, 0));
 		bp = NEXT_BLKP(bp);
 		PUT(HDRP(bp), PACK(csize-asize, 1));
+		PUT(FTRP(bp), PACK(csize-asize, 1));
 	}
 	else { 
 		PUT(HDRP(bp), PACK(csize, 0));
+		PUT(FTRP(bp), PACK(csize, 0));
 	}
 }
 /* $end mmplace */