Give this a try...got a few extra things in as well
Code:
 on *:start: {
  hmake qcount 10
  if $exists(qcount.hsh) { .hload qcount qcount.hsh }
}
alias queryfilter {
  if (!$1) || ($1 != $group(#queryfilter).status) {
    $iif($group(#queryfilter) == off,.enable,.disable) #queryfilter
    echo -a $iif($group(#queryfilter) == off,stopping query filter,starting query filter)
  }
  else echo -a Query filter is $group(#queryfilter).status
}
menu * {
  queryfilter
  .on : queryfilter on
  .off : queryfilter off
}
menu nicklist {
  Query Approval
  .add : .approved add
  .del : .approved del
}
alias approved {
  if $1 == add {
    var %a = 1
    while %a <= $snick(#ftres,0) {
      .hadd -m qcount $+(Approved.,$snick(#ftres,%a)) $snick(#ftres,%a)
      inc %a
    }
  }
  elseif $1 == del {
    var %a = 1
    while %a <= $snick(#ftres,0) {
      hdel qcount $+(Approved.,$snick(#ftres,%a))
      inc %a
    }
  }
}

#queryfilter off
on ^*:open:?:*: {
  if ($nick isop #ftres) || ($nick isvoice #ftres) { msg $nick sup7 $nick }
  elseif ($me isop #ftres) && ($hget(qcount,$address($nick,3)) > 1 ) {
    .hinc -m qcount $address($nick,3)
    .ban -ku $+ $calc(60 * $hget(qcount,$address($nick,3))) $nick 3 Couldn't read... could ya
  }
  elseif $hget(qcount,$+(Approved.,$address($nick,3))) {
    .msg $nick $read(Approval.txt)
  }
  else {
    .hinc -m qcount $address($nick,3)
    .msg $nick Don't msg ops/voices without permission. Repeat violators will be 4kicked/banned.
    .timer 1 4 msg $nick Did you get that?
  }
}
#queryfilter end
on *:EXIT: {
  .hsave -o qcount qcount.hsh
}
on *:disconnect: {
  .hsave -o qcount qcount.hsh
}
 


Query filter can now be turned on/off using /queryfilter or via the menu option. If the filter is already on/off and you go to turn it on/off, it'll tell you that it's already on/off

combined kick & mode +b command lines into .ban line
removed -m from timer, as using a millisecond timer makes no sense for a 4 second timer....easier on resources also

kick/ban times are now dependent on the number of times kick/banned starting at 2 minutes and increasing by a minute each time

removed the hfree command in the ON EXIT, as the table would be freed automatically, and added a ON DISCONNECT event.

saved file is looked for on start, and if found, loaded into the hash table.