minor modification, will be rewritted