Java solution, O(1) space, beat 98%
Using  double linked list and a mid node pointer.\nThe hardest part is moving mid pointer correctly.\nA flaw is there is a corner case in the code when excatly 
Using  double linked list and a mid node pointer.\nThe hardest part is moving mid pointer correctly.\nA flaw is there is a corner case in the code when excatly one node exists.\n\n```\nclass FrontMiddleBackQueue {\n    static class Node {\n        Node prev, next;\n        int val;\n        \n        public Node(int val) {\n            this.val = val;\n        }\n    }\n    \n    Node head, mid, tail;\n    int size = 0;\n    \n    public FrontMiddleBackQueue() {\n        head = new Node(-1);\n        tail = new Node(-1);\n        head.next = tail;\n        tail.prev = head;\n        mid = head;\n    }\n    \n    public void pushFront(int val) {\n        Node node = new Node(val);\n        node.next = head.next;\n        node.prev = head;\n        head.next.prev = node;\n        head.next = node;\n        if (++size == 1) mid = node;\n        else if (size % 2 == 0) mid = mid.prev;\n    }\n    \n    public void pushMiddle(int val) {\n        Node node = new Node(val);\n        Node tempMid = mid;\n        if (size++ % 2 == 1) {\n            tempMid = mid.prev;\n        }\n        node.next = tempMid.next;\n        node.prev = tempMid;\n        tempMid.next.prev = node;\n        tempMid.next = node;\n        \n        mid = node;\n    }\n    \n    public void pushBack(int val) {\n        Node node = new Node(val);\n        node.prev = tail.prev;\n        node.next = tail;\n        tail.prev.next = node;\n        tail.prev = node;\n        if (++size == 1) mid = node;\n        else if (size % 2 == 1) mid = mid.next;\n    }\n    \n    private void moveForwards() {\n        if (++size % 2 == 1) {\n            mid = mid.next;\n        }\n    }\n    \n    public int popFront() {\n        if (head.next == tail) return -1;\n        if (--size == 0) mid = head;\n        else if (size % 2 == 1) mid = mid.next;\n        \n        Node node = head.next;\n        int val = node.val;\n        head.next = node.next;\n        node.next.prev = head;\n        node.next = null;\n        node.prev = null;\n        \n        return val;\n    }\n    \n    public int popMiddle() {\n        if (head.next == tail) return -1;\n        Node node = mid;\n        if (size-- % 2 == 1) mid = mid.prev;\n        else mid = mid.next;\n        \n        int val = node.val;\n        node.next.prev = node.prev;\n        node.prev.next = node.next;\n        node.next = null;\n        node.prev = null;\n        \n        return val;\n    }\n    \n    public int popBack() {\n        if (head.next == tail) return -1;\n        if (--size == 0) mid = head;\n        else if (size % 2 == 0) mid = mid.prev;\n        \n        Node node = tail.prev;\n        int val = node.val;\n        \n        tail.prev = node.prev;\n        node.prev.next = tail;\n        node.next = null;\n        node.prev = null;\n        \n        return val;\n    }\n}\n\n```
[]