Edit in JSFiddle

ko.bindingHandlers.flash = {
    init: function(element) {
        $(element).hide();
    },
    update: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        if (value) {
            $(element).stop().hide().text(value).fadeIn(function() {
                clearTimeout($(element).data("timeout"));
                $(element).data("timeout", setTimeout(function() {
                    $(element).fadeOut();
                    valueAccessor()(null);
                }, 3000));
            });
        }
    },
    timeout: null
};

var Student = function(id, name, gender) {
    this.id = id;
    this.name = ko.observable(name);
    this.gender = gender;
};

var Table = function(id, students) {
    this.students = ko.observableArray(students);
    this.students.id = id;
};

var SeatingChartModel = function(tables, availableStudents) {
    var self = this;
    this.tables = ko.observableArray(tables);
    this.availableStudents = ko.observableArray(availableStudents);
    this.availableStudents.id = "Available Students";
    this.lastAction = ko.observable();
    this.lastError = ko.observable();
    this.maximumStudents = 4;
    this.isTableFull = function(parent) {
        return parent().length < self.maximumStudents;
    };

    this.updateLastAction = function(arg) {
        self.lastAction("Moved " + arg.item.name() + " from " + arg.sourceParent.id + " (seat " + (arg.sourceIndex + 1) + ") to " + arg.targetParent.id + " (seat " + (arg.targetIndex + 1) + ")");
    };

    //verify that if a fourth member is added, there is at least one member of each gender
    this.verifyAssignments = function(arg) {
        var gender, found,
            parent = arg.targetParent;

        if (parent.id !== "Available Students" && parent().length === 3 && parent.indexOf(arg.item) < 0) {
            gender = arg.item.gender;
            if (!ko.utils.arrayFirst(parent(), function(student) { return student.gender !== gender;})) {
                self.lastError("Cannot move " + arg.item.name() + " to " + arg.targetParent.id + " because there would be too many " + gender + " students");
                arg.cancelDrop = true;
            }
        }
    };
};

var extraStudents = [
    new Student(16, "Parker", "male"),
    new Student(17, "Dennis", "male"),
    new Student(18, "Angel", "female")
];

var initialTables = [
    new Table("Table One",  [
        new Student(1, "Bobby", "male"),
        new Student(2, "Ted", "male"),
        new Student(3, "Jim", "male")
    ]),
    new Table("Table Two", [
        new Student(4, "Michelle", "female"),
        new Student(5, "Erin", "female"),
        new Student(6, "Chase", "male")
    ]),
    new Table("Table Three", [
        new Student(7, "Denise", "female"),
        new Student(8, "Chip", "male"),
        new Student(9, "Kylie", "female")
    ]),
    new Table("Table Four", [
        new Student(10, "Cheryl", "female"),
        new Student(11, "Doug", "male"),
        new Student(12, "Connor", "male")
    ]),
    new Table("Table Five", [
        new Student(13, "Cody", "male"),
        new Student(14, "Farrah", "female"),
        new Student(15, "Lyla", "female")
    ])
];

var vm = new SeatingChartModel(initialTables, extraStudents);

ko.bindingHandlers.sortable.beforeMove = vm.verifyAssignments;
ko.bindingHandlers.sortable.afterMove = vm.updateLastAction;

ko.applyBindings(vm);
<div>Seating Assignments</div>
<div class="note">Rules: no more than 4 students per table. Must have at least one student of each gender at a full table.</div>
<div id="main" data-bind="foreach: tables">
    <div class="table">
        <span data-bind="text: students.id"></span>
        <div class="seats" data-bind="sortable: { data: students, allowDrop: $root.isTableFull }">
            <div class="student" data-bind="text: name"></div>
        </div>
        <div class="count" data-bind="text: students().length + '/' + $root.maximumStudents, css: { ready: students().length < $root.maximumStudents }"></div>
    </div>
</div>

<div id="extra">
    <div>Available Students</div>
    <div class="new" data-bind="sortable: availableStudents">
        <div class="student" data-bind="text: name"></div>
    </div>
</div>

<div id="message" data-bind="flash: lastAction"></div>
<div id="error" data-bind="flash: lastError"></div>

<div id="master">
    <div>Master List</div>
    <table>
        <tr>
            <th></th>
            <th>Seat One</th>
            <th>Seat Two</th>
            <th>Seat Three</th>
            <th>Seat Four</th>
        </tr>
        <tbody data-bind="foreach: tables">
            <tr>
                <th data-bind="text: students.id"></th>
                <!-- ko foreach: students -->
                <td data-bind="text: name"></td>
                <!-- /ko -->
            </tr>
        </tbody>
        <tr>
            <th>Available</th>
            <!-- ko foreach: availableStudents -->
            <td data-bind="text: name"></td>
            <!-- /ko -->
        </tr>
    </table>
</div>
body {
    font-family: arial;
}

.table {
    float: left;
    text-align: center;
    margin-right: 5px;
}

.table span {
    font-size: .75em;
}

.seats {
    border: solid 3px #666;
    width: 75px;
    height: 100px;
    background-color: #666;
    margin: 5px;
    padding: 2px;
    border-radius: 5px;
    box-shadow: 2px 2px 2px #999;
}

.ko_container {
    border: solid 3px green;
}

.student {
    background-color: #444;
    color: #fff;
    border-radius: 3px;
    margin: 2px;
    padding: 1px;
    text-align: center;
    width: 70px;
    cursor: move;
}

.new {
    border: solid 1px #444;
    background-color: #ccc;
    height: 25px;
    width: 500px;
    padding: 2px;
    border-radius: 5px;
}

.new div {
    float: left;
}

.note {
    font-style: italic;
    font-size: .75em;
    color: #888;
    margin-bottom: 10px;
}

.count {
    color: #666;
}

.ready {
    color: green;
}

#extra {
    clear: both;
    padding-top: 20px;
}

#master {
    margin-top: 40px;
}


#master td, th {
    font-size: .75em;
    text-align: center;
    padding: 1px;
    border: solid 1px black;
}

#master th {
    color: #666;
}

#message, #error {
    font-size: .75em;
    margin-top: 10px;
    background-color: orange;
    color: #444;
    padding: 2px;
    width: 500px;
    text-align: center;
    border-radius: 5px;
    box-shadow: 2px 2px 2px #999;
    position: absolute;
}

#error {
    background-color: #ff3333;
    color: #ddd;
}